aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-14 20:40:19 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-14 20:40:19 +0100
commit556e999c85ecbf9ce0a7d51305bc38c203ffcb00 (patch)
treefba239dfad5ba00aa4e8ed69ecb29b11dd616460 /src
parent79fdfe53119ac01cb1a1d06609c79aabcac7b946 (diff)
indexer and ast works together with foreign packages
Diffstat (limited to 'src')
-rw-r--r--src/index/build.odin4
-rw-r--r--src/index/clone.odin174
-rw-r--r--src/index/collector.odin302
-rw-r--r--src/index/indexer.odin5
-rw-r--r--src/index/memory_index.odin6
-rw-r--r--src/index/symbol.odin110
-rw-r--r--src/server/analysis.odin94
-rw-r--r--src/server/documents.odin2
8 files changed, 555 insertions, 142 deletions
diff --git a/src/index/build.odin b/src/index/build.odin
index acab4a5..8f3c114 100644
--- a/src/index/build.odin
+++ b/src/index/build.odin
@@ -19,14 +19,14 @@ import "shared:common"
symbol_collection: SymbolCollection;
+
build_static_index :: proc(allocator := context.allocator, config: ^common.Config) {
//right now just collect the symbols from core
core_path := config.collections["core"];
-
- symbol_collection = make_symbol_collection(allocator);
+ symbol_collection = make_symbol_collection(allocator, config);
walk_static_index_build := proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
diff --git a/src/index/clone.odin b/src/index/clone.odin
new file mode 100644
index 0000000..2354b8a
--- /dev/null
+++ b/src/index/clone.odin
@@ -0,0 +1,174 @@
+package index
+
+import "core:mem"
+import "core:fmt"
+import "core:odin/tokenizer"
+import "core:odin/ast"
+import "core:strings"
+
+clone_type :: proc{
+ clone_node,
+ clone_expr,
+ clone_array,
+ clone_dynamic_array,
+};
+
+clone_array :: proc(array: $A/[]^$T, allocator := context.allocator) -> A {
+ if len(array) == 0 {
+ return nil;
+ }
+ res := make(A, len(array));
+ for elem, i in array {
+ res[i] = auto_cast clone_type(elem, allocator);
+ }
+ return res;
+}
+
+clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator := context.allocator) -> A {
+ if len(array) == 0 {
+ return nil;
+ }
+ res := make(A, len(array));
+ for elem, i in array {
+ res[i] = auto_cast clone_type(elem, allocator);
+ }
+ return res;
+}
+
+clone_expr :: proc(node: ^ast.Expr, allocator := context.allocator) -> ^ast.Expr {
+ return cast(^ast.Expr)clone_node(node, allocator);
+}
+
+clone_node :: proc(node: ^ast.Node, allocator := context.allocator) -> ^ast.Node {
+
+ using ast;
+
+ if node == nil {
+ return nil;
+ }
+
+ size := size_of(Node);
+ align := align_of(Node);
+ ti := type_info_of(node.derived.id);
+ if ti != nil {
+ size = ti.size;
+ align = ti.align;
+ }
+
+ res := cast(^Node)mem.alloc(size, align, allocator);
+ src: rawptr = node;
+ if node.derived != nil {
+ src = node.derived.data;
+ }
+ mem.copy(res, src, size);
+ res.derived.data = rawptr(res);
+
+ switch n in node.derived {
+ case Bad_Expr:
+ case Ident:
+ r := cast(^Ident)res;
+ r.name = strings.clone(n.name, allocator);
+ case Implicit:
+ case Undef:
+ case Basic_Lit:
+
+ case Ellipsis:
+ r := cast(^Ellipsis)res;
+ r.expr = clone_type(r.expr, allocator);
+ case Tag_Expr:
+ r := cast(^Tag_Expr)res;
+ r.expr = clone_type(r.expr, allocator);
+ case Unary_Expr:
+ r := cast(^Unary_Expr)res;
+ r.expr = clone_type(r.expr, allocator);
+ case Binary_Expr:
+ r := cast(^Binary_Expr)res;
+ r.left = clone_type(r.left, allocator);
+ r.right = clone_type(r.right, allocator);
+ case Paren_Expr:
+ r := cast(^Paren_Expr)res;
+ r.expr = clone_type(r.expr, allocator);
+ case Selector_Expr:
+ r := cast(^Selector_Expr)res;
+ r.expr = clone_type(r.expr, allocator);
+ r.field = auto_cast clone_type(r.field, allocator);
+ case Slice_Expr:
+ r := cast(^Slice_Expr)res;
+ r.expr = clone_type(r.expr, allocator);
+ r.low = clone_type(r.low, allocator);
+ r.high = clone_type(r.high, allocator);
+ case Attribute:
+ r := cast(^Attribute)res;
+ r.elems = clone_type(r.elems, allocator);
+ case Distinct_Type:
+ r := cast(^Distinct_Type)res;
+ r.type = clone_type(r.type, allocator);
+ case Opaque_Type:
+ r := cast(^Opaque_Type)res;
+ r.type = clone_type(r.type, allocator);
+ case Proc_Type:
+ r := cast(^Proc_Type)res;
+ r.params = auto_cast clone_type(r.params, allocator);
+ r.results = auto_cast clone_type(r.results, allocator);
+ case Pointer_Type:
+ r := cast(^Pointer_Type)res;
+ r.elem = clone_type(r.elem, allocator);
+ case Array_Type:
+ r := cast(^Array_Type)res;
+ r.len = clone_type(r.len, allocator);
+ r.elem = clone_type(r.elem, allocator);
+ case Dynamic_Array_Type:
+ r := cast(^Dynamic_Array_Type)res;
+ r.elem = clone_type(r.elem, allocator);
+ case Struct_Type:
+ r := cast(^Struct_Type)res;
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator);
+ r.align = clone_type(r.align, allocator);
+ r.fields = auto_cast clone_type(r.fields, allocator);
+ case Field:
+ r := cast(^Field)res;
+ r.names = clone_type(r.names, allocator);
+ r.type = clone_type(r.type, allocator);
+ r.default_value = clone_type(r.default_value, allocator);
+ case Field_List:
+ r := cast(^Field_List)res;
+ r.list = clone_type(r.list, allocator);
+ case Field_Value:
+ r := cast(^Field_Value)res;
+ r.field = clone_type(r.field, allocator);
+ r.value = clone_type(r.value, allocator);
+ case Union_Type:
+ r := cast(^Union_Type)res;
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator);
+ r.align = clone_type(r.align, allocator);
+ r.variants = clone_type(r.variants, allocator);
+ case Enum_Type:
+ r := cast(^Enum_Type)res;
+ r.base_type = clone_type(r.base_type, allocator);
+ r.fields = clone_type(r.fields, allocator);
+ case Bit_Field_Type:
+ r := cast(^Bit_Field_Type)res;
+ r.fields = clone_type(r.fields, allocator);
+ case Bit_Set_Type:
+ r := cast(^Bit_Set_Type)res;
+ r.elem = clone_type(r.elem, allocator);
+ r.underlying = clone_type(r.underlying, allocator);
+ case Map_Type:
+ r := cast(^Map_Type)res;
+ r.key = clone_type(r.key, allocator);
+ r.value = clone_type(r.value, allocator);
+ case Call_Expr:
+ r := cast(^Call_Expr)res;
+ r.expr = clone_type(r.expr, allocator);
+ r.args = clone_type(r.args, allocator);
+ case Typeid_Type:
+ r := cast(^Typeid_Type)res;
+ r.specialization = clone_type(r.specialization, allocator);
+ case:
+ fmt.panicf("Unhandled node kind: %T", n);
+ }
+
+ return res;
+}
+
+
diff --git a/src/index/collector.odin b/src/index/collector.odin
new file mode 100644
index 0000000..68691dd
--- /dev/null
+++ b/src/index/collector.odin
@@ -0,0 +1,302 @@
+package index
+
+import "core:odin/ast"
+import "core:hash"
+import "core:strings"
+import "core:mem"
+import "core:fmt"
+import "core:path/filepath"
+import "core:path"
+
+import "shared:common"
+
+
+SymbolCollection :: struct {
+ allocator: mem.Allocator,
+ config: ^common.Config,
+ symbols: map[string] Symbol,
+ unique_strings: map[string] string, //store all our strings as unique strings and reference them to save memory.
+};
+
+
+get_index_unique_string :: proc(collection: ^SymbolCollection, s: string) -> string {
+
+ //i'm hashing this string way to much
+ if _, ok := collection.unique_strings[s]; !ok {
+ collection.unique_strings[s] = strings.clone(s, collection.allocator);
+ }
+
+ return collection.unique_strings[s];
+}
+
+
+make_symbol_collection :: proc(allocator := context.allocator, config: ^common.Config) -> SymbolCollection {
+ return SymbolCollection {
+ allocator = allocator,
+ config = config,
+ symbols = make(map[string] Symbol, 16, allocator),
+ unique_strings = make(map[string] string, 16, allocator),
+ };
+}
+
+collect_struct_fields :: proc(collection: ^SymbolCollection, fields: ^ast.Field_List, package_map: map [string] string) -> SymbolStructValue {
+
+ names := make([dynamic] string, 0, collection.allocator);
+ types := make([dynamic] ^ast.Expr, 0, collection.allocator);
+
+ for field in fields.list {
+
+ for n in field.names {
+ identifier := n.derived.(ast.Ident);
+ append(&names, get_index_unique_string(collection, identifier.name));
+ append(&types, clone_type(field.type, collection.allocator));
+ }
+
+ }
+
+ for t in types {
+ replace_package_alias(t, package_map, collection);
+ }
+
+ value := SymbolStructValue {
+ names = names[:],
+ types = types[:],
+ };
+
+ return value;
+}
+
+
+
+collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error {
+
+ forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator);
+ directory := path.dir(forward, context.temp_allocator);
+ package_map := get_package_mapping(file, collection.config);
+
+ for decl in file.decls {
+
+ symbol: Symbol;
+
+ if value_decl, ok := decl.derived.(ast.Value_Decl); ok {
+
+ name := string(file.src[value_decl.names[0].pos.offset:value_decl.names[0].end.offset]);
+
+ if len(value_decl.values) == 1 {
+
+ token: ast.Node;
+ token_type: SymbolType;
+
+ switch v in value_decl.values[0].derived {
+ case ast.Proc_Lit:
+ token = v;
+ token_type = .Function;
+
+ if v.type.params != nil {
+ symbol.signature = get_index_unique_string(collection,
+ strings.concatenate( {"(", string(file.src[v.type.params.pos.offset:v.type.params.end.offset]), ")"},
+ context.temp_allocator));
+ }
+ case ast.Struct_Type:
+ token = v;
+ token_type = .Struct;
+ symbol.value = collect_struct_fields(collection, v.fields, package_map);
+ case: // default
+ break;
+ }
+
+ symbol.range = common.get_token_range(token, file.src);
+ symbol.name = get_index_unique_string(collection, name);
+ symbol.scope = get_index_unique_string(collection, directory);
+ symbol.type = token_type;
+ symbol.uri = get_index_unique_string(collection, uri);
+
+ //id := hash.murmur64(transmute([]u8)strings.concatenate({symbol.scope, name}, context.temp_allocator));
+
+ collection.symbols[strings.concatenate({symbol.scope, name}, context.temp_allocator)] = symbol;
+ }
+
+ }
+ }
+
+ return .None;
+}
+
+
+/*
+ Gets the map from import alias to absolute package directory
+*/
+get_package_mapping :: proc(file: ast.File, config: ^common.Config) -> map [string] string {
+
+ package_map := make(map [string] string, 0, context.temp_allocator);
+
+ for imp, index in file.imports {
+
+ //collection specified
+ if i := strings.index(imp.fullpath, ":"); i != -1 {
+
+ collection := imp.fullpath[1:i];
+ p := imp.fullpath[i+1:len(imp.fullpath)-1];
+
+ dir, ok := config.collections[collection];
+
+ if !ok {
+ continue;
+ }
+
+ name: string;
+
+ full := path.join(elems = {dir, p}, allocator = context.temp_allocator);
+
+ if imp.name.text != "" {
+ name = imp.name.text;
+ }
+
+ else {
+ name = path.base(full, false, context.temp_allocator);
+ }
+
+ package_map[name] = full;
+
+ }
+
+ else {
+
+ }
+
+ }
+
+
+ return package_map;
+}
+
+
+/*
+ We can't have the alias names for packages with selector expression since that is specific to every files import, instead just replace it with the absolute
+ package name(absolute directory path)
+*/
+
+replace_package_alias :: proc{
+ replace_package_alias_node,
+ replace_package_alias_expr,
+ replace_package_alias_array,
+ replace_package_alias_dynamic_array,
+};
+
+replace_package_alias_array :: proc(array: $A/[]^$T, package_map: map [string] string, collection: ^SymbolCollection) {
+
+ for elem, i in array {
+ replace_package_alias(elem, package_map, collection);
+ }
+
+}
+
+replace_package_alias_dynamic_array :: proc(array: $A/[dynamic]^$T, package_map: map [string] string, collection: ^SymbolCollection) {
+
+ for elem, i in array {
+ replace_package_alias(elem, package_map, collection);
+ }
+
+}
+
+replace_package_alias_expr :: proc(node: ^ast.Expr, package_map: map [string] string, collection: ^SymbolCollection) {
+ replace_package_alias_node(node, package_map, collection);
+}
+
+replace_package_alias_node :: proc(node: ^ast.Node, package_map: map [string] string, collection: ^SymbolCollection) {
+
+ using ast;
+
+ if node == nil {
+ return;
+ }
+
+ switch n in node.derived {
+ case Bad_Expr:
+ case Ident:
+ case Implicit:
+ case Undef:
+ case Basic_Lit:
+ case Ellipsis:
+ replace_package_alias(n.expr, package_map, collection);
+ case Tag_Expr:
+ replace_package_alias(n.expr, package_map, collection);
+ case Unary_Expr:
+ replace_package_alias(n.expr, package_map, collection);
+ case Binary_Expr:
+ replace_package_alias(n.left, package_map, collection);
+ replace_package_alias(n.right, package_map, collection);
+ case Paren_Expr:
+ replace_package_alias(n.expr, package_map, collection);
+ case Selector_Expr:
+
+ if ident := &n.expr.derived.(Ident); ident != nil {
+
+ if package_name, ok := package_map[ident.name]; ok {
+ ident.name = get_index_unique_string(collection, package_name);
+ }
+
+ }
+
+ else {
+ replace_package_alias(n.expr, package_map, collection);
+ replace_package_alias(n.field, package_map, collection);
+ }
+ case Slice_Expr:
+ replace_package_alias(n.expr, package_map, collection);
+ replace_package_alias(n.low, package_map, collection);
+ replace_package_alias(n.high, package_map, collection);
+ case Attribute:
+ replace_package_alias(n.elems, package_map, collection);
+ case Distinct_Type:
+ replace_package_alias(n.type, package_map, collection);
+ case Opaque_Type:
+ replace_package_alias(n.type, package_map, collection);
+ case Proc_Type:
+ replace_package_alias(n.params, package_map, collection);
+ replace_package_alias(n.results, package_map, collection);
+ case Pointer_Type:
+ replace_package_alias(n.elem, package_map, collection);
+ case Array_Type:
+ replace_package_alias(n.len, package_map, collection);
+ replace_package_alias(n.elem, package_map, collection);
+ case Dynamic_Array_Type:
+ replace_package_alias(n.elem, package_map, collection);
+ case Struct_Type:
+ replace_package_alias(n.poly_params, package_map, collection);
+ replace_package_alias(n.align, package_map, collection);
+ replace_package_alias(n.fields, package_map, collection);
+ case Field:
+ replace_package_alias(n.names, package_map, collection);
+ replace_package_alias(n.type, package_map, collection);
+ replace_package_alias(n.default_value, package_map, collection);
+ case Field_List:
+ replace_package_alias(n.list, package_map, collection);
+ case Field_Value:
+ replace_package_alias(n.field, package_map, collection);
+ replace_package_alias(n.value, package_map, collection);
+ case Union_Type:
+ replace_package_alias(n.poly_params, package_map, collection);
+ replace_package_alias(n.align, package_map, collection);
+ replace_package_alias(n.variants, package_map, collection);
+ case Enum_Type:
+ replace_package_alias(n.base_type, package_map, collection);
+ replace_package_alias(n.fields, package_map, collection);
+ case Bit_Field_Type:
+ replace_package_alias(n.fields, package_map, collection);
+ case Bit_Set_Type:
+ replace_package_alias(n.elem, package_map, collection);
+ replace_package_alias(n.underlying, package_map, collection);
+ case Map_Type:
+ replace_package_alias(n.key, package_map, collection);
+ replace_package_alias(n.value, package_map, collection);
+ case Call_Expr:
+ replace_package_alias(n.expr, package_map, collection);
+ replace_package_alias(n.args, package_map, collection);
+ case Typeid_Type:
+ replace_package_alias(n.specialization, package_map, collection);
+ case:
+ fmt.panicf("Unhandled node kind: %T", n);
+ }
+
+} \ No newline at end of file
diff --git a/src/index/indexer.odin b/src/index/indexer.odin
index 235303d..88e5419 100644
--- a/src/index/indexer.odin
+++ b/src/index/indexer.odin
@@ -3,6 +3,7 @@ package index
import "core:odin/ast"
import "core:fmt"
import "core:strings"
+import "core:log"
/*
@@ -44,7 +45,9 @@ indexer: Indexer;
lookup :: proc(name: string, scope: string) -> (Symbol, bool) {
- return memory_index_lookup(&indexer.static_index, name, scope);
+ symbol, ok := memory_index_lookup(&indexer.static_index, name, scope);
+ //log.infof("lookup name: %v scope: %v, symbol %v", name, scope, symbol);
+ return symbol, ok;
}
diff --git a/src/index/memory_index.odin b/src/index/memory_index.odin
index e9c0135..c3b38bf 100644
--- a/src/index/memory_index.odin
+++ b/src/index/memory_index.odin
@@ -26,10 +26,8 @@ make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
}
memory_index_lookup :: proc(index: ^MemoryIndex, name: string, scope: string) -> (Symbol, bool) {
-
- hashed := hash.murmur64(transmute([]u8)strings.concatenate({scope, name}, context.temp_allocator));
-
- return index.collection.symbols[hashed];
+ //hashed := hash.murmur64(transmute([]u8)strings.concatenate({scope, name}, context.temp_allocator));
+ return index.collection.symbols[strings.concatenate({scope, name}, context.temp_allocator)];
}
memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, scope: [] string) -> ([] Symbol, bool) {
diff --git a/src/index/symbol.odin b/src/index/symbol.odin
index 0906e74..46624d5 100644
--- a/src/index/symbol.odin
+++ b/src/index/symbol.odin
@@ -16,6 +16,12 @@ import "shared:common"
*/
+
+SymbolFile :: struct {
+ imports: [] string,
+};
+
+
SymbolStructValue :: struct {
names: [] string,
types: [] ^ast.Expr,
@@ -38,6 +44,7 @@ Symbol :: struct {
signature: string,
type: SymbolType,
value: SymbolValue,
+ file: ^SymbolFile,
};
SymbolType :: enum {
@@ -46,105 +53,4 @@ SymbolType :: enum {
Package = 9, //set by ast symbol
Keyword = 14, //set by ast symbol
Struct = 22,
-};
-
-SymbolCollection :: struct {
- allocator: mem.Allocator,
- symbols: map[u64] Symbol,
- unique_strings: map[u64] string, //store all our strings as unique strings and reference them to save memory.
-};
-
-get_index_unique_string :: proc(collection: ^SymbolCollection, s: string) -> string {
-
- id := hash.murmur64(transmute([]u8)s);
-
- if _, ok := collection.unique_strings[id]; !ok {
- collection.unique_strings[id] = strings.clone(s, collection.allocator);
- }
-
- return collection.unique_strings[id];
-}
-
-make_symbol_collection :: proc(allocator := context.allocator) -> SymbolCollection {
- return SymbolCollection {
- allocator = allocator,
- symbols = make(map[u64] Symbol, 16, allocator),
- unique_strings = make(map[u64] string, 16, allocator),
- };
-}
-
-collect_struct_fields :: proc(collection: ^SymbolCollection, fields: ^ast.Field_List, src: [] byte) -> SymbolStructValue {
-
- names := make([dynamic] string, 0, collection.allocator);
- types := make([dynamic] ^ast.Expr, 0, collection.allocator);
-
- for field in fields.list {
-
- for n in field.names {
- identifier := n.derived.(ast.Ident);
- append(&names, get_index_unique_string(collection, identifier.name));
- append(&types, ast.clone_expr(field.type));
- }
-
- }
-
- value := SymbolStructValue {
- names = names[:],
- types = types[:],
- };
-
- return value;
-}
-
-collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error {
-
- forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator);
- directory := path.dir(forward, context.temp_allocator);
-
- for decl in file.decls {
-
- symbol: Symbol;
-
- if value_decl, ok := decl.derived.(ast.Value_Decl); ok {
-
- name := string(file.src[value_decl.names[0].pos.offset:value_decl.names[0].end.offset]);
-
- if len(value_decl.values) == 1 {
-
- token: ast.Node;
- token_type: SymbolType;
-
- switch v in value_decl.values[0].derived {
- case ast.Proc_Lit:
- token = v;
- token_type = .Function;
-
- if v.type.params != nil {
- symbol.signature = get_index_unique_string(collection,
- strings.concatenate( {"(", string(file.src[v.type.params.pos.offset:v.type.params.end.offset]), ")"},
- context.temp_allocator));
- }
- case ast.Struct_Type:
- token = v;
- token_type = .Struct;
- symbol.value = collect_struct_fields(collection, v.fields, file.src);
- case: // default
- break;
- }
-
- symbol.range = common.get_token_range(token, file.src);
- symbol.name = get_index_unique_string(collection, name);
- symbol.scope = get_index_unique_string(collection, directory);
- symbol.type = token_type;
- symbol.uri = get_index_unique_string(collection, uri);
-
- id := hash.murmur64(transmute([]u8)strings.concatenate({symbol.scope, name}, context.temp_allocator));
-
- collection.symbols[id] = symbol;
- }
-
- }
- }
-
- return .None;
-}
+}; \ No newline at end of file
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 1bef7f4..b23b6d8 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -35,17 +35,24 @@ AstContext :: struct {
globals: map [string] ^ast.Expr,
file: ast.File,
allocator: mem.Allocator,
- imports: [] Package,
- foreign_package: bool,
+ imports: [] Package, //imports for the current document
+ current_package: string,
+ document_package: string,
+ use_globals: bool,
+ use_locals: bool,
};
-make_ast_context :: proc(file: ast.File, imports: [] Package, allocator := context.temp_allocator) -> AstContext {
+make_ast_context :: proc(file: ast.File, imports: [] Package, package_name: string, allocator := context.temp_allocator) -> AstContext {
ast_context := AstContext {
locals = make(map [string] ^ast.Expr, 0, allocator),
globals = make(map [string] ^ast.Expr, 0, allocator),
file = file,
imports = imports,
+ use_locals = true,
+ use_globals = true,
+ document_package = package_name,
+ current_package = package_name,
};
return ast_context;
@@ -68,21 +75,30 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
if selector, ok := resolve_type_expression(ast_context, v.expr); ok {
+ ast_context.use_locals = false;
+
switch s in selector.value {
case index.SymbolStructValue:
+
+ if selector.uri != "" {
+ ast_context.current_package = selector.scope;
+ }
+
for name, i in s.names {
if v.field != nil && strings.compare(name, v.field.name) == 0 {
return resolve_type_expression(ast_context, s.types[i], false);
}
}
case index.SymbolPackageValue:
- //TODO(Daniel, when we go into a package we are no longer in our project and cannot look at globals and locals)
+
+ ast_context.current_package = selector.scope;
+
if v.field != nil {
- //ast_context.foreign_package = true;
return index.lookup(v.field.name, selector.scope);
}
else {
+ log.error("No field");
return index.Symbol {}, false;
}
@@ -107,9 +123,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
using ast;
- log.info(node.name);
-
- if local, ok := ast_context.locals[node.name]; !ast_context.foreign_package && ok {
+ if local, ok := ast_context.locals[node.name]; ast_context.use_locals && ok {
switch v in local.derived {
case Ident:
@@ -136,7 +150,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
}
}
- else if global, ok := ast_context.globals[node.name]; !ast_context.foreign_package && ok {
+ else if global, ok := ast_context.globals[node.name]; ast_context.use_globals && ok {
switch v in global.derived {
case Ident:
@@ -164,7 +178,9 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
}
//keywords
- else if node.name == "int" || node.name == "string" {
+ else if node.name == "int" || node.name == "string"
+ || node.name == "u64" || node.name == "f32"
+ || node.name == "i64" || node.name == "i32" {
symbol := index.Symbol {
type = .Keyword,
@@ -176,25 +192,43 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
//imports - probably have this higher to check imports befure everything else
else {
- for imp in ast_context.imports {
-
- if strings.compare(imp.base, node.name) == 0 {
+ //right now we replace the package ident with the absolute directory name, so it should have '/' which is not a valid ident character
+ if strings.contains(node.name, "/") {
- symbol := index.Symbol {
+ symbol := index.Symbol {
type = .Package,
- scope = imp.name,
+ scope = node.name,
value = index.SymbolPackageValue {
}
};
- return symbol, true;
+ return symbol, true;
+
+ }
+
+ else {
+
+ for imp in ast_context.imports {
+
+ if strings.compare(imp.base, node.name) == 0 {
+
+ symbol := index.Symbol {
+ type = .Package,
+ scope = imp.name,
+ value = index.SymbolPackageValue {
+ }
+ };
+
+ return symbol, true;
+ }
+
}
}
//last option is to check the index
-
+ return index.lookup(node.name, ast_context.current_package);
//TODO(daniel, index can be used on identifiers if using is in the function scope)
@@ -329,7 +363,7 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
location: common.Location;
- ast_context := make_ast_context(document.ast, document.imports);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name);
uri: string;
@@ -387,7 +421,6 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
}
case index.SymbolPackageValue:
if symbol, ok := index.lookup(field, selector.scope); ok {
- log.info(symbol);
location.range = symbol.range;
uri = symbol.uri;
}
@@ -424,7 +457,7 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
list: CompletionList;
- ast_context := make_ast_context(document.ast, document.imports);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name);
position_context, ok := get_document_position_context(document, position, .Completion);
@@ -449,6 +482,10 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
}
+ if selector.uri != "" {
+ ast_context.current_package = selector.scope;
+ }
+
field: string;
if position_context.field != nil {
@@ -480,6 +517,8 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
list.isIncomplete = false;
case index.SymbolPackageValue:
+ list.isIncomplete = true;
+
if field != "" {
if searched, ok := index.fuzzy_search(selector.name, {selector.scope}); ok {
@@ -491,12 +530,11 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
}
else {
+ log.errorf("Failed to fuzzy search, field: %v, package: %v", field, selector.scope);
return list, true;
}
}
-
- list.isIncomplete = true;
}
}
@@ -512,8 +550,6 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
list.items[i].kind = cast(CompletionItemKind) symbol.type;
}
- log.info(list);
-
return list, true;
}
@@ -521,7 +557,7 @@ get_signature_information :: proc(document: ^Document, position: common.Position
signature_help: SignatureHelp;
- ast_context := make_ast_context(document.ast, document.imports);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name);
position_context, ok := get_document_position_context(document, position, .SignatureHelp);
@@ -542,8 +578,6 @@ get_signature_information :: proc(document: ^Document, position: common.Position
call: index.Symbol;
call, ok = resolve_type_expression(&ast_context, position_context.call);
- log.info(call);
-
signature_information := make([] SignatureInformation, 1, context.temp_allocator);
signature_information[0].label = strings.concatenate({call.name, call.signature}, context.temp_allocator);
@@ -632,11 +666,7 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
//do we still have recursive dots?
if strings.contains(string(str), ".") {
- log.info(common.get_ast_node_string(node, position_context.file.src));
- log.info(n.derived);
-
e := parser.parse_expr(&p, true); //MEMORY LEAK - need to modify parser to allow for temp allocator
-
position_context.selector = e;
}
@@ -670,10 +700,8 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
case Tag_Expr:
get_document_position(n.expr, position_context);
case Unary_Expr:
- log.info("%v", n.op.text);
get_document_position(n.expr, position_context);
case Binary_Expr:
- log.info("%v", n.op.text);
get_document_position(n.left, position_context);
get_document_position(n.right, position_context);
case Paren_Expr:
diff --git a/src/server/documents.odin b/src/server/documents.odin
index a626ec3..689e1c0 100644
--- a/src/server/documents.odin
+++ b/src/server/documents.odin
@@ -33,6 +33,7 @@ Document :: struct {
diagnosed_errors: bool,
ast: ast.File,
imports: [] Package,
+ package_name: string,
};
DocumentStorage :: struct {
@@ -346,6 +347,7 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse
}
document.imports = make([]Package, len(document.ast.imports));
+ document.package_name = path.dir(document.uri.path, context.allocator); //todo(memory leak)
for imp, index in document.ast.imports {