aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-05-11 20:35:08 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-05-11 20:35:08 +0200
commit2d1164287a3dcf08d1b8cc8457a2b5dd4f4a896a (patch)
treefd5e91bb9a1e068eadef73bf52c4909687babddd /src
parentf06cf17a90e8f181e8717588e1398efb06b802cc (diff)
Start working on file resolving
Diffstat (limited to 'src')
-rw-r--r--src/server/analysis.odin296
-rw-r--r--src/server/caches.odin2
-rw-r--r--src/server/file_resolve.odin110
-rw-r--r--src/server/imports.odin4
-rw-r--r--src/server/references.odin2
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,
)