From d41f60bba9df248179f13ac45df9f2ecfda5e7b3 Mon Sep 17 00:00:00 2001 From: Jon Sully Date: Fri, 12 May 2023 22:55:04 +0100 Subject: [PATCH 1/2] LSP: Add Go to Definition support for `Ast::Variable` --- .../location/variable_block_statement_target | 55 ++++++++++ .../variable_casebranch_enumdestructuring | 61 +++++++++++ .../location/variable_component_connect | 60 +++++++++++ .../location/variable_component_connect_as | 60 +++++++++++ .../location/variable_component_constant | 57 ++++++++++ .../location/variable_component_function | 59 ++++++++++ .../location/variable_component_get | 59 ++++++++++ .../location/variable_component_property | 57 ++++++++++ .../location/variable_component_state | 57 ++++++++++ .../definition/location/variable_for | 55 ++++++++++ .../location/variable_for_argument_stop | 43 ++++++++ .../definition/location/variable_for_subject | 55 ++++++++++ .../location/variable_function_argument | 53 +++++++++ .../location/variable_function_argument_stop | 29 +++++ .../location/variable_nextcall_component | 59 ++++++++++ .../location/variable_nextcall_record | 74 +++++++++++++ .../location/variable_nextcall_store | 55 ++++++++++ .../location/variable_nextcall_value | 58 ++++++++++ .../location/variable_recordfield_key | 63 +++++++++++ .../location/variable_recordfield_value | 63 +++++++++++ .../location/variable_store_constant | 55 ++++++++++ .../location/variable_store_function | 57 ++++++++++ .../definition/location/variable_store_get | 61 +++++++++++ .../definition/location/variable_store_state | 59 ++++++++++ .../variable_block_statement_target | 75 +++++++++++++ .../variable_casebranch_enumdestructuring | 81 ++++++++++++++ .../location_link/variable_component_connect | 80 ++++++++++++++ .../variable_component_connect_as | 80 ++++++++++++++ .../location_link/variable_component_constant | 77 +++++++++++++ .../location_link/variable_component_function | 79 ++++++++++++++ .../location_link/variable_component_get | 79 ++++++++++++++ .../location_link/variable_component_property | 77 +++++++++++++ .../location_link/variable_component_state | 77 +++++++++++++ .../definition/location_link/variable_for | 75 +++++++++++++ .../location_link/variable_for_argument_stop | 43 ++++++++ .../location_link/variable_for_subject | 75 +++++++++++++ .../location_link/variable_function_argument | 73 +++++++++++++ .../variable_function_argument_stop | 29 +++++ .../location_link/variable_nextcall_component | 79 ++++++++++++++ .../location_link/variable_nextcall_record | 94 ++++++++++++++++ .../location_link/variable_nextcall_store | 75 +++++++++++++ .../location_link/variable_nextcall_value | 78 ++++++++++++++ .../location_link/variable_recordfield_key | 83 ++++++++++++++ .../location_link/variable_recordfield_value | 83 ++++++++++++++ .../location_link/variable_store_constant | 75 +++++++++++++ .../location_link/variable_store_function | 77 +++++++++++++ .../location_link/variable_store_get | 81 ++++++++++++++ .../location_link/variable_store_state | 79 ++++++++++++++ src/ls/definition/enum_id.cr | 37 +++++-- src/ls/definition/variable.cr | 101 ++++++++++++++++++ 50 files changed, 3295 insertions(+), 11 deletions(-) create mode 100644 spec/language_server/definition/location/variable_block_statement_target create mode 100644 spec/language_server/definition/location/variable_casebranch_enumdestructuring create mode 100644 spec/language_server/definition/location/variable_component_connect create mode 100644 spec/language_server/definition/location/variable_component_connect_as create mode 100644 spec/language_server/definition/location/variable_component_constant create mode 100644 spec/language_server/definition/location/variable_component_function create mode 100644 spec/language_server/definition/location/variable_component_get create mode 100644 spec/language_server/definition/location/variable_component_property create mode 100644 spec/language_server/definition/location/variable_component_state create mode 100644 spec/language_server/definition/location/variable_for create mode 100644 spec/language_server/definition/location/variable_for_argument_stop create mode 100644 spec/language_server/definition/location/variable_for_subject create mode 100644 spec/language_server/definition/location/variable_function_argument create mode 100644 spec/language_server/definition/location/variable_function_argument_stop create mode 100644 spec/language_server/definition/location/variable_nextcall_component create mode 100644 spec/language_server/definition/location/variable_nextcall_record create mode 100644 spec/language_server/definition/location/variable_nextcall_store create mode 100644 spec/language_server/definition/location/variable_nextcall_value create mode 100644 spec/language_server/definition/location/variable_recordfield_key create mode 100644 spec/language_server/definition/location/variable_recordfield_value create mode 100644 spec/language_server/definition/location/variable_store_constant create mode 100644 spec/language_server/definition/location/variable_store_function create mode 100644 spec/language_server/definition/location/variable_store_get create mode 100644 spec/language_server/definition/location/variable_store_state create mode 100644 spec/language_server/definition/location_link/variable_block_statement_target create mode 100644 spec/language_server/definition/location_link/variable_casebranch_enumdestructuring create mode 100644 spec/language_server/definition/location_link/variable_component_connect create mode 100644 spec/language_server/definition/location_link/variable_component_connect_as create mode 100644 spec/language_server/definition/location_link/variable_component_constant create mode 100644 spec/language_server/definition/location_link/variable_component_function create mode 100644 spec/language_server/definition/location_link/variable_component_get create mode 100644 spec/language_server/definition/location_link/variable_component_property create mode 100644 spec/language_server/definition/location_link/variable_component_state create mode 100644 spec/language_server/definition/location_link/variable_for create mode 100644 spec/language_server/definition/location_link/variable_for_argument_stop create mode 100644 spec/language_server/definition/location_link/variable_for_subject create mode 100644 spec/language_server/definition/location_link/variable_function_argument create mode 100644 spec/language_server/definition/location_link/variable_function_argument_stop create mode 100644 spec/language_server/definition/location_link/variable_nextcall_component create mode 100644 spec/language_server/definition/location_link/variable_nextcall_record create mode 100644 spec/language_server/definition/location_link/variable_nextcall_store create mode 100644 spec/language_server/definition/location_link/variable_nextcall_value create mode 100644 spec/language_server/definition/location_link/variable_recordfield_key create mode 100644 spec/language_server/definition/location_link/variable_recordfield_value create mode 100644 spec/language_server/definition/location_link/variable_store_constant create mode 100644 spec/language_server/definition/location_link/variable_store_function create mode 100644 spec/language_server/definition/location_link/variable_store_get create mode 100644 spec/language_server/definition/location_link/variable_store_state create mode 100644 src/ls/definition/variable.cr diff --git a/spec/language_server/definition/location/variable_block_statement_target b/spec/language_server/definition/location/variable_block_statement_target new file mode 100644 index 000000000..d75cc726f --- /dev/null +++ b/spec/language_server/definition/location/variable_block_statement_target @@ -0,0 +1,55 @@ +module Test { + fun upperCaseMint : String { + let test = + "Mint" + + String.toUpperCase(test) + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 23 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 2, + "character": 8 + }, + "end": { + "line": 2, + "character": 12 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_casebranch_enumdestructuring b/spec/language_server/definition/location/variable_casebranch_enumdestructuring new file mode 100644 index 000000000..e359f6743 --- /dev/null +++ b/spec/language_server/definition/location/variable_casebranch_enumdestructuring @@ -0,0 +1,61 @@ +enum Status { + Error + Ok(text : String) +} + +module Test { + fun toString (status : Status) : String { + case status { + Status::Ok(text) => text + Status::Error => "error" + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 8, + "character": 26 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 8, + "character": 17 + }, + "end": { + "line": 8, + "character": 21 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_connect b/spec/language_server/definition/location/variable_component_connect new file mode 100644 index 000000000..7d687e9ec --- /dev/null +++ b/spec/language_server/definition/location/variable_component_connect @@ -0,0 +1,60 @@ +component Test { + connect Theme exposing { primary } + + fun render : Html { +
+ <{ primary }> +
+ } +} +------------------------------------------------------------------file test.mint +store Theme { + state primary : String = "#00a0e8" +} +-----------------------------------------------------------------file store.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 27 + }, + "end": { + "line": 1, + "character": 34 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_connect_as b/spec/language_server/definition/location/variable_component_connect_as new file mode 100644 index 000000000..fcbfd2e46 --- /dev/null +++ b/spec/language_server/definition/location/variable_component_connect_as @@ -0,0 +1,60 @@ +component Test { + connect Theme exposing { primary as primaryColor } + + fun render : Html { +
+ <{ primaryColor }> +
+ } +} +------------------------------------------------------------------file test.mint +store Theme { + state primary : String = "#00a0e8" +} +-----------------------------------------------------------------file store.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 38 + }, + "end": { + "line": 1, + "character": 50 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_constant b/spec/language_server/definition/location/variable_component_constant new file mode 100644 index 000000000..60cb16028 --- /dev/null +++ b/spec/language_server/definition/location/variable_component_constant @@ -0,0 +1,57 @@ +component Test { + const TEXT = "Mint" + + fun render : Html { +
+ <{ TEXT }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_function b/spec/language_server/definition/location/variable_component_function new file mode 100644 index 000000000..5e2911d5d --- /dev/null +++ b/spec/language_server/definition/location/variable_component_function @@ -0,0 +1,59 @@ +component Test { + fun text : String { + "Mint" + } + + fun render : Html { +
+ <{ text() }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 7, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 10 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_get b/spec/language_server/definition/location/variable_component_get new file mode 100644 index 000000000..f0b6cec56 --- /dev/null +++ b/spec/language_server/definition/location/variable_component_get @@ -0,0 +1,59 @@ +component Test { + get text : String { + "Mint" + } + + fun render : Html { +
+ <{ text }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 7, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 10 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_property b/spec/language_server/definition/location/variable_component_property new file mode 100644 index 000000000..6be5ab434 --- /dev/null +++ b/spec/language_server/definition/location/variable_component_property @@ -0,0 +1,57 @@ +component Test { + property text : String = "Mint" + + fun render : Html { +
+ <{ text }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 11 + }, + "end": { + "line": 1, + "character": 15 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_component_state b/spec/language_server/definition/location/variable_component_state new file mode 100644 index 000000000..afce458b6 --- /dev/null +++ b/spec/language_server/definition/location/variable_component_state @@ -0,0 +1,57 @@ +component Test { + state text : String = "Mint" + + fun render : Html { +
+ <{ text }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_for b/spec/language_server/definition/location/variable_for new file mode 100644 index 000000000..7effba3f8 --- /dev/null +++ b/spec/language_server/definition/location/variable_for @@ -0,0 +1,55 @@ +module Test { + fun uppercase (values : Array(String)) : Array(String) { + for value of values { + String.toUpperCase(value) + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 3, + "character": 25 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 2, + "character": 8 + }, + "end": { + "line": 2, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_for_argument_stop b/spec/language_server/definition/location/variable_for_argument_stop new file mode 100644 index 000000000..359d8768a --- /dev/null +++ b/spec/language_server/definition/location/variable_for_argument_stop @@ -0,0 +1,43 @@ +module Test { + fun uppercase (value : String) : Array(String) { + for value of String.split(value, ",") { + String.toUpperCase(value) + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 2, + "character": 8 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": null, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_for_subject b/spec/language_server/definition/location/variable_for_subject new file mode 100644 index 000000000..003e00b12 --- /dev/null +++ b/spec/language_server/definition/location/variable_for_subject @@ -0,0 +1,55 @@ +module Test { + fun uppercase (value : String) : Array(String) { + for value of String.split(value, ",") { + String.toUpperCase(value) + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 2, + "character": 30 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 17 + }, + "end": { + "line": 1, + "character": 22 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_function_argument b/spec/language_server/definition/location/variable_function_argument new file mode 100644 index 000000000..aa54676df --- /dev/null +++ b/spec/language_server/definition/location/variable_function_argument @@ -0,0 +1,53 @@ +module Test { + fun toString (status : String) : String { + status + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 2, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 16 + }, + "end": { + "line": 1, + "character": 22 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_function_argument_stop b/spec/language_server/definition/location/variable_function_argument_stop new file mode 100644 index 000000000..58f659bae --- /dev/null +++ b/spec/language_server/definition/location/variable_function_argument_stop @@ -0,0 +1,29 @@ +store Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + next { text: text } + } +} +------------------------------------------------------------------file test.mint +{ + "jsonrpc": "2.0", + "id": 0, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 3, + "character": 12 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": null, + "id": 0 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_nextcall_component b/spec/language_server/definition/location/variable_nextcall_component new file mode 100644 index 000000000..0f8c2f191 --- /dev/null +++ b/spec/language_server/definition/location/variable_nextcall_component @@ -0,0 +1,59 @@ +component Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + next { text: text } + } + + fun render { +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 11 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_nextcall_record b/spec/language_server/definition/location/variable_nextcall_record new file mode 100644 index 000000000..c03cad4ba --- /dev/null +++ b/spec/language_server/definition/location/variable_nextcall_record @@ -0,0 +1,74 @@ +record Article { + id : Number, + description : String, + title : String +} + +store Test { + state article : Article = + { + id: 1, + description: "Mint Lang", + title: "Mint" + } + + fun load : Promise(Void) { + next + { + article: + { + id: 1, + description: "Mint Lang", + title: "Mint" + } + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 20, + "character": 12 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 2, + "character": 2 + }, + "end": { + "line": 2, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_nextcall_store b/spec/language_server/definition/location/variable_nextcall_store new file mode 100644 index 000000000..bb9adba8e --- /dev/null +++ b/spec/language_server/definition/location/variable_nextcall_store @@ -0,0 +1,55 @@ +store Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + next { text: text } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 11 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_nextcall_value b/spec/language_server/definition/location/variable_nextcall_value new file mode 100644 index 000000000..e6621c346 --- /dev/null +++ b/spec/language_server/definition/location/variable_nextcall_value @@ -0,0 +1,58 @@ +store Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + let newText = + "Mint" + + next { text: newText } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 7, + "character": 17 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 4, + "character": 8 + }, + "end": { + "line": 4, + "character": 15 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_recordfield_key b/spec/language_server/definition/location/variable_recordfield_key new file mode 100644 index 000000000..6bbf9f18d --- /dev/null +++ b/spec/language_server/definition/location/variable_recordfield_key @@ -0,0 +1,63 @@ +record Article { + id : Number, + description : String, + title : String +} + +module Test { + fun makeArticle (title : String) : Article { + { + id: 1, + description: "Mint Lang", + title: title + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 9, + "character": 6 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 4 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_recordfield_value b/spec/language_server/definition/location/variable_recordfield_value new file mode 100644 index 000000000..374e8cb6d --- /dev/null +++ b/spec/language_server/definition/location/variable_recordfield_value @@ -0,0 +1,63 @@ +record Article { + id : Number, + description : String, + title : String +} +---------------------------------------------------------------file article.mint +module Test { + fun makeArticle (title : String) : Article { + { + id: 1, + description: "Mint Lang", + title: title + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 13 + } + }, + "method": "textDocument/definition" +} +------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 19 + }, + "end": { + "line": 1, + "character": 24 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_store_constant b/spec/language_server/definition/location/variable_store_constant new file mode 100644 index 000000000..afcf3dd85 --- /dev/null +++ b/spec/language_server/definition/location/variable_store_constant @@ -0,0 +1,55 @@ +store Test { + const TITLE = "title" + + fun getTitle : String { + TITLE + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_store_function b/spec/language_server/definition/location/variable_store_function new file mode 100644 index 000000000..8f27064df --- /dev/null +++ b/spec/language_server/definition/location/variable_store_function @@ -0,0 +1,57 @@ +store Test { + fun load (text : String) : Promise(Void) { + Promise.never() + } + + fun dashboard : Promise(Void) { + await load("Mint") + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 6, + "character": 10 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 10 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_store_get b/spec/language_server/definition/location/variable_store_get new file mode 100644 index 000000000..ff9211007 --- /dev/null +++ b/spec/language_server/definition/location/variable_store_get @@ -0,0 +1,61 @@ +store Test { + get description : String { + "description" + } + + fun load (text : String) : Promise(Void) { + Promise.never() + } + + fun dashboard : Promise(Void) { + await load(description) + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 10, + "character": 15 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 17 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_store_state b/spec/language_server/definition/location/variable_store_state new file mode 100644 index 000000000..a70091112 --- /dev/null +++ b/spec/language_server/definition/location/variable_store_state @@ -0,0 +1,59 @@ +store Test { + state title : String = "title" + + fun load (text : String) : Promise(Void) { + Promise.never() + } + + fun dashboard : Promise(Void) { + await load(title) + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 8, + "character": 15 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_block_statement_target b/spec/language_server/definition/location_link/variable_block_statement_target new file mode 100644 index 000000000..07e7d96b5 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_block_statement_target @@ -0,0 +1,75 @@ +module Test { + fun upperCaseMint : String { + let test = + "Mint" + + String.toUpperCase(test) + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 23 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 23 + }, + "end": { + "line": 5, + "character": 27 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 2, + "character": 4 + }, + "end": { + "line": 3, + "character": 12 + } + }, + "targetSelectionRange": { + "start": { + "line": 2, + "character": 8 + }, + "end": { + "line": 2, + "character": 12 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_casebranch_enumdestructuring b/spec/language_server/definition/location_link/variable_casebranch_enumdestructuring new file mode 100644 index 000000000..4eba5aceb --- /dev/null +++ b/spec/language_server/definition/location_link/variable_casebranch_enumdestructuring @@ -0,0 +1,81 @@ +enum Status { + Error + Ok(text : String) +} + +module Test { + fun toString (status : Status) : String { + case status { + Status::Ok(text) => text + Status::Error => "error" + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 8, + "character": 26 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 8, + "character": 26 + }, + "end": { + "line": 8, + "character": 30 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 8, + "character": 6 + }, + "end": { + "line": 8, + "character": 22 + } + }, + "targetSelectionRange": { + "start": { + "line": 8, + "character": 17 + }, + "end": { + "line": 8, + "character": 21 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_connect b/spec/language_server/definition/location_link/variable_component_connect new file mode 100644 index 000000000..1b2cef32f --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_connect @@ -0,0 +1,80 @@ +component Test { + connect Theme exposing { primary } + + fun render : Html { +
+ <{ primary }> +
+ } +} +------------------------------------------------------------------file test.mint +store Theme { + state primary : String = "#00a0e8" +} +-----------------------------------------------------------------file store.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 9 + }, + "end": { + "line": 5, + "character": 16 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 36 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 27 + }, + "end": { + "line": 1, + "character": 34 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_connect_as b/spec/language_server/definition/location_link/variable_component_connect_as new file mode 100644 index 000000000..6effa0999 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_connect_as @@ -0,0 +1,80 @@ +component Test { + connect Theme exposing { primary as primaryColor } + + fun render : Html { +
+ <{ primaryColor }> +
+ } +} +------------------------------------------------------------------file test.mint +store Theme { + state primary : String = "#00a0e8" +} +-----------------------------------------------------------------file store.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 9 + }, + "end": { + "line": 5, + "character": 21 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 52 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 38 + }, + "end": { + "line": 1, + "character": 50 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_constant b/spec/language_server/definition/location_link/variable_component_constant new file mode 100644 index 000000000..03022a727 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_constant @@ -0,0 +1,77 @@ +component Test { + const TEXT = "Mint" + + fun render : Html { +
+ <{ TEXT }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 9 + }, + "end": { + "line": 5, + "character": 13 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 21 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_function b/spec/language_server/definition/location_link/variable_component_function new file mode 100644 index 000000000..00126bf09 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_function @@ -0,0 +1,79 @@ +component Test { + fun text : String { + "Mint" + } + + fun render : Html { +
+ <{ text() }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 7, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 7, + "character": 9 + }, + "end": { + "line": 7, + "character": 13 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 3, + "character": 3 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 10 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_get b/spec/language_server/definition/location_link/variable_component_get new file mode 100644 index 000000000..1d5fcd4ca --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_get @@ -0,0 +1,79 @@ +component Test { + get text : String { + "Mint" + } + + fun render : Html { +
+ <{ text }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 7, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 7, + "character": 9 + }, + "end": { + "line": 7, + "character": 13 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 5, + "character": 2 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 10 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_property b/spec/language_server/definition/location_link/variable_component_property new file mode 100644 index 000000000..ce61b0357 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_property @@ -0,0 +1,77 @@ +component Test { + property text : String = "Mint" + + fun render : Html { +
+ <{ text }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 9 + }, + "end": { + "line": 5, + "character": 13 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 33 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 11 + }, + "end": { + "line": 1, + "character": 15 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_component_state b/spec/language_server/definition/location_link/variable_component_state new file mode 100644 index 000000000..e8705f482 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_component_state @@ -0,0 +1,77 @@ +component Test { + state text : String = "Mint" + + fun render : Html { +
+ <{ text }> +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 9 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 9 + }, + "end": { + "line": 5, + "character": 13 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 30 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_for b/spec/language_server/definition/location_link/variable_for new file mode 100644 index 000000000..abd703d41 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_for @@ -0,0 +1,75 @@ +module Test { + fun uppercase (values : Array(String)) : Array(String) { + for value of values { + String.toUpperCase(value) + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 3, + "character": 25 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 3, + "character": 25 + }, + "end": { + "line": 3, + "character": 30 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 2, + "character": 4 + }, + "end": { + "line": 5, + "character": 2 + } + }, + "targetSelectionRange": { + "start": { + "line": 2, + "character": 8 + }, + "end": { + "line": 2, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_for_argument_stop b/spec/language_server/definition/location_link/variable_for_argument_stop new file mode 100644 index 000000000..951f304ff --- /dev/null +++ b/spec/language_server/definition/location_link/variable_for_argument_stop @@ -0,0 +1,43 @@ +module Test { + fun uppercase (value : String) : Array(String) { + for value of String.split(value, ",") { + String.toUpperCase(value) + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 2, + "character": 8 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": null, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_for_subject b/spec/language_server/definition/location_link/variable_for_subject new file mode 100644 index 000000000..3c41c018e --- /dev/null +++ b/spec/language_server/definition/location_link/variable_for_subject @@ -0,0 +1,75 @@ +module Test { + fun uppercase (value : String) : Array(String) { + for value of String.split(value, ",") { + String.toUpperCase(value) + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 2, + "character": 30 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 2, + "character": 30 + }, + "end": { + "line": 2, + "character": 35 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 17 + }, + "end": { + "line": 1, + "character": 31 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 17 + }, + "end": { + "line": 1, + "character": 22 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_function_argument b/spec/language_server/definition/location_link/variable_function_argument new file mode 100644 index 000000000..78b9f72a3 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_function_argument @@ -0,0 +1,73 @@ +module Test { + fun toString (status : String) : String { + status + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 2, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 2, + "character": 4 + }, + "end": { + "line": 2, + "character": 10 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 16 + }, + "end": { + "line": 1, + "character": 31 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 16 + }, + "end": { + "line": 1, + "character": 22 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_function_argument_stop b/spec/language_server/definition/location_link/variable_function_argument_stop new file mode 100644 index 000000000..58f659bae --- /dev/null +++ b/spec/language_server/definition/location_link/variable_function_argument_stop @@ -0,0 +1,29 @@ +store Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + next { text: text } + } +} +------------------------------------------------------------------file test.mint +{ + "jsonrpc": "2.0", + "id": 0, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 3, + "character": 12 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": null, + "id": 0 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_nextcall_component b/spec/language_server/definition/location_link/variable_nextcall_component new file mode 100644 index 000000000..65bb1e6ff --- /dev/null +++ b/spec/language_server/definition/location_link/variable_nextcall_component @@ -0,0 +1,79 @@ +component Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + next { text: text } + } + + fun render { +
+ } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 11 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 4, + "character": 11 + }, + "end": { + "line": 4, + "character": 15 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 26 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_nextcall_record b/spec/language_server/definition/location_link/variable_nextcall_record new file mode 100644 index 000000000..b8a376929 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_nextcall_record @@ -0,0 +1,94 @@ +record Article { + id : Number, + description : String, + title : String +} + +store Test { + state article : Article = + { + id: 1, + description: "Mint Lang", + title: "Mint" + } + + fun load : Promise(Void) { + next + { + article: + { + id: 1, + description: "Mint Lang", + title: "Mint" + } + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 20, + "character": 12 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 20, + "character": 12 + }, + "end": { + "line": 20, + "character": 23 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 2, + "character": 2 + }, + "end": { + "line": 2, + "character": 22 + } + }, + "targetSelectionRange": { + "start": { + "line": 2, + "character": 2 + }, + "end": { + "line": 2, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_nextcall_store b/spec/language_server/definition/location_link/variable_nextcall_store new file mode 100644 index 000000000..61de09f1c --- /dev/null +++ b/spec/language_server/definition/location_link/variable_nextcall_store @@ -0,0 +1,75 @@ +store Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + next { text: text } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 11 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 4, + "character": 11 + }, + "end": { + "line": 4, + "character": 15 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 26 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 12 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_nextcall_value b/spec/language_server/definition/location_link/variable_nextcall_value new file mode 100644 index 000000000..bd00bd2e9 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_nextcall_value @@ -0,0 +1,78 @@ +store Test { + state text : String = "" + + fun load (text : String) : Promise(Void) { + let newText = + "Mint" + + next { text: newText } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 7, + "character": 17 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 7, + "character": 17 + }, + "end": { + "line": 7, + "character": 24 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 4, + "character": 4 + }, + "end": { + "line": 5, + "character": 12 + } + }, + "targetSelectionRange": { + "start": { + "line": 4, + "character": 8 + }, + "end": { + "line": 4, + "character": 15 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_recordfield_key b/spec/language_server/definition/location_link/variable_recordfield_key new file mode 100644 index 000000000..5846bfacb --- /dev/null +++ b/spec/language_server/definition/location_link/variable_recordfield_key @@ -0,0 +1,83 @@ +record Article { + id : Number, + description : String, + title : String +} + +module Test { + fun makeArticle (title : String) : Article { + { + id: 1, + description: "Mint Lang", + title: title + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 9, + "character": 6 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 9, + "character": 6 + }, + "end": { + "line": 9, + "character": 8 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 13 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 4 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_recordfield_value b/spec/language_server/definition/location_link/variable_recordfield_value new file mode 100644 index 000000000..c80653428 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_recordfield_value @@ -0,0 +1,83 @@ +record Article { + id : Number, + description : String, + title : String +} +---------------------------------------------------------------file article.mint +module Test { + fun makeArticle (title : String) : Article { + { + id: 1, + description: "Mint Lang", + title: title + } + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 5, + "character": 13 + } + }, + "method": "textDocument/definition" +} +------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 5, + "character": 13 + }, + "end": { + "line": 5, + "character": 18 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 19 + }, + "end": { + "line": 1, + "character": 33 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 19 + }, + "end": { + "line": 1, + "character": 24 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_store_constant b/spec/language_server/definition/location_link/variable_store_constant new file mode 100644 index 000000000..30d3dd4f7 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_store_constant @@ -0,0 +1,75 @@ +store Test { + const TITLE = "title" + + fun getTitle : String { + TITLE + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 4, + "character": 4 + }, + "end": { + "line": 4, + "character": 9 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 23 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_store_function b/spec/language_server/definition/location_link/variable_store_function new file mode 100644 index 000000000..fa4c95c04 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_store_function @@ -0,0 +1,77 @@ +store Test { + fun load (text : String) : Promise(Void) { + Promise.never() + } + + fun dashboard : Promise(Void) { + await load("Mint") + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 6, + "character": 10 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 6, + "character": 10 + }, + "end": { + "line": 6, + "character": 14 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 3, + "character": 3 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 10 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_store_get b/spec/language_server/definition/location_link/variable_store_get new file mode 100644 index 000000000..853222a93 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_store_get @@ -0,0 +1,81 @@ +store Test { + get description : String { + "description" + } + + fun load (text : String) : Promise(Void) { + Promise.never() + } + + fun dashboard : Promise(Void) { + await load(description) + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 10, + "character": 15 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 10, + "character": 15 + }, + "end": { + "line": 10, + "character": 26 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 5, + "character": 2 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 6 + }, + "end": { + "line": 1, + "character": 17 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_store_state b/spec/language_server/definition/location_link/variable_store_state new file mode 100644 index 000000000..9c05f619f --- /dev/null +++ b/spec/language_server/definition/location_link/variable_store_state @@ -0,0 +1,79 @@ +store Test { + state title : String = "title" + + fun load (text : String) : Promise(Void) { + Promise.never() + } + + fun dashboard : Promise(Void) { + await load(title) + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 8, + "character": 15 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 8, + "character": 15 + }, + "end": { + "line": 8, + "character": 20 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 32 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/src/ls/definition/enum_id.cr b/src/ls/definition/enum_id.cr index 9be315861..8ce0d84c1 100644 --- a/src/ls/definition/enum_id.cr +++ b/src/ls/definition/enum_id.cr @@ -2,20 +2,35 @@ module Mint module LS class Definition < LSP::RequestMessage def definition(node : Ast::EnumId, server : Server, workspace : Workspace, stack : Array(Ast::Node)) - return unless name = node.name - return unless enum_node = - workspace.ast.enums.find(&.name.value.==(name.value)) + name = node.name - return if Core.ast.enums.includes?(enum_node) + # When `.name` is nil the node is used as a CONSTANT + if name.nil? + stack.each do |parent| + case parent + when Ast::Component, Ast::Store + parent.constants.each do |constant| + if node.option.value == constant.name.value + return location_link server, node.option, constant.name, constant + end + end + end + end + else + return unless enum_node = + workspace.ast.enums.find(&.name.value.==(name.value)) - case - when cursor_intersects?(name) - location_link server, name, enum_node.name, enum_node - when cursor_intersects?(node.option) - return unless option = - enum_node.try &.options.find(&.value.value.==(node.option.value)) + return if Core.ast.enums.includes?(enum_node) - location_link server, node.option, option.value, option + case + when cursor_intersects?(name) + location_link server, name, enum_node.name, enum_node + when cursor_intersects?(node.option) + return unless option = + enum_node.try &.options.find(&.value.value.==(node.option.value)) + + location_link server, node.option, option.value, option + end end end end diff --git a/src/ls/definition/variable.cr b/src/ls/definition/variable.cr new file mode 100644 index 000000000..8894f9bb8 --- /dev/null +++ b/src/ls/definition/variable.cr @@ -0,0 +1,101 @@ +module Mint + module LS + class Definition < LSP::RequestMessage + def definition(node : Ast::Variable, server : Server, workspace : Workspace, stack : Array(Ast::Node)) + lookup = workspace.type_checker.variables[node]? + + if lookup + variable_lookup_parent(node, lookup[1], server, workspace) || + variable_connect(node, lookup[2], server) || + variable_lookup(node, lookup[0], server) + else + variable_record_key(node, server, workspace, stack) || + variable_next_key(node, server, workspace, stack) + end + end + + def variable_connect(node : Ast::Variable, parents : Array(TypeChecker::Scope::Node), server : Server) + # Check to see if this variable is defined as an Ast::ConnectVariable + # as the `.variables` cache links directly to the stores state/function etc + return unless component = parents.select(Ast::Component).first? + + component.connects.each do |connect| + connect.keys.each do |key| + variable = key.name || key.variable + + if variable.value == node.value + return location_link server, node, variable, connect + end + end + end + end + + def variable_lookup_parent(node : Ast::Variable, target : TypeChecker::Scope::Node, server : Server, workspace : Workspace) + case target + when Tuple(String, TypeChecker::Checkable, Ast::Node) + case variable = target[2] + when Ast::Variable + # For some variables in the .variables` cache, we only have access to the + # target Ast::Variable and not its containing node, so we must search for it + return unless parent = workspace + .ast + .nodes + .select { |other| other.is_a?(Ast::EnumDestructuring) || other.is_a?(Ast::Statement) || other.is_a?(Ast::For) } + .select(&.input.file.==(variable.input.file)) + .find { |other| other.from < variable.from && other.to > variable.to } + + location_link server, node, variable, parent + end + end + end + + def variable_lookup(node : Ast::Variable, target : Ast::Node | TypeChecker::Checkable, server : Server) + case item = target + when Ast::Node + name = case item + when Ast::Property, + Ast::Constant, + Ast::Function, + Ast::State, + Ast::Get, + Ast::Argument + item.name + else + item + end + + location_link server, node, name, item + end + end + + def variable_record_key(node : Ast::Variable, server : Server, workspace : Workspace, stack : Array(Ast::Node)) + case field = stack[1]? + when Ast::RecordField + return unless record_name = workspace.type_checker.record_field_lookup[field]? + + return unless record_definition_field = workspace + .ast + .records + .find(&.name.value.==(record_name)) + .try(&.fields.find(&.key.value.==(node.value))) + + location_link server, node, record_definition_field.key, record_definition_field + end + end + + def variable_next_key(node : Ast::Variable, server : Server, workspace : Workspace, stack : Array(Ast::Node)) + case next_call = stack[3]? + when Ast::NextCall + return unless parent = workspace.type_checker.lookups[next_call] + + return unless state = case parent + when Ast::Provider, Ast::Component, Ast::Store + parent.states.find(&.name.value.==(node.value)) + end + + location_link server, node, state.name, state + end + end + end + end +end From 126f24c539eb2b6c504416344e8b6c6ab152537b Mon Sep 17 00:00:00 2001 From: Jon Sully Date: Fri, 21 Jul 2023 17:47:11 +0100 Subject: [PATCH 2/2] LSP: Add Go to Definition support for constants in Suite/Module/Providers --- .../location/variable_module_constant | 55 +++++++++++++ .../location/variable_provider_constant | 59 ++++++++++++++ .../location/variable_suite_constant | 55 +++++++++++++ .../location_link/variable_module_constant | 75 ++++++++++++++++++ .../location_link/variable_provider_constant | 79 +++++++++++++++++++ .../location_link/variable_suite_constant | 75 ++++++++++++++++++ src/ls/definition/enum_id.cr | 6 +- 7 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 spec/language_server/definition/location/variable_module_constant create mode 100644 spec/language_server/definition/location/variable_provider_constant create mode 100644 spec/language_server/definition/location/variable_suite_constant create mode 100644 spec/language_server/definition/location_link/variable_module_constant create mode 100644 spec/language_server/definition/location_link/variable_provider_constant create mode 100644 spec/language_server/definition/location_link/variable_suite_constant diff --git a/spec/language_server/definition/location/variable_module_constant b/spec/language_server/definition/location/variable_module_constant new file mode 100644 index 000000000..0a6d47701 --- /dev/null +++ b/spec/language_server/definition/location/variable_module_constant @@ -0,0 +1,55 @@ +module Test { + const TITLE = "title" + + fun title : String { + TITLE + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_provider_constant b/spec/language_server/definition/location/variable_provider_constant new file mode 100644 index 000000000..8e3ff65e5 --- /dev/null +++ b/spec/language_server/definition/location/variable_provider_constant @@ -0,0 +1,59 @@ +record Subscription { + a : Bool +} + +provider Provider : Subscription { + const TITLE = "title" + + fun title : String { + TITLE + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 8, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 5, + "character": 8 + }, + "end": { + "line": 5, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location/variable_suite_constant b/spec/language_server/definition/location/variable_suite_constant new file mode 100644 index 000000000..26b459d6b --- /dev/null +++ b/spec/language_server/definition/location/variable_suite_constant @@ -0,0 +1,55 @@ +suite "Test" { + const TITLE = "title" + + test "it has a constant" { + TITLE == "title" + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": false + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + }, + "uri": "file://#{root_path}/test.mint" + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_module_constant b/spec/language_server/definition/location_link/variable_module_constant new file mode 100644 index 000000000..f9adb0c1b --- /dev/null +++ b/spec/language_server/definition/location_link/variable_module_constant @@ -0,0 +1,75 @@ +module Test { + const TITLE = "title" + + fun title : String { + TITLE + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 4, + "character": 4 + }, + "end": { + "line": 4, + "character": 9 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 23 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_provider_constant b/spec/language_server/definition/location_link/variable_provider_constant new file mode 100644 index 000000000..4f18c8a0a --- /dev/null +++ b/spec/language_server/definition/location_link/variable_provider_constant @@ -0,0 +1,79 @@ +record Subscription { + a : Bool +} + +provider Provider : Subscription { + const TITLE = "title" + + fun title : String { + TITLE + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 8, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 8, + "character": 4 + }, + "end": { + "line": 8, + "character": 9 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 5, + "character": 2 + }, + "end": { + "line": 5, + "character": 23 + } + }, + "targetSelectionRange": { + "start": { + "line": 5, + "character": 8 + }, + "end": { + "line": 5, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/spec/language_server/definition/location_link/variable_suite_constant b/spec/language_server/definition/location_link/variable_suite_constant new file mode 100644 index 000000000..cdc6aa815 --- /dev/null +++ b/spec/language_server/definition/location_link/variable_suite_constant @@ -0,0 +1,75 @@ +suite "Test" { + const TITLE = "title" + + test "it has a constant" { + TITLE == "title" + } +} +------------------------------------------------------------------file test.mint +{ + "id": 0, + "method": "initialize", + "params": { + "capabilities": { + "textDocument": { + "definition": { + "linkSupport": true + } + } + } + } +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "id": 1, + "params": { + "textDocument": { + "uri": "file://#{root_path}/test.mint" + }, + "position": { + "line": 4, + "character": 4 + } + }, + "method": "textDocument/definition" +} +-------------------------------------------------------------------------request +{ + "jsonrpc": "2.0", + "result": { + "originSelectionRange": { + "start": { + "line": 4, + "character": 4 + }, + "end": { + "line": 4, + "character": 9 + } + }, + "targetUri": "file://#{root_path}/test.mint", + "targetRange": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 23 + } + }, + "targetSelectionRange": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 13 + } + } + }, + "id": 1 +} +------------------------------------------------------------------------response diff --git a/src/ls/definition/enum_id.cr b/src/ls/definition/enum_id.cr index 8ce0d84c1..0b4c91b91 100644 --- a/src/ls/definition/enum_id.cr +++ b/src/ls/definition/enum_id.cr @@ -8,7 +8,11 @@ module Mint if name.nil? stack.each do |parent| case parent - when Ast::Component, Ast::Store + when Ast::Component, + Ast::Store, + Ast::Suite, + Ast::Module, + Ast::Provider parent.constants.each do |constant| if node.option.value == constant.name.value return location_link server, node.option, constant.name, constant