@@ -4,8 +4,8 @@ use tower_lsp::lsp_types::{
44 CodeActionOrCommand , CodeActionParams , CodeActionProviderCapability , CodeActionResponse ,
55 CodeLens , CodeLensOptions , CodeLensParams , Command , DidChangeConfigurationParams ,
66 DidChangeTextDocumentParams , DidOpenTextDocumentParams , ExecuteCommandOptions ,
7- ExecuteCommandParams , InitializeParams , InitializeResult , InitializedParams , MessageType ,
8- ServerCapabilities , TextDocumentSyncCapability , TextDocumentSyncKind ,
7+ ExecuteCommandParams , InitializeParams , InitializeResult , InitializedParams , Location ,
8+ MessageType , ServerCapabilities , TextDocumentSyncCapability , TextDocumentSyncKind ,
99} ;
1010use tracing:: { debug, info} ;
1111
@@ -23,7 +23,7 @@ use super::supported_commands::SupportedCommands;
2323pub struct LSPServerInner < C > {
2424 interactor : LspInteractor < C > ,
2525 query_executor : QueryExecutor ,
26- component_factory : ComponentFactory ,
26+ component_factory : Option < ComponentFactory > ,
2727}
2828
2929impl < C > LSPServerInner < C > {
@@ -33,7 +33,7 @@ impl<C> LSPServerInner<C> {
3333 LSPServerInner {
3434 interactor : LspInteractor :: new ( client, document_database. clone ( ) ) ,
3535 query_executor : QueryExecutor :: new ( document_database. clone ( ) ) ,
36- component_factory : Default :: default ( ) , // to be initialized in the initialize method of the LSP
36+ component_factory : None , // to be initialized in the initialize method of the LSP
3737 }
3838 }
3939}
5050
5151 debug ! ( "updating with configuration: {config:?}" ) ;
5252
53- self . component_factory . initialize_with ( config) ;
53+ let mut factory = ComponentFactory :: default ( ) ;
54+ factory. initialize_with ( config) ;
55+ self . component_factory = Some ( factory) ;
5456
5557 debug ! ( "updated configuration" ) ;
5658 Ok ( ( ) )
@@ -61,6 +63,20 @@ impl<C> LSPServerInner<C>
6163where
6264 C : LSPClient + Send + Sync + ' static ,
6365{
66+ async fn get_commands_for_document (
67+ & self ,
68+ uri : & tower_lsp:: lsp_types:: Url ,
69+ ) -> Result < Vec < command_generator:: CommandInfo > > {
70+ let Some ( content) = self . query_executor . get_document_text ( uri. as_str ( ) ) . await else {
71+ return Err ( Error :: internal_error ( ) . with_message ( format ! (
72+ "unable to extract document content for document: {uri}"
73+ ) ) ) ;
74+ } ;
75+
76+ let commands = command_generator:: generate_commands_for_uri ( uri, & content) ;
77+ Ok ( commands)
78+ }
79+
6480 pub async fn initialize (
6581 & mut self ,
6682 initialize_params : InitializeParams ,
@@ -128,19 +144,9 @@ where
128144 & self ,
129145 params : CodeActionParams ,
130146 ) -> Result < Option < CodeActionResponse > > {
131- let Some ( content) = self
132- . query_executor
133- . get_document_text ( params. text_document . uri . as_str ( ) )
134- . await
135- else {
136- return Err ( Error :: internal_error ( ) . with_message ( format ! (
137- "unable to extract document content for document: {}" ,
138- & params. text_document. uri
139- ) ) ) ;
140- } ;
141-
142- let commands =
143- command_generator:: generate_commands_for_uri ( & params. text_document . uri , & content) ;
147+ let commands = self
148+ . get_commands_for_document ( & params. text_document . uri )
149+ . await ?;
144150 let code_actions: Vec < CodeActionOrCommand > = commands
145151 . into_iter ( )
146152 . filter ( |cmd| cmd. range . start . line == params. range . start . line )
@@ -157,19 +163,9 @@ where
157163 }
158164
159165 pub async fn code_lens ( & self , params : CodeLensParams ) -> Result < Option < Vec < CodeLens > > > {
160- let Some ( content) = self
161- . query_executor
162- . get_document_text ( params. text_document . uri . as_str ( ) )
163- . await
164- else {
165- return Err ( Error :: internal_error ( ) . with_message ( format ! (
166- "unable to extract document content for document: {}" ,
167- & params. text_document. uri
168- ) ) ) ;
169- } ;
170-
171- let commands =
172- command_generator:: generate_commands_for_uri ( & params. text_document . uri , & content) ;
166+ let commands = self
167+ . get_commands_for_document ( & params. text_document . uri )
168+ . await ?;
173169 let code_lenses = commands
174170 . into_iter ( )
175171 . map ( |cmd| CodeLens {
@@ -186,49 +182,63 @@ where
186182 Ok ( Some ( code_lenses) )
187183 }
188184
185+ fn component_factory_mut ( & mut self ) -> Result < & mut ComponentFactory > {
186+ self . component_factory
187+ . as_mut ( )
188+ . ok_or_else ( || Error :: internal_error ( ) . with_message ( "LSP not initialized" ) )
189+ }
190+
191+ async fn execute_base_image_scan (
192+ & mut self ,
193+ location : Location ,
194+ image : String ,
195+ ) -> Result < Option < Value > > {
196+ let image_scanner = self . component_factory_mut ( ) ?. image_scanner ( ) . map_err ( |e| {
197+ Error :: internal_error ( ) . with_message ( format ! ( "unable to create image scanner: {e}" ) )
198+ } ) ?;
199+ let mut command =
200+ ScanBaseImageCommand :: new ( & image_scanner, & self . interactor , location, image) ;
201+ command. execute ( ) . await . map ( |_| None )
202+ }
203+
204+ async fn execute_build_and_scan ( & mut self , location : Location ) -> Result < Option < Value > > {
205+ let factory = self . component_factory_mut ( ) ?;
206+ let image_scanner = factory. image_scanner ( ) . map_err ( |e| {
207+ Error :: internal_error ( ) . with_message ( format ! ( "unable to create image scanner: {e}" ) )
208+ } ) ?;
209+ let image_builder = factory. image_builder ( ) . map_err ( |e| {
210+ Error :: internal_error ( ) . with_message ( format ! ( "unable to create image builder: {e}" ) )
211+ } ) ?;
212+ let mut command =
213+ BuildAndScanCommand :: new ( & image_builder, & image_scanner, & self . interactor , location) ;
214+ command. execute ( ) . await . map ( |_| None )
215+ }
216+
189217 pub async fn execute_command ( & mut self , params : ExecuteCommandParams ) -> Result < Option < Value > > {
190218 let command: SupportedCommands = params. try_into ( ) ?;
191219
192220 let result = match command. clone ( ) {
193221 SupportedCommands :: ExecuteBaseImageScan { location, image } => {
194- let image_scanner = self . component_factory . image_scanner ( ) . map_err ( |e| {
195- Error :: internal_error ( )
196- . with_message ( format ! ( "unable to create image scanner: {e}" ) )
197- } ) ?;
198- let mut command =
199- ScanBaseImageCommand :: new ( & image_scanner, & self . interactor , location, image) ;
200- command. execute ( ) . await . map ( |_| None )
222+ self . execute_base_image_scan ( location, image) . await
201223 }
202224
203225 SupportedCommands :: ExecuteBuildAndScan { location } => {
204- let image_scanner = self . component_factory . image_scanner ( ) . map_err ( |e| {
205- Error :: internal_error ( )
206- . with_message ( format ! ( "unable to create image scanner: {e}" ) )
207- } ) ?;
208- let image_builder = self . component_factory . image_builder ( ) . map_err ( |e| {
209- Error :: internal_error ( )
210- . with_message ( format ! ( "unable to create image builder: {e}" ) )
211- } ) ?;
212- let mut command = BuildAndScanCommand :: new (
213- & image_builder,
214- & image_scanner,
215- & self . interactor ,
216- location,
217- ) ;
218- command. execute ( ) . await . map ( |_| None )
226+ self . execute_build_and_scan ( location) . await
219227 }
220228 } ;
221229
222- match result {
223- Ok ( _ ) => result ,
224- Err ( mut e ) => {
225- self . interactor
226- . show_message ( MessageType :: ERROR , e . to_string ( ) . as_str ( ) )
227- . await ;
228- e . message = format ! ( "error calling command: '{command}': {e}" ) . into ( ) ;
229- Err ( e )
230- }
230+ if let Err ( e ) = & result {
231+ self . interactor
232+ . show_message ( MessageType :: ERROR , e . to_string ( ) . as_str ( ) )
233+ . await ;
234+ return Err ( Error {
235+ code : e . code ,
236+ message : format ! ( "error calling command: '{command}': {}" , e . message ) . into ( ) ,
237+ data : e . data . clone ( ) ,
238+ } ) ;
231239 }
240+
241+ result
232242 }
233243
234244 pub async fn shutdown ( & self ) -> Result < ( ) > {
0 commit comments