diff options
| author | Daniel Gavin <danielgavin5@hotmail.com> | 2021-05-05 23:43:12 +0200 |
|---|---|---|
| committer | Daniel Gavin <danielgavin5@hotmail.com> | 2021-05-05 23:43:12 +0200 |
| commit | 28ce0ddfebfd671094e8da231923ff96fb72dd47 (patch) | |
| tree | 62505e3c9959b3c41ef9f1580702679d92f668a7 /src | |
| parent | d25e7a8dfd64e492e4fe23876f2ccc646ed18c57 (diff) | |
begun argument underlining
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 28 | ||||
| -rw-r--r-- | src/server/signature.odin | 50 | ||||
| -rw-r--r-- | src/testing/testing.odin | 10 |
3 files changed, 84 insertions, 4 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index cd505ce..d7ac8ef 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -57,6 +57,7 @@ DocumentPositionContext :: struct { hint: DocumentPositionContextHint, global_lhs_stmt: bool, import_stmt: ^ast.Import_Decl, + call_commas: []int, } DocumentLocal :: struct { @@ -2285,6 +2286,29 @@ get_document_symbols :: proc(document: ^Document) -> []DocumentSymbol { } /* + Parser gives ranges of expression, but not actually where the commas are placed. +*/ +get_call_commas :: proc(position_context: ^DocumentPositionContext, document: ^Document) { + + if position_context.call == nil { + return; + } + + commas := make([dynamic]int, 0, 10, context.temp_allocator); + + if call, ok := position_context.call.derived.(ast.Call_Expr); ok { + for i := call.open.offset; i < call.close.offset; i += 1 { + + if document.text[i] == ',' { + append(&commas, i); + } + } + } + + position_context.call_commas = commas[:]; +} + +/* Figure out what exactly is at the given position and whether it is in a function, struct, etc. */ get_document_position_context :: proc(document: ^Document, position: common.Position, hint: DocumentPositionContextHint) -> (DocumentPositionContext, bool) { @@ -2357,6 +2381,10 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi fallback_position_context_signature(document, position, &position_context); } + if hint == .SignatureHelp { + get_call_commas(&position_context, document); + } + return position_context, true; } diff --git a/src/server/signature.odin b/src/server/signature.odin index 883bd2e..64028c8 100644 --- a/src/server/signature.odin +++ b/src/server/signature.odin @@ -16,7 +16,36 @@ import "core:slice" import "shared:common" import "shared:index" - +SignatureInformationCapabilities :: struct { + parameterInformation: ParameterInformationCapabilities, +} + +SignatureHelpClientCapabilities :: struct { + dynamicRegistration: bool, + signatureInformation: SignatureInformationCapabilities, + contextSupport: bool, +} + +SignatureHelpOptions :: struct { + triggerCharacters: []string, + retriggerCharacters: []string, +} + +SignatureHelp :: struct { + signatures: []SignatureInformation, + activeSignature: int, + activeParameter: int, +} + +SignatureInformation :: struct { + label: string, + documentation: string, + parameters: []ParameterInformation, +} + +ParameterInformation :: struct { + label: string, +} get_signature_information :: proc(document: ^Document, position: common.Position) -> (SignatureHelp, bool) { @@ -40,15 +69,30 @@ get_signature_information :: proc(document: ^Document, position: common.Position get_locals(document.ast, position_context.function, &ast_context, &position_context); } + for comma, i in position_context.call_commas { + if position_context.position > comma { + signature_help.activeParameter = i+1; + } else if position_context.position == comma { + signature_help.activeParameter = i; + } + } + call: index.Symbol; call, ok = resolve_type_expression(&ast_context, position_context.call); signature_information := make([dynamic]SignatureInformation, context.temp_allocator); - if _, ok := call.value.(index.SymbolProcedureValue); ok { + if value, ok := call.value.(index.SymbolProcedureValue); ok { + parameters := make([]ParameterInformation, len(value.arg_types), context.temp_allocator); + + for arg, i in value.arg_types { + parameters[i].label = common.get_ast_node_string(arg, document.ast.src); + } + info := SignatureInformation { label = concatenate_symbols_information(&ast_context, call, false), documentation = call.doc, + parameters = parameters, }; append(&signature_information, info); } else if value, ok := call.value.(index.SymbolAggregateValue); ok { @@ -62,8 +106,6 @@ get_signature_information :: proc(document: ^Document, position: common.Position } signature_help.signatures = signature_information[:]; - signature_help.activeSignature = 0; - signature_help.activeParameter = 0; return signature_help, true; }
\ No newline at end of file diff --git a/src/testing/testing.odin b/src/testing/testing.odin index e74fb0e..7b30e93 100644 --- a/src/testing/testing.odin +++ b/src/testing/testing.odin @@ -145,6 +145,16 @@ expect_signature_labels :: proc(t: ^testing.T, src: ^Source, expect_labels: []st } +expect_signature_parameter_position :: proc(t: ^testing.T, src: ^Source, position: int) { + setup(src); + + help, ok := server.get_signature_information(src.document, src.position); + + if help.activeParameter != position { + testing.errorf(t, "expected parameter position %v, but received %v", position, help.activeParameter); + } +} + expect_completion_details :: proc(t: ^testing.T, src: ^Source, trigger_character: string, expect_details: []string) { setup(src); |