OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 | 7 |
8 import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; | 8 import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; |
9 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; | 9 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; |
10 import 'package:analysis_server/src/services/correction/assist.dart'; | 10 import 'package:analysis_server/src/services/correction/assist.dart'; |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 if (declaredIdentifier.type != null) { | 214 if (declaredIdentifier.type != null) { |
215 _coverageMarker(); | 215 _coverageMarker(); |
216 return; | 216 return; |
217 } | 217 } |
218 DartType type = declaredIdentifier.identifier.bestType; | 218 DartType type = declaredIdentifier.identifier.bestType; |
219 if (type is! InterfaceType && type is! FunctionType) { | 219 if (type is! InterfaceType && type is! FunctionType) { |
220 _coverageMarker(); | 220 _coverageMarker(); |
221 return; | 221 return; |
222 } | 222 } |
223 _configureTargetLocation(node); | 223 _configureTargetLocation(node); |
224 Set<Source> librariesToImport = new Set<Source>(); | |
225 String typeSource = utils.getTypeSource(type, librariesToImport); | |
226 if (typeSource == null) { | |
227 // The type source might be null if the type is private. | |
228 _coverageMarker(); | |
229 return; | |
230 } | |
231 | 224 |
232 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); | 225 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
| 226 bool validChange = true; |
233 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { | 227 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { |
234 Token keyword = declaredIdentifier.keyword; | 228 Token keyword = declaredIdentifier.keyword; |
235 if (keyword.keyword == Keyword.VAR) { | 229 if (keyword.keyword == Keyword.VAR) { |
236 builder.addSimpleReplacement(range.token(keyword), typeSource); | 230 builder.addReplacement(range.token(keyword), (DartEditBuilder builder) { |
| 231 validChange = builder.writeType(type); |
| 232 }); |
237 } else { | 233 } else { |
238 builder.addSimpleInsertion( | 234 builder.addInsertion(declaredIdentifier.identifier.offset, |
239 declaredIdentifier.identifier.offset, '$typeSource '); | 235 (DartEditBuilder builder) { |
| 236 validChange = builder.writeType(type); |
| 237 builder.write(' '); |
| 238 }); |
240 } | 239 } |
241 builder.importLibraries(librariesToImport); | |
242 }); | 240 }); |
243 _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); | 241 if (validChange) { |
| 242 _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); |
| 243 } |
244 } | 244 } |
245 | 245 |
246 Future<Null> _addProposal_addTypeAnnotation_SimpleFormalParameter() async { | 246 Future<Null> _addProposal_addTypeAnnotation_SimpleFormalParameter() async { |
247 AstNode node = this.node; | 247 AstNode node = this.node; |
248 // should be the name of a simple parameter | 248 // should be the name of a simple parameter |
249 if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) { | 249 if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) { |
250 _coverageMarker(); | 250 _coverageMarker(); |
251 return; | 251 return; |
252 } | 252 } |
253 SimpleIdentifier name = node; | 253 SimpleIdentifier name = node; |
254 SimpleFormalParameter parameter = node.parent; | 254 SimpleFormalParameter parameter = node.parent; |
255 // the parameter should not have a type | 255 // the parameter should not have a type |
256 if (parameter.type != null) { | 256 if (parameter.type != null) { |
257 _coverageMarker(); | 257 _coverageMarker(); |
258 return; | 258 return; |
259 } | 259 } |
260 // prepare the type | 260 // prepare the type |
261 DartType type = parameter.element.type; | 261 DartType type = parameter.element.type; |
262 // TODO(scheglov) If the parameter is in a method declaration, and if the | 262 // TODO(scheglov) If the parameter is in a method declaration, and if the |
263 // method overrides a method that has a type for the corresponding | 263 // method overrides a method that has a type for the corresponding |
264 // parameter, it would be nice to copy down the type from the overridden | 264 // parameter, it would be nice to copy down the type from the overridden |
265 // method. | 265 // method. |
266 if (type is! InterfaceType) { | 266 if (type is! InterfaceType) { |
267 _coverageMarker(); | 267 _coverageMarker(); |
268 return; | 268 return; |
269 } | 269 } |
270 // prepare type source | 270 // prepare type source |
271 _configureTargetLocation(node); | 271 _configureTargetLocation(node); |
272 Set<Source> librariesToImport = new Set<Source>(); | |
273 String typeSource = utils.getTypeSource(type, librariesToImport); | |
274 // type source might be null, if the type is private | |
275 if (typeSource == null) { | |
276 _coverageMarker(); | |
277 return; | |
278 } | |
279 | 272 |
280 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); | 273 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
| 274 bool validChange = true; |
281 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { | 275 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { |
282 builder.addSimpleInsertion(name.offset, '$typeSource '); | 276 builder.addInsertion(name.offset, (DartEditBuilder builder) { |
283 builder.importLibraries(librariesToImport); | 277 validChange = builder.writeType(type); |
| 278 builder.write(' '); |
| 279 }); |
284 }); | 280 }); |
285 _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); | 281 if (validChange) { |
| 282 _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); |
| 283 } |
286 } | 284 } |
287 | 285 |
288 Future<Null> _addProposal_addTypeAnnotation_VariableDeclaration() async { | 286 Future<Null> _addProposal_addTypeAnnotation_VariableDeclaration() async { |
289 AstNode node = this.node; | 287 AstNode node = this.node; |
290 // prepare VariableDeclarationList | 288 // prepare VariableDeclarationList |
291 VariableDeclarationList declarationList = | 289 VariableDeclarationList declarationList = |
292 node.getAncestor((node) => node is VariableDeclarationList); | 290 node.getAncestor((node) => node is VariableDeclarationList); |
293 if (declarationList == null) { | 291 if (declarationList == null) { |
294 _coverageMarker(); | 292 _coverageMarker(); |
295 return; | 293 return; |
(...skipping 22 matching lines...) Expand all Loading... |
318 return; | 316 return; |
319 } | 317 } |
320 DartType type = initializer.bestType; | 318 DartType type = initializer.bestType; |
321 // prepare type source | 319 // prepare type source |
322 if ((type is! InterfaceType || type.isDartCoreNull) && | 320 if ((type is! InterfaceType || type.isDartCoreNull) && |
323 type is! FunctionType) { | 321 type is! FunctionType) { |
324 _coverageMarker(); | 322 _coverageMarker(); |
325 return; | 323 return; |
326 } | 324 } |
327 _configureTargetLocation(node); | 325 _configureTargetLocation(node); |
328 Set<Source> librariesToImport = new Set<Source>(); | |
329 String typeSource = utils.getTypeSource(type, librariesToImport); | |
330 // type source might be null, if the type is private | |
331 if (typeSource == null) { | |
332 _coverageMarker(); | |
333 return; | |
334 } | |
335 | 326 |
336 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); | 327 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
337 if (unitLibraryFile == file) { | 328 bool validChange = true; |
338 // TODO(brianwilkerson) Make ChangeBuilder merge multiple edits to the | 329 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { |
339 // same file so that only the else block is necessary. | 330 Token keyword = declarationList.keyword; |
340 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { | 331 if (keyword?.keyword == Keyword.VAR) { |
341 Token keyword = declarationList.keyword; | 332 builder.addReplacement(range.token(keyword), (DartEditBuilder builder) { |
342 if (keyword?.keyword == Keyword.VAR) { | 333 validChange = builder.writeType(type); |
343 builder.addSimpleReplacement(range.token(keyword), typeSource); | 334 }); |
344 } else { | 335 } else { |
345 builder.addSimpleInsertion(variable.offset, '$typeSource '); | 336 builder.addInsertion(variable.offset, (DartEditBuilder builder) { |
346 } | 337 validChange = builder.writeType(type); |
347 builder.importLibraries(librariesToImport); | 338 builder.write(' '); |
348 }); | 339 }); |
349 } else { | 340 } |
350 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { | 341 }); |
351 Token keyword = declarationList.keyword; | 342 if (validChange) { |
352 if (keyword?.keyword == Keyword.VAR) { | 343 _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); |
353 builder.addSimpleReplacement(range.token(keyword), typeSource); | |
354 } else { | |
355 builder.addSimpleInsertion(variable.offset, '$typeSource '); | |
356 } | |
357 }); | |
358 await changeBuilder.addFileEdit(unitLibraryFile, | |
359 (DartFileEditBuilder builder) { | |
360 builder.importLibraries(librariesToImport); | |
361 }); | |
362 } | 344 } |
363 _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); | |
364 } | 345 } |
365 | 346 |
366 Future<Null> _addProposal_assignToLocalVariable() async { | 347 Future<Null> _addProposal_assignToLocalVariable() async { |
367 // prepare enclosing ExpressionStatement | 348 // prepare enclosing ExpressionStatement |
368 ExpressionStatement expressionStatement; | 349 ExpressionStatement expressionStatement; |
369 for (AstNode node = this.node; node != null; node = node.parent) { | 350 for (AstNode node = this.node; node != null; node = node.parent) { |
370 if (node is ExpressionStatement) { | 351 if (node is ExpressionStatement) { |
371 expressionStatement = node; | 352 expressionStatement = node; |
372 break; | 353 break; |
373 } | 354 } |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 node.parent is FieldFormalParameter && | 1065 node.parent is FieldFormalParameter && |
1085 node.parent.parent is FormalParameterList && | 1066 node.parent.parent is FormalParameterList && |
1086 node.parent.parent.parent is ConstructorDeclaration) { | 1067 node.parent.parent.parent is ConstructorDeclaration) { |
1087 ConstructorDeclaration constructor = node.parent.parent.parent; | 1068 ConstructorDeclaration constructor = node.parent.parent.parent; |
1088 FormalParameterList parameterList = node.parent.parent; | 1069 FormalParameterList parameterList = node.parent.parent; |
1089 FieldFormalParameter parameter = node.parent; | 1070 FieldFormalParameter parameter = node.parent; |
1090 ParameterElement parameterElement = parameter.element; | 1071 ParameterElement parameterElement = parameter.element; |
1091 String name = (node as SimpleIdentifier).name; | 1072 String name = (node as SimpleIdentifier).name; |
1092 // prepare type | 1073 // prepare type |
1093 DartType type = parameterElement.type; | 1074 DartType type = parameterElement.type; |
1094 Set<Source> librariesToImport = new Set<Source>(); | |
1095 String typeCode = utils.getTypeSource(type, librariesToImport); | |
1096 | 1075 |
1097 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); | 1076 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
1098 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { | 1077 await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { |
1099 // replace parameter | 1078 // replace parameter |
1100 if (type.isDynamic) { | 1079 if (type.isDynamic) { |
1101 builder.addSimpleReplacement(range.node(parameter), name); | 1080 builder.addSimpleReplacement(range.node(parameter), name); |
1102 } else { | 1081 } else { |
1103 builder.addSimpleReplacement( | 1082 builder.addReplacement(range.node(parameter), |
1104 range.node(parameter), '$typeCode $name'); | 1083 (DartEditBuilder builder) { |
| 1084 builder.writeType(type); |
| 1085 builder.write(' '); |
| 1086 builder.write(name); |
| 1087 }); |
1105 } | 1088 } |
1106 // add field initializer | 1089 // add field initializer |
1107 List<ConstructorInitializer> initializers = constructor.initializers; | 1090 List<ConstructorInitializer> initializers = constructor.initializers; |
1108 if (initializers.isEmpty) { | 1091 if (initializers.isEmpty) { |
1109 builder.addSimpleInsertion(parameterList.end, ' : $name = $name'); | 1092 builder.addSimpleInsertion(parameterList.end, ' : $name = $name'); |
1110 } else { | 1093 } else { |
1111 builder.addSimpleInsertion(initializers.last.end, ', $name = $name'); | 1094 builder.addSimpleInsertion(initializers.last.end, ', $name = $name'); |
1112 } | 1095 } |
1113 }); | 1096 }); |
1114 _addAssistFromBuilder( | 1097 _addAssistFromBuilder( |
(...skipping 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 class _SimpleIdentifierRecursiveAstVisitor extends RecursiveAstVisitor { | 2561 class _SimpleIdentifierRecursiveAstVisitor extends RecursiveAstVisitor { |
2579 final _SimpleIdentifierVisitor visitor; | 2562 final _SimpleIdentifierVisitor visitor; |
2580 | 2563 |
2581 _SimpleIdentifierRecursiveAstVisitor(this.visitor); | 2564 _SimpleIdentifierRecursiveAstVisitor(this.visitor); |
2582 | 2565 |
2583 @override | 2566 @override |
2584 visitSimpleIdentifier(SimpleIdentifier node) { | 2567 visitSimpleIdentifier(SimpleIdentifier node) { |
2585 visitor(node); | 2568 visitor(node); |
2586 } | 2569 } |
2587 } | 2570 } |
OLD | NEW |