aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-06 14:10:10 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-11-02 16:43:11 -0500
commit5001367cbca3b456501ec5cd80032ece388cccca (patch)
tree5967e916ed9d38e9396bbd0fce9e68c9d639ccc4 /src
parent5163a1a307b920b5ba4bc26131536f97546c7052 (diff)
Remove fallback code with selector completions (requires odin parser changes)
Diffstat (limited to 'src')
-rw-r--r--src/server/completion.odin25
-rw-r--r--src/server/position_context.odin237
-rw-r--r--src/server/signature.odin8
3 files changed, 13 insertions, 257 deletions
diff --git a/src/server/completion.odin b/src/server/completion.odin
index f3c0d56..ae14d4e 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -98,6 +98,8 @@ get_completion_list :: proc(
if !position_in_node(selector_call.call, position_context.position) {
completion_type = .Selector
}
+ } else if selector, ok := position_context.selector_expr.derived.(^ast.Selector_Expr); ok {
+ completion_type = .Selector
}
} else if _, ok := position_context.selector.derived.(^ast.Implicit_Selector_Expr); !ok {
// variadic args seem to work by setting it as an implicit selector expr, in that case
@@ -1017,23 +1019,18 @@ get_selector_completion :: proc(
if symbol, ok := resolve_type_expression(ast_context, v.types[i]); ok {
if expr, ok := position_context.selector.derived.(^ast.Selector_Expr); ok {
- if expr.op.text == "->" && symbol.type != .Function {
- continue
- }
- }
-
- if position_context.arrow {
- if symbol.type != .Function && symbol.type != .Type_Function {
- continue
- }
- if .ObjCIsClassMethod in symbol.flags {
- assert(.ObjC in symbol.flags)
+ if expr.op.kind == .Arrow_Right {
+ if symbol.type != .Function && symbol.type != .Type_Function {
+ continue
+ }
+ if .ObjCIsClassMethod in symbol.flags {
+ assert(.ObjC in symbol.flags)
+ continue
+ }
+ } else if .ObjC in selector.flags {
continue
}
}
- if !position_context.arrow && .ObjC in selector.flags {
- continue
- }
construct_struct_field_symbol(&symbol, selector.name, v, i)
append(results, CompletionResult{symbol = symbol})
diff --git a/src/server/position_context.odin b/src/server/position_context.odin
index 1aa2ec1..5c74b9c 100644
--- a/src/server/position_context.odin
+++ b/src/server/position_context.odin
@@ -4,7 +4,6 @@ import "core:log"
import "core:odin/ast"
import "core:odin/parser"
import "core:odin/tokenizer"
-import "core:strings"
import "core:unicode/utf8"
import "src:common"
@@ -140,10 +139,6 @@ get_document_position_context :: proc(
position_context.parent_binary = nil
}
- if hint == .Completion && position_context.selector == nil && position_context.field == nil {
- fallback_position_context_completion(document, position, &position_context)
- }
-
if (hint == .SignatureHelp || hint == .Completion) && position_context.call == nil {
fallback_position_context_signature(document, position, &position_context)
}
@@ -155,235 +150,6 @@ get_document_position_context :: proc(
return position_context, true
}
-//terrible fallback code
-fallback_position_context_completion :: proc(
- document: ^Document,
- position: common.Position,
- position_context: ^DocumentPositionContext,
-) {
- paren_count: int
- bracket_count: int
- end: int
- start: int
- empty_dot: bool
- empty_arrow: bool
- last_dot: bool
- last_arrow: bool
- dots_seen: int
- partial_arrow: bool
-
- i := position_context.position - 1
-
- end = i
-
- for i > 0 {
- c := position_context.file.src[i]
-
- if c == '(' && paren_count == 0 {
- start = i + 1
- break
- } else if c == '[' && bracket_count == 0 {
- start = i + 1
- break
- } else if c == ']' && !last_dot && !last_arrow {
- start = i + 1
- break
- } else if c == ')' && !last_dot && !last_arrow {
- start = i + 1
- break
- } else if c == ')' {
- paren_count -= 1
- } else if c == '(' {
- paren_count += 1
- } else if c == '[' {
- bracket_count += 1
- } else if c == ']' {
- bracket_count -= 1
- } else if c == '.' {
- dots_seen += 1
- last_dot = true
- i -= 1
- continue
- } else if position_context.file.src[max(0, i - 1)] == '-' && c == '>' {
- last_arrow = true
- i -= 2
- continue
- }
-
- //ignore everything in the bracket
- if bracket_count != 0 || paren_count != 0 {
- i -= 1
- continue
- }
-
- //yeah..
- if c == ' ' ||
- c == '{' ||
- c == ',' ||
- c == '}' ||
- c == '^' ||
- c == ':' ||
- c == '\n' ||
- c == '\r' ||
- c == '\t' ||
- c == '=' ||
- c == '<' ||
- c == '-' ||
- c == '!' ||
- c == '+' ||
- c == '&' ||
- c == '|' {
- start = i + 1
- break
- } else if c == '>' {
- partial_arrow = true
- }
-
- last_dot = false
- last_arrow = false
-
- i -= 1
- }
-
- if i >= 0 && position_context.file.src[end] == '.' {
- empty_dot = true
- end -= 1
- } else if i >= 0 && position_context.file.src[max(0, end - 1)] == '-' && position_context.file.src[end] == '>' {
- empty_arrow = true
- end -= 2
- position_context.arrow = true
- }
-
- begin_offset := max(0, start)
- end_offset := max(start, end + 1)
- line_offset := begin_offset
-
- if line_offset < len(position_context.file.src) {
- for line_offset > 0 {
- c := position_context.file.src[line_offset]
- if c == '\n' || c == '\r' {
- line_offset += 1
- break
- }
- line_offset -= 1
- }
- }
-
- str := position_context.file.src[0:end_offset]
-
- if empty_dot && end_offset - begin_offset == 0 {
- position_context.implicit = true
- return
- }
-
- s := string(position_context.file.src[begin_offset:end_offset])
-
- if !partial_arrow {
- only_whitespaces := true
-
- for r in s {
- if !strings.is_space(r) {
- only_whitespaces = false
- }
- }
-
- if only_whitespaces {
- return
- }
- }
-
- p := parser.Parser {
- err = common.parser_warning_handler, //empty
- warn = common.parser_warning_handler, //empty
- flags = {.Optional_Semicolons},
- file = &position_context.file,
- }
-
- tokenizer.init(&p.tok, str, position_context.file.fullpath, common.parser_warning_handler)
-
- p.tok.ch = ' '
- p.tok.line_count = position.line + 1
- p.tok.line_offset = line_offset
- p.tok.offset = begin_offset
- p.tok.read_offset = begin_offset
-
- tokenizer.advance_rune(&p.tok)
-
- if p.tok.ch == utf8.RUNE_BOM {
- tokenizer.advance_rune(&p.tok)
- }
-
- parser.advance_token(&p)
-
- context.allocator = context.temp_allocator
-
- e := parser.parse_expr(&p, true)
-
- if empty_dot || empty_arrow {
- position_context.selector = e
- } else if s, ok := e.derived.(^ast.Selector_Expr); ok {
- position_context.selector = s.expr
- position_context.field = s.field
- } else if s, ok := e.derived.(^ast.Implicit_Selector_Expr); ok {
- position_context.implicit = true
- position_context.implicit_selector_expr = s
- } else if s, ok := e.derived.(^ast.Tag_Expr); ok {
- position_context.tag = s.expr
- } else if bad_expr, ok := e.derived.(^ast.Bad_Expr); ok {
- //this is most likely because of use of 'in', 'context', etc.
- //try to go back one dot.
-
- src_with_dot := string(position_context.file.src[0:min(len(position_context.file.src), end_offset + 1)])
- last_dot := strings.last_index(src_with_dot, ".")
-
- if last_dot == -1 {
- return
- }
-
- tokenizer.init(
- &p.tok,
- position_context.file.src[0:last_dot],
- position_context.file.fullpath,
- common.parser_warning_handler,
- )
-
- p.tok.ch = ' '
- p.tok.line_count = position.line + 1
- p.tok.line_offset = line_offset
- p.tok.offset = begin_offset
- p.tok.read_offset = begin_offset
-
- tokenizer.advance_rune(&p.tok)
-
- if p.tok.ch == utf8.RUNE_BOM {
- tokenizer.advance_rune(&p.tok)
- }
-
- parser.advance_token(&p)
-
- e := parser.parse_expr(&p, true)
-
- if e == nil {
- position_context.abort_completion = true
- return
- } else if e, ok := e.derived.(^ast.Bad_Expr); ok {
- position_context.abort_completion = true
- return
- }
-
- position_context.selector = e
-
- ident := new_type(ast.Ident, e.pos, e.end, context.temp_allocator)
- ident.name = string(position_context.file.src[last_dot + 1:end_offset])
-
- if ident.name != "" {
- position_context.field = ident
- }
- } else {
- position_context.identifier = e
- }
-}
-
fallback_position_context_signature :: proc(
document: ^Document,
position: common.Position,
@@ -653,7 +419,8 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
case ^Selector_Expr:
if (position_context.hint == .Definition ||
position_context.hint == .Hover ||
- position_context.hint == .TypeDefinition) &&
+ position_context.hint == .TypeDefinition ||
+ position_context.hint == .Completion) &&
n.field != nil {
position_context.selector = n.expr
position_context.field = n.field
diff --git a/src/server/signature.odin b/src/server/signature.odin
index 9ffe92b..51f919d 100644
--- a/src/server/signature.odin
+++ b/src/server/signature.odin
@@ -1,16 +1,8 @@
package server
-import "core:fmt"
import "core:log"
-import "core:mem"
import "core:odin/ast"
-import "core:odin/parser"
import "core:odin/tokenizer"
-import "core:path/filepath"
-import path "core:path/slashpath"
-import "core:slice"
-import "core:sort"
-import "core:strconv"
import "core:strings"
import "src:common"