aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-05-29 21:40:01 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-05-29 21:40:01 +0200
commit2219138b240d0b8d8e71601b7852f666df316fea (patch)
treea551ecb0c420e60a4544e3bc483512345fa933be /src/server
parent9cf3c6313e77b0c3d80b8ffc298b20ab2d5b633d (diff)
More work on renaming
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin1
-rw-r--r--src/server/build.odin9
-rw-r--r--src/server/references.odin223
-rw-r--r--src/server/rename.odin55
-rw-r--r--src/server/requests.odin6
-rw-r--r--src/server/types.odin2
6 files changed, 151 insertions, 145 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 6f86dd3..91c5b6a 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2212,6 +2212,7 @@ resolve_location_identifier :: proc(
uri := common.create_uri(local.lhs.pos.file, ast_context.allocator)
symbol.pkg = ast_context.document_package
symbol.uri = uri.uri
+ symbol.flags |= {.Local}
return symbol, true
} else if global, ok := ast_context.globals[node.name]; ok {
symbol.range = common.get_token_range(
diff --git a/src/server/build.odin b/src/server/build.odin
index aca1796..69e63b2 100644
--- a/src/server/build.odin
+++ b/src/server/build.odin
@@ -160,14 +160,7 @@ setup_index :: proc() {
)
indexer.index = make_memory_index(symbol_collection)
- dir_exe, ok := filepath.abs(path.dir(os.args[0], context.temp_allocator))
-
- if !ok {
- log.error(
- "Failed to find ols executable path to build the builtin packages",
- )
- return
- }
+ dir_exe := common.get_executable_path()
try_build_package(path.join({dir_exe, "builtin"}))
}
diff --git a/src/server/references.odin b/src/server/references.odin
index 31fac9c..f1939c1 100644
--- a/src/server/references.odin
+++ b/src/server/references.odin
@@ -10,6 +10,7 @@ import "core:odin/parser"
import "core:os"
import "core:path/filepath"
import path "core:path/slashpath"
+import "core:slice"
import "core:strings"
import "src:common"
@@ -24,6 +25,8 @@ walk_directories :: proc(
err: os.Errno,
skip_dir: bool,
) {
+ document := cast(^Document)user_data
+
if info.is_dir {
return 0, false
}
@@ -33,7 +36,10 @@ walk_directories :: proc(
}
if strings.contains(info.name, ".odin") {
- append(&fullpaths, strings.clone(info.fullpath))
+ slash_path, _ := filepath.to_slash(info.fullpath)
+ if slash_path != document.fullpath {
+ append(&fullpaths, strings.clone(info.fullpath))
+ }
}
return 0, false
@@ -56,6 +62,7 @@ position_in_struct_names :: proc(
resolve_references :: proc(
+ document: ^Document,
ast_context: ^AstContext,
position_context: ^DocumentPositionContext,
) -> (
@@ -71,15 +78,11 @@ resolve_references :: proc(
ok: bool
pkg := ""
- filepath.walk(
- filepath.dir(os.args[0], context.allocator),
- walk_directories,
- nil,
- )
+ filepath.walk(common.get_executable_path(), walk_directories, document)
for workspace in common.config.workspace_folders {
uri, _ := common.parse_uri(workspace.uri, context.temp_allocator)
- filepath.walk(uri.path, walk_directories, nil)
+ filepath.walk(uri.path, walk_directories, document)
}
reset_ast_context(ast_context)
@@ -149,112 +152,144 @@ resolve_references :: proc(
}
}
- if !ok {
- return {}, true
- }
+ arena: runtime.Arena
- resolve_arena: mem.Arena
- mem.arena_init(&resolve_arena, make([]byte, mem.Megabyte * 25))
+ _ = runtime.arena_init(
+ &arena,
+ mem.Megabyte * 40,
+ runtime.default_allocator(),
+ )
- context.allocator = mem.arena_allocator(&resolve_arena)
+ defer runtime.arena_destroy(&arena)
- for fullpath in fullpaths {
- data, ok := os.read_entire_file(fullpath, context.allocator)
+ context.allocator = runtime.arena_allocator(&arena)
- if !ok {
- log.errorf("failed to read entire file for indexing %v", fullpath)
- continue
- }
+ fullpaths := slice.unique(fullpaths[:])
- p := parser.Parser {
- err = log_error_handler,
- warn = log_warning_handler,
- flags = {.Optional_Semicolons},
- }
+ if .Local not_in symbol.flags {
+ for fullpath in fullpaths {
+ dir := filepath.dir(fullpath)
+ base := filepath.base(dir)
+ forward_dir, _ := filepath.to_slash(dir)
- dir := filepath.dir(fullpath)
- base := filepath.base(dir)
- forward_dir, _ := filepath.to_slash(dir)
+ data, ok := os.read_entire_file(fullpath, context.allocator)
- pkg := new(ast.Package)
- pkg.kind = .Normal
- pkg.fullpath = fullpath
- pkg.name = base
+ if !ok {
+ log.errorf(
+ "failed to read entire file for indexing %v",
+ fullpath,
+ )
+ continue
+ }
- if base == "runtime" {
- pkg.kind = .Runtime
- }
+ p := parser.Parser {
+ err = log_error_handler,
+ warn = log_warning_handler,
+ flags = {.Optional_Semicolons},
+ }
- file := ast.File {
- fullpath = fullpath,
- src = string(data),
- pkg = pkg,
- }
- ok = parser.parse_file(&p, &file)
+ pkg := new(ast.Package)
+ pkg.kind = .Normal
+ pkg.fullpath = fullpath
+ pkg.name = base
- if !ok {
- if !strings.contains(fullpath, "builtin.odin") &&
- !strings.contains(fullpath, "intrinsics.odin") {
- log.errorf("error in parse file for indexing %v", fullpath)
+ if base == "runtime" {
+ pkg.kind = .Runtime
}
- continue
- }
- uri := common.create_uri(fullpath, context.allocator)
+ file := ast.File {
+ fullpath = fullpath,
+ src = string(data),
+ pkg = pkg,
+ }
- document := Document {
- ast = file,
- }
+ ok = parser.parse_file(&p, &file)
- document.uri = uri
- document.text = transmute([]u8)file.src
- document.used_text = len(file.src)
+ if !ok {
+ if !strings.contains(fullpath, "builtin.odin") &&
+ !strings.contains(fullpath, "intrinsics.odin") {
+ log.errorf("error in parse file for indexing %v", fullpath)
+ }
+ continue
+ }
- document_setup(&document)
+ uri := common.create_uri(fullpath, context.allocator)
- parse_imports(&document, &common.config)
+ document := Document {
+ ast = file,
+ }
- in_pkg := false
+ document.uri = uri
+ document.text = transmute([]u8)file.src
+ document.used_text = len(file.src)
- for pkg in document.imports {
- if pkg.name == symbol.pkg || forward_dir == symbol.pkg {
- in_pkg = true
- continue
- }
- }
+ document_setup(&document)
- if in_pkg {
- symbols_and_nodes := resolve_entire_file(
- &document,
- resolve_flag,
- context.allocator,
- )
+ parse_imports(&document, &common.config)
+
+ in_pkg := false
+
+ for pkg in document.imports {
+ if pkg.name == symbol.pkg {
+ in_pkg = true
+ continue
+ }
+ }
- for k, v in symbols_and_nodes {
- if v.symbol.uri == symbol.uri &&
- v.symbol.range == symbol.range {
- node_uri := common.create_uri(
- v.node.pos.file,
- ast_context.allocator,
- )
-
- location := common.Location {
- range = common.get_token_range(
- v.node^,
- string(document.text),
- ),
- uri = strings.clone(
- node_uri.uri,
+ if in_pkg {
+ symbols_and_nodes := resolve_entire_file(
+ &document,
+ resolve_flag,
+ context.allocator,
+ )
+
+ for k, v in symbols_and_nodes {
+ if v.symbol.uri == symbol.uri &&
+ v.symbol.range == symbol.range {
+ node_uri := common.create_uri(
+ v.node.pos.file,
ast_context.allocator,
- ),
+ )
+
+ location := common.Location {
+ range = common.get_token_range(
+ v.node^,
+ string(document.text),
+ ),
+ uri = strings.clone(
+ node_uri.uri,
+ ast_context.allocator,
+ ),
+ }
+ append(&locations, location)
}
- append(&locations, location)
}
}
+
+ free_all(context.allocator)
}
+ }
- free_all(context.allocator)
+ symbols_and_nodes := resolve_entire_file(
+ document,
+ resolve_flag,
+ context.allocator,
+ )
+
+ for k, v in symbols_and_nodes {
+ if v.symbol.uri == symbol.uri && v.symbol.range == symbol.range {
+ node_uri := common.create_uri(
+ v.node.pos.file,
+ ast_context.allocator,
+ )
+
+ location := common.Location {
+ range = common.get_token_range(v.node^, string(document.text)),
+ uri = strings.clone(node_uri.uri, ast_context.allocator),
+ }
+ append(&locations, location)
+ }
}
return locations[:], true
@@ -267,21 +302,13 @@ get_references :: proc(
[]common.Location,
bool,
) {
- data := make([]byte, mem.Megabyte * 55, runtime.default_allocator())
- defer delete(data)
-
- arena: mem.Arena
- mem.arena_init(&arena, data)
-
- context.allocator = mem.arena_allocator(&arena)
-
ast_context := make_ast_context(
document.ast,
document.imports,
document.package_name,
document.uri.uri,
document.fullpath,
- context.allocator,
+ context.temp_allocator,
)
position_context, ok := get_document_position_context(
@@ -303,7 +330,11 @@ get_references :: proc(
)
}
- locations, ok2 := resolve_references(&ast_context, &position_context)
+ locations, ok2 := resolve_references(
+ document,
+ &ast_context,
+ &position_context,
+ )
temp_locations := make([dynamic]common.Location, 0, context.temp_allocator)
diff --git a/src/server/rename.odin b/src/server/rename.odin
index 252ebaa..bf9ca8d 100644
--- a/src/server/rename.odin
+++ b/src/server/rename.odin
@@ -17,21 +17,13 @@ get_rename :: proc(
WorkspaceEdit,
bool,
) {
- data := make([]byte, mem.Megabyte * 55, runtime.default_allocator())
- defer delete(data)
-
- arena: mem.Arena
- mem.arena_init(&arena, data)
-
- context.allocator = mem.arena_allocator(&arena)
-
ast_context := make_ast_context(
document.ast,
document.imports,
document.package_name,
document.uri.uri,
document.fullpath,
- context.allocator,
+ context.temp_allocator,
)
position_context, ok := get_document_position_context(
@@ -53,30 +45,21 @@ get_rename :: proc(
)
}
- locations, ok2 := resolve_references(&ast_context, &position_context)
-
- document_edits := make(
- map[string][dynamic]TextEdit,
- 0,
- context.temp_allocator,
+ locations, ok2 := resolve_references(
+ document,
+ &ast_context,
+ &position_context,
)
+ changes := make(map[string][dynamic]TextEdit, 0, context.temp_allocator)
+
for location in locations {
edits: ^[dynamic]TextEdit
- /*
- if location.range.start.line <= position.line &&
- position.line <= location.range.end.line &&
- location.range.start.character <= position.character &&
- position.character <= location.range.end.character {
- continue
- }
- */
-
- if edits = &document_edits[location.uri]; edits == nil {
- document_edits[strings.clone(location.uri, context.temp_allocator)] =
+ if edits = &changes[location.uri]; edits == nil {
+ changes[strings.clone(location.uri, context.temp_allocator)] =
make([dynamic]TextEdit, context.temp_allocator)
- edits = &document_edits[location.uri]
+ edits = &changes[location.uri]
}
append(edits, TextEdit{newText = new_text, range = location.range})
@@ -84,19 +67,15 @@ get_rename :: proc(
workspace: WorkspaceEdit
- document_changes := make([dynamic]TextDocumentEdit, context.temp_allocator)
+ workspace.changes = make(
+ map[string][]TextEdit,
+ len(changes),
+ context.temp_allocator,
+ )
- for k, v in document_edits {
- append(
- &document_changes,
- TextDocumentEdit {
- edits = v[:],
- textDocument = {uri = k, version = document.version},
- },
- )
+ for k, v in changes {
+ workspace.changes[k] = v[:]
}
- workspace.documentChanges = document_changes[:]
-
return workspace, true
}
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 8af1141..ba91419 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -558,7 +558,9 @@ read_ols_initialize_options :: proc(
context.temp_allocator,
)
- config.collections[strings.clone(it.name)] = strings.clone(slashed_path)
+ config.collections[strings.clone(it.name)] = strings.clone(
+ slashed_path,
+ )
} else {
log.errorf(
"Failed to find absolute address of collection: %v",
@@ -743,7 +745,7 @@ request_initialize :: proc(
if uri, ok := common.parse_uri(project_uri, context.temp_allocator); ok {
global_ols_config_path := path.join(
- elems = {
+ elems = {
filepath.dir(os.args[0], context.temp_allocator),
"ols.json",
},
diff --git a/src/server/types.odin b/src/server/types.odin
index 9cc1e01..bb6d00f 100644
--- a/src/server/types.odin
+++ b/src/server/types.odin
@@ -484,7 +484,7 @@ TextDocumentEdit :: struct {
}
WorkspaceEdit :: struct {
- documentChanges: []TextDocumentEdit,
+ changes: map[string][]TextEdit,
}
WorkspaceSymbolParams :: struct {