aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-06-13 19:58:44 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-06-13 19:58:44 +0200
commit582a1b1c1b42065d3bd22bd0f23bfd3ec38cdae4 (patch)
treeedc281df609d163d11d933d2f824035b144ef088 /src/server
parent3c05ab67cd6b811a0993e49f2ca1ed75e0aca8e3 (diff)
add prepare rename
Diffstat (limited to 'src/server')
-rw-r--r--src/server/collector.odin8
-rw-r--r--src/server/references.odin80
-rw-r--r--src/server/rename.odin46
-rw-r--r--src/server/requests.odin38
-rw-r--r--src/server/types.odin13
5 files changed, 153 insertions, 32 deletions
diff --git a/src/server/collector.odin b/src/server/collector.odin
index eecf2ed..bdc69a6 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -39,6 +39,7 @@ SymbolPackage :: struct {
symbols: map[string]Symbol,
objc_structs: map[string]ObjcStruct, //mapping from struct name to function
methods: map[Method][dynamic]Symbol,
+ imports: [dynamic]string, //Used for references to figure whether the package is even able to reference the symbol
}
get_index_unique_string :: proc {
@@ -100,6 +101,7 @@ delete_symbol_collection :: proc(collection: SymbolCollection) {
delete(v.methods)
delete(v.objc_structs)
delete(v.symbols)
+ delete(v.imports)
}
delete(collection.packages)
@@ -566,6 +568,10 @@ collect_objc :: proc(
}
}
+collect_imports :: proc(collection: ^SymbolCollection, file: ast.File) {
+
+}
+
collect_symbols :: proc(
collection: ^SymbolCollection,
file: ast.File,
@@ -577,6 +583,8 @@ collect_symbols :: proc(
exprs := common.collect_globals(file, true)
+ collect_imports(collection, file)
+
for expr in exprs {
symbol: Symbol
diff --git a/src/server/references.odin b/src/server/references.odin
index d56ae62..17add83 100644
--- a/src/server/references.odin
+++ b/src/server/references.odin
@@ -51,35 +51,21 @@ walk_directories :: proc(
return 0, false
}
-resolve_references :: proc(
+prepare_references :: proc(
document: ^Document,
ast_context: ^AstContext,
position_context: ^DocumentPositionContext,
) -> (
- []common.Location,
- bool,
+ symbol: Symbol,
+ resolve_flag: ResolveReferenceFlag,
+ ok: bool,
) {
- locations := make([dynamic]common.Location, 0, ast_context.allocator)
- fullpaths = make([dynamic]string, 0, ast_context.allocator)
-
- resolve_flag: ResolveReferenceFlag
+ ok = false
reference := ""
- symbol: Symbol
- ok: bool
pkg := ""
- when !ODIN_TEST {
- for workspace in common.config.workspace_folders {
- uri, _ := common.parse_uri(workspace.uri, context.temp_allocator)
- filepath.walk(uri.path, walk_directories, document)
- }
- }
-
- reset_ast_context(ast_context)
-
-
if position_context.label != nil {
- return {}, true
+ return
} else if position_context.struct_type != nil {
found := false
done_struct: for field in position_context.struct_type.fields.list {
@@ -98,7 +84,7 @@ resolve_references :: proc(
}
}
if !found {
- return {}, false
+ return
}
} else if position_context.enum_type != nil {
/*
@@ -123,7 +109,7 @@ resolve_references :: proc(
}
*/
} else if position_context.bitset_type != nil {
- return {}, true
+ return
} else if position_context.union_type != nil {
found := false
for variant in position_context.union_type.variants {
@@ -137,19 +123,19 @@ resolve_references :: proc(
resolve_flag = .Identifier
if !ok {
- return {}, false
+ return
}
found = true
break
} else {
- return {}, false
+ return
}
}
}
if !found {
- return {}, false
+ return
}
} else if position_context.field_value != nil &&
@@ -165,12 +151,12 @@ resolve_references :: proc(
)
if !ok {
- return {}, false
+ return
}
//Only support structs for now
if _, ok := symbol.value.(SymbolStructValue); !ok {
- return {}, false
+ return
}
resolve_flag = .Field
@@ -189,7 +175,7 @@ resolve_references :: proc(
symbol, ok = resolve_location_identifier(ast_context, ident^)
if !ok {
- return {}, true
+ return
}
resolve_flag = .Base
@@ -211,7 +197,7 @@ resolve_references :: proc(
)
if !ok {
- return {}, true
+ return
}
} else if position_context.identifier != nil {
ident := position_context.identifier.derived.(^ast.Ident)
@@ -222,12 +208,46 @@ resolve_references :: proc(
resolve_flag = .Identifier
if !ok {
- return {}, true
+ return
}
} else {
+ return
+ }
+
+ return symbol, resolve_flag, true
+}
+
+resolve_references :: proc(
+ document: ^Document,
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+) -> (
+ []common.Location,
+ bool,
+) {
+ locations := make([dynamic]common.Location, 0, ast_context.allocator)
+ fullpaths = make([dynamic]string, 0, ast_context.allocator)
+
+ symbol, resolve_flag, ok := prepare_references(
+ document,
+ ast_context,
+ position_context,
+ )
+
+ if !ok {
return {}, true
}
+ when !ODIN_TEST {
+ for workspace in common.config.workspace_folders {
+ uri, _ := common.parse_uri(workspace.uri, context.temp_allocator)
+ filepath.walk(uri.path, walk_directories, document)
+ }
+ }
+
+ reset_ast_context(ast_context)
+
+
arena: runtime.Arena
_ = runtime.arena_init(
diff --git a/src/server/rename.odin b/src/server/rename.odin
index bf9ca8d..6041641 100644
--- a/src/server/rename.odin
+++ b/src/server/rename.odin
@@ -79,3 +79,49 @@ get_rename :: proc(
return workspace, true
}
+
+
+get_prepare_rename :: proc(
+ document: ^Document,
+ position: common.Position,
+) -> (
+ common.Range,
+ bool,
+) {
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ context.temp_allocator,
+ )
+
+ position_context, ok := get_document_position_context(
+ document,
+ position,
+ .Hover,
+ )
+
+ get_globals(document.ast, &ast_context)
+
+ ast_context.current_package = ast_context.document_package
+
+ if position_context.function != nil {
+ get_locals(
+ document.ast,
+ position_context.function,
+ &ast_context,
+ &position_context,
+ )
+ }
+
+ symbol, _, ok2 := prepare_references(
+ document,
+ &ast_context,
+ &position_context,
+ )
+
+
+ return symbol.range, ok2
+}
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 3ca38d6..2773dcc 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -275,6 +275,7 @@ call_map: map[string]proc(
"textDocument/inlayHint" = request_inlay_hint,
"textDocument/documentLink" = request_document_links,
"textDocument/rename" = request_rename,
+ "textDocument/prepareRename" = request_prepare_rename,
"textDocument/references" = request_references,
"window/progress" = request_noop,
"workspace/symbol" = request_workspace_symbols,
@@ -802,7 +803,7 @@ request_initialize :: proc(
change = 2,
save = {includeText = true},
},
- renameProvider = config.enable_rename,
+ renameProvider = RenameOptions{prepareProvider = true},
workspaceSymbolProvider = true,
referencesProvider = config.enable_references,
definitionProvider = true,
@@ -1491,6 +1492,41 @@ request_document_links :: proc(
return .None
}
+request_prepare_rename :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
+ params_object, ok := params.(json.Object)
+
+ if !ok {
+ return .ParseError
+ }
+
+ rename_param: PrepareRenameParams
+
+ if unmarshal(params, rename_param, context.temp_allocator) != nil {
+ return .ParseError
+ }
+
+ document := document_get(rename_param.textDocument.uri)
+
+ if document == nil {
+ return .InternalError
+ }
+
+ if range, ok := get_prepare_rename(document, rename_param.position); ok {
+ response := make_response_message(params = range, id = id)
+ send_response(response, writer)
+ } else {
+ response := make_response_message(params = nil, id = id)
+ send_response(response, writer)
+ }
+
+ return .None
+}
+
request_rename :: proc(
params: json.Value,
id: RequestId,
diff --git a/src/server/types.odin b/src/server/types.odin
index bb6d00f..632b61d 100644
--- a/src/server/types.odin
+++ b/src/server/types.odin
@@ -30,6 +30,7 @@ ResponseParams :: union {
[]DocumentLink,
[]WorkspaceSymbol,
WorkspaceEdit,
+ common.Range,
}
ResponseMessage :: struct {
@@ -102,12 +103,17 @@ ServerCapabilities :: struct {
hoverProvider: bool,
documentFormattingProvider: bool,
inlayHintProvider: bool,
- renameProvider: bool,
+ renameProvider: RenameOptions,
referencesProvider: bool,
workspaceSymbolProvider: bool,
documentLinkProvider: DocumentLinkOptions,
}
+RenameOptions :: struct {
+ prepareProvider: bool,
+}
+
+
CompletionOptions :: struct {
resolveProvider: bool,
triggerCharacters: []string,
@@ -468,6 +474,11 @@ RenameParams :: struct {
position: common.Position,
}
+PrepareRenameParams :: struct {
+ textDocument: TextDocumentIdentifier,
+ position: common.Position,
+}
+
ReferenceParams :: struct {
textDocument: TextDocumentIdentifier,
position: common.Position,