diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2024-05-11 20:35:08 +0200 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2024-05-11 20:35:08 +0200 |
| commit | 2d1164287a3dcf08d1b8cc8457a2b5dd4f4a896a (patch) | |
| tree | fd5e91bb9a1e068eadef73bf52c4909687babddd /src | |
| parent | f06cf17a90e8f181e8717588e1398efb06b802cc (diff) | |
Start working on file resolving
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 296 | ||||
| -rw-r--r-- | src/server/caches.odin | 2 | ||||
| -rw-r--r-- | src/server/file_resolve.odin | 110 | ||||
| -rw-r--r-- | src/server/imports.odin | 4 | ||||
| -rw-r--r-- | src/server/references.odin | 2 |
5 files changed, 116 insertions, 298 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 2f6f20e..2a80ea3 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1308,7 +1308,8 @@ internal_resolve_type_identifier :: proc( signature = node.name, pkg = ast_context.current_package, value = SymbolUntypedValue{type = .Bool}, - }, true + }, + true case: return { type = .Keyword, @@ -1316,7 +1317,8 @@ internal_resolve_type_identifier :: proc( name = ident.name, pkg = ast_context.current_package, value = SymbolBasicValue{ident = ident}, - }, true + }, + true } } @@ -3788,296 +3790,6 @@ clear_locals :: proc(ast_context: ^AstContext) { clear(&ast_context.usings) } -ResolveReferenceFlag :: enum { - None, - Variable, - Constant, - StructElement, - EnumElement, -} - -resolve_entire_file :: proc( - document: ^Document, - reference := "", - flag := ResolveReferenceFlag.None, - save_unresolved := false, - allocator := context.allocator, -) -> map[uintptr]SymbolAndNode { - ast_context := make_ast_context( - document.ast, - document.imports, - document.package_name, - document.uri.uri, - document.fullpath, - allocator, - ) - - get_globals(document.ast, &ast_context) - - ast_context.current_package = ast_context.document_package - - symbols := make(map[uintptr]SymbolAndNode, 10000, allocator) - - for decl in document.ast.decls { - if _, is_value := decl.derived.(^ast.Value_Decl); !is_value { - continue - } - - resolve_entire_decl( - &ast_context, - document, - decl, - &symbols, - reference, - flag, - save_unresolved, - allocator, - ) - clear(&ast_context.locals) - } - - return symbols -} - -resolve_entire_decl :: proc( - ast_context: ^AstContext, - document: ^Document, - decl: ^ast.Node, - symbols: ^map[uintptr]SymbolAndNode, - reference := "", - flag := ResolveReferenceFlag.None, - save_unresolved := false, - allocator := context.allocator, -) { - Scope :: struct { - offset: int, - id: int, - } - - Visit_Data :: struct { - ast_context: ^AstContext, - symbols: ^map[uintptr]SymbolAndNode, - scopes: [dynamic]Scope, - id_counter: int, - last_visit: ^ast.Node, - resolve_flag: ResolveReferenceFlag, - reference: string, - save_unresolved: bool, - document: ^Document, - } - - data := Visit_Data { - ast_context = ast_context, - symbols = symbols, - scopes = make([dynamic]Scope, allocator), - resolve_flag = flag, - reference = reference, - document = document, - save_unresolved = save_unresolved, - } - - visit :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor { - if node == nil || visitor == nil { - return nil - } - data := cast(^Visit_Data)visitor.data - ast_context := data.ast_context - - reset_ast_context(ast_context) - - data.last_visit = node - - //It's somewhat silly to check the scope everytime, but the alternative is to implement my own walker function. - if len(data.scopes) > 0 { - current_scope := data.scopes[len(data.scopes) - 1] - - if current_scope.offset < node.end.offset { - clear_local_group(ast_context, current_scope.id) - - pop(&data.scopes) - - if len(data.scopes) > 0 { - current_scope = data.scopes[len(data.scopes) - 1] - ast_context.local_id = current_scope.id - } else { - ast_context.local_id = 0 - } - } - } - - #partial switch v in node.derived { - case ^ast.Proc_Lit: - if v.body == nil { - break - } - - scope: Scope - scope.id = data.id_counter - scope.offset = node.end.offset - data.id_counter += 1 - ast_context.local_id = scope.id - - append(&data.scopes, scope) - add_local_group(ast_context, scope.id) - - position_context: DocumentPositionContext - position_context.position = node.end.offset - - get_locals_proc_param_and_results( - ast_context.file, - v^, - ast_context, - &position_context, - ) - get_locals_stmt( - ast_context.file, - cast(^ast.Stmt)node, - ast_context, - &position_context, - ) - case ^ast.If_Stmt, - ^ast.For_Stmt, - ^ast.Range_Stmt, - ^ast.Inline_Range_Stmt: - scope: Scope - scope.id = data.id_counter - scope.offset = node.end.offset - data.id_counter += 1 - ast_context.local_id = scope.id - - append(&data.scopes, scope) - add_local_group(ast_context, scope.id) - - position_context: DocumentPositionContext - position_context.position = node.end.offset - get_locals_stmt( - ast_context.file, - cast(^ast.Stmt)node, - ast_context, - &position_context, - ) - } - - if data.resolve_flag == .None { - #partial switch v in node.derived { - case ^ast.Ident: - if symbol, ok := resolve_type_identifier(ast_context, v^); ok { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - symbol = symbol, - is_resolved = true, - } - } else if data.save_unresolved { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - } - } - case ^ast.Selector_Expr: - if symbol, ok := resolve_type_expression(ast_context, &v.node); - ok { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - symbol = symbol, - is_resolved = true, - } - } else if data.save_unresolved { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - } - } - case ^ast.Call_Expr: - if symbol, ok := resolve_type_expression(ast_context, &v.node); - ok { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - symbol = symbol, - is_resolved = true, - } - } else if data.save_unresolved { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - } - } - } - } else { - #partial done: switch v in node.derived { - case ^ast.Selector_Expr: - document: ^Document = data.document - - position_context := DocumentPositionContext { - position = v.pos.offset, - } - - get_document_position_decls( - document.ast.decls[:], - &position_context, - ) - - if symbol, ok := resolve_location_selector(ast_context, v); - ok { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v.field, - symbol = symbol, - } - } - - if _, is_ident := v.field.derived.(^ast.Ident); is_ident { - if data.resolve_flag == .Constant || - data.resolve_flag == .Variable { - return nil - } - } - case ^ast.Ident: - if data.resolve_flag == .Variable && v.name != data.reference { - break done - } - - document: ^Document = data.document - - position_context := DocumentPositionContext { - position = v.pos.offset, - } - - get_document_position_decls( - document.ast.decls[:], - &position_context, - ) - - if position_context.field_value != nil && - position_in_node( - position_context.field_value.field, - v.pos.offset, - ) { - break done - } else if position_context.struct_type != nil && - data.resolve_flag != .StructElement { - break done - } else if position_context.enum_type != nil && - data.resolve_flag != .EnumElement { - break done - } - - if symbol, ok := resolve_location_identifier(ast_context, v^); - ok { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = v, - symbol = symbol, - } - } - } - } - - return visitor - } - - visitor := ast.Visitor { - data = &data, - visit = visit, - } - - ast.walk(&visitor, decl) -} - concatenate_symbol_information :: proc { concatenate_raw_symbol_information, concatenate_raw_string_information, diff --git a/src/server/caches.odin b/src/server/caches.odin index d286624..a861cc6 100644 --- a/src/server/caches.odin +++ b/src/server/caches.odin @@ -24,9 +24,7 @@ resolve_entire_file_cached :: proc( file_resolve_cache.files[document.uri.uri] = FileResolve { symbols = resolve_entire_file( document, - "", .None, - false, common.scratch_allocator(document.allocator), ), } diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin new file mode 100644 index 0000000..5645025 --- /dev/null +++ b/src/server/file_resolve.odin @@ -0,0 +1,110 @@ +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:reflect" +import "core:slice" +import "core:sort" +import "core:strconv" +import "core:strings" +import "core:unicode/utf8" + +import "src:common" + +ResolveReferenceFlag :: enum { + None, + Variable, + Constant, + StructElement, + EnumElement, +} + +resolve_entire_file :: proc( + document: ^Document, + flag := ResolveReferenceFlag.None, + allocator := context.allocator, +) -> map[uintptr]SymbolAndNode { + ast_context := make_ast_context( + document.ast, + document.imports, + document.package_name, + document.uri.uri, + document.fullpath, + allocator, + ) + + get_globals(document.ast, &ast_context) + + + ast_context.current_package = ast_context.document_package + + symbols := make(map[uintptr]SymbolAndNode, 10000, allocator) + + for decl in document.ast.decls { + if _, is_value := decl.derived.(^ast.Value_Decl); !is_value { + continue + } + + resolve_decl(&ast_context, document, decl, &symbols, allocator) + clear(&ast_context.locals) + } + + return symbols +} + +FileResolveData :: struct { + ast_context: ^AstContext, + symbols: ^map[uintptr]SymbolAndNode, + id_counter: int, + document: ^Document, +} + + +@(private = "file") +resolve_decl :: proc( + ast_context: ^AstContext, + document: ^Document, + decl: ^ast.Node, + symbols: ^map[uintptr]SymbolAndNode, + allocator := context.allocator, +) { + data := FileResolveData { + ast_context = ast_context, + symbols = symbols, + document = document, + } + +} + +@(private = "file") +resolve_node :: proc( + ast_context: ^AstContext, + document: ^Document, + node: ^ast.Node, + symbols: ^map[uintptr]SymbolAndNode, + data: FileResolveData, + allocator := context.allocator, +) { + + +} + +@(private = "file") +resolve_nodes :: proc( + ast_context: ^AstContext, + document: ^Document, + array: []$T/^ast.Node, + symbols: ^map[uintptr]SymbolAndNode, + data: FileResolveData, + allocator := context.allocator, +) { + for elem in array { + resolve_node(elem) + } +} diff --git a/src/server/imports.odin b/src/server/imports.odin index 7bdf6a9..cd2271d 100644 --- a/src/server/imports.odin +++ b/src/server/imports.odin @@ -1,7 +1,7 @@ package server -import "core:odin/ast" import "core:mem" +import "core:odin/ast" fix_imports :: proc(document: ^Document) { @@ -11,7 +11,7 @@ fix_imports :: proc(document: ^Document) { context.allocator = mem.arena_allocator(&arena) - symbols_and_nodes := resolve_entire_file(document, "", .None, true) + symbols_and_nodes := resolve_entire_file(document, .None) } diff --git a/src/server/references.odin b/src/server/references.odin index 49d95bf..31fac9c 100644 --- a/src/server/references.odin +++ b/src/server/references.odin @@ -227,9 +227,7 @@ resolve_references :: proc( if in_pkg { symbols_and_nodes := resolve_entire_file( &document, - reference, resolve_flag, - false, context.allocator, ) |