diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/analysis.odin | 45 | ||||
| -rw-r--r-- | src/server/file_resolve.odin | 79 | ||||
| -rw-r--r-- | src/server/references.odin | 67 |
3 files changed, 154 insertions, 37 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 61855ef..99b2acb 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -133,14 +133,17 @@ make_ast_context :: proc( } set_ast_package_deferred :: proc(ast_context: ^AstContext, pkg: string) { + assert(ast_context.deferred_count > 0) ast_context.deferred_count -= 1 ast_context.current_package = ast_context.deferred_package[ast_context.deferred_count] - assert(ast_context.deferred_count >= 0) } @(deferred_in = set_ast_package_deferred) set_ast_package_set_scoped :: proc(ast_context: ^AstContext, pkg: string) { + if ast_context.deferred_count >= DeferredDepth { + return + } ast_context.deferred_package[ast_context.deferred_count] = ast_context.current_package ast_context.deferred_count += 1 @@ -148,14 +151,17 @@ set_ast_package_set_scoped :: proc(ast_context: ^AstContext, pkg: string) { } set_ast_package_none_deferred :: proc(ast_context: ^AstContext) { + assert(ast_context.deferred_count > 0) ast_context.deferred_count -= 1 ast_context.current_package = ast_context.deferred_package[ast_context.deferred_count] - assert(ast_context.deferred_count >= 0) } @(deferred_in = set_ast_package_none_deferred) set_ast_package_scoped :: proc(ast_context: ^AstContext) { + if ast_context.deferred_count >= DeferredDepth { + return + } ast_context.deferred_package[ast_context.deferred_count] = ast_context.current_package ast_context.deferred_count += 1 @@ -165,10 +171,10 @@ set_ast_package_from_symbol_deferred :: proc( ast_context: ^AstContext, symbol: Symbol, ) { + assert(ast_context.deferred_count > 0) ast_context.deferred_count -= 1 ast_context.current_package = ast_context.deferred_package[ast_context.deferred_count] - assert(ast_context.deferred_count >= 0) } @(deferred_in = set_ast_package_from_symbol_deferred) @@ -176,6 +182,10 @@ set_ast_package_from_symbol_scoped :: proc( ast_context: ^AstContext, symbol: Symbol, ) { + if ast_context.deferred_count >= DeferredDepth { + return + } + ast_context.deferred_package[ast_context.deferred_count] = ast_context.current_package ast_context.deferred_count += 1 @@ -822,11 +832,6 @@ resolve_type_expression :: proc( Symbol, bool, ) { - //Try to prevent stack overflows and prevent indexing out of bounds. - if ast_context.deferred_count >= DeferredDepth { - return {}, false - } - clear(&ast_context.recursion_map) return internal_resolve_type_expression(ast_context, node) } @@ -842,6 +847,11 @@ internal_resolve_type_expression :: proc( return {}, false } + //Try to prevent stack overflows and prevent indexing out of bounds. + if ast_context.deferred_count >= DeferredDepth { + return {}, false + } + set_ast_package_scoped(ast_context) if check_node_recursion(ast_context, node) { @@ -1317,11 +1327,6 @@ resolve_type_identifier :: proc( Symbol, bool, ) { - //Try to prevent stack overflows and prevent indexing out of bounds. - if ast_context.deferred_count > DeferredDepth { - return {}, false - } - return internal_resolve_type_identifier(ast_context, node) } @@ -1338,6 +1343,11 @@ internal_resolve_type_identifier :: proc( return {}, false } + //Try to prevent stack overflows and prevent indexing out of bounds. + if ast_context.deferred_count >= DeferredDepth { + return {}, false + } + set_ast_package_scoped(ast_context) if v, ok := common.keyword_map[node.name]; ok { @@ -2326,6 +2336,15 @@ resolve_location_implicit_selector :: proc( symbol.range = v.ranges[i] } } + case SymbolUnionValue: + enum_value := unwrap_super_enum(ast_context, v) or_return + for name, i in enum_value.names { + if strings.compare(name, implicit_selector.field.name) == 0 { + symbol.range = enum_value.ranges[i] + } + } + case: + ok = false } return symbol, ok diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin index 3c1ed17..ebf984d 100644 --- a/src/server/file_resolve.odin +++ b/src/server/file_resolve.odin @@ -30,6 +30,8 @@ reset_position_context :: proc(position_context: ^DocumentPositionContext) { position_context.parent_comp_lit = nil position_context.identifier = nil position_context.call = nil + position_context.binary = nil + position_context.parent_binary = nil } resolve_entire_file :: proc( @@ -170,6 +172,23 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) { resolve_node(n.expr, data) resolve_node(n.call, data) + case ^Implicit_Selector_Expr: + data.position_context.implicit = true + data.position_context.implicit_selector_expr = n + if data.flag != .None { + data.position_context.position = n.pos.offset + if symbol, ok := resolve_location_implicit_selector( + data.ast_context, + data.position_context, + n, + ); ok { + data.symbols[cast(uintptr)node] = SymbolAndNode { + node = n, + symbol = symbol, + } + } + } + resolve_node(n.field, data) case ^Selector_Expr: data.position_context.selector = n.expr data.position_context.field = n.field @@ -408,20 +427,6 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) { case ^Attribute: resolve_nodes(n.elems, data) case ^Field: - if data.flag != .None { - for name in n.names { - data.symbols[cast(uintptr)node] = SymbolAndNode { - node = name, - symbol = Symbol { - range = common.get_token_range( - name, - string(data.document.text), - ), - }, - } - } - } - resolve_nodes(n.names, data) resolve_node(n.type, data) resolve_node(n.default_value, data) @@ -453,15 +458,57 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) { resolve_node(n.poly_params, data) resolve_node(n.align, data) resolve_node(n.fields, data) + + if data.flag != .None { + for field in n.fields.list { + for name in field.names { + data.symbols[cast(uintptr)name] = SymbolAndNode { + node = name, + symbol = Symbol { + range = common.get_token_range( + name, + string(data.document.text), + ), + }, + } + } + } + } case ^Union_Type: data.position_context.union_type = n resolve_node(n.poly_params, data) resolve_node(n.align, data) resolve_nodes(n.variants, data) + + if data.flag != .None { + for variant in n.variants { + data.symbols[cast(uintptr)variant] = SymbolAndNode { + node = variant, + symbol = Symbol { + range = common.get_token_range( + variant, + string(data.document.text), + ), + }, + } + } + } case ^Enum_Type: data.position_context.enum_type = n resolve_node(n.base_type, data) resolve_nodes(n.fields, data) + + for field in n.fields { + data.symbols[cast(uintptr)field] = SymbolAndNode { + node = field, + symbol = Symbol { + range = common.get_token_range( + field, + string(data.document.text), + ), + }, + } + } case ^Bit_Set_Type: data.position_context.bitset_type = n resolve_node(n.elem, data) @@ -469,10 +516,6 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) { case ^Map_Type: resolve_node(n.key, data) resolve_node(n.value, data) - case ^Implicit_Selector_Expr: - data.position_context.implicit = true - data.position_context.implicit_selector_expr = n - resolve_node(n.field, data) case ^ast.Or_Else_Expr: resolve_node(n.x, data) resolve_node(n.y, data) diff --git a/src/server/references.odin b/src/server/references.odin index 160caba..1c77e45 100644 --- a/src/server/references.odin +++ b/src/server/references.odin @@ -81,7 +81,7 @@ resolve_references :: proc( if position_context.struct_type != nil { found := false - done: for field in position_context.struct_type.fields.list { + done_struct: for field in position_context.struct_type.fields.list { for name in field.names { if position_in_node(name, position_context.position) { symbol = Symbol { @@ -92,7 +92,7 @@ resolve_references :: proc( } found = true resolve_flag = .Field - break done + break done_struct } } } @@ -100,11 +100,48 @@ resolve_references :: proc( return {}, false } } else if position_context.enum_type != nil { - return {}, true + /* + found := false + done_enum: for field in position_context.struct_type.fields.list { + for name in field.names { + if position_in_node(name, position_context.position) { + symbol = Symbol { + range = common.get_token_range( + name, + string(document.text), + ), + } + found = true + resolve_flag = .Field + break done_enum + } + } + } + if !found { + return {}, false + } + */ } else if position_context.bitset_type != nil { return {}, true } else if position_context.union_type != nil { - return {}, true + found := false + for variant in position_context.union_type.variants { + if position_in_node(variant, position_context.position) { + symbol = Symbol { + range = common.get_token_range( + variant, + string(document.text), + ), + } + found = true + resolve_flag = .Identifier + break + } + } + if !found { + return {}, false + } + } else if position_context.field_value != nil && position_context.comp_lit != nil && !common.is_expr_basic_lit(position_context.field_value.field) && @@ -155,7 +192,17 @@ resolve_references :: proc( resolve_flag = .Field } } else if position_context.implicit { - return {}, true + resolve_flag = .Field + + symbol, ok = resolve_location_implicit_selector( + ast_context, + position_context, + position_context.implicit_selector_expr, + ) + + if !ok { + return {}, true + } } else if position_context.identifier != nil { ident := position_context.identifier.derived.(^ast.Ident) @@ -301,10 +348,18 @@ resolve_references :: proc( ast_context.allocator, ) + range := common.get_token_range(v.node^, string(document.text)) + + //We don't have to have the `.` with, otherwise it renames the dot. + if _, ok := v.node.derived.(^ast.Implicit_Selector_Expr); ok { + range.start.character += 1 + } + location := common.Location { - range = common.get_token_range(v.node^, string(document.text)), + range = range, uri = strings.clone(node_uri.uri, ast_context.allocator), } + append(&locations, location) } } |