Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Issue 2930793002: Finish refactoring FixProcessor to use ChangeBuilder (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/correction/flutter_util.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 import 'dart:core'; 7 import 'dart:core';
8 8
9 import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; 9 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
10 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; 10 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
11 import 'package:analysis_server/src/protocol_server.dart'
12 show doSourceChange_addElementEdit, doSourceChange_addSourceEdit;
13 import 'package:analysis_server/src/services/completion/dart/utilities.dart'; 11 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
14 import 'package:analysis_server/src/services/correction/fix.dart'; 12 import 'package:analysis_server/src/services/correction/fix.dart';
15 import 'package:analysis_server/src/services/correction/flutter_util.dart'; 13 import 'package:analysis_server/src/services/correction/flutter_util.dart';
16 import 'package:analysis_server/src/services/correction/levenshtein.dart'; 14 import 'package:analysis_server/src/services/correction/levenshtein.dart';
17 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
18 import 'package:analysis_server/src/services/correction/namespace.dart'; 15 import 'package:analysis_server/src/services/correction/namespace.dart';
19 import 'package:analysis_server/src/services/correction/source_buffer.dart';
20 import 'package:analysis_server/src/services/correction/strings.dart'; 16 import 'package:analysis_server/src/services/correction/strings.dart';
21 import 'package:analysis_server/src/services/correction/util.dart'; 17 import 'package:analysis_server/src/services/correction/util.dart';
22 import 'package:analysis_server/src/services/search/hierarchy.dart'; 18 import 'package:analysis_server/src/services/search/hierarchy.dart';
23 import 'package:analyzer/dart/ast/ast.dart'; 19 import 'package:analyzer/dart/ast/ast.dart';
24 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 20 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
25 import 'package:analyzer/dart/ast/token.dart'; 21 import 'package:analyzer/dart/ast/token.dart';
26 import 'package:analyzer/dart/element/element.dart'; 22 import 'package:analyzer/dart/element/element.dart';
27 import 'package:analyzer/dart/element/type.dart'; 23 import 'package:analyzer/dart/element/type.dart';
28 import 'package:analyzer/error/error.dart'; 24 import 'package:analyzer/error/error.dart';
29 import 'package:analyzer/file_system/file_system.dart'; 25 import 'package:analyzer/file_system/file_system.dart';
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 String file; 107 String file;
112 int fileStamp; 108 int fileStamp;
113 CompilationUnitElement unitElement; 109 CompilationUnitElement unitElement;
114 Source unitSource; 110 Source unitSource;
115 LibraryElement unitLibraryElement; 111 LibraryElement unitLibraryElement;
116 File unitLibraryFile; 112 File unitLibraryFile;
117 Folder unitLibraryFolder; 113 Folder unitLibraryFolder;
118 114
119 final List<Fix> fixes = <Fix>[]; 115 final List<Fix> fixes = <Fix>[];
120 116
121 SourceChange change = new SourceChange('<message>');
122 final LinkedHashMap<String, LinkedEditGroup> linkedPositionGroups =
123 new LinkedHashMap<String, LinkedEditGroup>();
124 Position exitPosition = null;
125 Set<Source> librariesToImport = new Set<Source>();
126
127 CorrectionUtils utils; 117 CorrectionUtils utils;
128 int errorOffset; 118 int errorOffset;
129 int errorLength; 119 int errorLength;
130 int errorEnd; 120 int errorEnd;
131 SourceRange errorRange; 121 SourceRange errorRange;
132 AstNode node; 122 AstNode node;
133 AstNode coveredNode; 123 AstNode coveredNode;
134 124
135 TypeProvider _typeProvider; 125 TypeProvider _typeProvider;
136 TypeSystem _typeSystem; 126 TypeSystem _typeSystem;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 node = new NodeLocator2(errorOffset).searchWithin(unit); 191 node = new NodeLocator2(errorOffset).searchWithin(unit);
202 coveredNode = 192 coveredNode =
203 new NodeLocator2(errorOffset, errorEnd - 1).searchWithin(unit); 193 new NodeLocator2(errorOffset, errorEnd - 1).searchWithin(unit);
204 // analyze ErrorCode 194 // analyze ErrorCode
205 ErrorCode errorCode = error.errorCode; 195 ErrorCode errorCode = error.errorCode;
206 if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) { 196 if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) {
207 await _addFix_boolInsteadOfBoolean(); 197 await _addFix_boolInsteadOfBoolean();
208 } 198 }
209 if (errorCode == 199 if (errorCode ==
210 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) { 200 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
211 _addFix_replaceWithConstInstanceCreation(); 201 await _addFix_replaceWithConstInstanceCreation();
212 } 202 }
213 if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT || 203 if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT ||
214 errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) { 204 errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) {
215 await _addFix_addAsync(); 205 await _addFix_addAsync();
216 } 206 }
217 if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION) { 207 if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION) {
218 if (node is Annotation) { 208 if (node is Annotation) {
219 Annotation annotation = node; 209 Annotation annotation = node;
220 Identifier name = annotation.name; 210 Identifier name = annotation.name;
221 if (name != null && name.staticElement == null) { 211 if (name != null && name.staticElement == null) {
222 node = name; 212 node = name;
223 if (annotation.arguments == null) { 213 if (annotation.arguments == null) {
224 await _addFix_importLibrary_withTopLevelVariable(); 214 await _addFix_importLibrary_withTopLevelVariable();
225 } else { 215 } else {
226 await _addFix_importLibrary_withType(); 216 await _addFix_importLibrary_withType();
227 await _addFix_createClass(); 217 await _addFix_createClass();
228 _addFix_undefinedClass_useSimilar(); 218 await _addFix_undefinedClass_useSimilar();
229 } 219 }
230 } 220 }
231 } 221 }
232 } 222 }
233 if (errorCode == 223 if (errorCode ==
234 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) { 224 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) {
235 await _addFix_createConstructorSuperExplicit(); 225 await _addFix_createConstructorSuperExplicit();
236 } 226 }
237 if (errorCode == 227 if (errorCode ==
238 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) { 228 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) {
239 await _addFix_createConstructorSuperImplicit(); 229 await _addFix_createConstructorSuperImplicit();
240 } 230 }
241 if (errorCode == 231 if (errorCode ==
242 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) { 232 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) {
243 await _addFix_createConstructorSuperExplicit(); 233 await _addFix_createConstructorSuperExplicit();
244 } 234 }
245 if (errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST) { 235 if (errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST) {
246 _addFix_createImportUri(); 236 await _addFix_createImportUri();
247 _addFix_createPartUri(); 237 await _addFix_createPartUri();
248 } 238 }
249 if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) { 239 if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) {
250 await _addFix_canBeNullAfterNullAware(); 240 await _addFix_canBeNullAfterNullAware();
251 } 241 }
252 if (errorCode == HintCode.DEAD_CODE) { 242 if (errorCode == HintCode.DEAD_CODE) {
253 _addFix_removeDeadCode(); 243 await _addFix_removeDeadCode();
254 } 244 }
255 if (errorCode == HintCode.DIVISION_OPTIMIZATION) { 245 if (errorCode == HintCode.DIVISION_OPTIMIZATION) {
256 _addFix_useEffectiveIntegerDivision(); 246 await _addFix_useEffectiveIntegerDivision();
257 } 247 }
258 if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) { 248 if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
259 await _addFix_isNotNull(); 249 await _addFix_isNotNull();
260 } 250 }
261 if (errorCode == HintCode.TYPE_CHECK_IS_NULL) { 251 if (errorCode == HintCode.TYPE_CHECK_IS_NULL) {
262 await _addFix_isNull(); 252 await _addFix_isNull();
263 } 253 }
264 if (errorCode == HintCode.UNDEFINED_GETTER) { 254 if (errorCode == HintCode.UNDEFINED_GETTER) {
265 _addFix_undefinedClassAccessor_useSimilar(); 255 await _addFix_undefinedClassAccessor_useSimilar();
266 await _addFix_createField(); 256 await _addFix_createField();
267 await _addFix_createGetter(); 257 await _addFix_createGetter();
268 } 258 }
269 if (errorCode == HintCode.UNDEFINED_SETTER) { 259 if (errorCode == HintCode.UNDEFINED_SETTER) {
270 _addFix_undefinedClassAccessor_useSimilar(); 260 await _addFix_undefinedClassAccessor_useSimilar();
271 await _addFix_createField(); 261 await _addFix_createField();
272 } 262 }
273 if (errorCode == HintCode.UNNECESSARY_CAST) { 263 if (errorCode == HintCode.UNNECESSARY_CAST) {
274 _addFix_removeUnnecessaryCast(); 264 await _addFix_removeUnnecessaryCast();
275 } 265 }
276 if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) { 266 if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) {
277 _addFix_removeUnusedCatchClause(); 267 await _addFix_removeUnusedCatchClause();
278 } 268 }
279 if (errorCode == HintCode.UNUSED_CATCH_STACK) { 269 if (errorCode == HintCode.UNUSED_CATCH_STACK) {
280 _addFix_removeUnusedCatchStack(); 270 await _addFix_removeUnusedCatchStack();
281 } 271 }
282 if (errorCode == HintCode.UNUSED_IMPORT) { 272 if (errorCode == HintCode.UNUSED_IMPORT) {
283 _addFix_removeUnusedImport(); 273 await _addFix_removeUnusedImport();
284 } 274 }
285 if (errorCode == ParserErrorCode.EXPECTED_TOKEN) { 275 if (errorCode == ParserErrorCode.EXPECTED_TOKEN) {
286 await _addFix_insertSemicolon(); 276 await _addFix_insertSemicolon();
287 } 277 }
288 if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) { 278 if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) {
289 _addFix_removeParameters_inGetterDeclaration(); 279 await _addFix_removeParameters_inGetterDeclaration();
290 } 280 }
291 if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) { 281 if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) {
292 _addFix_replaceVarWithDynamic(); 282 await _addFix_replaceVarWithDynamic();
293 } 283 }
294 if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) { 284 if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) {
295 await _addFix_makeFieldNotFinal(); 285 await _addFix_makeFieldNotFinal();
296 } 286 }
297 if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) { 287 if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) {
298 await _addFix_makeEnclosingClassAbstract(); 288 await _addFix_makeEnclosingClassAbstract();
299 } 289 }
300 if (errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS || 290 if (errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS ||
301 errorCode == 291 errorCode ==
302 StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED) { 292 StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED) {
(...skipping 28 matching lines...) Expand all
331 await _addFix_createNoSuchMethod(); 321 await _addFix_createNoSuchMethod();
332 // implement methods 322 // implement methods
333 await _addFix_createMissingOverrides(); 323 await _addFix_createMissingOverrides();
334 } 324 }
335 if (errorCode == CompileTimeErrorCode.UNDEFINED_CLASS || 325 if (errorCode == CompileTimeErrorCode.UNDEFINED_CLASS ||
336 errorCode == StaticWarningCode.CAST_TO_NON_TYPE || 326 errorCode == StaticWarningCode.CAST_TO_NON_TYPE ||
337 errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME || 327 errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME ||
338 errorCode == StaticWarningCode.UNDEFINED_CLASS) { 328 errorCode == StaticWarningCode.UNDEFINED_CLASS) {
339 await _addFix_importLibrary_withType(); 329 await _addFix_importLibrary_withType();
340 await _addFix_createClass(); 330 await _addFix_createClass();
341 _addFix_undefinedClass_useSimilar(); 331 await _addFix_undefinedClass_useSimilar();
342 } 332 }
343 if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) { 333 if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) {
344 await _addFix_createConstructor_forUninitializedFinalFields(); 334 await _addFix_createConstructor_forUninitializedFinalFields();
345 } 335 }
346 if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 || 336 if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 ||
347 errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 || 337 errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 ||
348 errorCode == 338 errorCode ==
349 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) { 339 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) {
350 _addFix_updateConstructor_forUninitializedFinalFields(); 340 await _addFix_updateConstructor_forUninitializedFinalFields();
351 } 341 }
352 if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) { 342 if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
353 _addFix_undefinedClassAccessor_useSimilar(); 343 await _addFix_undefinedClassAccessor_useSimilar();
354 await _addFix_createClass(); 344 await _addFix_createClass();
355 await _addFix_createField(); 345 await _addFix_createField();
356 await _addFix_createGetter(); 346 await _addFix_createGetter();
357 _addFix_createFunction_forFunctionType(); 347 await _addFix_createFunction_forFunctionType();
358 await _addFix_importLibrary_withType(); 348 await _addFix_importLibrary_withType();
359 await _addFix_importLibrary_withTopLevelVariable(); 349 await _addFix_importLibrary_withTopLevelVariable();
360 await _addFix_createLocalVariable(); 350 await _addFix_createLocalVariable();
361 } 351 }
362 if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) { 352 if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) {
363 await _addFix_illegalAsyncReturnType(); 353 await _addFix_illegalAsyncReturnType();
364 } 354 }
365 if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) { 355 if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
366 _addFix_useStaticAccess_method(); 356 await _addFix_useStaticAccess_method();
367 _addFix_useStaticAccess_property(); 357 await _addFix_useStaticAccess_property();
368 } 358 }
369 if (errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT) { 359 if (errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT) {
370 await _addFix_changeTypeAnnotation(); 360 await _addFix_changeTypeAnnotation();
371 } 361 }
372 if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) { 362 if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) {
373 _addFix_removeParentheses_inGetterInvocation(); 363 await _addFix_removeParentheses_inGetterInvocation();
374 } 364 }
375 if (errorCode == StaticTypeWarningCode.NON_BOOL_CONDITION) { 365 if (errorCode == StaticTypeWarningCode.NON_BOOL_CONDITION) {
376 await _addFix_nonBoolCondition_addNotNull(); 366 await _addFix_nonBoolCondition_addNotNull();
377 } 367 }
378 if (errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT) { 368 if (errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT) {
379 await _addFix_importLibrary_withType(); 369 await _addFix_importLibrary_withType();
380 await _addFix_createClass(); 370 await _addFix_createClass();
381 } 371 }
382 if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) { 372 if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) {
383 await _addFix_importLibrary_withFunction(); 373 await _addFix_importLibrary_withFunction();
384 _addFix_undefinedFunction_useSimilar(); 374 await _addFix_undefinedFunction_useSimilar();
385 _addFix_undefinedFunction_create(); 375 await _addFix_undefinedFunction_create();
386 } 376 }
387 if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) { 377 if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) {
388 _addFix_undefinedClassAccessor_useSimilar(); 378 await _addFix_undefinedClassAccessor_useSimilar();
389 await _addFix_createField(); 379 await _addFix_createField();
390 await _addFix_createGetter(); 380 await _addFix_createGetter();
391 _addFix_createFunction_forFunctionType(); 381 await _addFix_createFunction_forFunctionType();
392 } 382 }
393 if (errorCode == HintCode.UNDEFINED_METHOD || 383 if (errorCode == HintCode.UNDEFINED_METHOD ||
394 errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) { 384 errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
395 await _addFix_importLibrary_withFunction(); 385 await _addFix_importLibrary_withFunction();
396 _addFix_undefinedMethod_useSimilar(); 386 await _addFix_undefinedMethod_useSimilar();
397 _addFix_undefinedMethod_create(); 387 await _addFix_undefinedMethod_create();
398 _addFix_undefinedFunction_create(); 388 await _addFix_undefinedFunction_create();
399 } 389 }
400 if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) { 390 if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) {
401 _addFix_undefinedClassAccessor_useSimilar(); 391 await _addFix_undefinedClassAccessor_useSimilar();
402 await _addFix_createField(); 392 await _addFix_createField();
403 } 393 }
404 if (errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER || 394 if (errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER ||
405 errorCode == StaticWarningCode.UNDEFINED_NAMED_PARAMETER) { 395 errorCode == StaticWarningCode.UNDEFINED_NAMED_PARAMETER) {
406 _addFix_convertFlutterChild(); 396 await _addFix_convertFlutterChild();
407 _addFix_convertFlutterChildren(); 397 await _addFix_convertFlutterChildren();
408 } 398 }
409 // lints 399 // lints
410 if (errorCode is LintCode) { 400 if (errorCode is LintCode) {
411 if (errorCode.name == LintNames.annotate_overrides) { 401 if (errorCode.name == LintNames.annotate_overrides) {
412 _addLintFixAddOverrideAnnotation(); 402 await _addFix_addOverrideAnnotation();
413 } 403 }
414 if (errorCode.name == LintNames.avoid_annotating_with_dynamic) { 404 if (errorCode.name == LintNames.avoid_annotating_with_dynamic) {
415 _addFix_removeTypeName(); 405 await _addFix_removeTypeName();
416 } 406 }
417 if (errorCode.name == LintNames.avoid_init_to_null) { 407 if (errorCode.name == LintNames.avoid_init_to_null) {
418 _addFix_removeInitializer(); 408 await _addFix_removeInitializer();
419 } 409 }
420 if (errorCode.name == LintNames.avoid_return_types_on_setters) { 410 if (errorCode.name == LintNames.avoid_return_types_on_setters) {
421 _addFix_removeTypeName(); 411 await _addFix_removeTypeName();
422 } 412 }
423 if (errorCode.name == LintNames.avoid_types_on_closure_parameters) { 413 if (errorCode.name == LintNames.avoid_types_on_closure_parameters) {
424 _addFix_replaceWithIdentifier(); 414 await _addFix_replaceWithIdentifier();
425 } 415 }
426 if (errorCode.name == LintNames.await_only_futures) { 416 if (errorCode.name == LintNames.await_only_futures) {
427 _addFix_removeAwait(); 417 await _addFix_removeAwait();
428 } 418 }
429 if (errorCode.name == LintNames.empty_statements) { 419 if (errorCode.name == LintNames.empty_statements) {
430 _addFix_removeEmptyStatement(); 420 await _addFix_removeEmptyStatement();
431 } 421 }
432 if (errorCode.name == LintNames.prefer_collection_literals) { 422 if (errorCode.name == LintNames.prefer_collection_literals) {
433 _addFix_replaceWithLiteral(); 423 await _addFix_replaceWithLiteral();
434 } 424 }
435 if (errorCode.name == LintNames.prefer_conditional_assignment) { 425 if (errorCode.name == LintNames.prefer_conditional_assignment) {
436 _addFix_replaceWithConditionalAssignment(); 426 await _addFix_replaceWithConditionalAssignment();
437 } 427 }
438 if (errorCode.name == LintNames.unnecessary_brace_in_string_interp) { 428 if (errorCode.name == LintNames.unnecessary_brace_in_string_interp) {
439 _addLintRemoveInterpolationBraces(); 429 await _addFix_removeInterpolationBraces();
440 } 430 }
441 if (errorCode.name == LintNames.unnecessary_lambdas) { 431 if (errorCode.name == LintNames.unnecessary_lambdas) {
442 _addFix_replaceWithTearOff(); 432 await _addFix_replaceWithTearOff();
443 } 433 }
444 if (errorCode.name == LintNames.unnecessary_override) { 434 if (errorCode.name == LintNames.unnecessary_override) {
445 _addFix_removeMethodDeclaration(); 435 await _addFix_removeMethodDeclaration();
446 } 436 }
447 if (errorCode.name == LintNames.unnecessary_this) { 437 if (errorCode.name == LintNames.unnecessary_this) {
448 _addFix_removeThisExpression(); 438 await _addFix_removeThisExpression();
449 } 439 }
450 } 440 }
451 // done 441 // done
452 return fixes; 442 return fixes;
453 } 443 }
454 444
455 /** 445 /**
456 * Adds a new [SourceEdit] to [change].
457 */
458 void _addEdit(Element target, SourceEdit edit) {
459 if (target == null) {
460 target = unitElement;
461 }
462 Source source = target.source;
463 if (source.isInSystemLibrary) {
464 return;
465 }
466 doSourceChange_addElementEdit(change, target, edit);
467 }
468
469 void _addFix(FixKind kind, List args, {bool importsOnly: false}) {
470 if (change.edits.isEmpty && !importsOnly) {
471 return;
472 }
473 // configure Change
474 change.message = formatList(kind.message, args);
475 linkedPositionGroups.values
476 .forEach((group) => change.addLinkedEditGroup(group));
477 change.selection = exitPosition;
478 // add imports
479 addLibraryImports(change, unitLibraryElement, librariesToImport);
480 // add Fix
481 Fix fix = new Fix(kind, change);
482 fixes.add(fix);
483 // clear
484 change = new SourceChange('<message>');
485 linkedPositionGroups.clear();
486 exitPosition = null;
487 librariesToImport.clear();
488 }
489
490 /**
491 * Returns `true` if the `async` proposal was added. 446 * Returns `true` if the `async` proposal was added.
492 */ 447 */
493 Future<Null> _addFix_addAsync() async { 448 Future<Null> _addFix_addAsync() async {
494 FunctionBody body = node.getAncestor((n) => n is FunctionBody); 449 FunctionBody body = node.getAncestor((n) => n is FunctionBody);
495 if (body != null && body.keyword == null) { 450 if (body != null && body.keyword == null) {
496 TypeProvider typeProvider = await this.typeProvider; 451 TypeProvider typeProvider = await this.typeProvider;
497 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 452 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
498 await changeBuilder.addFileEdit(file, fileStamp, 453 await changeBuilder.addFileEdit(file, fileStamp,
499 (DartFileEditBuilder builder) { 454 (DartFileEditBuilder builder) {
500 builder.convertFunctionFromSyncToAsync(body, typeProvider); 455 builder.convertFunctionFromSyncToAsync(body, typeProvider);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 builder.write(','); 627 builder.write(',');
673 } 628 }
674 }); 629 });
675 }); 630 });
676 _addFixFromBuilder( 631 _addFixFromBuilder(
677 changeBuilder, DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, 632 changeBuilder, DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT,
678 args: [paramName]); 633 args: [paramName]);
679 } 634 }
680 } 635 }
681 636
637 Future<Null> _addFix_addOverrideAnnotation() async {
638 ClassMember member = node.getAncestor((n) => n is ClassMember);
639 if (member == null) {
640 return;
641 }
642
643 //TODO(pq): migrate annotation edit building to change_builder
644
645 // Handle doc comments.
646 Token token = member.beginToken;
647 if (token is CommentToken) {
648 token = (token as CommentToken).parent;
649 }
650
651 Position exitPosition = new Position(file, token.offset - 1);
652 String indent = utils.getIndent(1);
653 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
654 await changeBuilder.addFileEdit(file, fileStamp,
scheglov 2017/06/07 21:27:32 1. This code: new DartChangeBuilder(), then "addFi
655 (DartFileEditBuilder builder) {
scheglov 2017/06/07 21:27:32 3. Consider removing DartFileEditBuilder annotatio
656 builder.addSimpleReplacement(
657 range.startLength(token, 0), '@override$eol$indent');
658 });
659 changeBuilder.setSelection(exitPosition);
660 _addFixFromBuilder(changeBuilder, DartFixKind.LINT_ADD_OVERRIDE);
661 }
662
682 Future<Null> _addFix_boolInsteadOfBoolean() async { 663 Future<Null> _addFix_boolInsteadOfBoolean() async {
683 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 664 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
684 await changeBuilder.addFileEdit(file, fileStamp, 665 await changeBuilder.addFileEdit(file, fileStamp,
685 (DartFileEditBuilder builder) { 666 (DartFileEditBuilder builder) {
686 builder.addSimpleReplacement(range.error(error), 'bool'); 667 builder.addSimpleReplacement(range.error(error), 'bool');
687 }); 668 });
688 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_BOOLEAN_WITH_BOOL); 669 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_BOOLEAN_WITH_BOOL);
689 } 670 }
690 671
691 Future<Null> _addFix_canBeNullAfterNullAware() async { 672 Future<Null> _addFix_canBeNullAfterNullAware() async {
(...skipping 24 matching lines...) Expand all
716 if (declaration is VariableDeclaration && 697 if (declaration is VariableDeclaration &&
717 declaration.initializer == coveredNode) { 698 declaration.initializer == coveredNode) {
718 AstNode variableList = declaration.parent; 699 AstNode variableList = declaration.parent;
719 if (variableList is VariableDeclarationList && 700 if (variableList is VariableDeclarationList &&
720 variableList.variables.length == 1) { 701 variableList.variables.length == 1) {
721 TypeAnnotation typeNode = variableList.type; 702 TypeAnnotation typeNode = variableList.type;
722 if (typeNode != null) { 703 if (typeNode != null) {
723 Expression initializer = coveredNode; 704 Expression initializer = coveredNode;
724 DartType newType = initializer.bestType; 705 DartType newType = initializer.bestType;
725 if (newType is InterfaceType || newType is FunctionType) { 706 if (newType is InterfaceType || newType is FunctionType) {
726 String newTypeSource =
727 utils.getTypeSource(newType, librariesToImport);
728 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 707 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
729 await changeBuilder.addFileEdit(file, fileStamp, 708 await changeBuilder.addFileEdit(file, fileStamp,
730 (DartFileEditBuilder builder) { 709 (DartFileEditBuilder builder) {
731 builder.addSimpleReplacement(range.node(typeNode), newTypeSource); 710 builder.addReplacement(range.node(typeNode),
711 (DartEditBuilder builder) {
712 builder.writeType(newType);
713 });
732 }); 714 });
733 _addFixFromBuilder( 715 _addFixFromBuilder(
734 changeBuilder, DartFixKind.CHANGE_TYPE_ANNOTATION, 716 changeBuilder, DartFixKind.CHANGE_TYPE_ANNOTATION, args: [
735 args: [resolutionMap.typeForTypeName(typeNode), newTypeSource]); 717 resolutionMap.typeForTypeName(typeNode),
718 newType.displayName
719 ]);
736 } 720 }
737 } 721 }
738 } 722 }
739 } 723 }
740 } 724 }
741 725
742 void _addFix_convertFlutterChild() { 726 Future<Null> _addFix_convertFlutterChild() async {
743 NamedExpression namedExp = findFlutterNamedExpression(node, 'child'); 727 NamedExpression namedExp = findFlutterNamedExpression(node, 'child');
744 if (namedExp == null) { 728 if (namedExp == null) {
745 return; 729 return;
746 } 730 }
747 InstanceCreationExpression childArg = getChildWidget(namedExp, false); 731 InstanceCreationExpression childArg = getChildWidget(namedExp, false);
748 if (childArg != null) { 732 if (childArg != null) {
749 convertFlutterChildToChildren( 733 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
750 childArg, 734 await changeBuilder.addFileEdit(file, fileStamp,
751 namedExp, 735 (DartFileEditBuilder builder) {
752 eol, 736 convertFlutterChildToChildren2(
753 utils.getNodeText, 737 builder,
754 utils.getLinePrefix, 738 childArg,
755 utils.getIndent, 739 namedExp,
756 utils.getText, 740 eol,
757 _addInsertEdit, 741 utils.getNodeText,
758 _addRemoveEdit, 742 utils.getLinePrefix,
759 _addReplaceEdit, 743 utils.getIndent,
760 range.node); 744 utils.getText,
761 _addFix(DartFixKind.CONVERT_FLUTTER_CHILD, []); 745 range.node);
746 });
747 _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD);
762 return; 748 return;
763 } 749 }
764 ListLiteral listArg = getChildList(namedExp); 750 ListLiteral listArg = getChildList(namedExp);
765 if (listArg != null) { 751 if (listArg != null) {
766 _addInsertEdit(namedExp.offset + 'child'.length, 'ren'); 752 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
767 if (listArg.typeArguments == null) { 753 await changeBuilder.addFileEdit(file, fileStamp,
768 _addInsertEdit(listArg.offset, '<Widget>'); 754 (DartFileEditBuilder builder) {
769 } 755 builder.addSimpleInsertion(namedExp.offset + 'child'.length, 'ren');
770 _addFix(DartFixKind.CONVERT_FLUTTER_CHILD, []); 756 if (listArg.typeArguments == null) {
757 builder.addSimpleInsertion(listArg.offset, '<Widget>');
758 }
759 });
760 _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD);
771 } 761 }
772 } 762 }
773 763
774 void _addFix_convertFlutterChildren() { 764 Future<Null> _addFix_convertFlutterChildren() async {
775 // TODO(messick) Implement _addFix_convertFlutterChildren() 765 // TODO(messick) Implement _addFix_convertFlutterChildren()
776 } 766 }
777 767
778 Future<Null> _addFix_createClass() async { 768 Future<Null> _addFix_createClass() async {
779 Element prefixElement = null; 769 Element prefixElement = null;
780 String name = null; 770 String name = null;
781 SimpleIdentifier nameNode; 771 SimpleIdentifier nameNode;
782 if (node is SimpleIdentifier) { 772 if (node is SimpleIdentifier) {
783 AstNode parent = node.parent; 773 AstNode parent = node.parent;
784 if (parent is PrefixedIdentifier) { 774 if (parent is PrefixedIdentifier) {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 String proposalName = _getConstructorProposalName(superConstructor); 1022 String proposalName = _getConstructorProposalName(superConstructor);
1033 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 1023 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1034 await changeBuilder.addFileEdit(file, fileStamp, 1024 await changeBuilder.addFileEdit(file, fileStamp,
1035 (DartFileEditBuilder builder) { 1025 (DartFileEditBuilder builder) {
1036 builder.addInsertion(insertOffset, (DartEditBuilder builder) { 1026 builder.addInsertion(insertOffset, (DartEditBuilder builder) {
1037 builder.write(prefix); 1027 builder.write(prefix);
1038 // add super constructor name 1028 // add super constructor name
1039 builder.write('super'); 1029 builder.write('super');
1040 if (!isEmpty(constructorName)) { 1030 if (!isEmpty(constructorName)) {
1041 builder.write('.'); 1031 builder.write('.');
1042 builder.write(constructorName); 1032 builder.addSimpleLinkedEdit('NAME', constructorName);
1043 } 1033 }
1044 // add arguments 1034 // add arguments
1045 builder.write('('); 1035 builder.write('(');
1046 bool firstParameter = true; 1036 bool firstParameter = true;
1047 for (ParameterElement parameter in superConstructor.parameters) { 1037 for (ParameterElement parameter in superConstructor.parameters) {
1048 // skip non-required parameters 1038 // skip non-required parameters
1049 if (parameter.parameterKind != ParameterKind.REQUIRED) { 1039 if (parameter.parameterKind != ParameterKind.REQUIRED) {
1050 break; 1040 break;
1051 } 1041 }
1052 // comma 1042 // comma
(...skipping 22 matching lines...) Expand all
1075 String targetClassName = targetClassElement.name; 1065 String targetClassName = targetClassElement.name;
1076 // add proposals for all super constructors 1066 // add proposals for all super constructors
1077 for (ConstructorElement superConstructor in superType.constructors) { 1067 for (ConstructorElement superConstructor in superType.constructors) {
1078 superConstructor = ConstructorMember.from(superConstructor, superType); 1068 superConstructor = ConstructorMember.from(superConstructor, superType);
1079 String constructorName = superConstructor.name; 1069 String constructorName = superConstructor.name;
1080 // skip private 1070 // skip private
1081 if (Identifier.isPrivateName(constructorName)) { 1071 if (Identifier.isPrivateName(constructorName)) {
1082 continue; 1072 continue;
1083 } 1073 }
1084 // prepare parameters and arguments 1074 // prepare parameters and arguments
1085 SourceBuilder parametersBuffer = new SourceBuilder.buffer(); 1075 Iterable<ParameterElement> requiredParameters =
1086 SourceBuilder argumentsBuffer = new SourceBuilder.buffer(); 1076 superConstructor.parameters.where(
1087 bool firstParameter = true; 1077 (parameter) => parameter.parameterKind == ParameterKind.REQUIRED);
1088 for (ParameterElement parameter in superConstructor.parameters) {
1089 // skip non-required parameters
1090 if (parameter.parameterKind != ParameterKind.REQUIRED) {
1091 break;
1092 }
1093 // comma
1094 if (firstParameter) {
1095 firstParameter = false;
1096 } else {
1097 parametersBuffer.append(', ');
1098 argumentsBuffer.append(', ');
1099 }
1100 // name
1101 String parameterName = parameter.displayName;
1102 if (parameterName.length > 1 && parameterName.startsWith('_')) {
1103 parameterName = parameterName.substring(1);
1104 }
1105 // parameter & argument
1106 _appendParameterSource(parametersBuffer, parameter.type, parameterName);
1107 argumentsBuffer.append(parameterName);
1108 }
1109 // add proposal 1078 // add proposal
1110 ClassMemberLocation targetLocation = 1079 ClassMemberLocation targetLocation =
1111 utils.prepareNewConstructorLocation(targetClassNode); 1080 utils.prepareNewConstructorLocation(targetClassNode);
1112 String proposalName = _getConstructorProposalName(superConstructor); 1081 String proposalName = _getConstructorProposalName(superConstructor);
1113 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 1082 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1114 await changeBuilder.addFileEdit(file, fileStamp, 1083 await changeBuilder.addFileEdit(file, fileStamp,
1115 (DartFileEditBuilder builder) { 1084 (DartFileEditBuilder builder) {
1116 builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { 1085 builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
1086 void writeParameters(bool includeType) {
1087 bool firstParameter = true;
1088 for (ParameterElement parameter in requiredParameters) {
1089 if (firstParameter) {
1090 firstParameter = false;
1091 } else {
1092 builder.write(', ');
1093 }
1094 String parameterName = parameter.displayName;
1095 if (parameterName.length > 1 && parameterName.startsWith('_')) {
1096 parameterName = parameterName.substring(1);
1097 }
1098 if (includeType && builder.writeType(parameter.type)) {
1099 builder.write(' ');
1100 }
1101 builder.write(parameterName);
1102 }
1103 }
1104
1117 builder.write(targetLocation.prefix); 1105 builder.write(targetLocation.prefix);
1118 builder.write(targetClassName); 1106 builder.write(targetClassName);
1119 if (!constructorName.isEmpty) { 1107 if (!constructorName.isEmpty) {
1120 builder.addSimpleLinkedEdit('NAME', '.$constructorName'); 1108 builder.write('.');
1109 builder.addSimpleLinkedEdit('NAME', constructorName);
1121 } 1110 }
1122 builder.write('('); 1111 builder.write('(');
1123 builder.write(parametersBuffer.toString()); 1112 writeParameters(true);
1124 builder.write(') : super'); 1113 builder.write(') : super');
1125 if (!constructorName.isEmpty) { 1114 if (!constructorName.isEmpty) {
1126 builder.write('.'); 1115 builder.write('.');
1127 builder.write(constructorName); 1116 builder.addSimpleLinkedEdit('NAME', constructorName);
1128 } 1117 }
1129 builder.write('('); 1118 builder.write('(');
1130 builder.write(argumentsBuffer.toString()); 1119 writeParameters(false);
1131 builder.write(');'); 1120 builder.write(');');
1132 builder.write(targetLocation.suffix); 1121 builder.write(targetLocation.suffix);
1133 }); 1122 });
1134 builder.importLibraries(librariesToImport);
1135 }); 1123 });
1136 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_SUPER, 1124 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_SUPER,
1137 args: [proposalName]); 1125 args: [proposalName]);
1138 } 1126 }
1139 } 1127 }
1140 1128
1141 Future<Null> _addFix_createField() async { 1129 Future<Null> _addFix_createField() async {
1142 if (node is! SimpleIdentifier) { 1130 if (node is! SimpleIdentifier) {
1143 return; 1131 return;
1144 } 1132 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 isStatic: staticModifier, 1195 isStatic: staticModifier,
1208 nameGroupName: 'NAME', 1196 nameGroupName: 'NAME',
1209 type: fieldType, 1197 type: fieldType,
1210 typeGroupName: 'TYPE'); 1198 typeGroupName: 'TYPE');
1211 builder.write(targetLocation.suffix); 1199 builder.write(targetLocation.suffix);
1212 }); 1200 });
1213 }); 1201 });
1214 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FIELD, args: [name]); 1202 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FIELD, args: [name]);
1215 } 1203 }
1216 1204
1217 void _addFix_createFunction_forFunctionType() { 1205 Future<Null> _addFix_createFunction_forFunctionType() async {
1218 if (node is SimpleIdentifier) { 1206 if (node is SimpleIdentifier) {
1219 SimpleIdentifier nameNode = node as SimpleIdentifier; 1207 SimpleIdentifier nameNode = node as SimpleIdentifier;
1220 // prepare argument expression (to get parameter) 1208 // prepare argument expression (to get parameter)
1221 ClassElement targetElement; 1209 ClassElement targetElement;
1222 Expression argument; 1210 Expression argument;
1223 { 1211 {
1224 Expression target = getQualifiedPropertyTarget(node); 1212 Expression target = getQualifiedPropertyTarget(node);
1225 if (target != null) { 1213 if (target != null) {
1226 DartType targetType = target.bestType; 1214 DartType targetType = target.bestType;
1227 if (targetType != null && targetType.element is ClassElement) { 1215 if (targetType != null && targetType.element is ClassElement) {
(...skipping 20 matching lines...) Expand all
1248 if (parameterType is InterfaceType && parameterType.isDartCoreFunction) { 1236 if (parameterType is InterfaceType && parameterType.isDartCoreFunction) {
1249 ExecutableElement element = new MethodElementImpl('', -1); 1237 ExecutableElement element = new MethodElementImpl('', -1);
1250 parameterType = new FunctionTypeImpl(element); 1238 parameterType = new FunctionTypeImpl(element);
1251 } 1239 }
1252 if (parameterType is! FunctionType) { 1240 if (parameterType is! FunctionType) {
1253 return; 1241 return;
1254 } 1242 }
1255 FunctionType functionType = parameterType as FunctionType; 1243 FunctionType functionType = parameterType as FunctionType;
1256 // add proposal 1244 // add proposal
1257 if (targetElement != null) { 1245 if (targetElement != null) {
1258 _addProposal_createFunction_method(targetElement, functionType); 1246 await _addProposal_createFunction_method(targetElement, functionType);
1259 } else { 1247 } else {
1260 _addProposal_createFunction_function(functionType); 1248 await _addProposal_createFunction_function(functionType);
1261 } 1249 }
1262 } 1250 }
1263 } 1251 }
1264 1252
1265 Future<Null> _addFix_createGetter() async { 1253 Future<Null> _addFix_createGetter() async {
1266 if (node is! SimpleIdentifier) { 1254 if (node is! SimpleIdentifier) {
1267 return; 1255 return;
1268 } 1256 }
1269 SimpleIdentifier nameNode = node; 1257 SimpleIdentifier nameNode = node;
1270 String name = nameNode.name; 1258 String name = nameNode.name;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 isStatic: staticModifier, 1319 isStatic: staticModifier,
1332 nameGroupName: 'NAME', 1320 nameGroupName: 'NAME',
1333 returnType: fieldType, 1321 returnType: fieldType,
1334 returnTypeGroupName: 'TYPE'); 1322 returnTypeGroupName: 'TYPE');
1335 builder.write(targetLocation.suffix); 1323 builder.write(targetLocation.suffix);
1336 }); 1324 });
1337 }); 1325 });
1338 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_GETTER, args: [name]); 1326 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_GETTER, args: [name]);
1339 } 1327 }
1340 1328
1341 void _addFix_createImportUri() { 1329 Future<Null> _addFix_createImportUri() async {
1342 // TODO(brianwilkerson) Generalize this to allow other valid string literals . 1330 // TODO(brianwilkerson) Generalize this to allow other valid string literals .
1343 // TODO(brianwilkerson) Support the case where the node's parent is a Config uration. 1331 // TODO(brianwilkerson) Support the case where the node's parent is a Config uration.
1344 if (node is SimpleStringLiteral && node.parent is ImportDirective) { 1332 if (node is SimpleStringLiteral && node.parent is ImportDirective) {
1345 ImportDirective importDirective = node.parent; 1333 ImportDirective importDirective = node.parent;
1346 Source source = importDirective.uriSource; 1334 Source source = importDirective.uriSource;
1347 if (source != null) { 1335 if (source != null) {
1348 String file = source.fullName; 1336 String file = source.fullName;
1349 if (isAbsolute(file) && AnalysisEngine.isDartFileName(file)) { 1337 if (isAbsolute(file) && AnalysisEngine.isDartFileName(file)) {
1350 String libName = _computeLibraryName(file); 1338 String libName = _computeLibraryName(file);
1351 SourceEdit edit = new SourceEdit(0, 0, 'library $libName;$eol$eol'); 1339 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1352 doSourceChange_addSourceEdit(change, source, edit, isNewFile: true); 1340 await changeBuilder.addFileEdit(source.fullName, -1,
1353 _addFix(DartFixKind.CREATE_FILE, [source.shortName]); 1341 (DartFileEditBuilder builder) {
1342 builder.addSimpleInsertion(0, 'library $libName;$eol$eol');
1343 });
1344 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE,
1345 args: [source.shortName]);
1354 } 1346 }
1355 } 1347 }
1356 } 1348 }
1357 } 1349 }
1358 1350
1359 Future<Null> _addFix_createLocalVariable() async { 1351 Future<Null> _addFix_createLocalVariable() async {
1360 if (node is! SimpleIdentifier) { 1352 if (node is! SimpleIdentifier) {
1361 return; 1353 return;
1362 } 1354 }
1363 SimpleIdentifier nameNode = node; 1355 SimpleIdentifier nameNode = node;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 // append method 1560 // append method
1569 builder.write(prefix); 1561 builder.write(prefix);
1570 builder.write( 1562 builder.write(
1571 'noSuchMethod(Invocation invocation) => super.noSuchMethod(invocatio n);'); 1563 'noSuchMethod(Invocation invocation) => super.noSuchMethod(invocatio n);');
1572 builder.write(eol); 1564 builder.write(eol);
1573 }); 1565 });
1574 }); 1566 });
1575 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_NO_SUCH_METHOD); 1567 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_NO_SUCH_METHOD);
1576 } 1568 }
1577 1569
1578 void _addFix_createPartUri() { 1570 Future<Null> _addFix_createPartUri() async {
1579 // TODO(brianwilkerson) Generalize this to allow other valid string literals . 1571 // TODO(brianwilkerson) Generalize this to allow other valid string literals .
1580 if (node is SimpleStringLiteral && node.parent is PartDirective) { 1572 if (node is SimpleStringLiteral && node.parent is PartDirective) {
1581 PartDirective partDirective = node.parent; 1573 PartDirective partDirective = node.parent;
1582 Source source = partDirective.uriSource; 1574 Source source = partDirective.uriSource;
1583 if (source != null) { 1575 if (source != null) {
1584 String libName = unitLibraryElement.name; 1576 String libName = unitLibraryElement.name;
1585 SourceEdit edit = new SourceEdit(0, 0, 'part of $libName;$eol$eol'); 1577 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1586 doSourceChange_addSourceEdit(change, source, edit, isNewFile: true); 1578 await changeBuilder.addFileEdit(source.fullName, -1,
1587 _addFix(DartFixKind.CREATE_FILE, [source.shortName]); 1579 (DartFileEditBuilder builder) {
1580 // TODO(brianwilkerson) Consider using the URI rather than name
1581 builder.addSimpleInsertion(0, 'part of $libName;$eol$eol');
1582 });
1583 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE,
1584 args: [source.shortName]);
1588 } 1585 }
1589 } 1586 }
1590 } 1587 }
1591 1588
1592 Future<Null> _addFix_illegalAsyncReturnType() async { 1589 Future<Null> _addFix_illegalAsyncReturnType() async {
1593 // prepare the existing type 1590 // prepare the existing type
1594 TypeAnnotation typeName = node.getAncestor((n) => n is TypeAnnotation); 1591 TypeAnnotation typeName = node.getAncestor((n) => n is TypeAnnotation);
1595 TypeProvider typeProvider = this.typeProvider; 1592 TypeProvider typeProvider = this.typeProvider;
1596 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 1593 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1597 await changeBuilder.addFileEdit(file, fileStamp, 1594 await changeBuilder.addFileEdit(file, fileStamp,
1598 (DartFileEditBuilder builder) { 1595 (DartFileEditBuilder builder) {
1599 builder.replaceTypeWithFuture(typeName, typeProvider); 1596 builder.replaceTypeWithFuture(typeName, typeProvider);
1600 }); 1597 });
1601 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE); 1598 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE);
1602 } 1599 }
1603 1600
1604 void _addFix_importLibrary(FixKind kind, Source library) { 1601 Future<Null> _addFix_importLibrary(FixKind kind, Source library) async {
1605 librariesToImport.add(library);
1606 String libraryUri = getLibrarySourceUri(unitLibraryElement, library); 1602 String libraryUri = getLibrarySourceUri(unitLibraryElement, library);
1607 _addFix(kind, [libraryUri], importsOnly: true); 1603 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1604 await changeBuilder.addFileEdit(file, fileStamp,
1605 (DartFileEditBuilder builder) {
1606 builder.importLibraries([library]);
1607 });
1608 _addFixFromBuilder(changeBuilder, kind, args: [libraryUri]);
1608 } 1609 }
1609 1610
1610 Future<Null> _addFix_importLibrary_withElement(String name, 1611 Future<Null> _addFix_importLibrary_withElement(String name,
1611 List<ElementKind> elementKinds, TopLevelDeclarationKind kind2) async { 1612 List<ElementKind> elementKinds, TopLevelDeclarationKind kind2) async {
1612 // ignore if private 1613 // ignore if private
1613 if (name.startsWith('_')) { 1614 if (name.startsWith('_')) {
1614 return; 1615 return;
1615 } 1616 }
1616 // may be there is an existing import, 1617 // may be there is an existing import,
1617 // but it is with prefix and we don't use this prefix 1618 // but it is with prefix and we don't use this prefix
1618 Set<Source> alreadyImportedWithPrefix = new Set<Source>(); 1619 Set<Source> alreadyImportedWithPrefix = new Set<Source>();
1619 for (ImportElement imp in unitLibraryElement.imports) { 1620 for (ImportElement imp in unitLibraryElement.imports) {
1620 // prepare element 1621 // prepare element
1621 LibraryElement libraryElement = imp.importedLibrary; 1622 LibraryElement libraryElement = imp.importedLibrary;
1622 Element element = getExportedElement(libraryElement, name); 1623 Element element = getExportedElement(libraryElement, name);
1623 if (element == null) { 1624 if (element == null) {
1624 continue; 1625 continue;
1625 } 1626 }
1626 if (element is PropertyAccessorElement) { 1627 if (element is PropertyAccessorElement) {
1627 element = (element as PropertyAccessorElement).variable; 1628 element = (element as PropertyAccessorElement).variable;
1628 } 1629 }
1629 if (!elementKinds.contains(element.kind)) { 1630 if (!elementKinds.contains(element.kind)) {
1630 continue; 1631 continue;
1631 } 1632 }
1632 // may be apply prefix 1633 // may be apply prefix
1633 PrefixElement prefix = imp.prefix; 1634 PrefixElement prefix = imp.prefix;
1634 if (prefix != null) { 1635 if (prefix != null) {
1635 _addReplaceEdit(range.startLength(node, 0), '${prefix.displayName}.'); 1636 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1636 _addFix(DartFixKind.IMPORT_LIBRARY_PREFIX, 1637 await changeBuilder.addFileEdit(file, fileStamp,
1637 [libraryElement.displayName, prefix.displayName]); 1638 (DartFileEditBuilder builder) {
1639 builder.addSimpleReplacement(
1640 range.startLength(node, 0), '${prefix.displayName}.');
1641 });
1642 _addFixFromBuilder(changeBuilder, DartFixKind.IMPORT_LIBRARY_PREFIX,
1643 args: [libraryElement.displayName, prefix.displayName]);
1638 continue; 1644 continue;
1639 } 1645 }
1640 // may be update "show" directive 1646 // may be update "show" directive
1641 List<NamespaceCombinator> combinators = imp.combinators; 1647 List<NamespaceCombinator> combinators = imp.combinators;
1642 if (combinators.length == 1 && combinators[0] is ShowElementCombinator) { 1648 if (combinators.length == 1 && combinators[0] is ShowElementCombinator) {
1643 ShowElementCombinator showCombinator = 1649 ShowElementCombinator showCombinator =
1644 combinators[0] as ShowElementCombinator; 1650 combinators[0] as ShowElementCombinator;
1645 // prepare new set of names to show 1651 // prepare new set of names to show
1646 Set<String> showNames = new SplayTreeSet<String>(); 1652 Set<String> showNames = new SplayTreeSet<String>();
1647 showNames.addAll(showCombinator.shownNames); 1653 showNames.addAll(showCombinator.shownNames);
1648 showNames.add(name); 1654 showNames.add(name);
1649 // prepare library name - unit name or 'dart:name' for SDK library 1655 // prepare library name - unit name or 'dart:name' for SDK library
1650 String libraryName = libraryElement.definingCompilationUnit.displayName; 1656 String libraryName = libraryElement.definingCompilationUnit.displayName;
1651 if (libraryElement.isInSdk) { 1657 if (libraryElement.isInSdk) {
1652 libraryName = imp.uri; 1658 libraryName = imp.uri;
1653 } 1659 }
1654 // don't add this library again 1660 // don't add this library again
1655 alreadyImportedWithPrefix.add(libraryElement.source); 1661 alreadyImportedWithPrefix.add(libraryElement.source);
1656 // update library 1662 // update library
1657 String newShowCode = 'show ${showNames.join(', ')}'; 1663 String newShowCode = 'show ${showNames.join(', ')}';
1658 int offset = showCombinator.offset; 1664 int offset = showCombinator.offset;
1659 int length = showCombinator.end - offset; 1665 int length = showCombinator.end - offset;
1660 _addReplaceEdit( 1666 String libraryFile = unitLibraryElement.source.fullName;
1661 new SourceRange(offset, length), newShowCode, unitLibraryElement); 1667 int libraryStamp = unitLibraryElement.context
1662 _addFix(DartFixKind.IMPORT_LIBRARY_SHOW, [libraryName]); 1668 .getModificationStamp(unitLibraryElement.source);
1669 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1670 await changeBuilder.addFileEdit(libraryFile, libraryStamp,
1671 (DartFileEditBuilder builder) {
1672 builder.addSimpleReplacement(
1673 new SourceRange(offset, length), newShowCode);
1674 });
1675 _addFixFromBuilder(changeBuilder, DartFixKind.IMPORT_LIBRARY_SHOW,
1676 args: [libraryName]);
1663 } 1677 }
1664 } 1678 }
1665 // Find new top-level declarations. 1679 // Find new top-level declarations.
1666 { 1680 {
1667 List<TopLevelDeclarationInSource> declarations = 1681 List<TopLevelDeclarationInSource> declarations =
1668 await getTopLevelDeclarations(name); 1682 await getTopLevelDeclarations(name);
1669 for (TopLevelDeclarationInSource declaration in declarations) { 1683 for (TopLevelDeclarationInSource declaration in declarations) {
1670 // Check the kind. 1684 // Check the kind.
1671 if (declaration.declaration.kind != kind2) { 1685 if (declaration.declaration.kind != kind2) {
1672 continue; 1686 continue;
(...skipping 14 matching lines...) Expand all
1687 // Bad: non-API. 1701 // Bad: non-API.
1688 fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3; 1702 fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3;
1689 } else if (declaration.isExported) { 1703 } else if (declaration.isExported) {
1690 // Ugly: exports. 1704 // Ugly: exports.
1691 fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2; 1705 fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2;
1692 } else { 1706 } else {
1693 // Good: direct declaration. 1707 // Good: direct declaration.
1694 fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1; 1708 fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
1695 } 1709 }
1696 // Add the fix. 1710 // Add the fix.
1697 _addFix_importLibrary(fixKind, librarySource); 1711 await _addFix_importLibrary(fixKind, librarySource);
1698 } 1712 }
1699 } 1713 }
1700 } 1714 }
1701 1715
1702 Future<Null> _addFix_importLibrary_withFunction() async { 1716 Future<Null> _addFix_importLibrary_withFunction() async {
1703 if (node is SimpleIdentifier && node.parent is MethodInvocation) { 1717 if (node is SimpleIdentifier && node.parent is MethodInvocation) {
1704 MethodInvocation invocation = node.parent as MethodInvocation; 1718 MethodInvocation invocation = node.parent as MethodInvocation;
1705 if (invocation.realTarget == null && invocation.methodName == node) { 1719 if (invocation.realTarget == null && invocation.methodName == node) {
1706 String name = (node as SimpleIdentifier).name; 1720 String name = (node as SimpleIdentifier).name;
1707 await _addFix_importLibrary_withElement(name, 1721 await _addFix_importLibrary_withElement(name,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 1853
1840 Future<Null> _addFix_nonBoolCondition_addNotNull() async { 1854 Future<Null> _addFix_nonBoolCondition_addNotNull() async {
1841 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); 1855 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1842 await changeBuilder.addFileEdit(file, fileStamp, 1856 await changeBuilder.addFileEdit(file, fileStamp,
1843 (DartFileEditBuilder builder) { 1857 (DartFileEditBuilder builder) {
1844 builder.addSimpleInsertion(error.offset + error.length, ' != null'); 1858 builder.addSimpleInsertion(error.offset + error.length, ' != null');
1845 }); 1859 });
1846 _addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL); 1860 _addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL);
1847 } 1861 }
1848 1862
1849 void _addFix_removeAwait() { 1863 Future<Null> _addFix_removeAwait() async {
1850 final awaitExpression = node; 1864 final awaitExpression = node;
1851 if (awaitExpression is AwaitExpression) { 1865 if (awaitExpression is AwaitExpression) {
1852 final awaitToken = awaitExpression.awaitKeyword; 1866 final awaitToken = awaitExpression.awaitKeyword;
1853 _addRemoveEdit(range.startStart(awaitToken, awaitToken.next)); 1867 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1854 _addFix(DartFixKind.REMOVE_AWAIT, []); 1868 await changeBuilder.addFileEdit(file, fileStamp,
1869 (DartFileEditBuilder builder) {
1870 builder.addDeletion(range.startStart(awaitToken, awaitToken.next));
1871 });
1872 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_AWAIT);
1855 } 1873 }
1856 } 1874 }
1857 1875
1858 void _addFix_removeDeadCode() { 1876 Future<Null> _addFix_removeDeadCode() async {
1859 AstNode coveringNode = this.coveredNode; 1877 AstNode coveringNode = this.coveredNode;
1860 if (coveringNode is Expression) { 1878 if (coveringNode is Expression) {
1861 AstNode parent = coveredNode.parent; 1879 AstNode parent = coveredNode.parent;
1862 if (parent is BinaryExpression) { 1880 if (parent is BinaryExpression) {
1863 if (parent.rightOperand == coveredNode) { 1881 if (parent.rightOperand == coveredNode) {
1864 _addRemoveEdit(range.endEnd(parent.leftOperand, coveredNode)); 1882 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1865 _addFix(DartFixKind.REMOVE_DEAD_CODE, []); 1883 await changeBuilder.addFileEdit(file, fileStamp,
1884 (DartFileEditBuilder builder) {
1885 builder.addDeletion(range.endEnd(parent.leftOperand, coveredNode));
1886 });
1887 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
1866 } 1888 }
1867 } 1889 }
1868 } else if (coveringNode is Block) { 1890 } else if (coveringNode is Block) {
1869 Block block = coveringNode; 1891 Block block = coveringNode;
1870 List<Statement> statementsToRemove = <Statement>[]; 1892 List<Statement> statementsToRemove = <Statement>[];
1871 for (Statement statement in block.statements) { 1893 for (Statement statement in block.statements) {
1872 if (range.node(statement).intersects(errorRange)) { 1894 if (range.node(statement).intersects(errorRange)) {
1873 statementsToRemove.add(statement); 1895 statementsToRemove.add(statement);
1874 } 1896 }
1875 } 1897 }
1876 if (statementsToRemove.isNotEmpty) { 1898 if (statementsToRemove.isNotEmpty) {
1877 SourceRange rangeToRemove = 1899 SourceRange rangeToRemove =
1878 utils.getLinesRangeStatements(statementsToRemove); 1900 utils.getLinesRangeStatements(statementsToRemove);
1879 _addRemoveEdit(rangeToRemove); 1901 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1880 _addFix(DartFixKind.REMOVE_DEAD_CODE, []); 1902 await changeBuilder.addFileEdit(file, fileStamp,
1903 (DartFileEditBuilder builder) {
1904 builder.addDeletion(rangeToRemove);
1905 });
1906 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
1881 } 1907 }
1882 } else if (coveringNode is Statement) { 1908 } else if (coveringNode is Statement) {
1883 SourceRange rangeToRemove = 1909 SourceRange rangeToRemove =
1884 utils.getLinesRangeStatements(<Statement>[coveringNode]); 1910 utils.getLinesRangeStatements(<Statement>[coveringNode]);
1885 _addRemoveEdit(rangeToRemove); 1911 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1886 _addFix(DartFixKind.REMOVE_DEAD_CODE, []); 1912 await changeBuilder.addFileEdit(file, fileStamp,
1913 (DartFileEditBuilder builder) {
1914 builder.addDeletion(rangeToRemove);
1915 });
1916 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
1887 } 1917 }
1888 } 1918 }
1889 1919
1890 void _addFix_removeEmptyStatement() { 1920 Future<Null> _addFix_removeEmptyStatement() async {
1891 EmptyStatement emptyStatement = node; 1921 EmptyStatement emptyStatement = node;
1892 if (emptyStatement.parent is Block) { 1922 if (emptyStatement.parent is Block) {
1893 _addRemoveEdit(utils.getLinesRange(range.node(emptyStatement))); 1923 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1894 _addFix(DartFixKind.REMOVE_EMPTY_STATEMENT, []); 1924 await changeBuilder.addFileEdit(file, fileStamp,
1925 (DartFileEditBuilder builder) {
1926 builder.addDeletion(utils.getLinesRange(range.node(emptyStatement)));
1927 });
1928 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_STATEMENT);
1895 } else { 1929 } else {
1896 _addReplaceEdit( 1930 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1897 range.endEnd(emptyStatement.beginToken.previous, emptyStatement), 1931 await changeBuilder.addFileEdit(file, fileStamp,
1898 ' {}'); 1932 (DartFileEditBuilder builder) {
1899 _addFix(DartFixKind.REPLACE_WITH_BRACKETS, []); 1933 builder.addSimpleReplacement(
1934 range.endEnd(emptyStatement.beginToken.previous, emptyStatement),
1935 ' {}');
1936 });
1937 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_BRACKETS);
1900 } 1938 }
1901 } 1939 }
1902 1940
1903 void _addFix_removeInitializer() { 1941 Future<Null> _addFix_removeInitializer() async {
1904 // Retrieve the linted node. 1942 // Retrieve the linted node.
1905 VariableDeclaration ancestor = 1943 VariableDeclaration ancestor =
1906 node.getAncestor((a) => a is VariableDeclaration); 1944 node.getAncestor((a) => a is VariableDeclaration);
1907 if (ancestor == null) { 1945 if (ancestor == null) {
1908 return; 1946 return;
1909 } 1947 }
1910 _addRemoveEdit(range.endEnd(ancestor.name, ancestor.initializer)); 1948 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1911 _addFix(DartFixKind.REMOVE_INITIALIZER, []); 1949 await changeBuilder.addFileEdit(file, fileStamp,
1950 (DartFileEditBuilder builder) {
1951 builder.addDeletion(range.endEnd(ancestor.name, ancestor.initializer));
1952 });
1953 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_INITIALIZER);
1912 } 1954 }
1913 1955
1914 void _addFix_removeMethodDeclaration() { 1956 Future<Null> _addFix_removeInterpolationBraces() async {
1957 AstNode node = this.node;
1958 if (node is InterpolationExpression) {
1959 Token right = node.rightBracket;
1960 if (node.expression != null && right != null) {
1961 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1962 await changeBuilder.addFileEdit(file, fileStamp,
1963 (DartFileEditBuilder builder) {
1964 builder.addSimpleReplacement(
1965 range.startStart(node, node.expression), r'$');
1966 builder.addDeletion(range.token(right));
1967 });
1968 _addFixFromBuilder(
1969 changeBuilder, DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES);
1970 } else {}
1971 }
1972 }
1973
1974 Future<Null> _addFix_removeMethodDeclaration() async {
1915 MethodDeclaration declaration = 1975 MethodDeclaration declaration =
1916 node.getAncestor((node) => node is MethodDeclaration); 1976 node.getAncestor((node) => node is MethodDeclaration);
1917 if (declaration != null) { 1977 if (declaration != null) {
1918 _addRemoveEdit(utils.getLinesRange(range.node(declaration))); 1978 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1919 _addFix(DartFixKind.REMOVE_METHOD_DECLARATION, []); 1979 await changeBuilder.addFileEdit(file, fileStamp,
1980 (DartFileEditBuilder builder) {
1981 builder.addDeletion(utils.getLinesRange(range.node(declaration)));
1982 });
1983 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_METHOD_DECLARATION);
1920 } 1984 }
1921 } 1985 }
1922 1986
1923 void _addFix_removeParameters_inGetterDeclaration() { 1987 Future<Null> _addFix_removeParameters_inGetterDeclaration() async {
1924 if (node is MethodDeclaration) { 1988 if (node is MethodDeclaration) {
1925 MethodDeclaration method = node as MethodDeclaration; 1989 MethodDeclaration method = node as MethodDeclaration;
1926 SimpleIdentifier name = method.name; 1990 SimpleIdentifier name = method.name;
1927 FunctionBody body = method.body; 1991 FunctionBody body = method.body;
1928 if (name != null && body != null) { 1992 if (name != null && body != null) {
1929 _addReplaceEdit(range.endStart(name, body), ' '); 1993 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1930 _addFix(DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, []); 1994 await changeBuilder.addFileEdit(file, fileStamp,
1995 (DartFileEditBuilder builder) {
1996 builder.addSimpleReplacement(range.endStart(name, body), ' ');
1997 });
1998 _addFixFromBuilder(
1999 changeBuilder, DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION);
1931 } 2000 }
1932 } 2001 }
1933 } 2002 }
1934 2003
1935 void _addFix_removeParentheses_inGetterInvocation() { 2004 Future<Null> _addFix_removeParentheses_inGetterInvocation() async {
1936 if (node is SimpleIdentifier && node.parent is MethodInvocation) { 2005 if (node is SimpleIdentifier && node.parent is MethodInvocation) {
1937 MethodInvocation invocation = node.parent as MethodInvocation; 2006 MethodInvocation invocation = node.parent as MethodInvocation;
1938 if (invocation.methodName == node && invocation.target != null) { 2007 if (invocation.methodName == node && invocation.target != null) {
1939 _addRemoveEdit(range.endEnd(node, invocation)); 2008 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1940 _addFix(DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, []); 2009 await changeBuilder.addFileEdit(file, fileStamp,
2010 (DartFileEditBuilder builder) {
2011 builder.addDeletion(range.endEnd(node, invocation));
2012 });
2013 _addFixFromBuilder(
2014 changeBuilder, DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION);
1941 } 2015 }
1942 } 2016 }
1943 } 2017 }
1944 2018
1945 void _addFix_removeThisExpression() { 2019 Future<Null> _addFix_removeThisExpression() async {
1946 final thisExpression = node is ThisExpression 2020 final thisExpression = node is ThisExpression
1947 ? node 2021 ? node
1948 : node.getAncestor((node) => node is ThisExpression); 2022 : node.getAncestor((node) => node is ThisExpression);
1949 final parent = thisExpression.parent; 2023 final parent = thisExpression.parent;
1950 if (parent is PropertyAccess) { 2024 if (parent is PropertyAccess) {
1951 _addRemoveEdit(range.startEnd(parent, parent.operator)); 2025 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1952 _addFix(DartFixKind.REMOVE_THIS_EXPRESSION, []); 2026 await changeBuilder.addFileEdit(file, fileStamp,
2027 (DartFileEditBuilder builder) {
2028 builder.addDeletion(range.startEnd(parent, parent.operator));
2029 });
2030 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION);
1953 } else if (parent is MethodInvocation) { 2031 } else if (parent is MethodInvocation) {
1954 _addRemoveEdit(range.startEnd(parent, parent.operator)); 2032 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1955 _addFix(DartFixKind.REMOVE_THIS_EXPRESSION, []); 2033 await changeBuilder.addFileEdit(file, fileStamp,
2034 (DartFileEditBuilder builder) {
2035 builder.addDeletion(range.startEnd(parent, parent.operator));
2036 });
2037 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION);
1956 } 2038 }
1957 } 2039 }
1958 2040
1959 void _addFix_removeTypeName() { 2041 Future<Null> _addFix_removeTypeName() async {
1960 final TypeName type = node.getAncestor((node) => node is TypeName); 2042 final TypeName type = node.getAncestor((node) => node is TypeName);
1961 if (type != null) { 2043 if (type != null) {
1962 _addRemoveEdit(range.startStart(type, type.endToken.next)); 2044 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1963 _addFix(DartFixKind.REMOVE_TYPE_NAME, []); 2045 await changeBuilder.addFileEdit(file, fileStamp,
2046 (DartFileEditBuilder builder) {
2047 builder.addDeletion(range.startStart(type, type.endToken.next));
2048 });
2049 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_NAME);
1964 } 2050 }
1965 } 2051 }
1966 2052
1967 void _addFix_removeUnnecessaryCast() { 2053 Future<Null> _addFix_removeUnnecessaryCast() async {
1968 if (coveredNode is! AsExpression) { 2054 if (coveredNode is! AsExpression) {
1969 return; 2055 return;
1970 } 2056 }
1971 AsExpression asExpression = coveredNode as AsExpression; 2057 AsExpression asExpression = coveredNode as AsExpression;
1972 Expression expression = asExpression.expression; 2058 Expression expression = asExpression.expression;
1973 int expressionPrecedence = getExpressionPrecedence(expression); 2059 int expressionPrecedence = getExpressionPrecedence(expression);
1974 // remove 'as T' from 'e as T' 2060 // remove 'as T' from 'e as T'
1975 _addRemoveEdit(range.endEnd(expression, asExpression)); 2061 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1976 _removeEnclosingParentheses(asExpression, expressionPrecedence); 2062 await changeBuilder.addFileEdit(file, fileStamp,
1977 // done 2063 (DartFileEditBuilder builder) {
1978 _addFix(DartFixKind.REMOVE_UNNECESSARY_CAST, []); 2064 builder.addDeletion(range.endEnd(expression, asExpression));
2065 _removeEnclosingParentheses(builder, asExpression, expressionPrecedence);
2066 });
2067 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNNECESSARY_CAST);
1979 } 2068 }
1980 2069
1981 void _addFix_removeUnusedCatchClause() { 2070 Future<Null> _addFix_removeUnusedCatchClause() async {
1982 if (node is SimpleIdentifier) { 2071 if (node is SimpleIdentifier) {
1983 AstNode catchClause = node.parent; 2072 AstNode catchClause = node.parent;
1984 if (catchClause is CatchClause && 2073 if (catchClause is CatchClause &&
1985 catchClause.exceptionParameter == node) { 2074 catchClause.exceptionParameter == node) {
1986 _addRemoveEdit( 2075 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
1987 range.startStart(catchClause.catchKeyword, catchClause.body)); 2076 await changeBuilder.addFileEdit(file, fileStamp,
1988 _addFix(DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE, []); 2077 (DartFileEditBuilder builder) {
2078 builder.addDeletion(
2079 range.startStart(catchClause.catchKeyword, catchClause.body));
2080 });
2081 _addFixFromBuilder(
2082 changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE);
1989 } 2083 }
1990 } 2084 }
1991 } 2085 }
1992 2086
1993 void _addFix_removeUnusedCatchStack() { 2087 Future<Null> _addFix_removeUnusedCatchStack() async {
1994 if (node is SimpleIdentifier) { 2088 if (node is SimpleIdentifier) {
1995 AstNode catchClause = node.parent; 2089 AstNode catchClause = node.parent;
1996 if (catchClause is CatchClause && 2090 if (catchClause is CatchClause &&
1997 catchClause.stackTraceParameter == node && 2091 catchClause.stackTraceParameter == node &&
1998 catchClause.exceptionParameter != null) { 2092 catchClause.exceptionParameter != null) {
1999 _addRemoveEdit(range.endEnd(catchClause.exceptionParameter, node)); 2093 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2000 _addFix(DartFixKind.REMOVE_UNUSED_CATCH_STACK, []); 2094 await changeBuilder.addFileEdit(file, fileStamp,
2095 (DartFileEditBuilder builder) {
2096 builder
2097 .addDeletion(range.endEnd(catchClause.exceptionParameter, node));
2098 });
2099 _addFixFromBuilder(
2100 changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_STACK);
2001 } 2101 }
2002 } 2102 }
2003 } 2103 }
2004 2104
2005 void _addFix_removeUnusedImport() { 2105 Future<Null> _addFix_removeUnusedImport() async {
2006 // prepare ImportDirective 2106 // prepare ImportDirective
2007 ImportDirective importDirective = 2107 ImportDirective importDirective =
2008 node.getAncestor((node) => node is ImportDirective); 2108 node.getAncestor((node) => node is ImportDirective);
2009 if (importDirective == null) { 2109 if (importDirective == null) {
2010 return; 2110 return;
2011 } 2111 }
2012 // remove the whole line with import 2112 // remove the whole line with import
2013 _addRemoveEdit(utils.getLinesRange(range.node(importDirective))); 2113 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2014 // done 2114 await changeBuilder.addFileEdit(file, fileStamp,
2015 _addFix(DartFixKind.REMOVE_UNUSED_IMPORT, []); 2115 (DartFileEditBuilder builder) {
2116 builder.addDeletion(utils.getLinesRange(range.node(importDirective)));
2117 });
2118 _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_IMPORT);
2016 } 2119 }
2017 2120
2018 void _addFix_replaceVarWithDynamic() { 2121 Future<Null> _addFix_replaceVarWithDynamic() async {
2019 _addReplaceEdit(range.error(error), 'dynamic'); 2122 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2020 _addFix(DartFixKind.REPLACE_VAR_WITH_DYNAMIC, []); 2123 await changeBuilder.addFileEdit(file, fileStamp,
2124 (DartFileEditBuilder builder) {
2125 builder.addSimpleReplacement(range.error(error), 'dynamic');
2126 });
2127 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_VAR_WITH_DYNAMIC);
2021 } 2128 }
2022 2129
2023 void _addFix_replaceWithConditionalAssignment() { 2130 Future<Null> _addFix_replaceWithConditionalAssignment() async {
2024 IfStatement ifStatement = node is IfStatement 2131 IfStatement ifStatement = node is IfStatement
2025 ? node 2132 ? node
2026 : node.getAncestor((node) => node is IfStatement); 2133 : node.getAncestor((node) => node is IfStatement);
2027 var thenStatement = ifStatement.thenStatement; 2134 var thenStatement = ifStatement.thenStatement;
2028 Statement uniqueStatement(Statement statement) { 2135 Statement uniqueStatement(Statement statement) {
2029 if (statement is Block) { 2136 if (statement is Block) {
2030 return uniqueStatement(statement.statements.first); 2137 return uniqueStatement(statement.statements.first);
2031 } 2138 }
2032 return statement; 2139 return statement;
2033 } 2140 }
2034 2141
2035 thenStatement = uniqueStatement(thenStatement); 2142 thenStatement = uniqueStatement(thenStatement);
2036 if (thenStatement is ExpressionStatement) { 2143 if (thenStatement is ExpressionStatement) {
2037 final expression = thenStatement.expression.unParenthesized; 2144 final expression = thenStatement.expression.unParenthesized;
2038 if (expression is AssignmentExpression) { 2145 if (expression is AssignmentExpression) {
2039 final buffer = new StringBuffer(); 2146 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2040 buffer.write(utils.getNodeText(expression.leftHandSide)); 2147 await changeBuilder.addFileEdit(file, fileStamp,
2041 buffer.write(' ??= '); 2148 (DartFileEditBuilder builder) {
2042 buffer.write(utils.getNodeText(expression.rightHandSide)); 2149 builder.addReplacement(range.node(ifStatement),
2043 buffer.write(';'); 2150 (DartEditBuilder builder) {
2044 _addReplaceEdit(range.node(ifStatement), buffer.toString()); 2151 builder.write(utils.getNodeText(expression.leftHandSide));
2045 _addFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT, []); 2152 builder.write(' ??= ');
2153 builder.write(utils.getNodeText(expression.rightHandSide));
2154 builder.write(';');
2155 });
2156 });
2157 _addFixFromBuilder(
2158 changeBuilder, DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT);
2046 } 2159 }
2047 } 2160 }
2048 } 2161 }
2049 2162
2050 void _addFix_replaceWithConstInstanceCreation() { 2163 Future<Null> _addFix_replaceWithConstInstanceCreation() async {
2051 if (coveredNode is InstanceCreationExpression) { 2164 if (coveredNode is InstanceCreationExpression) {
2052 var instanceCreation = coveredNode as InstanceCreationExpression; 2165 var instanceCreation = coveredNode as InstanceCreationExpression;
2053 _addReplaceEdit(range.token(instanceCreation.keyword), 'const'); 2166 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2054 _addFix(DartFixKind.USE_CONST, []); 2167 await changeBuilder.addFileEdit(file, fileStamp,
2168 (DartFileEditBuilder builder) {
2169 builder.addSimpleReplacement(
2170 range.token(instanceCreation.keyword), 'const');
2171 });
2172 _addFixFromBuilder(changeBuilder, DartFixKind.USE_CONST);
2055 } 2173 }
2056 } 2174 }
2057 2175
2058 void _addFix_replaceWithIdentifier() { 2176 Future<Null> _addFix_replaceWithIdentifier() async {
2059 final FunctionTypedFormalParameter functionTyped = 2177 final FunctionTypedFormalParameter functionTyped =
2060 node.getAncestor((node) => node is FunctionTypedFormalParameter); 2178 node.getAncestor((node) => node is FunctionTypedFormalParameter);
2061 if (functionTyped != null) { 2179 if (functionTyped != null) {
2062 _addReplaceEdit(range.node(functionTyped), 2180 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2063 utils.getNodeText(functionTyped.identifier)); 2181 await changeBuilder.addFileEdit(file, fileStamp,
2064 _addFix(DartFixKind.REPLACE_WITH_IDENTIFIER, []); 2182 (DartFileEditBuilder builder) {
2183 builder.addSimpleReplacement(range.node(functionTyped),
2184 utils.getNodeText(functionTyped.identifier));
2185 });
2186 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_IDENTIFIER);
2065 } else { 2187 } else {
2066 _addFix_removeTypeName(); 2188 await _addFix_removeTypeName();
2067 } 2189 }
2068 } 2190 }
2069 2191
2070 void _addFix_replaceWithLiteral() { 2192 Future<Null> _addFix_replaceWithLiteral() async {
2071 final InstanceCreationExpression instanceCreation = 2193 final InstanceCreationExpression instanceCreation =
2072 node.getAncestor((node) => node is InstanceCreationExpression); 2194 node.getAncestor((node) => node is InstanceCreationExpression);
2073 final InterfaceType type = instanceCreation.staticType; 2195 final InterfaceType type = instanceCreation.staticType;
2074 final buffer = new StringBuffer();
2075 final generics = instanceCreation.constructorName.type.typeArguments; 2196 final generics = instanceCreation.constructorName.type.typeArguments;
2076 if (generics != null) { 2197 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2077 buffer.write(utils.getNodeText(generics)); 2198 await changeBuilder.addFileEdit(file, fileStamp,
2078 } 2199 (DartFileEditBuilder builder) {
2079 if (type.name == 'List') { 2200 builder.addReplacement(range.node(instanceCreation),
2080 buffer.write('[]'); 2201 (DartEditBuilder builder) {
2081 } else { 2202 if (generics != null) {
2082 buffer.write('{}'); 2203 builder.write(utils.getNodeText(generics));
2083 } 2204 }
2084 _addReplaceEdit(range.node(instanceCreation), buffer.toString()); 2205 if (type.name == 'List') {
2085 _addFix(DartFixKind.REPLACE_WITH_LITERAL, []); 2206 builder.write('[]');
2207 } else {
2208 builder.write('{}');
2209 }
2210 });
2211 });
2212 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_LITERAL);
2086 } 2213 }
2087 2214
2088 void _addFix_replaceWithTearOff() { 2215 Future<Null> _addFix_replaceWithTearOff() async {
2089 FunctionExpression ancestor = 2216 FunctionExpression ancestor =
2090 node.getAncestor((a) => a is FunctionExpression); 2217 node.getAncestor((a) => a is FunctionExpression);
2091 if (ancestor == null) { 2218 if (ancestor == null) {
2092 return; 2219 return;
2093 } 2220 }
2094 void addFixOfExpression(InvocationExpression expression) { 2221 Future<Null> addFixOfExpression(InvocationExpression expression) async {
2095 final buffer = new StringBuffer(); 2222 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2096 if (expression is MethodInvocation && expression.target != null) { 2223 await changeBuilder.addFileEdit(file, fileStamp,
2097 buffer.write(utils.getNodeText(expression.target)); 2224 (DartFileEditBuilder builder) {
2098 buffer.write('.'); 2225 builder.addReplacement(range.node(ancestor), (DartEditBuilder builder) {
2099 } 2226 if (expression is MethodInvocation && expression.target != null) {
2100 buffer.write(utils.getNodeText(expression.function)); 2227 builder.write(utils.getNodeText(expression.target));
2101 _addReplaceEdit(range.node(ancestor), buffer.toString()); 2228 builder.write('.');
2102 _addFix(DartFixKind.REPLACE_WITH_TEAR_OFF, []); 2229 }
2230 builder.write(utils.getNodeText(expression.function));
2231 });
2232 });
2233 _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_TEAR_OFF);
2103 } 2234 }
2104 2235
2105 final body = ancestor.body; 2236 final body = ancestor.body;
2106 if (body is ExpressionFunctionBody) { 2237 if (body is ExpressionFunctionBody) {
2107 final expression = body.expression; 2238 final expression = body.expression;
2108 addFixOfExpression(expression.unParenthesized); 2239 await addFixOfExpression(expression.unParenthesized);
2109 } else if (body is BlockFunctionBody) { 2240 } else if (body is BlockFunctionBody) {
2110 final statement = body.block.statements.first; 2241 final statement = body.block.statements.first;
2111 if (statement is ExpressionStatement) { 2242 if (statement is ExpressionStatement) {
2112 final expression = statement.expression; 2243 final expression = statement.expression;
2113 addFixOfExpression(expression.unParenthesized); 2244 await addFixOfExpression(expression.unParenthesized);
2114 } else if (statement is ReturnStatement) { 2245 } else if (statement is ReturnStatement) {
2115 final expression = statement.expression; 2246 final expression = statement.expression;
2116 addFixOfExpression(expression.unParenthesized); 2247 await addFixOfExpression(expression.unParenthesized);
2117 } 2248 }
2118 } 2249 }
2119 } 2250 }
2120 2251
2121 void _addFix_undefinedClass_useSimilar() { 2252 Future<Null> _addFix_undefinedClass_useSimilar() async {
2122 AstNode node = this.node; 2253 AstNode node = this.node;
2123 // Prepare the optional import prefix name. 2254 // Prepare the optional import prefix name.
2124 String prefixName = null; 2255 String prefixName = null;
2125 if (node is SimpleIdentifier && node.staticElement is PrefixElement) { 2256 if (node is SimpleIdentifier && node.staticElement is PrefixElement) {
2126 AstNode parent = node.parent; 2257 AstNode parent = node.parent;
2127 if (parent is PrefixedIdentifier && 2258 if (parent is PrefixedIdentifier &&
2128 parent.prefix == node && 2259 parent.prefix == node &&
2129 parent.parent is TypeName) { 2260 parent.parent is TypeName) {
2130 prefixName = (node as SimpleIdentifier).name; 2261 prefixName = (node as SimpleIdentifier).name;
2131 node = parent.identifier; 2262 node = parent.identifier;
(...skipping 16 matching lines...) Expand all
2148 // Check elements from imports. 2279 // Check elements from imports.
2149 for (ImportElement importElement in unitLibraryElement.imports) { 2280 for (ImportElement importElement in unitLibraryElement.imports) {
2150 if (importElement.prefix?.name == prefixName) { 2281 if (importElement.prefix?.name == prefixName) {
2151 Map<String, Element> namespace = getImportNamespace(importElement); 2282 Map<String, Element> namespace = getImportNamespace(importElement);
2152 finder._updateList(namespace.values); 2283 finder._updateList(namespace.values);
2153 } 2284 }
2154 } 2285 }
2155 // If we have a close enough element, suggest to use it. 2286 // If we have a close enough element, suggest to use it.
2156 if (finder._element != null) { 2287 if (finder._element != null) {
2157 String closestName = finder._element.name; 2288 String closestName = finder._element.name;
2158 _addReplaceEdit(range.node(node), closestName);
2159 // Add proposal.
2160 if (closestName != null) { 2289 if (closestName != null) {
2161 _addFix(DartFixKind.CHANGE_TO, [closestName]); 2290 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2291 await changeBuilder.addFileEdit(file, fileStamp,
2292 (DartFileEditBuilder builder) {
2293 builder.addSimpleReplacement(range.node(node), closestName);
2294 });
2295 _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO,
2296 args: [closestName]);
2162 } 2297 }
2163 } 2298 }
2164 } 2299 }
2165 } 2300 }
2166 2301
2167 void _addFix_undefinedClassAccessor_useSimilar() { 2302 Future<Null> _addFix_undefinedClassAccessor_useSimilar() async {
2168 AstNode node = this.node; 2303 AstNode node = this.node;
2169 if (node is SimpleIdentifier) { 2304 if (node is SimpleIdentifier) {
2170 // prepare target 2305 // prepare target
2171 Expression target = null; 2306 Expression target = null;
2172 if (node.parent is PrefixedIdentifier) { 2307 if (node.parent is PrefixedIdentifier) {
2173 PrefixedIdentifier invocation = node.parent as PrefixedIdentifier; 2308 PrefixedIdentifier invocation = node.parent as PrefixedIdentifier;
2174 target = invocation.prefix; 2309 target = invocation.prefix;
2175 } 2310 }
2176 // find getter 2311 // find getter
2177 if (node.inGetterContext()) { 2312 if (node.inGetterContext()) {
2178 _addFix_undefinedClassMember_useSimilar(target, (Element element) { 2313 await _addFix_undefinedClassMember_useSimilar(target,
2314 (Element element) {
2179 return element is PropertyAccessorElement && element.isGetter || 2315 return element is PropertyAccessorElement && element.isGetter ||
2180 element is FieldElement && element.getter != null; 2316 element is FieldElement && element.getter != null;
2181 }); 2317 });
2182 } 2318 }
2183 // find setter 2319 // find setter
2184 if (node.inSetterContext()) { 2320 if (node.inSetterContext()) {
2185 _addFix_undefinedClassMember_useSimilar(target, (Element element) { 2321 await _addFix_undefinedClassMember_useSimilar(target,
2322 (Element element) {
2186 return element is PropertyAccessorElement && element.isSetter || 2323 return element is PropertyAccessorElement && element.isSetter ||
2187 element is FieldElement && element.setter != null; 2324 element is FieldElement && element.setter != null;
2188 }); 2325 });
2189 } 2326 }
2190 } 2327 }
2191 } 2328 }
2192 2329
2193 void _addFix_undefinedClassMember_useSimilar( 2330 Future<Null> _addFix_undefinedClassMember_useSimilar(
2194 Expression target, ElementPredicate predicate) { 2331 Expression target, ElementPredicate predicate) async {
2195 if (node is SimpleIdentifier) { 2332 if (node is SimpleIdentifier) {
2196 String name = (node as SimpleIdentifier).name; 2333 String name = (node as SimpleIdentifier).name;
2197 _ClosestElementFinder finder = 2334 _ClosestElementFinder finder =
2198 new _ClosestElementFinder(name, predicate, MAX_LEVENSHTEIN_DISTANCE); 2335 new _ClosestElementFinder(name, predicate, MAX_LEVENSHTEIN_DISTANCE);
2199 // unqualified invocation 2336 // unqualified invocation
2200 if (target == null) { 2337 if (target == null) {
2201 ClassDeclaration clazz = 2338 ClassDeclaration clazz =
2202 node.getAncestor((node) => node is ClassDeclaration); 2339 node.getAncestor((node) => node is ClassDeclaration);
2203 if (clazz != null) { 2340 if (clazz != null) {
2204 ClassElement classElement = clazz.element; 2341 ClassElement classElement = clazz.element;
2205 _updateFinderWithClassMembers(finder, classElement); 2342 _updateFinderWithClassMembers(finder, classElement);
2206 } 2343 }
2207 } else { 2344 } else {
2208 DartType type = target.bestType; 2345 DartType type = target.bestType;
2209 if (type is InterfaceType) { 2346 if (type is InterfaceType) {
2210 ClassElement classElement = type.element; 2347 ClassElement classElement = type.element;
2211 _updateFinderWithClassMembers(finder, classElement); 2348 _updateFinderWithClassMembers(finder, classElement);
2212 } 2349 }
2213 } 2350 }
2214 // if we have close enough element, suggest to use it 2351 // if we have close enough element, suggest to use it
2215 if (finder._element != null) { 2352 if (finder._element != null) {
2216 String closestName = finder._element.name; 2353 String closestName = finder._element.name;
2217 _addReplaceEdit(range.node(node), closestName); 2354 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2218 _addFix(DartFixKind.CHANGE_TO, [closestName]); 2355 await changeBuilder.addFileEdit(file, fileStamp,
2356 (DartFileEditBuilder builder) {
2357 builder.addSimpleReplacement(range.node(node), closestName);
2358 });
2359 _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO,
2360 args: [closestName]);
2219 } 2361 }
2220 } 2362 }
2221 } 2363 }
2222 2364
2223 void _addFix_undefinedFunction_create() { 2365 Future<Null> _addFix_undefinedFunction_create() async {
2224 // should be the name of the invocation 2366 // should be the name of the invocation
2225 if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else { 2367 if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else {
2226 return; 2368 return;
2227 } 2369 }
2228 String name = (node as SimpleIdentifier).name; 2370 String name = (node as SimpleIdentifier).name;
2229 MethodInvocation invocation = node.parent as MethodInvocation; 2371 MethodInvocation invocation = node.parent as MethodInvocation;
2230 // function invocation has no target 2372 // function invocation has no target
2231 Expression target = invocation.realTarget; 2373 Expression target = invocation.realTarget;
2232 if (target != null) { 2374 if (target != null) {
2233 return; 2375 return;
2234 } 2376 }
2235 // prepare environment 2377 // prepare environment
2236 int insertOffset; 2378 int insertOffset;
2237 String sourcePrefix; 2379 String sourcePrefix;
2238 AstNode enclosingMember = 2380 AstNode enclosingMember =
2239 node.getAncestor((node) => node is CompilationUnitMember); 2381 node.getAncestor((node) => node is CompilationUnitMember);
2240 insertOffset = enclosingMember.end; 2382 insertOffset = enclosingMember.end;
2241 sourcePrefix = '$eol$eol'; 2383 sourcePrefix = '$eol$eol';
2242 utils.targetClassElement = null; 2384 utils.targetClassElement = null;
2243 // build method source 2385 // build method source
2244 SourceBuilder sb = new SourceBuilder(file, insertOffset); 2386 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2245 { 2387 await changeBuilder.addFileEdit(file, fileStamp,
2246 sb.append(sourcePrefix); 2388 (DartFileEditBuilder builder) {
2247 // append return type 2389 builder.addInsertion(insertOffset, (DartEditBuilder builder) {
2248 { 2390 builder.write(sourcePrefix);
2249 DartType type = _inferUndefinedExpressionType(invocation); 2391 // append return type
2250 _appendType(sb, type, groupId: 'RETURN_TYPE'); 2392 {
2251 } 2393 DartType type = _inferUndefinedExpressionType(invocation);
2252 // append name 2394 if (builder.writeType(type, groupName: 'RETURN_TYPE')) {
2253 { 2395 builder.write(' ');
2254 sb.startPosition('NAME'); 2396 }
2255 sb.append(name); 2397 }
2256 sb.endPosition(); 2398 // append name
2257 } 2399 builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) {
2258 _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList); 2400 builder.write(name);
2259 sb.append(') {$eol}'); 2401 });
2260 } 2402 builder.write('(');
2261 // insert source 2403 builder.writeParametersMatchingArguments(invocation.argumentList);
2262 _insertBuilder(sb, unitElement); 2404 builder.write(') {$eol}');
2263 _addLinkedPosition('NAME', sb, range.node(node)); 2405 });
2264 // add proposal 2406 builder.addLinkedPosition(range.node(node), 'NAME');
2265 _addFix(DartFixKind.CREATE_FUNCTION, [name]); 2407 });
2408 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION,
2409 args: [name]);
2266 } 2410 }
2267 2411
2268 void _addFix_undefinedFunction_useSimilar() { 2412 Future<Null> _addFix_undefinedFunction_useSimilar() async {
2269 AstNode node = this.node; 2413 AstNode node = this.node;
2270 if (node is SimpleIdentifier) { 2414 if (node is SimpleIdentifier) {
2271 // Prepare the optional import prefix name. 2415 // Prepare the optional import prefix name.
2272 String prefixName = null; 2416 String prefixName = null;
2273 { 2417 {
2274 AstNode invocation = node.parent; 2418 AstNode invocation = node.parent;
2275 if (invocation is MethodInvocation && invocation.methodName == node) { 2419 if (invocation is MethodInvocation && invocation.methodName == node) {
2276 Expression target = invocation.target; 2420 Expression target = invocation.target;
2277 if (target is SimpleIdentifier && 2421 if (target is SimpleIdentifier &&
2278 target.staticElement is PrefixElement) { 2422 target.staticElement is PrefixElement) {
(...skipping 15 matching lines...) Expand all
2294 // Check unprefixed imports. 2438 // Check unprefixed imports.
2295 for (ImportElement importElement in unitLibraryElement.imports) { 2439 for (ImportElement importElement in unitLibraryElement.imports) {
2296 if (importElement.prefix?.name == prefixName) { 2440 if (importElement.prefix?.name == prefixName) {
2297 Map<String, Element> namespace = getImportNamespace(importElement); 2441 Map<String, Element> namespace = getImportNamespace(importElement);
2298 finder._updateList(namespace.values); 2442 finder._updateList(namespace.values);
2299 } 2443 }
2300 } 2444 }
2301 // If we have a close enough element, suggest to use it. 2445 // If we have a close enough element, suggest to use it.
2302 if (finder._element != null) { 2446 if (finder._element != null) {
2303 String closestName = finder._element.name; 2447 String closestName = finder._element.name;
2304 _addReplaceEdit(range.node(node), closestName); 2448 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2305 _addFix(DartFixKind.CHANGE_TO, [closestName]); 2449 await changeBuilder.addFileEdit(file, fileStamp,
2450 (DartFileEditBuilder builder) {
2451 builder.addSimpleReplacement(range.node(node), closestName);
2452 });
2453 _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO,
2454 args: [closestName]);
2306 } 2455 }
2307 } 2456 }
2308 } 2457 }
2309 2458
2310 void _addFix_undefinedMethod_create() { 2459 Future<Null> _addFix_undefinedMethod_create() async {
2311 if (node is SimpleIdentifier && node.parent is MethodInvocation) { 2460 if (node is SimpleIdentifier && node.parent is MethodInvocation) {
2312 String name = (node as SimpleIdentifier).name; 2461 String name = (node as SimpleIdentifier).name;
2313 MethodInvocation invocation = node.parent as MethodInvocation; 2462 MethodInvocation invocation = node.parent as MethodInvocation;
2314 // prepare environment 2463 // prepare environment
2315 Element targetElement; 2464 Element targetElement;
2316 bool staticModifier = false; 2465 bool staticModifier = false;
2317 2466
2318 ClassDeclaration targetClassNode; 2467 ClassDeclaration targetClassNode;
2319 Expression target = invocation.realTarget; 2468 Expression target = invocation.realTarget;
2320 if (target == null) { 2469 if (target == null) {
(...skipping 28 matching lines...) Expand all
2349 } 2498 }
2350 // use different utils 2499 // use different utils
2351 CompilationUnitElement targetUnitElement = 2500 CompilationUnitElement targetUnitElement =
2352 getCompilationUnitElement(targetClassElement); 2501 getCompilationUnitElement(targetClassElement);
2353 CompilationUnit targetUnit = getParsedUnit(targetUnitElement); 2502 CompilationUnit targetUnit = getParsedUnit(targetUnitElement);
2354 utils = new CorrectionUtils(targetUnit); 2503 utils = new CorrectionUtils(targetUnit);
2355 } 2504 }
2356 ClassMemberLocation targetLocation = 2505 ClassMemberLocation targetLocation =
2357 utils.prepareNewMethodLocation(targetClassNode); 2506 utils.prepareNewMethodLocation(targetClassNode);
2358 String targetFile = targetElement.source.fullName; 2507 String targetFile = targetElement.source.fullName;
2508 int targetStamp =
2509 targetElement.context.getModificationStamp(targetElement.source);
2359 // build method source 2510 // build method source
2360 SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset); 2511 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2361 { 2512 await changeBuilder.addFileEdit(targetFile, targetStamp,
2362 sb.append(targetLocation.prefix); 2513 (DartFileEditBuilder builder) {
2363 // maybe "static" 2514 builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
2364 if (staticModifier) { 2515 builder.write(targetLocation.prefix);
2365 sb.append('static '); 2516 // maybe "static"
2517 if (staticModifier) {
2518 builder.write('static ');
2519 }
2520 // append return type
2521 {
2522 DartType type = _inferUndefinedExpressionType(invocation);
2523 if (builder.writeType(type, groupName: 'RETURN_TYPE')) {
2524 builder.write(' ');
2525 }
2526 }
2527 // append name
2528 builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) {
2529 builder.write(name);
2530 });
2531 builder.write('(');
2532 builder.writeParametersMatchingArguments(invocation.argumentList);
2533 builder.write(') {}');
2534 builder.write(targetLocation.suffix);
2535 });
2536 if (targetFile == file) {
2537 builder.addLinkedPosition(range.node(node), 'NAME');
2366 } 2538 }
2367 // append return type 2539 });
2368 { 2540 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD,
2369 DartType type = _inferUndefinedExpressionType(invocation); 2541 args: [name]);
2370 _appendType(sb, type, groupId: 'RETURN_TYPE');
2371 }
2372 // append name
2373 {
2374 sb.startPosition('NAME');
2375 sb.append(name);
2376 sb.endPosition();
2377 }
2378 _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList);
2379 sb.append(') {}');
2380 sb.append(targetLocation.suffix);
2381 }
2382 // insert source
2383 _insertBuilder(sb, targetElement);
2384 // add linked positions
2385 if (targetFile == file) {
2386 _addLinkedPosition('NAME', sb, range.node(node));
2387 }
2388 // add proposal
2389 _addFix(DartFixKind.CREATE_METHOD, [name]);
2390 } 2542 }
2391 } 2543 }
2392 2544
2393 void _addFix_undefinedMethod_create_parameters( 2545 Future<Null> _addFix_undefinedMethod_useSimilar() async {
2394 SourceBuilder sb, ArgumentList argumentList) {
2395 Set<String> usedNames = new Set<String>();
2396 // append parameters
2397 sb.append('(');
2398 List<Expression> arguments = argumentList.arguments;
2399 bool hasNamedParameters = false;
2400 for (int i = 0; i < arguments.length; i++) {
2401 Expression argument = arguments[i];
2402 // append separator
2403 if (i != 0) {
2404 sb.append(', ');
2405 }
2406 // append parameter
2407 if (argument is NamedExpression && !hasNamedParameters) {
2408 hasNamedParameters = true;
2409 sb.append('{');
2410 }
2411 _appendParameterForArgument(sb, usedNames, i, argument);
2412 }
2413 if (hasNamedParameters) {
2414 sb.append('}');
2415 }
2416 }
2417
2418 void _addFix_undefinedMethod_useSimilar() {
2419 if (node.parent is MethodInvocation) { 2546 if (node.parent is MethodInvocation) {
2420 MethodInvocation invocation = node.parent as MethodInvocation; 2547 MethodInvocation invocation = node.parent as MethodInvocation;
2421 _addFix_undefinedClassMember_useSimilar(invocation.realTarget, 2548 await _addFix_undefinedClassMember_useSimilar(invocation.realTarget,
2422 (Element element) => element is MethodElement && !element.isOperator); 2549 (Element element) => element is MethodElement && !element.isOperator);
2423 } 2550 }
2424 } 2551 }
2425 2552
2426 /** 2553 /**
2427 * Here we handle cases when a constructors does not initialize all of the 2554 * Here we handle cases when a constructors does not initialize all of the
2428 * final fields. 2555 * final fields.
2429 */ 2556 */
2430 void _addFix_updateConstructor_forUninitializedFinalFields() { 2557 Future<Null> _addFix_updateConstructor_forUninitializedFinalFields() async {
2431 if (node is! SimpleIdentifier || node.parent is! ConstructorDeclaration) { 2558 if (node is! SimpleIdentifier || node.parent is! ConstructorDeclaration) {
2432 return; 2559 return;
2433 } 2560 }
2434 ConstructorDeclaration constructor = node.parent; 2561 ConstructorDeclaration constructor = node.parent;
2435 // add these fields 2562 // add these fields
2436 List<FieldElement> fields = 2563 List<FieldElement> fields =
2437 ErrorVerifier.computeNotInitializedFields(constructor); 2564 ErrorVerifier.computeNotInitializedFields(constructor);
2438 // prepare new parameters code 2565 // prepare new parameters code
2439 fields.sort((a, b) => a.nameOffset - b.nameOffset); 2566 fields.sort((a, b) => a.nameOffset - b.nameOffset);
2440 String fieldParametersCode = 2567 String fieldParametersCode =
2441 fields.map((field) => 'this.${field.name}').join(', '); 2568 fields.map((field) => 'this.${field.name}').join(', ');
2442 // prepare the last required parameter 2569 // prepare the last required parameter
2443 FormalParameter lastRequiredParameter; 2570 FormalParameter lastRequiredParameter;
2444 List<FormalParameter> parameters = constructor.parameters.parameters; 2571 List<FormalParameter> parameters = constructor.parameters.parameters;
2445 for (FormalParameter parameter in parameters) { 2572 for (FormalParameter parameter in parameters) {
2446 if (parameter.kind == ParameterKind.REQUIRED) { 2573 if (parameter.kind == ParameterKind.REQUIRED) {
2447 lastRequiredParameter = parameter; 2574 lastRequiredParameter = parameter;
2448 } 2575 }
2449 } 2576 }
2450 // append new field formal initializers 2577 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2451 if (lastRequiredParameter != null) { 2578 await changeBuilder.addFileEdit(file, fileStamp,
2452 _addInsertEdit(lastRequiredParameter.end, ', $fieldParametersCode'); 2579 (DartFileEditBuilder builder) {
2453 } else { 2580 // append new field formal initializers
2454 int offset = constructor.parameters.leftParenthesis.end; 2581 if (lastRequiredParameter != null) {
2455 if (parameters.isNotEmpty) { 2582 builder.addSimpleInsertion(
2456 fieldParametersCode += ', '; 2583 lastRequiredParameter.end, ', $fieldParametersCode');
2584 } else {
2585 int offset = constructor.parameters.leftParenthesis.end;
2586 if (parameters.isNotEmpty) {
2587 fieldParametersCode += ', ';
2588 }
2589 builder.addSimpleInsertion(offset, fieldParametersCode);
2457 } 2590 }
2458 _addInsertEdit(offset, fieldParametersCode); 2591 });
2459 } 2592 _addFixFromBuilder(changeBuilder, DartFixKind.ADD_FIELD_FORMAL_PARAMETERS);
2460 // add proposal
2461 _addFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, []);
2462 } 2593 }
2463 2594
2464 void _addFix_useEffectiveIntegerDivision() { 2595 Future<Null> _addFix_useEffectiveIntegerDivision() async {
2465 for (AstNode n = node; n != null; n = n.parent) { 2596 for (AstNode n = node; n != null; n = n.parent) {
2466 if (n is MethodInvocation && 2597 if (n is MethodInvocation &&
2467 n.offset == errorOffset && 2598 n.offset == errorOffset &&
2468 n.length == errorLength) { 2599 n.length == errorLength) {
2469 Expression target = n.target.unParenthesized; 2600 Expression target = (n as MethodInvocation).target.unParenthesized;
2470 // replace "/" with "~/" 2601 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2471 BinaryExpression binary = target as BinaryExpression; 2602 await changeBuilder.addFileEdit(file, fileStamp,
2472 _addReplaceEdit(range.token(binary.operator), '~/'); 2603 (DartFileEditBuilder builder) {
2473 // remove everything before and after 2604 // replace "/" with "~/"
2474 _addRemoveEdit(range.startStart(n, binary.leftOperand)); 2605 BinaryExpression binary = target as BinaryExpression;
2475 _addRemoveEdit(range.endEnd(binary.rightOperand, n)); 2606 builder.addSimpleReplacement(range.token(binary.operator), '~/');
2476 // add proposal 2607 // remove everything before and after
2477 _addFix(DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION, []); 2608 builder.addDeletion(range.startStart(n, binary.leftOperand));
2609 builder.addDeletion(range.endEnd(binary.rightOperand, n));
2610 });
2611 _addFixFromBuilder(
2612 changeBuilder, DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION);
2478 // done 2613 // done
2479 break; 2614 break;
2480 } 2615 }
2481 } 2616 }
2482 } 2617 }
2483 2618
2484 /** 2619 /**
2485 * Adds a fix that replaces [target] with a reference to the class declaring 2620 * Adds a fix that replaces [target] with a reference to the class declaring
2486 * the given [element]. 2621 * the given [element].
2487 */ 2622 */
2488 void _addFix_useStaticAccess(AstNode target, Element element) { 2623 Future<Null> _addFix_useStaticAccess(AstNode target, Element element) async {
2489 Element declaringElement = element.enclosingElement; 2624 Element declaringElement = element.enclosingElement;
2490 if (declaringElement is ClassElement) { 2625 if (declaringElement is ClassElement) {
2491 DartType declaringType = declaringElement.type; 2626 DartType declaringType = declaringElement.type;
2492 String declaringTypeCode = 2627 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2493 utils.getTypeSource(declaringType, librariesToImport); 2628 await changeBuilder.addFileEdit(file, fileStamp,
2494 // replace "target" with class name 2629 (DartFileEditBuilder builder) {
2495 _addReplaceEdit(range.node(target), declaringTypeCode); 2630 // replace "target" with class name
2496 // add proposal 2631 builder.addReplacement(range.node(target), (DartEditBuilder builder) {
2497 _addFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, [declaringType]); 2632 builder.writeType(declaringType);
2633 });
2634 });
2635 _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO_STATIC_ACCESS,
2636 args: [declaringType]);
2498 } 2637 }
2499 } 2638 }
2500 2639
2501 void _addFix_useStaticAccess_method() { 2640 Future<Null> _addFix_useStaticAccess_method() async {
2502 if (node is SimpleIdentifier && node.parent is MethodInvocation) { 2641 if (node is SimpleIdentifier && node.parent is MethodInvocation) {
2503 MethodInvocation invocation = node.parent as MethodInvocation; 2642 MethodInvocation invocation = node.parent as MethodInvocation;
2504 if (invocation.methodName == node) { 2643 if (invocation.methodName == node) {
2505 Expression target = invocation.target; 2644 Expression target = invocation.target;
2506 Element invokedElement = invocation.methodName.bestElement; 2645 Element invokedElement = invocation.methodName.bestElement;
2507 _addFix_useStaticAccess(target, invokedElement); 2646 await _addFix_useStaticAccess(target, invokedElement);
2508 } 2647 }
2509 } 2648 }
2510 } 2649 }
2511 2650
2512 void _addFix_useStaticAccess_property() { 2651 Future<Null> _addFix_useStaticAccess_property() async {
2513 if (node is SimpleIdentifier && node.parent is PrefixedIdentifier) { 2652 if (node is SimpleIdentifier && node.parent is PrefixedIdentifier) {
2514 PrefixedIdentifier prefixed = node.parent as PrefixedIdentifier; 2653 PrefixedIdentifier prefixed = node.parent as PrefixedIdentifier;
2515 if (prefixed.identifier == node) { 2654 if (prefixed.identifier == node) {
2516 Expression target = prefixed.prefix; 2655 Expression target = prefixed.prefix;
2517 Element invokedElement = prefixed.identifier.bestElement; 2656 Element invokedElement = prefixed.identifier.bestElement;
2518 _addFix_useStaticAccess(target, invokedElement); 2657 await _addFix_useStaticAccess(target, invokedElement);
2519 } 2658 }
2520 } 2659 }
2521 } 2660 }
2522 2661
2523 void _addFixFromBuilder(DartChangeBuilder builder, FixKind kind, 2662 void _addFixFromBuilder(DartChangeBuilder builder, FixKind kind,
2524 {List args: null, bool importsOnly: false}) { 2663 {List args: null, bool importsOnly: false}) {
2525 SourceChange change = builder.sourceChange; 2664 SourceChange change = builder.sourceChange;
2526 if (change.edits.isEmpty && !importsOnly) { 2665 if (change.edits.isEmpty && !importsOnly) {
2527 return; 2666 return;
2528 } 2667 }
2529 change.message = formatList(kind.message, args); 2668 change.message = formatList(kind.message, args);
2530 fixes.add(new Fix(kind, change)); 2669 fixes.add(new Fix(kind, change));
2531 } 2670 }
2532 2671
2533 /** 2672 /**
2534 * Adds a new [SourceEdit] to [change].
2535 */
2536 void _addInsertEdit(int offset, String text, [Element target]) {
2537 SourceEdit edit = new SourceEdit(offset, 0, text);
2538 _addEdit(target, edit);
2539 }
2540
2541 /**
2542 * Adds a single linked position to [groupId].
2543 */
2544 void _addLinkedPosition(String groupId, SourceBuilder sb, SourceRange range) {
2545 // prepare offset
2546 int offset = range.offset;
2547 if (sb.offset <= offset) {
2548 int delta = sb.length;
2549 offset += delta;
2550 }
2551 // prepare group
2552 LinkedEditGroup group = _getLinkedPosition(groupId);
2553 // add position
2554 Position position = new Position(file, offset);
2555 group.addPosition(position, range.length);
2556 }
2557
2558 void _addLintFixAddOverrideAnnotation() {
2559 ClassMember member = node.getAncestor((n) => n is ClassMember);
2560 if (member == null) {
2561 return;
2562 }
2563
2564 //TODO(pq): migrate annotation edit building to change_builder
2565
2566 // Handle doc comments.
2567 Token token = member.beginToken;
2568 if (token is CommentToken) {
2569 token = (token as CommentToken).parent;
2570 }
2571
2572 exitPosition = new Position(file, token.offset - 1);
2573 String indent = utils.getIndent(1);
2574 _addReplaceEdit(range.startLength(token, 0), '@override$eol$indent');
2575 _addFix(DartFixKind.LINT_ADD_OVERRIDE, []);
2576 }
2577
2578 void _addLintRemoveInterpolationBraces() {
2579 AstNode node = this.node;
2580 if (node is InterpolationExpression) {
2581 Token right = node.rightBracket;
2582 if (node.expression != null && right != null) {
2583 _addReplaceEdit(range.startStart(node, node.expression), r'$');
2584 _addRemoveEdit(range.token(right));
2585 _addFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES, []);
2586 }
2587 }
2588 }
2589
2590 /**
2591 * Prepares proposal for creating function corresponding to the given 2673 * Prepares proposal for creating function corresponding to the given
2592 * [FunctionType]. 2674 * [FunctionType].
2593 */ 2675 */
2594 void _addProposal_createFunction( 2676 Future<DartChangeBuilder> _addProposal_createFunction(
2595 FunctionType functionType, 2677 FunctionType functionType,
2596 String name, 2678 String name,
2597 Source targetSource, 2679 Source targetSource,
2598 int insertOffset, 2680 int insertOffset,
2599 bool isStatic, 2681 bool isStatic,
2600 String prefix, 2682 String prefix,
2601 String sourcePrefix, 2683 String sourcePrefix,
2602 String sourceSuffix, 2684 String sourceSuffix,
2603 Element target) { 2685 Element target) async {
2604 // build method source 2686 // build method source
2605 String targetFile = targetSource.fullName; 2687 String targetFile = targetSource.fullName;
2606 SourceBuilder sb = new SourceBuilder(targetFile, insertOffset); 2688 int timeStamp = target.context.getModificationStamp(targetSource);
2607 { 2689 DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
2608 sb.append(sourcePrefix); 2690 await changeBuilder.addFileEdit(targetFile, timeStamp,
2609 sb.append(prefix); 2691 (DartFileEditBuilder builder) {
2610 // may be static 2692 builder.addInsertion(insertOffset, (DartEditBuilder builder) {
2611 if (isStatic) { 2693 builder.write(sourcePrefix);
2612 sb.append('static '); 2694 builder.write(prefix);
2695 // may be static
2696 if (isStatic) {
2697 builder.write('static ');
2698 }
2699 // append return type
2700 if (builder.writeType(functionType.returnType,
2701 groupName: 'RETURN_TYPE')) {
2702 builder.write(' ');
2703 }
2704 // append name
2705 builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) {
2706 builder.write(name);
2707 });
2708 // append parameters
2709 builder.write('(');
2710 List<ParameterElement> parameters = functionType.parameters;
2711 for (int i = 0; i < parameters.length; i++) {
2712 ParameterElement parameter = parameters[i];
2713 // append separator
2714 if (i != 0) {
2715 builder.write(', ');
2716 }
2717 // append type name
2718 DartType type = parameter.type;
2719 if (!type.isDynamic) {
2720 builder.addLinkedEdit('TYPE$i',
2721 (DartLinkedEditBuilder innerBuilder) {
2722 builder.writeType(type);
2723 innerBuilder.addSuperTypesAsSuggestions(type);
2724 });
2725 builder.write(' ');
2726 }
2727 // append parameter name
2728 builder.addLinkedEdit('ARG$i', (DartLinkedEditBuilder builder) {
2729 builder.write(parameter.displayName);
2730 });
2731 }
2732 builder.write(')');
2733 // close method
2734 builder.write(' {$eol$prefix}');
2735 builder.write(sourceSuffix);
2736 });
2737 if (targetSource == unitSource) {
2738 builder.addLinkedPosition(range.node(node), 'NAME');
2613 } 2739 }
2614 // append return type 2740 });
2615 _appendType(sb, functionType.returnType, groupId: 'RETURN_TYPE'); 2741 return changeBuilder;
2616 // append name
2617 {
2618 sb.startPosition('NAME');
2619 sb.append(name);
2620 sb.endPosition();
2621 }
2622 // append parameters
2623 sb.append('(');
2624 List<ParameterElement> parameters = functionType.parameters;
2625 for (int i = 0; i < parameters.length; i++) {
2626 ParameterElement parameter = parameters[i];
2627 // append separator
2628 if (i != 0) {
2629 sb.append(', ');
2630 }
2631 // append type name
2632 DartType type = parameter.type;
2633 if (!type.isDynamic) {
2634 String typeSource = utils.getTypeSource(type, librariesToImport);
2635 {
2636 sb.startPosition('TYPE$i');
2637 sb.append(typeSource);
2638 _addSuperTypeProposals(sb, type);
2639 sb.endPosition();
2640 }
2641 sb.append(' ');
2642 }
2643 // append parameter name
2644 {
2645 sb.startPosition('ARG$i');
2646 sb.append(parameter.displayName);
2647 sb.endPosition();
2648 }
2649 }
2650 sb.append(')');
2651 // close method
2652 sb.append(' {$eol$prefix}');
2653 sb.append(sourceSuffix);
2654 }
2655 // insert source
2656 _insertBuilder(sb, target);
2657 // add linked positions
2658 if (targetSource == unitSource) {
2659 _addLinkedPosition('NAME', sb, range.node(node));
2660 }
2661 } 2742 }
2662 2743
2663 /** 2744 /**
2664 * Adds proposal for creating method corresponding to the given [FunctionType] in the given 2745 * Adds proposal for creating method corresponding to the given [FunctionType] in the given
2665 * [ClassElement]. 2746 * [ClassElement].
2666 */ 2747 */
2667 void _addProposal_createFunction_function(FunctionType functionType) { 2748 Future<Null> _addProposal_createFunction_function(
2749 FunctionType functionType) async {
2668 String name = (node as SimpleIdentifier).name; 2750 String name = (node as SimpleIdentifier).name;
2669 // prepare environment 2751 // prepare environment
2670 int insertOffset = unit.end; 2752 int insertOffset = unit.end;
2671 // prepare prefix 2753 // prepare prefix
2672 String prefix = ''; 2754 String prefix = '';
2673 String sourcePrefix = '$eol'; 2755 String sourcePrefix = '$eol';
2674 String sourceSuffix = eol; 2756 String sourceSuffix = eol;
2675 _addProposal_createFunction(functionType, name, unitSource, insertOffset, 2757 DartChangeBuilder changeBuilder = await _addProposal_createFunction(
2676 false, prefix, sourcePrefix, sourceSuffix, unitElement); 2758 functionType,
2677 // add proposal 2759 name,
2678 _addFix(DartFixKind.CREATE_FUNCTION, [name]); 2760 unitSource,
2761 insertOffset,
2762 false,
2763 prefix,
2764 sourcePrefix,
2765 sourceSuffix,
2766 unitElement);
2767 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION,
2768 args: [name]);
2679 } 2769 }
2680 2770
2681 /** 2771 /**
2682 * Adds proposal for creating method corresponding to the given [FunctionType] in the given 2772 * Adds proposal for creating method corresponding to the given [FunctionType] in the given
2683 * [ClassElement]. 2773 * [ClassElement].
2684 */ 2774 */
2685 void _addProposal_createFunction_method( 2775 Future<Null> _addProposal_createFunction_method(
2686 ClassElement targetClassElement, FunctionType functionType) { 2776 ClassElement targetClassElement, FunctionType functionType) async {
2687 String name = (node as SimpleIdentifier).name; 2777 String name = (node as SimpleIdentifier).name;
2688 // prepare environment 2778 // prepare environment
2689 Source targetSource = targetClassElement.source; 2779 Source targetSource = targetClassElement.source;
2690 // prepare insert offset 2780 // prepare insert offset
2691 ClassDeclaration targetClassNode = 2781 ClassDeclaration targetClassNode =
2692 getParsedClassElementNode(targetClassElement); 2782 getParsedClassElementNode(targetClassElement);
2693 int insertOffset = targetClassNode.end - 1; 2783 int insertOffset = targetClassNode.end - 1;
2694 // prepare prefix 2784 // prepare prefix
2695 String prefix = ' '; 2785 String prefix = ' ';
2696 String sourcePrefix; 2786 String sourcePrefix;
2697 if (targetClassNode.members.isEmpty) { 2787 if (targetClassNode.members.isEmpty) {
2698 sourcePrefix = ''; 2788 sourcePrefix = '';
2699 } else { 2789 } else {
2700 sourcePrefix = eol; 2790 sourcePrefix = eol;
2701 } 2791 }
2702 String sourceSuffix = eol; 2792 String sourceSuffix = eol;
2703 _addProposal_createFunction( 2793 DartChangeBuilder changeBuilder = await _addProposal_createFunction(
2704 functionType, 2794 functionType,
2705 name, 2795 name,
2706 targetSource, 2796 targetSource,
2707 insertOffset, 2797 insertOffset,
2708 _inStaticContext(), 2798 _inStaticContext(),
2709 prefix, 2799 prefix,
2710 sourcePrefix, 2800 sourcePrefix,
2711 sourceSuffix, 2801 sourceSuffix,
2712 targetClassElement); 2802 targetClassElement);
2713 // add proposal 2803 _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, args: [name]);
2714 _addFix(DartFixKind.CREATE_METHOD, [name]);
2715 } 2804 }
2716 2805
2717 /** 2806 /**
2718 * Adds a new [Edit] to [edits].
2719 */
2720 void _addRemoveEdit(SourceRange range) {
2721 _addReplaceEdit(range, '');
2722 }
2723
2724 /**
2725 * Adds a new [SourceEdit] to [change].
2726 */
2727 void _addReplaceEdit(SourceRange range, String text, [Element target]) {
2728 SourceEdit edit = new SourceEdit(range.offset, range.length, text);
2729 _addEdit(target, edit);
2730 }
2731
2732 void _appendParameterForArgument(
2733 SourceBuilder sb, Set<String> excluded, int index, Expression argument) {
2734 DartType type = argument.bestType;
2735 if (type == null || type.isBottom || type.isDartCoreNull) {
2736 type = DynamicTypeImpl.instance;
2737 }
2738 // append type name
2739 String typeSource = utils.getTypeSource(type, librariesToImport);
2740 if (typeSource != 'dynamic') {
2741 sb.startPosition('TYPE$index');
2742 sb.append(typeSource);
2743 _addSuperTypeProposals(sb, type);
2744 sb.endPosition();
2745 sb.append(' ');
2746 }
2747 // append parameter name
2748 if (argument is NamedExpression) {
2749 sb.append(argument.name.label.name);
2750 } else {
2751 List<String> suggestions =
2752 _getArgumentNameSuggestions(excluded, type, argument, index);
2753 String favorite = suggestions[0];
2754 excluded.add(favorite);
2755 sb.startPosition('ARG$index');
2756 sb.append(favorite);
2757 sb.addSuggestions(LinkedEditSuggestionKind.PARAMETER, suggestions);
2758 sb.endPosition();
2759 }
2760 }
2761
2762 void _appendParameters(SourceBuilder sb, List<ParameterElement> parameters) {
2763 sb.append('(');
2764 bool firstParameter = true;
2765 bool sawNamed = false;
2766 bool sawPositional = false;
2767 for (ParameterElement parameter in parameters) {
2768 if (!firstParameter) {
2769 sb.append(', ');
2770 } else {
2771 firstParameter = false;
2772 }
2773 // may be optional
2774 ParameterKind parameterKind = parameter.parameterKind;
2775 if (parameterKind == ParameterKind.NAMED) {
2776 if (!sawNamed) {
2777 sb.append('{');
2778 sawNamed = true;
2779 }
2780 }
2781 if (parameterKind == ParameterKind.POSITIONAL) {
2782 if (!sawPositional) {
2783 sb.append('[');
2784 sawPositional = true;
2785 }
2786 }
2787 // parameter
2788 _appendParameterSource(sb, parameter.type, parameter.name);
2789 // default value
2790 String defaultCode = parameter.defaultValueCode;
2791 if (defaultCode != null) {
2792 if (sawPositional) {
2793 sb.append(' = ');
2794 } else {
2795 sb.append(': ');
2796 }
2797 sb.append(defaultCode);
2798 }
2799 }
2800 // close parameters
2801 if (sawNamed) {
2802 sb.append('}');
2803 }
2804 if (sawPositional) {
2805 sb.append(']');
2806 }
2807 sb.append(')');
2808 }
2809
2810 void _appendParameterSource(SourceBuilder sb, DartType type, String name) {
2811 String parameterSource =
2812 utils.getParameterSource(type, name, librariesToImport);
2813 sb.append(parameterSource);
2814 }
2815
2816 void _appendType(SourceBuilder sb, DartType type,
2817 {String groupId, bool orVar: false, bool trailingSpace: true}) {
2818 if (type != null && !type.isDynamic) {
2819 String typeSource = utils.getTypeSource(type, librariesToImport);
2820 if (groupId != null) {
2821 sb.startPosition(groupId);
2822 sb.append(typeSource);
2823 sb.endPosition();
2824 } else {
2825 sb.append(typeSource);
2826 }
2827 if (trailingSpace) {
2828 sb.append(' ');
2829 }
2830 } else if (orVar) {
2831 sb.append('var ');
2832 }
2833 }
2834
2835 /**
2836 * Computes the name of the library at the given [path]. 2807 * Computes the name of the library at the given [path].
2837 * See https://www.dartlang.org/articles/style-guide/#names for conventions. 2808 * See https://www.dartlang.org/articles/style-guide/#names for conventions.
2838 */ 2809 */
2839 String _computeLibraryName(String path) { 2810 String _computeLibraryName(String path) {
2840 Context pathContext = resourceProvider.pathContext; 2811 Context pathContext = resourceProvider.pathContext;
2841 String packageFolder = _computePackageFolder(path); 2812 String packageFolder = _computePackageFolder(path);
2842 if (packageFolder == null) { 2813 if (packageFolder == null) {
2843 return pathContext.basenameWithoutExtension(path); 2814 return pathContext.basenameWithoutExtension(path);
2844 } 2815 }
2845 String packageName = pathContext.basename(packageFolder); 2816 String packageName = pathContext.basename(packageFolder);
(...skipping 25 matching lines...) Expand all
2871 } 2842 }
2872 String pubspecFolderNew = pathContext.dirname(pubspecFolder); 2843 String pubspecFolderNew = pathContext.dirname(pubspecFolder);
2873 if (pubspecFolderNew == pubspecFolder) { 2844 if (pubspecFolderNew == pubspecFolder) {
2874 return null; 2845 return null;
2875 } 2846 }
2876 pubspecFolder = pubspecFolderNew; 2847 pubspecFolder = pubspecFolderNew;
2877 } 2848 }
2878 } 2849 }
2879 2850
2880 /** 2851 /**
2881 * @return the string to display as the name of the given constructor in a pro posal name. 2852 * Return the string to display as the name of the given constructor in a
2853 * proposal name.
2882 */ 2854 */
2883 String _getConstructorProposalName(ConstructorElement constructor) { 2855 String _getConstructorProposalName(ConstructorElement constructor) {
2884 SourceBuilder proposalNameBuffer = new SourceBuilder.buffer(); 2856 StringBuffer buffer = new StringBuffer();
2885 proposalNameBuffer.append('super'); 2857 buffer.write('super');
2886 // may be named
2887 String constructorName = constructor.displayName; 2858 String constructorName = constructor.displayName;
2888 if (!constructorName.isEmpty) { 2859 if (!constructorName.isEmpty) {
2889 proposalNameBuffer.append('.'); 2860 buffer.write('.');
2890 proposalNameBuffer.append(constructorName); 2861 buffer.write(constructorName);
2891 } 2862 }
2892 // parameters 2863 buffer.write('(...)');
2893 _appendParameters(proposalNameBuffer, constructor.parameters); 2864 return buffer.toString();
2894 // done
2895 return proposalNameBuffer.toString();
2896 } 2865 }
2897 2866
2898 /** 2867 /**
2899 * Returns the [DartType] with given name from the `dart:core` library. 2868 * Returns the [DartType] with given name from the `dart:core` library.
2900 */ 2869 */
2901 DartType _getCoreType(String name) { 2870 DartType _getCoreType(String name) {
2902 List<LibraryElement> libraries = unitLibraryElement.importedLibraries; 2871 List<LibraryElement> libraries = unitLibraryElement.importedLibraries;
2903 for (LibraryElement library in libraries) { 2872 for (LibraryElement library in libraries) {
2904 if (library.isDartCore) { 2873 if (library.isDartCore) {
2905 ClassElement classElement = library.getType(name); 2874 ClassElement classElement = library.getType(name);
2906 if (classElement != null) { 2875 if (classElement != null) {
2907 return classElement.type; 2876 return classElement.type;
2908 } 2877 }
2909 return null; 2878 return null;
2910 } 2879 }
2911 } 2880 }
2912 return null; 2881 return null;
2913 } 2882 }
2914 2883
2915 /** 2884 /**
2916 * Returns an existing or just added [LinkedEditGroup] with [groupId].
2917 */
2918 LinkedEditGroup _getLinkedPosition(String groupId) {
2919 LinkedEditGroup group = linkedPositionGroups[groupId];
2920 if (group == null) {
2921 group = new LinkedEditGroup.empty();
2922 linkedPositionGroups[groupId] = group;
2923 }
2924 return group;
2925 }
2926
2927 /**
2928 * Returns an expected [DartType] of [expression], may be `null` if cannot be 2885 * Returns an expected [DartType] of [expression], may be `null` if cannot be
2929 * inferred. 2886 * inferred.
2930 */ 2887 */
2931 DartType _inferUndefinedExpressionType(Expression expression) { 2888 DartType _inferUndefinedExpressionType(Expression expression) {
2932 AstNode parent = expression.parent; 2889 AstNode parent = expression.parent;
2933 // myFunction(); 2890 // myFunction();
2934 if (parent is ExpressionStatement) { 2891 if (parent is ExpressionStatement) {
2935 if (expression is MethodInvocation) { 2892 if (expression is MethodInvocation) {
2936 return VoidTypeImpl.instance; 2893 return VoidTypeImpl.instance;
2937 } 2894 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 operatorType == TokenType.BAR_BAR) { 3001 operatorType == TokenType.BAR_BAR) {
3045 return coreTypeBool; 3002 return coreTypeBool;
3046 } 3003 }
3047 } 3004 }
3048 } 3005 }
3049 // we don't know 3006 // we don't know
3050 return null; 3007 return null;
3051 } 3008 }
3052 3009
3053 /** 3010 /**
3054 * Inserts the given [SourceBuilder] at its offset.
3055 */
3056 void _insertBuilder(SourceBuilder builder, Element target) {
3057 String text = builder.toString();
3058 _addInsertEdit(builder.offset, text, target);
3059 // add linked positions
3060 builder.linkedPositionGroups.forEach((String id, LinkedEditGroup group) {
3061 LinkedEditGroup fixGroup = _getLinkedPosition(id);
3062 group.positions.forEach((Position position) {
3063 fixGroup.addPosition(position, group.length);
3064 });
3065 group.suggestions.forEach((LinkedEditSuggestion suggestion) {
3066 fixGroup.addSuggestion(suggestion);
3067 });
3068 });
3069 }
3070
3071 /**
3072 * Returns `true` if [node] is in static context. 3011 * Returns `true` if [node] is in static context.
3073 */ 3012 */
3074 bool _inStaticContext() { 3013 bool _inStaticContext() {
3075 // constructor initializer cannot reference "this" 3014 // constructor initializer cannot reference "this"
3076 if (node.getAncestor((node) => node is ConstructorInitializer) != null) { 3015 if (node.getAncestor((node) => node is ConstructorInitializer) != null) {
3077 return true; 3016 return true;
3078 } 3017 }
3079 // field initializer cannot reference "this" 3018 // field initializer cannot reference "this"
3080 if (node.getAncestor((node) => node is FieldDeclaration) != null) { 3019 if (node.getAncestor((node) => node is FieldDeclaration) != null) {
3081 return true; 3020 return true;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3136 // TODO(brianwilkerson) We have lost the ability for clients to know whether 3075 // TODO(brianwilkerson) We have lost the ability for clients to know whether
3137 // it is safe to apply an edit. 3076 // it is safe to apply an edit.
3138 return driver.fsState.getFileForPath(filePath).exists ? 0 : -1; 3077 return driver.fsState.getFileForPath(filePath).exists ? 0 : -1;
3139 } 3078 }
3140 3079
3141 /** 3080 /**
3142 * Removes any [ParenthesizedExpression] enclosing [expr]. 3081 * Removes any [ParenthesizedExpression] enclosing [expr].
3143 * 3082 *
3144 * [exprPrecedence] - the effective precedence of [expr]. 3083 * [exprPrecedence] - the effective precedence of [expr].
3145 */ 3084 */
3146 void _removeEnclosingParentheses(Expression expr, int exprPrecedence) { 3085 void _removeEnclosingParentheses(
3086 DartFileEditBuilder builder, Expression expr, int exprPrecedence) {
3147 while (expr.parent is ParenthesizedExpression) { 3087 while (expr.parent is ParenthesizedExpression) {
3148 ParenthesizedExpression parenthesized = 3088 ParenthesizedExpression parenthesized =
3149 expr.parent as ParenthesizedExpression; 3089 expr.parent as ParenthesizedExpression;
3150 if (getExpressionParentPrecedence(parenthesized) > exprPrecedence) { 3090 if (getExpressionParentPrecedence(parenthesized) > exprPrecedence) {
3151 break; 3091 break;
3152 } 3092 }
3153 _addRemoveEdit(range.token(parenthesized.leftParenthesis)); 3093 builder.addDeletion(range.token(parenthesized.leftParenthesis));
3154 _addRemoveEdit(range.token(parenthesized.rightParenthesis)); 3094 builder.addDeletion(range.token(parenthesized.rightParenthesis));
3155 expr = parenthesized; 3095 expr = parenthesized;
3156 } 3096 }
3157 } 3097 }
3158 3098
3159 void _updateFinderWithClassMembers( 3099 void _updateFinderWithClassMembers(
3160 _ClosestElementFinder finder, ClassElement clazz) { 3100 _ClosestElementFinder finder, ClassElement clazz) {
3161 if (clazz != null) { 3101 if (clazz != null) {
3162 List<Element> members = getMembers(clazz); 3102 List<Element> members = getMembers(clazz);
3163 finder._updateList(members); 3103 finder._updateList(members);
3164 } 3104 }
3165 } 3105 }
3166 3106
3167 static void _addSuperTypeProposals(SourceBuilder sb, DartType type,
3168 [Set<DartType> alreadyAdded]) {
3169 alreadyAdded ??= new Set<DartType>();
3170 if (type is InterfaceType && alreadyAdded.add(type)) {
3171 sb.addSuggestion(LinkedEditSuggestionKind.TYPE, type.displayName);
3172 _addSuperTypeProposals(sb, type.superclass, alreadyAdded);
3173 for (InterfaceType interfaceType in type.interfaces) {
3174 _addSuperTypeProposals(sb, interfaceType, alreadyAdded);
3175 }
3176 }
3177 }
3178
3179 /**
3180 * @return the suggestions for given [Type] and [DartExpression], not empty.
3181 */
3182 static List<String> _getArgumentNameSuggestions(
3183 Set<String> excluded, DartType type, Expression expression, int index) {
3184 List<String> suggestions =
3185 getVariableNameSuggestionsForExpression(type, expression, excluded);
3186 if (suggestions.length != 0) {
3187 return suggestions;
3188 }
3189 return <String>['arg$index'];
3190 }
3191
3192 static bool _isNameOfType(String name) { 3107 static bool _isNameOfType(String name) {
3193 if (name.isEmpty) { 3108 if (name.isEmpty) {
3194 return false; 3109 return false;
3195 } 3110 }
3196 String firstLetter = name.substring(0, 1); 3111 String firstLetter = name.substring(0, 1);
3197 if (firstLetter.toUpperCase() != firstLetter) { 3112 if (firstLetter.toUpperCase() != firstLetter) {
3198 return false; 3113 return false;
3199 } 3114 }
3200 return true; 3115 return true;
3201 } 3116 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3260 } 3175 }
3261 } 3176 }
3262 } 3177 }
3263 3178
3264 void _updateList(Iterable<Element> elements) { 3179 void _updateList(Iterable<Element> elements) {
3265 for (Element element in elements) { 3180 for (Element element in elements) {
3266 _update(element); 3181 _update(element);
3267 } 3182 }
3268 } 3183 }
3269 } 3184 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/correction/flutter_util.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698