aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2021-05-05 23:43:12 +0200
committerDaniel Gavin <danielgavin5@hotmail.com>2021-05-05 23:43:12 +0200
commit28ce0ddfebfd671094e8da231923ff96fb72dd47 (patch)
tree62505e3c9959b3c41ef9f1580702679d92f668a7 /src
parentd25e7a8dfd64e492e4fe23876f2ccc646ed18c57 (diff)
begun argument underlining
Diffstat (limited to 'src')
-rw-r--r--src/server/analysis.odin28
-rw-r--r--src/server/signature.odin50
-rw-r--r--src/testing/testing.odin10
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);