@@ -7,26 +7,26 @@ use async_lsp::ResponseError;
7
7
use fm:: { FileId , FileMap , PathString } ;
8
8
use lsp_types:: {
9
9
CodeAction , CodeActionKind , CodeActionOrCommand , CodeActionParams , CodeActionResponse ,
10
- Position , Range , TextDocumentPositionParams , TextEdit , Url , WorkspaceEdit ,
10
+ TextDocumentPositionParams , TextEdit , Url , WorkspaceEdit ,
11
11
} ;
12
- use noirc_errors:: { Location , Span } ;
12
+ use noirc_errors:: Span ;
13
13
use noirc_frontend:: {
14
- ast:: { Ident , Path , Visitor } ,
14
+ ast:: { ConstructorExpression , Path , Visitor } ,
15
15
graph:: CrateId ,
16
16
hir:: def_map:: { CrateDefMap , LocalModuleId , ModuleId } ,
17
- macros_api:: { ModuleDefId , NodeInterner } ,
17
+ macros_api:: NodeInterner ,
18
+ } ;
19
+ use noirc_frontend:: {
18
20
parser:: { Item , ItemKind , ParsedSubModule } ,
19
21
ParsedModule ,
20
22
} ;
21
23
22
- use crate :: {
23
- byte_span_to_range,
24
- modules:: { get_parent_module_id, module_full_path, module_id_path} ,
25
- utils, LspState ,
26
- } ;
24
+ use crate :: { utils, LspState } ;
27
25
28
26
use super :: { process_request, to_lsp_location} ;
29
27
28
+ mod fill_struct_fields;
29
+ mod import_or_qualify;
30
30
#[ cfg( test) ]
31
31
mod tests;
32
32
@@ -68,6 +68,7 @@ struct CodeActionFinder<'a> {
68
68
uri : Url ,
69
69
files : & ' a FileMap ,
70
70
file : FileId ,
71
+ source : & ' a str ,
71
72
lines : Vec < & ' a str > ,
72
73
byte_index : usize ,
73
74
/// The module ID in scope. This might change as we traverse the AST
@@ -108,6 +109,7 @@ impl<'a> CodeActionFinder<'a> {
108
109
uri,
109
110
files,
110
111
file,
112
+ source,
111
113
lines : source. lines ( ) . collect ( ) ,
112
114
byte_index,
113
115
module_id,
@@ -137,46 +139,7 @@ impl<'a> CodeActionFinder<'a> {
137
139
Some ( code_actions)
138
140
}
139
141
140
- fn push_import_code_action ( & mut self , full_path : & str ) {
141
- let line = self . auto_import_line as u32 ;
142
- let character = ( self . nesting * 4 ) as u32 ;
143
- let indent = " " . repeat ( self . nesting * 4 ) ;
144
- let mut newlines = "\n " ;
145
-
146
- // If the line we are inserting into is not an empty line, insert an extra line to make some room
147
- if let Some ( line_text) = self . lines . get ( line as usize ) {
148
- if !line_text. trim ( ) . is_empty ( ) {
149
- newlines = "\n \n " ;
150
- }
151
- }
152
-
153
- let title = format ! ( "Import {}" , full_path) ;
154
- let text_edit = TextEdit {
155
- range : Range { start : Position { line, character } , end : Position { line, character } } ,
156
- new_text : format ! ( "use {};{}{}" , full_path, newlines, indent) ,
157
- } ;
158
-
159
- let code_action = self . new_quick_fix ( title, text_edit) ;
160
- self . code_actions . push ( CodeActionOrCommand :: CodeAction ( code_action) ) ;
161
- }
162
-
163
- fn push_qualify_code_action ( & mut self , ident : & Ident , prefix : & str , full_path : & str ) {
164
- let Some ( range) = byte_span_to_range (
165
- self . files ,
166
- self . file ,
167
- ident. span ( ) . start ( ) as usize ..ident. span ( ) . start ( ) as usize ,
168
- ) else {
169
- return ;
170
- } ;
171
-
172
- let title = format ! ( "Qualify as {}" , full_path) ;
173
- let text_edit = TextEdit { range, new_text : format ! ( "{}::" , prefix) } ;
174
-
175
- let code_action = self . new_quick_fix ( title, text_edit) ;
176
- self . code_actions . push ( CodeActionOrCommand :: CodeAction ( code_action) ) ;
177
- }
178
-
179
- fn new_quick_fix ( & self , title : String , text_edit : TextEdit ) -> CodeAction {
142
+ fn new_quick_fix ( & self , title : String , text_edit : TextEdit ) -> CodeActionOrCommand {
180
143
let mut changes = HashMap :: new ( ) ;
181
144
changes. insert ( self . uri . clone ( ) , vec ! [ text_edit] ) ;
182
145
@@ -186,7 +149,7 @@ impl<'a> CodeActionFinder<'a> {
186
149
change_annotations : None ,
187
150
} ;
188
151
189
- CodeAction {
152
+ CodeActionOrCommand :: CodeAction ( CodeAction {
190
153
title,
191
154
kind : Some ( CodeActionKind :: QUICKFIX ) ,
192
155
diagnostics : None ,
@@ -195,7 +158,7 @@ impl<'a> CodeActionFinder<'a> {
195
158
is_preferred : None ,
196
159
disabled : None ,
197
160
data : None ,
198
- }
161
+ } )
199
162
}
200
163
201
164
fn includes_span ( & self , span : Span ) -> bool {
@@ -244,69 +207,16 @@ impl<'a> Visitor for CodeActionFinder<'a> {
244
207
}
245
208
246
209
fn visit_path ( & mut self , path : & Path ) {
247
- if path. segments . len ( ) != 1 {
248
- return ;
249
- }
250
-
251
- let ident = & path. segments [ 0 ] . ident ;
252
- if !self . includes_span ( ident. span ( ) ) {
253
- return ;
254
- }
255
-
256
- let location = Location :: new ( ident. span ( ) , self . file ) ;
257
- if self . interner . find_referenced ( location) . is_some ( ) {
258
- return ;
259
- }
260
-
261
- let current_module_parent_id = get_parent_module_id ( self . def_maps , self . module_id ) ;
262
-
263
- // The Path doesn't resolve to anything so it means it's an error and maybe we
264
- // can suggest an import or to fully-qualify the path.
265
- for ( name, entries) in self . interner . get_auto_import_names ( ) {
266
- if name != & ident. 0 . contents {
267
- continue ;
268
- }
269
-
270
- for ( module_def_id, visibility, defining_module) in entries {
271
- let module_full_path = if let Some ( defining_module) = defining_module {
272
- module_id_path (
273
- * defining_module,
274
- & self . module_id ,
275
- current_module_parent_id,
276
- self . interner ,
277
- )
278
- } else {
279
- let Some ( module_full_path) = module_full_path (
280
- * module_def_id,
281
- * visibility,
282
- self . module_id ,
283
- current_module_parent_id,
284
- self . interner ,
285
- ) else {
286
- continue ;
287
- } ;
288
- module_full_path
289
- } ;
290
-
291
- let full_path = if defining_module. is_some ( )
292
- || !matches ! ( module_def_id, ModuleDefId :: ModuleId ( ..) )
293
- {
294
- format ! ( "{}::{}" , module_full_path, name)
295
- } else {
296
- module_full_path. clone ( )
297
- } ;
210
+ self . import_or_qualify ( path) ;
211
+ }
298
212
299
- let qualify_prefix = if let ModuleDefId :: ModuleId ( ..) = module_def_id {
300
- let mut segments: Vec < _ > = module_full_path. split ( "::" ) . collect ( ) ;
301
- segments. pop ( ) ;
302
- segments. join ( "::" )
303
- } else {
304
- module_full_path
305
- } ;
213
+ fn visit_constructor_expression (
214
+ & mut self ,
215
+ constructor : & ConstructorExpression ,
216
+ span : Span ,
217
+ ) -> bool {
218
+ self . fill_struct_fields ( constructor, span) ;
306
219
307
- self . push_import_code_action ( & full_path) ;
308
- self . push_qualify_code_action ( ident, & qualify_prefix, & full_path) ;
309
- }
310
- }
220
+ true
311
221
}
312
222
}
0 commit comments