aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin45
-rw-r--r--src/server/file_resolve.odin79
-rw-r--r--src/server/references.odin67
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)
}
}