1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
+ #nullable enable
3
4
4
5
using System . Collections . Generic ;
5
6
using System . Threading ;
14
15
using OmniSharp . Extensions . LanguageServer . Protocol . Client . Capabilities ;
15
16
using OmniSharp . Extensions . LanguageServer . Protocol ;
16
17
using System ;
17
- using PowerShellEditorServices . Services . PowerShell . Utility ;
18
18
19
19
namespace Microsoft . PowerShell . EditorServices . Handlers ;
20
20
21
+
21
22
/// <summary>
22
23
/// A handler for <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareRename">textDocument/prepareRename</a>
23
24
/// LSP Ref: <see cref="PrepareRename()"/>
@@ -26,7 +27,7 @@ internal class PrepareRenameHandler(WorkspaceService workspaceService) : IPrepar
26
27
{
27
28
public RenameRegistrationOptions GetRegistrationOptions ( RenameCapability capability , ClientCapabilities clientCapabilities ) => capability . PrepareSupport ? new ( ) { PrepareProvider = true } : new ( ) ;
28
29
29
- public async Task < RangeOrPlaceholderRange > Handle ( PrepareRenameParams request , CancellationToken cancellationToken )
30
+ public async Task < RangeOrPlaceholderRange ? > Handle ( PrepareRenameParams request , CancellationToken cancellationToken )
30
31
{
31
32
ScriptFile scriptFile = workspaceService . GetFile ( request . TextDocument . Uri ) ;
32
33
@@ -37,11 +38,28 @@ public async Task<RangeOrPlaceholderRange> Handle(PrepareRenameParams request, C
37
38
}
38
39
39
40
ScriptPositionAdapter position = request . Position ;
40
- Ast token = FindRenamableSymbol ( scriptFile , position ) ;
41
- if ( token is null ) { return null ; }
41
+ Ast target = FindRenamableSymbol ( scriptFile , position ) ;
42
+ if ( target is null ) { return null ; }
43
+ return target switch
44
+ {
45
+ FunctionDefinitionAst funcAst => GetFunctionNameExtent ( funcAst ) ,
46
+ _ => new ScriptExtentAdapter ( target . Extent )
47
+ } ;
48
+ }
49
+
50
+ private static ScriptExtentAdapter GetFunctionNameExtent ( FunctionDefinitionAst ast )
51
+ {
52
+ string name = ast . Name ;
53
+ // FIXME: Gather dynamically from the AST and include backticks and whatnot that might be present
54
+ int funcLength = "function " . Length ;
55
+ ScriptExtentAdapter funcExtent = new ( ast . Extent ) ;
42
56
43
- // TODO: Really should have a class with implicit convertors handing these conversions to avoid off-by-one mistakes.
44
- return new ScriptExtentAdapter ( token . Extent ) ;
57
+ // Get a range that represents only the function name
58
+ return funcExtent with
59
+ {
60
+ Start = funcExtent . Start . Delta ( 0 , funcLength ) ,
61
+ End = funcExtent . Start . Delta ( 0 , funcLength + name . Length )
62
+ } ;
45
63
}
46
64
47
65
/// <summary>
@@ -89,8 +107,15 @@ or CommandAst
89
107
if ( parent . GetCommandName ( ) != stringAst . Value ) { return false ; }
90
108
}
91
109
92
- return ast . Extent . Contains ( position ) ;
110
+ ScriptExtentAdapter target = ast switch
111
+ {
112
+ FunctionDefinitionAst funcAst => GetFunctionNameExtent ( funcAst ) ,
113
+ _ => new ScriptExtentAdapter ( ast . Extent )
114
+ } ;
115
+
116
+ return target . Contains ( position ) ;
93
117
} , true ) ;
118
+
94
119
return token ;
95
120
}
96
121
}
@@ -104,7 +129,7 @@ internal class RenameHandler(WorkspaceService workspaceService) : IRenameHandler
104
129
// RenameOptions may only be specified if the client states that it supports prepareSupport in its initial initialize request.
105
130
public RenameRegistrationOptions GetRegistrationOptions ( RenameCapability capability , ClientCapabilities clientCapabilities ) => capability . PrepareSupport ? new ( ) { PrepareProvider = true } : new ( ) ;
106
131
107
- public async Task < WorkspaceEdit > Handle ( RenameParams request , CancellationToken cancellationToken )
132
+ public async Task < WorkspaceEdit ? > Handle ( RenameParams request , CancellationToken cancellationToken )
108
133
{
109
134
ScriptFile scriptFile = workspaceService . GetFile ( request . TextDocument . Uri ) ;
110
135
ScriptPositionAdapter position = request . Position ;
@@ -179,7 +204,7 @@ internal static TextEdit[] RenameVariable(Ast symbol, Ast scriptAst, RenameParam
179
204
return visitor . Modifications . ToArray ( ) ;
180
205
181
206
}
182
- return null ;
207
+ return [ ] ;
183
208
}
184
209
}
185
210
@@ -205,12 +230,16 @@ public record ScriptPositionAdapter(IScriptPosition position) : IScriptPosition,
205
230
206
231
public ScriptPositionAdapter ( int Line , int Column ) : this ( new ScriptPosition ( null , Line , Column , null ) ) { }
207
232
public ScriptPositionAdapter ( ScriptPosition position ) : this ( ( IScriptPosition ) position ) { }
208
- public ScriptPositionAdapter ( Position position ) : this ( position . Line + 1 , position . Character + 1 ) { }
209
233
234
+ public ScriptPositionAdapter ( Position position ) : this ( position . Line + 1 , position . Character + 1 ) { }
210
235
public static implicit operator ScriptPositionAdapter ( Position position ) => new ( position ) ;
211
- public static implicit operator ScriptPositionAdapter ( ScriptPosition position ) => new ( position ) ;
236
+ public static implicit operator Position ( ScriptPositionAdapter scriptPosition ) => new
237
+ (
238
+ scriptPosition . position . LineNumber - 1 , scriptPosition . position . ColumnNumber - 1
239
+ ) ;
212
240
213
- public static implicit operator Position ( ScriptPositionAdapter scriptPosition ) => new ( scriptPosition . position . LineNumber - 1 , scriptPosition . position . ColumnNumber - 1 ) ;
241
+
242
+ public static implicit operator ScriptPositionAdapter ( ScriptPosition position ) => new ( position ) ;
214
243
public static implicit operator ScriptPosition ( ScriptPositionAdapter position ) => position ;
215
244
216
245
internal ScriptPositionAdapter Delta ( int LineAdjust , int ColumnAdjust ) => new (
@@ -241,19 +270,22 @@ internal record ScriptExtentAdapter(IScriptExtent extent) : IScriptExtent
241
270
public ScriptPositionAdapter End = new ( extent . EndScriptPosition ) ;
242
271
243
272
public static implicit operator ScriptExtentAdapter ( ScriptExtent extent ) => new ( extent ) ;
273
+
244
274
public static implicit operator ScriptExtentAdapter ( Range range ) => new ( new ScriptExtent (
245
275
// Will get shifted to 1-based
246
276
new ScriptPositionAdapter ( range . Start ) ,
247
277
new ScriptPositionAdapter ( range . End )
248
278
) ) ;
249
-
250
- public static implicit operator ScriptExtent ( ScriptExtentAdapter adapter ) => adapter ;
251
279
public static implicit operator Range ( ScriptExtentAdapter adapter ) => new ( )
252
280
{
281
+ // Will get shifted to 0-based
253
282
Start = adapter . Start ,
254
283
End = adapter . End
255
284
} ;
256
- public static implicit operator RangeOrPlaceholderRange ( ScriptExtentAdapter adapter ) => new ( adapter ) ;
285
+
286
+ public static implicit operator ScriptExtent ( ScriptExtentAdapter adapter ) => adapter ;
287
+
288
+ public static implicit operator RangeOrPlaceholderRange ( ScriptExtentAdapter adapter ) => new ( ( Range ) adapter ) ;
257
289
258
290
public IScriptPosition StartScriptPosition => Start ;
259
291
public IScriptPosition EndScriptPosition => End ;
@@ -272,11 +304,11 @@ internal record ScriptExtentAdapter(IScriptExtent extent) : IScriptExtent
272
304
273
305
public class RenameSymbolParams : IRequest < RenameSymbolResult >
274
306
{
275
- public string FileName { get ; set ; }
307
+ public string ? FileName { get ; set ; }
276
308
public int Line { get ; set ; }
277
309
public int Column { get ; set ; }
278
- public string RenameTo { get ; set ; }
279
- public RenameSymbolOptions Options { get ; set ; }
310
+ public string ? RenameTo { get ; set ; }
311
+ public RenameSymbolOptions ? Options { get ; set ; }
280
312
}
281
313
282
314
public class RenameSymbolResult
0 commit comments