diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2021-01-08 17:25:00 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2021-01-08 17:25:00 +0100 |
| commit | 4c9f32b8b83e42c6ebef9a787208d7cdf685263a (patch) | |
| tree | c456430ca76fda958a9b5913eb19fe87a38dc539 /src | |
| parent | c179291b234303685c47cdcc64598b88110225c3 (diff) | |
reduced dublicate from collecting globals in index and analysis + foreign procedure are not indexed
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/ast.odin | 70 | ||||
| -rw-r--r-- | src/index/collector.odin | 203 | ||||
| -rw-r--r-- | src/server/analysis.odin | 25 |
3 files changed, 155 insertions, 143 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin index 5bacaec..363b166 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -24,6 +24,76 @@ keyword_map : map [string] bool = "u8" = true, "i8" = true}; + +GlobalExpr :: struct { + name: string, + expr: ^ast.Expr, + mutable: bool, + docs: ^ast.Comment_Group, +}; + +collect_globals :: proc(file: ast.File) -> [] GlobalExpr { + + exprs := make([dynamic] GlobalExpr, context.temp_allocator); + + for decl in file.decls { + + if value_decl, ok := decl.derived.(ast.Value_Decl); ok { + + for name, i in value_decl.names { + + str := get_ast_node_string(name, file.src); + + if value_decl.type != nil { + append(&exprs, GlobalExpr { name = str, expr = value_decl.type, mutable = value_decl.is_mutable, docs = value_decl.docs }); + } + + else { + if len(value_decl.values) > i { + append(&exprs, GlobalExpr { name = str, expr = value_decl.values[i], docs = value_decl.docs }); + } + } + + } + + } + + else if foreign_decl, ok := decl.derived.(ast.Foreign_Block_Decl); ok { + + if foreign_decl.body == nil { + continue; + } + + if block, ok := foreign_decl.body.derived.(ast.Block_Stmt); ok { + + for stmt in block.stmts { + + if value_decl, ok := stmt.derived.(ast.Value_Decl); ok { + + for name, i in value_decl.names { + + str := get_ast_node_string(name, file.src); + + if value_decl.type != nil { + append(&exprs, GlobalExpr { name = str, expr = value_decl.type, mutable = value_decl.is_mutable, docs = value_decl.docs }); + } + + else { + if len(value_decl.values) > i { + append(&exprs, GlobalExpr { name = str, expr = value_decl.values[i], docs = value_decl.docs }); + } + } + } + } + } + } + } + } + + return exprs[:]; +} + + get_ast_node_string :: proc(node: ^ast.Node, src: [] byte) -> string { return string(src[node.pos.offset:node.end.offset]); } diff --git a/src/index/collector.odin b/src/index/collector.odin index 438366a..8b1560a 100644 --- a/src/index/collector.odin +++ b/src/index/collector.odin @@ -193,144 +193,103 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri directory := strings.to_lower(path.dir(forward, context.temp_allocator), context.temp_allocator); package_map := get_package_mapping(file, collection.config, uri); - for decl in file.decls { + exprs := common.collect_globals(file); + + for expr in exprs { symbol: Symbol; - if value_decl, ok := decl.derived.(ast.Value_Decl); ok { - //ERROR name is not completed or can be hovered - 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 = strings.concatenate( {"(", string(file.src[v.type.params.pos.offset:v.type.params.end.offset]), ")"}, - collection.allocator); - } - - if v.type.results != nil { - symbol.returns = strings.concatenate( {"(", string(file.src[v.type.results.pos.offset:v.type.results.end.offset]), ")"}, - collection.allocator); - } - - if v.type != nil { - symbol.value = collect_procedure_fields(collection, v.type, v.type.params, v.type.results, package_map); - } - case ast.Proc_Group: - token = v; - token_type = .Function; - symbol.value = SymbolProcedureGroupValue { - group = clone_type(value_decl.values[0], collection.allocator, &collection.unique_strings), - }; - case ast.Struct_Type: - token = v; - token_type = .Struct; - symbol.value = collect_struct_fields(collection, v, package_map); - symbol.signature = "struct"; - case ast.Enum_Type: - token = v; - token_type = .Enum; - symbol.value = collect_enum_fields(collection, v.fields, package_map); - symbol.signature = "enum"; - case ast.Union_Type: - token = v; - token_type = .Enum; - symbol.value = collect_union_fields(collection, v, package_map); - symbol.signature = "union"; - case ast.Basic_Lit: - token = v; - symbol.value = collect_generic(collection, value_decl.values[0], package_map); - case ast.Ident: - token = v; - token_type = .Keyword; - symbol.value = collect_generic(collection, value_decl.values[0], package_map); - case: // default - //log.infof("default %v", value_decl.values[0].derived); - break; - } - - symbol.range = common.get_token_range(token, file.src); - symbol.name = get_index_unique_string(collection, name); - symbol.pkg = get_index_unique_string(collection, directory); - symbol.type = token_type; - symbol.uri = get_index_unique_string(collection, uri); - - - if value_decl.docs != nil { - - tmp: string; - - for doc in value_decl.docs.list { - tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator); - } - - if tmp != "" { - replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator); - symbol.doc = strings.clone(replaced, collection.allocator); - } - - } - - cat := strings.concatenate({symbol.pkg, name}, context.temp_allocator); - - id := get_symbol_id(cat); - - //right now i'm not checking comments whether is for windows, linux, etc, and some packages do not specify that(os) - if v, ok := collection.symbols[id]; !ok { - collection.symbols[id] = symbol; - } - - else { - free_symbol(symbol, collection.allocator); - } + token: ast.Node; + token_type: SymbolType; - } + name := expr.name; - else { + switch v in expr.expr.derived { + case ast.Proc_Lit: + token = v; + token_type = .Function; - for name, i in value_decl.names { + if v.type.params != nil { + symbol.signature = strings.concatenate( {"(", string(file.src[v.type.params.pos.offset:v.type.params.end.offset]), ")"}, + collection.allocator); + } - str := common.get_ast_node_string(name, file.src); + if v.type.results != nil { + symbol.returns = strings.concatenate( {"(", string(file.src[v.type.results.pos.offset:v.type.results.end.offset]), ")"}, + collection.allocator); + } - symbol: Symbol; - symbol.range = common.get_token_range(name, file.src); - symbol.name = get_index_unique_string(collection, str); - symbol.pkg = get_index_unique_string(collection, directory); - symbol.uri = get_index_unique_string(collection, uri); - symbol.type = .Variable; + if v.type != nil { + symbol.value = collect_procedure_fields(collection, v.type, v.type.params, v.type.results, package_map); + } + case ast.Proc_Group: + token = v; + token_type = .Function; + symbol.value = SymbolProcedureGroupValue { + group = clone_type(expr.expr, collection.allocator, &collection.unique_strings), + }; + case ast.Struct_Type: + token = v; + token_type = .Struct; + symbol.value = collect_struct_fields(collection, v, package_map); + symbol.signature = "struct"; + case ast.Enum_Type: + token = v; + token_type = .Enum; + symbol.value = collect_enum_fields(collection, v.fields, package_map); + symbol.signature = "enum"; + case ast.Union_Type: + token = v; + token_type = .Enum; + symbol.value = collect_union_fields(collection, v, package_map); + symbol.signature = "union"; + case ast.Basic_Lit: + token = v; + symbol.value = collect_generic(collection, expr.expr, package_map); + case ast.Ident: + token = v; + token_type = .Keyword; + symbol.value = collect_generic(collection, expr.expr, package_map); + case: // default + //log.infof("default %v", value_decl.values[0].derived); + break; + } - if value_decl.type != nil { - symbol.value = collect_generic(collection, value_decl.type, package_map); - } + symbol.range = common.get_token_range(token, file.src); + symbol.name = get_index_unique_string(collection, name); + symbol.pkg = get_index_unique_string(collection, directory); + symbol.type = token_type; + symbol.uri = get_index_unique_string(collection, uri); - else { - if len(value_decl.values) > i { - symbol.value = collect_generic(collection, value_decl.values[i], package_map); - } - } - cat := strings.concatenate({symbol.pkg, str}, context.temp_allocator); + if expr.docs != nil { - id := get_symbol_id(cat); + tmp: string; - if v, ok := collection.symbols[id]; !ok { - collection.symbols[id] = symbol; - } + for doc in expr.docs.list { + tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator); + } - else { - free_symbol(symbol, collection.allocator); - } - } + if tmp != "" { + replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator); + symbol.doc = strings.clone(replaced, collection.allocator); } + } + + cat := strings.concatenate({symbol.pkg, name}, context.temp_allocator); + + id := get_symbol_id(cat); + + //right now i'm not checking comments whether is for windows, linux, etc, and some packages do not specify that(os) + if v, ok := collection.symbols[id]; !ok { + collection.symbols[id] = symbol; + } + + else { + free_symbol(symbol, collection.allocator); + } + } return .None; diff --git a/src/server/analysis.odin b/src/server/analysis.odin index d80e1d1..d729b6d 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1361,28 +1361,11 @@ get_globals :: proc(file: ast.File, ast_context: ^AstContext) { ast_context.variables["context"] = true; - for decl in file.decls { + exprs := common.collect_globals(file); - if value_decl, ok := decl.derived.(ast.Value_Decl); ok { - - for name, i in value_decl.names { - - str := common.get_ast_node_string(name, file.src); - - if value_decl.type != nil { - ast_context.globals[str] = value_decl.type; - ast_context.variables[str] = value_decl.is_mutable; - } - - else { - if len(value_decl.values) > i { - ast_context.globals[str] = value_decl.values[i]; - } - } - - } - - } + for expr in exprs { + ast_context.globals[expr.name] = expr.expr; + ast_context.variables[expr.name] = expr.mutable; } } |