aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-05-29 16:41:24 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-05-29 16:41:24 +0200
commit9cf3c6313e77b0c3d80b8ffc298b20ab2d5b633d (patch)
tree38e14e644432a8a3dd2d23634a7b65798731371d /src
parent3eb6d78ea9c2b67ca2bbcd4b775c70ab0558ab29 (diff)
Work on file resolve
Diffstat (limited to 'src')
-rw-r--r--src/server/file_resolve.odin217
-rw-r--r--src/server/semantic_tokens.odin8
-rw-r--r--src/server/symbol.odin7
-rw-r--r--src/testing/testing.odin38
4 files changed, 204 insertions, 66 deletions
diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin
index c3842a4..1aa5163 100644
--- a/src/server/file_resolve.odin
+++ b/src/server/file_resolve.odin
@@ -39,6 +39,8 @@ resolve_entire_file :: proc(
allocator,
)
+ position_context: DocumentPositionContext
+
get_globals(document.ast, &ast_context)
ast_context.current_package = ast_context.document_package
@@ -50,7 +52,15 @@ resolve_entire_file :: proc(
continue
}
- resolve_decl(&ast_context, document, decl, &symbols, allocator)
+ resolve_decl(
+ &position_context,
+ &ast_context,
+ document,
+ decl,
+ &symbols,
+ flag,
+ allocator,
+ )
clear(&ast_context.locals)
}
@@ -63,25 +73,54 @@ FileResolveData :: struct {
id_counter: int,
document: ^Document,
position_context: ^DocumentPositionContext,
+ flag: ResolveReferenceFlag,
}
@(private = "file")
resolve_decl :: proc(
+ position_context: ^DocumentPositionContext,
ast_context: ^AstContext,
document: ^Document,
decl: ^ast.Node,
symbols: ^map[uintptr]SymbolAndNode,
+ flag: ResolveReferenceFlag,
allocator := context.allocator,
) {
data := FileResolveData {
- ast_context = ast_context,
- symbols = symbols,
- document = document,
+ position_context = position_context,
+ ast_context = ast_context,
+ symbols = symbols,
+ document = document,
+ flag = flag,
}
resolve_node(decl, &data)
}
+
+@(private = "file")
+local_scope_deferred :: proc(data: ^FileResolveData, stmt: ^ast.Stmt) {
+ clear_local_group(data.ast_context, data.ast_context.local_id)
+ data.ast_context.local_id -= 1
+}
+
+@(deferred_in = local_scope_deferred)
+@(private = "file")
+local_scope :: proc(data: ^FileResolveData, stmt: ^ast.Stmt) {
+ data.ast_context.local_id += 1
+
+ add_local_group(data.ast_context, data.ast_context.local_id)
+
+ data.position_context.position = stmt.end.offset
+
+ get_locals_stmt(
+ data.ast_context.file,
+ stmt,
+ data.ast_context,
+ data.position_context,
+ )
+}
+
@(private = "file")
resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
using ast
@@ -90,11 +129,127 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
return
}
+ reset_ast_context(data.ast_context)
#partial switch n in node.derived {
case ^Bad_Expr:
case ^Ident:
data.position_context.identifier = node
+
+ if data.flag != .None {
+ if symbol, ok := resolve_location_identifier(data.ast_context, n^);
+ ok {
+ data.symbols[cast(uintptr)node] = SymbolAndNode {
+ node = n,
+ symbol = symbol,
+ }
+ }
+ } else {
+ if symbol, ok := resolve_type_identifier(data.ast_context, n^);
+ ok {
+ data.symbols[cast(uintptr)node] = SymbolAndNode {
+ node = n,
+ symbol = symbol,
+ }
+ }
+ }
+ case ^Selector_Call_Expr:
+ data.position_context.selector = n.expr
+ data.position_context.field = n.call
+ data.position_context.selector_expr = cast(^Selector_Expr)node
+
+ if _, ok := n.call.derived.(^ast.Call_Expr); ok {
+ data.position_context.call = n.call
+ }
+
+ resolve_node(n.expr, data)
+ resolve_node(n.call, data)
+ case ^Selector_Expr:
+ data.position_context.selector = n.expr
+ data.position_context.field = n.field
+ data.position_context.selector_expr = cast(^Selector_Expr)node
+
+ if data.flag != .None {
+ if symbol, ok := resolve_location_selector(data.ast_context, n);
+ ok {
+ data.symbols[cast(uintptr)node] = SymbolAndNode {
+ node = n,
+ symbol = symbol,
+ }
+ }
+ } else {
+ if symbol, ok := resolve_type_expression(
+ data.ast_context,
+ &n.node,
+ ); ok {
+ data.symbols[cast(uintptr)node] = SymbolAndNode {
+ node = n,
+ symbol = symbol,
+ }
+ }
+ }
+
+ resolve_node(n.expr, data)
+ resolve_node(n.field, data)
+ case ^Proc_Lit:
+ local_scope(data, n.body)
+
+ get_locals_proc_param_and_results(
+ data.ast_context.file,
+ n^,
+ data.ast_context,
+ data.position_context,
+ )
+
+ //log.error(data.ast_context.locals)
+
+ resolve_node(n.type, data)
+
+ data.position_context.function = cast(^Proc_Lit)node
+
+ append(
+ &data.position_context.functions,
+ data.position_context.function,
+ )
+
+ resolve_node(n.body, data)
+ case ^ast.Inline_Range_Stmt:
+ local_scope(data, n)
+ resolve_node(n.val0, data)
+ resolve_node(n.val1, data)
+ resolve_node(n.expr, data)
+ resolve_node(n.body, data)
+ case ^For_Stmt:
+ local_scope(data, n)
+ resolve_node(n.label, data)
+ resolve_node(n.init, data)
+ resolve_node(n.cond, data)
+ resolve_node(n.post, data)
+ resolve_node(n.body, data)
+ case ^Range_Stmt:
+ local_scope(data, n)
+ resolve_node(n.label, data)
+ resolve_nodes(n.vals, data)
+ resolve_node(n.expr, data)
+ resolve_node(n.body, data)
+ case ^Switch_Stmt:
+ local_scope(data, n)
+ data.position_context.switch_stmt = cast(^Switch_Stmt)node
+ resolve_node(n.label, data)
+ resolve_node(n.init, data)
+ resolve_node(n.cond, data)
+ resolve_node(n.body, data)
+ case ^If_Stmt:
+ local_scope(data, n)
+ resolve_node(n.label, data)
+ resolve_node(n.init, data)
+ resolve_node(n.cond, data)
+ resolve_node(n.body, data)
+ resolve_node(n.else_stmt, data)
+ case ^When_Stmt:
+ resolve_node(n.cond, data)
+ resolve_node(n.body, data)
+ resolve_node(n.else_stmt, data)
case ^Implicit:
if n.tok.text == "context" {
data.position_context.implicit_context = n
@@ -112,15 +267,7 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
resolve_node(n.elem, data)
case ^Ellipsis:
resolve_node(n.expr, data)
- case ^Proc_Lit:
- resolve_node(n.type, data)
- data.position_context.function = cast(^Proc_Lit)node
- append(
- &data.position_context.functions,
- data.position_context.function,
- )
- resolve_node(n.body, data)
case ^Comp_Lit:
//only set this for the parent comp literal, since we will need to walk through it to infer types.
if data.position_context.parent_comp_lit == nil {
@@ -148,24 +295,6 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
data.position_context.call = cast(^Expr)node
resolve_node(n.expr, data)
resolve_nodes(n.args, data)
- case ^Selector_Call_Expr:
- data.position_context.selector = n.expr
- data.position_context.field = n.call
- data.position_context.selector_expr = cast(^Selector_Expr)node
-
- if _, ok := n.call.derived.(^ast.Call_Expr); ok {
- data.position_context.call = n.call
- }
-
- resolve_node(n.expr, data)
- resolve_node(n.call, data)
-
- case ^Selector_Expr:
- data.position_context.selector = n.expr
- data.position_context.field = n.field
- data.position_context.selector_expr = cast(^Selector_Expr)node
- resolve_node(n.expr, data)
- resolve_node(n.field, data)
case ^Index_Expr:
resolve_node(n.expr, data)
resolve_node(n.index, data)
@@ -209,41 +338,14 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
case ^Block_Stmt:
resolve_node(n.label, data)
resolve_nodes(n.stmts, data)
- case ^If_Stmt:
- resolve_node(n.label, data)
- resolve_node(n.init, data)
- resolve_node(n.cond, data)
- resolve_node(n.body, data)
- resolve_node(n.else_stmt, data)
- case ^When_Stmt:
- resolve_node(n.cond, data)
- resolve_node(n.body, data)
- resolve_node(n.else_stmt, data)
case ^Return_Stmt:
data.position_context.returns = cast(^Return_Stmt)node
resolve_nodes(n.results, data)
case ^Defer_Stmt:
resolve_node(n.stmt, data)
- case ^For_Stmt:
- resolve_node(n.label, data)
- resolve_node(n.init, data)
- resolve_node(n.cond, data)
- resolve_node(n.post, data)
- resolve_node(n.body, data)
- case ^Range_Stmt:
- resolve_node(n.label, data)
- resolve_nodes(n.vals, data)
- resolve_node(n.expr, data)
- resolve_node(n.body, data)
case ^Case_Clause:
resolve_nodes(n.list, data)
resolve_nodes(n.body, data)
- case ^Switch_Stmt:
- data.position_context.switch_stmt = cast(^Switch_Stmt)node
- resolve_node(n.label, data)
- resolve_node(n.init, data)
- resolve_node(n.cond, data)
- resolve_node(n.body, data)
case ^Type_Switch_Stmt:
data.position_context.switch_type_stmt = cast(^Type_Switch_Stmt)node
resolve_node(n.label, data)
@@ -257,7 +359,6 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
case ^Bad_Decl:
case ^Value_Decl:
data.position_context.value_decl = cast(^Value_Decl)node
-
resolve_nodes(n.names, data)
resolve_node(n.type, data)
resolve_nodes(n.values, data)
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index 36e7c83..507cd18 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -562,11 +562,15 @@ visit_ident :: proc(
modifiers += {.ReadOnly}
}
+ //log.errorf("%# \n", symbol)
+
/* variable idents */
#partial switch symbol.type {
case .Variable, .Constant, .Function:
#partial switch _ in symbol.value {
- case SymbolProcedureValue, SymbolProcedureGroupValue, SymbolAggregateValue:
+ case SymbolProcedureValue,
+ SymbolProcedureGroupValue,
+ SymbolAggregateValue:
write_semantic_node(builder, ident, .Function, modifiers)
case:
write_semantic_node(builder, ident, .Variable, modifiers)
@@ -598,7 +602,5 @@ visit_ident :: proc(
case SymbolGenericValue, SymbolProcedureGroupValue, SymbolAggregateValue:
// unused
case:
- // log.errorf("Unexpected symbol value: %v", symbol.value);
- // panic(fmt.tprintf("Unexpected symbol value: %v", symbol.value));
}
}
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 39708d9..f833627 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -14,9 +14,8 @@ import "core:strings"
import "src:common"
SymbolAndNode :: struct {
- symbol: Symbol,
- node: ^ast.Node,
- is_resolved: bool,
+ symbol: Symbol,
+ node: ^ast.Node,
}
SymbolStructValue :: struct {
@@ -176,7 +175,7 @@ SymbolType :: enum {
Struct = 22,
Type_Function = 23,
Union = 7,
- Type = 8, //For maps, arrays, slices, dyn arrays, matrixes, etc
+ Type = 8, //For maps, arrays, slices, dyn arrays, matrixes, etc
Unresolved = 1, //Use text if not being able to resolve it.
}
diff --git a/src/testing/testing.odin b/src/testing/testing.odin
index 9f67ff0..225775c 100644
--- a/src/testing/testing.odin
+++ b/src/testing/testing.odin
@@ -58,7 +58,8 @@ setup :: proc(src: ^Source) {
} else if current == '\n' {
current_line += 1
current_character = 0
- } else if src.main[current_index:current_index + 3] == "{*}" {
+ } else if len(src.main) > current_index + 3 &&
+ src.main[current_index:current_index + 3] == "{*}" {
dst_slice := transmute([]u8)src.main[current_index:]
src_slice := transmute([]u8)src.main[current_index + 3:]
copy(dst_slice, src_slice)
@@ -383,3 +384,38 @@ expect_definition_locations :: proc(
}
}
}
+
+expect_symbol_location :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ expect_locations: []common.Location,
+) {
+ setup(src)
+ defer teardown(src)
+
+ symbol_and_nodes := server.resolve_entire_file(src.document, .None)
+
+ ok := true
+
+ for location in expect_locations {
+ match := false
+ for k, v in symbol_and_nodes {
+ if v.symbol.range == location.range {
+ match = true
+ }
+ }
+ if !match {
+ ok = false
+ testing.errorf(t, "Failed to match with location: %v", location)
+ }
+ }
+
+ if !ok {
+ testing.error(t, "Received:")
+ for k, v in symbol_and_nodes {
+ testing.errorf(t, "%v \n", v.symbol)
+ }
+ }
+
+
+}