99using Microsoft . PowerShell . EditorServices . Utility ;
1010using Newtonsoft . Json ;
1111using Newtonsoft . Json . Linq ;
12+ using System . Collections . Generic ;
1213using System . Linq ;
1314using System . Threading ;
1415using System . Threading . Tasks ;
1718
1819namespace Microsoft . PowerShell . EditorServices . CodeLenses
1920{
21+ /// <summary>
22+ /// Implements the CodeLens feature for EditorServices.
23+ /// </summary>
2024 internal class CodeLensFeature :
2125 FeatureComponentBase < ICodeLensProvider > ,
2226 ICodeLenses
2327 {
24- private EditorSession editorSession ;
25-
26- private JsonSerializer jsonSerializer =
27- JsonSerializer . Create (
28- Constants . JsonSerializerSettings ) ;
29-
30- public CodeLensFeature (
31- EditorSession editorSession ,
32- IMessageHandlers messageHandlers ,
33- ILogger logger )
34- : base ( logger )
35- {
36- this . editorSession = editorSession ;
37-
38- messageHandlers . SetRequestHandler (
39- CodeLensRequest . Type ,
40- this . HandleCodeLensRequest ) ;
41-
42- messageHandlers . SetRequestHandler (
43- CodeLensResolveRequest . Type ,
44- this . HandleCodeLensResolveRequest ) ;
45- }
4628
29+ /// <summary>
30+ /// Create a new CodeLens instance around a given editor session
31+ /// from the component registry.
32+ /// </summary>
33+ /// <param name="components">
34+ /// The component registry to provider other components and to register the CodeLens provider in.
35+ /// </param>
36+ /// <param name="editorSession">The editor session context of the CodeLens provider.</param>
37+ /// <returns>A new CodeLens provider for the given editor session.</returns>
4738 public static CodeLensFeature Create (
4839 IComponentRegistry components ,
4940 EditorSession editorSession )
5041 {
5142 var codeLenses =
5243 new CodeLensFeature (
5344 editorSession ,
54- components . Get < IMessageHandlers > ( ) ,
45+ JsonSerializer . Create ( Constants . JsonSerializerSettings ) ,
5546 components . Get < ILogger > ( ) ) ;
5647
48+ var messageHandlers = components . Get < IMessageHandlers > ( ) ;
49+
50+ messageHandlers . SetRequestHandler (
51+ CodeLensRequest . Type ,
52+ codeLenses . HandleCodeLensRequest ) ;
53+
54+ messageHandlers . SetRequestHandler (
55+ CodeLensResolveRequest . Type ,
56+ codeLenses . HandleCodeLensResolveRequest ) ;
57+
5758 codeLenses . Providers . Add (
5859 new ReferencesCodeLensProvider (
5960 editorSession ) ) ;
@@ -67,42 +68,78 @@ public static CodeLensFeature Create(
6768 return codeLenses ;
6869 }
6970
71+ /// <summary>
72+ /// The editor session context to get workspace and language server data from.
73+ /// </summary>
74+ private readonly EditorSession _editorSession ;
75+
76+ /// <summary>
77+ /// The json serializer instance for CodeLens object translation.
78+ /// </summary>
79+ private readonly JsonSerializer _jsonSerializer ;
80+
81+ /// <summary>
82+ ///
83+ /// </summary>
84+ /// <param name="editorSession"></param>
85+ /// <param name="jsonSerializer"></param>
86+ /// <param name="logger"></param>
87+ private CodeLensFeature (
88+ EditorSession editorSession ,
89+ JsonSerializer jsonSerializer ,
90+ ILogger logger )
91+ : base ( logger )
92+ {
93+ _editorSession = editorSession ;
94+ _jsonSerializer = jsonSerializer ;
95+ }
96+
97+ /// <summary>
98+ /// Get all the CodeLenses for a given script file.
99+ /// </summary>
100+ /// <param name="scriptFile">The PowerShell script file to get CodeLenses for.</param>
101+ /// <returns>All generated CodeLenses for the given script file.</returns>
70102 public CodeLens [ ] ProvideCodeLenses ( ScriptFile scriptFile )
71103 {
72- return
73- this . InvokeProviders ( p => p . ProvideCodeLenses ( scriptFile ) )
74- . SelectMany ( r => r )
75- . ToArray ( ) ;
104+ return InvokeProviders ( provider => provider . ProvideCodeLenses ( scriptFile ) )
105+ . SelectMany ( codeLens => codeLens )
106+ . ToArray ( ) ;
76107 }
77108
109+ /// <summary>
110+ /// Handles a request for CodeLenses from VSCode.
111+ /// </summary>
112+ /// <param name="codeLensParams">Parameters on the CodeLens request that was received.</param>
113+ /// <param name="requestContext"></param>
78114 private async Task HandleCodeLensRequest (
79115 CodeLensRequest codeLensParams ,
80116 RequestContext < LanguageServer . CodeLens [ ] > requestContext )
81117 {
82- JsonSerializer jsonSerializer =
83- JsonSerializer . Create (
84- Constants . JsonSerializerSettings ) ;
118+ ScriptFile scriptFile = _editorSession . Workspace . GetFile (
119+ codeLensParams . TextDocument . Uri ) ;
85120
86- var scriptFile =
87- this . editorSession . Workspace . GetFile (
88- codeLensParams . TextDocument . Uri ) ;
121+ CodeLens [ ] codeLensResults = ProvideCodeLenses ( scriptFile ) ;
89122
90- var codeLenses =
91- this . ProvideCodeLenses ( scriptFile )
92- . Select (
93- codeLens =>
94- codeLens . ToProtocolCodeLens (
95- new CodeLensData
96- {
97- Uri = codeLens . File . ClientFilePath ,
98- ProviderId = codeLens . Provider . ProviderId
99- } ,
100- this . jsonSerializer ) )
101- . ToArray ( ) ;
102-
103- await requestContext . SendResult ( codeLenses ) ;
123+ var codeLensResponse = new LanguageServer . CodeLens [ codeLensResults . Length ] ;
124+ for ( int i = 0 ; i < codeLensResults . Length ; i ++ )
125+ {
126+ codeLensResponse [ i ] = codeLensResults [ i ] . ToProtocolCodeLens (
127+ new CodeLensData
128+ {
129+ Uri = codeLensResults [ i ] . File . ClientFilePath ,
130+ ProviderId = codeLensResults [ i ] . Provider . ProviderId
131+ } ,
132+ _jsonSerializer ) ;
133+ }
134+
135+ await requestContext . SendResult ( codeLensResponse ) ;
104136 }
105137
138+ /// <summary>
139+ /// Handle a CodeLens resolve request from VSCode.
140+ /// </summary>
141+ /// <param name="codeLens">The CodeLens to be resolved/updated.</param>
142+ /// <param name="requestContext"></param>
106143 private async Task HandleCodeLensResolveRequest (
107144 LanguageServer . CodeLens codeLens ,
108145 RequestContext < LanguageServer . CodeLens > requestContext )
@@ -113,13 +150,13 @@ private async Task HandleCodeLensResolveRequest(
113150 CodeLensData codeLensData = codeLens . Data . ToObject < CodeLensData > ( ) ;
114151
115152 ICodeLensProvider originalProvider =
116- this . Providers . FirstOrDefault (
153+ Providers . FirstOrDefault (
117154 provider => provider . ProviderId . Equals ( codeLensData . ProviderId ) ) ;
118155
119156 if ( originalProvider != null )
120157 {
121158 ScriptFile scriptFile =
122- this . editorSession . Workspace . GetFile (
159+ _editorSession . Workspace . GetFile (
123160 codeLensData . Uri ) ;
124161
125162 ScriptRegion region = new ScriptRegion
@@ -143,7 +180,7 @@ await originalProvider.ResolveCodeLensAsync(
143180
144181 await requestContext . SendResult (
145182 resolvedCodeLens . ToProtocolCodeLens (
146- this . jsonSerializer ) ) ;
183+ _jsonSerializer ) ) ;
147184 }
148185 else
149186 {
@@ -153,6 +190,9 @@ await requestContext.SendError(
153190 }
154191 }
155192
193+ /// <summary>
194+ /// Represents data expected back in an LSP CodeLens response.
195+ /// </summary>
156196 private class CodeLensData
157197 {
158198 public string Uri { get ; set ; }
0 commit comments