aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2023-06-29 18:20:08 +0200
committerDanielGavin <danielgavin5@hotmail.com>2023-06-29 18:20:08 +0200
commitae78fc93465e7604c19af3f6a6339a6667cb8cf1 (patch)
treebb3965d1ad8ce26109f5d8aeed0564671c9a00ff
parentf2427a91ba14cb1fc730d42fea8d309a13608325 (diff)
Start working on having fake methods.
-rw-r--r--src/server/collector.odin72
-rw-r--r--src/server/completion.odin49
-rw-r--r--tests/completions_test.odin33
-rw-r--r--tests/hover_test.odin2
4 files changed, 147 insertions, 9 deletions
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 6dcfa53..1b9e72f 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -30,9 +30,15 @@ ObjcStruct :: struct {
ranges: [dynamic]common.Range,
}
+Method :: struct {
+ pkg: string,
+ name: string,
+}
+
SymbolPackage :: struct {
symbols: map[string]Symbol,
objc_structs: map[string]ObjcStruct, //mapping from struct name to function
+ methods: map[Method][dynamic]Symbol,
}
get_index_unique_string :: proc {
@@ -136,14 +142,6 @@ collect_procedure_fields :: proc(
return_types = returns[:],
arg_types = args[:],
generic = proc_type.generic,
- /*
- objc_name = common.get_attribute_objc_name(
- attributes,
- ) or_else "",
- objc_is_class_method = common.get_attribute_objc_is_class_method(
- attributes,
- ) or_else false,
- */
}
return value
@@ -437,6 +435,55 @@ collect_generic :: proc(
return value
}
+collect_method :: proc(collection: ^SymbolCollection, symbol: Symbol) {
+ pkg := &collection.packages[symbol.pkg]
+
+ if value, ok := symbol.value.(SymbolProcedureValue); ok {
+ if len(value.arg_types) == 0 {
+ return
+ }
+
+ expr, _, ok := common.unwrap_pointer(value.arg_types[0].type)
+
+ if !ok {
+ return
+ }
+
+ method: Method
+
+ #partial switch v in expr.derived {
+ case ^ast.Selector_Expr:
+ if ident, ok := v.expr.derived.(^ast.Ident); ok {
+ method.pkg = get_index_unique_string(collection, ident.name)
+ method.name = get_index_unique_string(collection, v.field.name)
+ } else {
+ return
+ }
+ case ^ast.Ident:
+ method.pkg = symbol.pkg
+ method.name = get_index_unique_string(collection, v.name)
+ case:
+ return
+ }
+
+ symbols := &pkg.methods[method]
+
+ if symbols == nil {
+ pkg.methods[method] = make([dynamic]Symbol, collection.allocator)
+ symbols = &pkg.methods[method]
+ }
+
+ if method.pkg != "$builtin" {
+ //fmt.println(method)
+ //fmt.println(symbol)
+ }
+
+ append(symbols, symbol)
+ }
+
+
+}
+
collect_objc :: proc(
collection: ^SymbolCollection,
attributes: []^ast.Attribute,
@@ -726,6 +773,11 @@ collect_symbols :: proc(
collection.packages[symbol.pkg] = {}
pkg = &collection.packages[symbol.pkg]
pkg.symbols = make(map[string]Symbol, 100, collection.allocator)
+ pkg.methods = make(
+ map[Method][dynamic]Symbol,
+ 100,
+ collection.allocator,
+ )
pkg.objc_structs = make(
map[string]ObjcStruct,
5,
@@ -737,6 +789,10 @@ collect_symbols :: proc(
collect_objc(collection, expr.attributes, symbol)
}
+ if symbol.type == .Function {
+ //collect_method(collection, symbol)
+ }
+
if v, ok := pkg.symbols[symbol.name]; !ok || v.name == "" {
pkg.symbols[symbol.name] = symbol
} else {
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 77cc399..572026f 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -162,6 +162,7 @@ get_attribute_completion :: proc(
list: ^CompletionList,
) {
+
}
get_directive_completion :: proc(
@@ -333,6 +334,8 @@ get_selector_completion :: proc(
}
}
+ //append_method_completion(ast_context, selector, &items)
+
#partial switch v in selector.value {
case SymbolFixedArrayValue:
list.isIncomplete = true
@@ -1608,6 +1611,52 @@ get_range_from_selection_start_to_dot :: proc(
return {}, false
}
+append_method_completion :: proc(
+ ast_context: ^AstContext,
+ symbol: Symbol,
+ items: ^[dynamic]CompletionItem,
+) {
+ if symbol.type != .Variable {
+ return
+ }
+
+ for k, v in indexer.index.collection.packages {
+ method := Method {
+ name = symbol.name,
+ pkg = symbol.pkg,
+ }
+ if symbols, ok := &v.methods[method]; ok {
+ for symbol in symbols {
+
+ resolve_unresolved_symbol(ast_context, &symbol)
+ build_procedure_symbol_signature(&symbol)
+
+ item := CompletionItem {
+ label = symbol.name,
+ kind = cast(CompletionItemKind)symbol.type,
+ detail = concatenate_symbol_information(
+ ast_context,
+ symbol,
+ true,
+ ),
+ documentation = symbol.doc,
+ }
+
+ if symbol.type == .Function && common.config.enable_snippets {
+ item.insertText = fmt.tprintf("%v($0)", item.label)
+ item.insertTextFormat = .Snippet
+ item.command = Command {
+ command = "editor.action.triggerParameterHints",
+ }
+ item.deprecated = .Deprecated in symbol.flags
+ }
+
+ append(items, item)
+ }
+ }
+ }
+}
+
append_magic_map_completion :: proc(
position_context: ^DocumentPositionContext,
symbol: Symbol,
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 15b3386..68efd37 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -2152,3 +2152,36 @@ ast_completion_struct_with_same_name_in_pkg :: proc(t: ^testing.T) {
test.expect_completion_details(t, &source, ".", {"A.lib_a: int"})
}
+
+@(test)
+zzast_completion_method_with_type :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package)
+
+ append(
+ &packages,
+ test.Package{
+ pkg = "my_package",
+ source = `package my_package
+ A :: struct {
+ lib_a: int,
+ }
+ proc_one :: proc(a: ^A) {}
+ proc_two :: proc(a: A) {}
+ `,
+ },
+ )
+
+ source := test.Source {
+ main = `package test
+ import "my_package"
+ main :: proc() {
+ a: my_package.A
+
+ a.{*}
+ }
+ `,
+ packages = packages[:],
+ }
+
+ test.expect_completion_details(t, &source, ".", {"ib_a: int"})
+}
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index a21ca70..30afc59 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -158,7 +158,7 @@ ast_hover_same_name_in_selector_and_field :: proc(t: ^testing.T) {
}
@(test)
-zzast_hover_on_sliced_result :: proc(t: ^testing.T) {
+ast_hover_on_sliced_result :: proc(t: ^testing.T) {
source := test.Source {
main = `package test
f :: proc() {