diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2024-06-13 19:58:44 +0200 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2024-06-13 19:58:44 +0200 |
| commit | 582a1b1c1b42065d3bd22bd0f23bfd3ec38cdae4 (patch) | |
| tree | edc281df609d163d11d933d2f824035b144ef088 /src | |
| parent | 3c05ab67cd6b811a0993e49f2ca1ed75e0aca8e3 (diff) | |
add prepare rename
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/collector.odin | 8 | ||||
| -rw-r--r-- | src/server/references.odin | 80 | ||||
| -rw-r--r-- | src/server/rename.odin | 46 | ||||
| -rw-r--r-- | src/server/requests.odin | 38 | ||||
| -rw-r--r-- | src/server/types.odin | 13 |
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, |