@@ -80,6 +80,8 @@ import {TraitOrContractConstantsCompletionProvider} from "@server/completion/pro
80
80
import { generateTlBTypeDoc } from "@server/documentation/tlb_type_documentation"
81
81
import { BouncedTypeCompletionProvider } from "@server/completion/providers/BouncedTypeCompletionProvider"
82
82
import { TopLevelCompletionProvider } from "@server/completion/providers/TopLevelCompletionProvider"
83
+ import { Intention , IntentionArguments , IntentionContext } from "@server/intentions/Intention"
84
+ import { AddExplicitType } from "@server/intentions/AddExplicitType"
83
85
84
86
/**
85
87
* Whenever LS is initialized.
@@ -1003,6 +1005,100 @@ connection.onInitialize(async (params: lsp.InitializeParams): Promise<lsp.Initia
1003
1005
} ,
1004
1006
)
1005
1007
1008
+ const intentions : Intention [ ] = [ new AddExplicitType ( ) ]
1009
+
1010
+ connection . onRequest (
1011
+ lsp . ExecuteCommandRequest . type ,
1012
+ async ( params : lsp . ExecuteCommandParams ) => {
1013
+ if ( params . command === "tact/executeGetScopeProvider" ) {
1014
+ const commandParams = params . arguments ?. [ 0 ] as
1015
+ | lsp . TextDocumentPositionParams
1016
+ | undefined
1017
+ if ( ! commandParams ) return "Invalid parameters"
1018
+
1019
+ const file = PARSED_FILES_CACHE . get ( commandParams . textDocument . uri )
1020
+ if ( ! file ) {
1021
+ return "File not found"
1022
+ }
1023
+
1024
+ const node = nodeAtPosition ( commandParams , file )
1025
+ if ( ! node ) {
1026
+ return "Node not found"
1027
+ }
1028
+
1029
+ const referent = new Referent ( node , file )
1030
+ const scope = referent . useScope ( )
1031
+ if ( ! scope ) return "Scope not found"
1032
+ if ( scope instanceof LocalSearchScope ) return scope . toString ( )
1033
+ return "GlobalSearchScope"
1034
+ }
1035
+
1036
+ if ( ! params . arguments || params . arguments . length === 0 ) return null
1037
+
1038
+ const intention = intentions . find ( intention => intention . id === params . command )
1039
+ if ( ! intention ) return null
1040
+
1041
+ const args = params . arguments [ 0 ] as IntentionArguments
1042
+
1043
+ const file = findFile ( args . fileUri )
1044
+
1045
+ const ctx : IntentionContext = {
1046
+ file : file ,
1047
+ position : args . position ,
1048
+ }
1049
+
1050
+ const edits = intention . invoke ( ctx )
1051
+ if ( ! edits ) return null
1052
+
1053
+ await connection . sendRequest ( lsp . ApplyWorkspaceEditRequest . method , {
1054
+ label : `Intention "${ intention . name } "` ,
1055
+ edit : edits ,
1056
+ } as lsp . ApplyWorkspaceEditParams )
1057
+
1058
+ return null
1059
+ } ,
1060
+ )
1061
+
1062
+ connection . onRequest (
1063
+ lsp . CodeActionRequest . type ,
1064
+ ( params : lsp . CodeActionParams ) : lsp . CodeAction [ ] | null => {
1065
+ const uri = params . textDocument . uri
1066
+ if ( uri . endsWith ( ".fif" ) ) {
1067
+ return null
1068
+ }
1069
+
1070
+ const file = findFile ( uri )
1071
+
1072
+ const ctx : IntentionContext = {
1073
+ file : file ,
1074
+ position : params . range . start ,
1075
+ }
1076
+
1077
+ const actions : lsp . CodeAction [ ] = [ ]
1078
+
1079
+ intentions . forEach ( intention => {
1080
+ if ( ! intention . is_available ( ctx ) ) return
1081
+
1082
+ actions . push ( {
1083
+ title : intention . name ,
1084
+ kind : lsp . CodeActionKind . QuickFix ,
1085
+ command : {
1086
+ title : intention . name ,
1087
+ command : intention . id ,
1088
+ arguments : [
1089
+ {
1090
+ fileUri : file . uri ,
1091
+ position : params . range . start ,
1092
+ } as IntentionArguments ,
1093
+ ] ,
1094
+ } ,
1095
+ } )
1096
+ } )
1097
+
1098
+ return actions
1099
+ } ,
1100
+ )
1101
+
1006
1102
connection . onRequest (
1007
1103
GetTypeAtPositionRequest ,
1008
1104
( params : GetTypeAtPositionParams ) : GetTypeAtPositionResponse => {
@@ -1207,37 +1303,14 @@ connection.onInitialize(async (params: lsp.InitializeParams): Promise<lsp.Initia
1207
1303
} ,
1208
1304
)
1209
1305
1210
- connection . onExecuteCommand ( params => {
1211
- if ( params . command !== "tact/executeGetScopeProvider" ) return
1212
-
1213
- const commandParams = params . arguments ?. [ 0 ] as lsp . TextDocumentPositionParams | undefined
1214
- if ( ! commandParams ) return "Invalid parameters"
1215
-
1216
- const file = PARSED_FILES_CACHE . get ( commandParams . textDocument . uri )
1217
- if ( ! file ) {
1218
- return "File not found"
1219
- }
1220
-
1221
- const node = nodeAtPosition ( commandParams , file )
1222
- if ( ! node ) {
1223
- return "Node not found"
1224
- }
1225
-
1226
- const referent = new Referent ( node , file )
1227
- const scope = referent . useScope ( )
1228
- if ( ! scope ) return "Scope not found"
1229
- if ( scope instanceof LocalSearchScope ) return scope . toString ( )
1230
- return "GlobalSearchScope"
1231
- } )
1232
-
1306
+ // noinspection JSUnusedLocalSymbols
1233
1307
const _needed = TypeInferer . inferType
1234
1308
1235
1309
console . info ( "Tact language server is ready!" )
1236
1310
1237
1311
return {
1238
1312
capabilities : {
1239
1313
textDocumentSync : lsp . TextDocumentSyncKind . Incremental ,
1240
- // codeActionProvider: true,
1241
1314
documentSymbolProvider : true ,
1242
1315
workspaceSymbolProvider : true ,
1243
1316
definitionProvider : true ,
@@ -1269,8 +1342,11 @@ connection.onInitialize(async (params: lsp.InitializeParams): Promise<lsp.Initia
1269
1342
codeLensProvider : {
1270
1343
resolveProvider : false ,
1271
1344
} ,
1345
+ codeActionProvider : {
1346
+ codeActionKinds : [ lsp . CodeActionKind . QuickFix ] ,
1347
+ } ,
1272
1348
executeCommandProvider : {
1273
- commands : [ "tact/executeGetScopeProvider" ] ,
1349
+ commands : [ ... [ "tact/executeGetScopeProvider" ] , ... intentions . map ( it => it . id ) ] ,
1274
1350
} ,
1275
1351
} ,
1276
1352
}
0 commit comments