aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/position.odin7
-rw-r--r--src/server/analysis.odin44
-rw-r--r--src/server/check.odin2
-rw-r--r--src/server/completion.odin2
-rw-r--r--src/server/requests.odin5
5 files changed, 46 insertions, 14 deletions
diff --git a/src/common/position.odin b/src/common/position.odin
index b222086..739f3aa 100644
--- a/src/common/position.odin
+++ b/src/common/position.odin
@@ -4,6 +4,7 @@ import "core:strings"
import "core:unicode/utf8"
import "core:fmt"
import "core:odin/ast"
+import "core:log"
/*
This file handles the conversion between utf-16 and utf-8 offsets in the text document
@@ -129,12 +130,16 @@ go_backwards_to_endline :: proc(offset: int, document_text: []u8) -> int {
get_token_range :: proc(node: ast.Node, document_text: string) -> Range {
range: Range
-
pos_offset := min(len(document_text) - 1, node.pos.offset)
end_offset := min(len(document_text) - 1, node.end.offset)
offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text)
+ if offset < 0 {
+ offset := 0
+ log.errorf("Failed to find offset in get_token_range: %v", node)
+ }
+
range.start.line = node.pos.line - 1
range.start.character = get_character_offset_u8_to_u16(
node.pos.column - 1,
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 7841140..6f86dd3 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -76,6 +76,8 @@ DocumentLocal :: struct {
parameter: bool,
}
+DeferredDepth :: 100
+
AstContext :: struct {
locals: map[int]map[string][dynamic]DocumentLocal, //locals all the way to the document position
globals: map[string]common.GlobalExpr,
@@ -86,7 +88,8 @@ AstContext :: struct {
imports: []Package, //imports for the current document
current_package: string,
document_package: string,
- saved_package: string,
+ deferred_package: [DeferredDepth]string, //When a package change happens when resolving
+ deferred_count: int,
use_locals: bool,
local_id: int,
call: ^ast.Call_Expr, //used to determine the types for generics and the correct function for overloaded functions
@@ -130,29 +133,42 @@ make_ast_context :: proc(
}
set_ast_package_deferred :: proc(ast_context: ^AstContext, pkg: string) {
- ast_context.current_package = ast_context.saved_package
+ 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) {
- ast_context.saved_package = ast_context.current_package
+ ast_context.deferred_package[ast_context.deferred_count] =
+ ast_context.current_package
+ ast_context.deferred_count += 1
ast_context.current_package = pkg
}
set_ast_package_none_deferred :: proc(ast_context: ^AstContext) {
- ast_context.current_package = ast_context.saved_package
+ 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) {
- ast_context.saved_package = ast_context.current_package
+ ast_context.deferred_package[ast_context.deferred_count] =
+ ast_context.current_package
+ ast_context.deferred_count += 1
}
set_ast_package_from_symbol_deferred :: proc(
ast_context: ^AstContext,
symbol: Symbol,
) {
- ast_context.current_package = ast_context.saved_package
+ 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)
@@ -160,7 +176,9 @@ set_ast_package_from_symbol_scoped :: proc(
ast_context: ^AstContext,
symbol: Symbol,
) {
- ast_context.saved_package = ast_context.current_package
+ ast_context.deferred_package[ast_context.deferred_count] =
+ ast_context.current_package
+ ast_context.deferred_count += 1
if symbol.pkg != "" {
ast_context.current_package = symbol.pkg
@@ -804,6 +822,11 @@ 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)
}
@@ -1294,6 +1317,11 @@ 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)
}
@@ -2064,7 +2092,7 @@ resolve_symbol_return :: proc(
}
}
- #partial switch v in &symbol.value {
+ #partial switch &v in symbol.value {
case SymbolProcedureGroupValue:
if symbol, ok := resolve_function_overload(
ast_context,
diff --git a/src/server/check.odin b/src/server/check.odin
index b18de55..9ad148a 100644
--- a/src/server/check.odin
+++ b/src/server/check.odin
@@ -131,7 +131,7 @@ check :: proc(
if code, ok, buffer = common.run_executable(
fmt.tprintf(
- "%v check %s %s %s %s %s %s",
+ "%v check \"%s\" %s %s %s %s %s",
command,
path,
strings.to_string(collection_builder),
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 948fee5..356903e 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -2000,7 +2000,7 @@ format_to_label_details :: proc(list: ^CompletionList) {
// detail = left
// description = right
- for item in &list.items {
+ for &item in list.items {
// log.errorf("item:%v: %v:%v", item.kind, item.label, item.detail)
#partial switch item.kind {
case .Function:
diff --git a/src/server/requests.odin b/src/server/requests.odin
index ded6970..8af1141 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -431,7 +431,6 @@ read_ols_initialize_options :: proc(
config.enable_checker_only_saved =
ols_config.enable_checker_only_saved.(bool) or_else config.enable_checker_only_saved
-
if ols_config.odin_command != "" {
config.odin_command = strings.clone(
@@ -1210,8 +1209,8 @@ notification_did_save :: proc(
corrected_uri := common.create_uri(fullpath, context.temp_allocator)
- for k, v in &indexer.index.collection.packages {
- for k2, v2 in &v.symbols {
+ for k, &v in indexer.index.collection.packages {
+ for k2, v2 in v.symbols {
if corrected_uri.uri == v2.uri {
free_symbol(v2, indexer.index.collection.allocator)
delete_key(&v.symbols, k2)