OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analysis_server.src.services.correction.fix_internal; | 5 library analysis_server.src.services.correction.fix_internal; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 import 'dart:core'; | 9 import 'dart:core'; |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 import 'package:analyzer/dart/ast/token.dart'; | 28 import 'package:analyzer/dart/ast/token.dart'; |
29 import 'package:analyzer/dart/element/element.dart'; | 29 import 'package:analyzer/dart/element/element.dart'; |
30 import 'package:analyzer/dart/element/type.dart'; | 30 import 'package:analyzer/dart/element/type.dart'; |
31 import 'package:analyzer/error/error.dart'; | 31 import 'package:analyzer/error/error.dart'; |
32 import 'package:analyzer/file_system/file_system.dart'; | 32 import 'package:analyzer/file_system/file_system.dart'; |
33 import 'package:analyzer/src/dart/ast/token.dart'; | 33 import 'package:analyzer/src/dart/ast/token.dart'; |
34 import 'package:analyzer/src/dart/ast/utilities.dart'; | 34 import 'package:analyzer/src/dart/ast/utilities.dart'; |
35 import 'package:analyzer/src/dart/element/element.dart'; | 35 import 'package:analyzer/src/dart/element/element.dart'; |
36 import 'package:analyzer/src/dart/element/member.dart'; | 36 import 'package:analyzer/src/dart/element/member.dart'; |
37 import 'package:analyzer/src/dart/element/type.dart'; | 37 import 'package:analyzer/src/dart/element/type.dart'; |
| 38 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; |
38 import 'package:analyzer/src/error/codes.dart'; | 39 import 'package:analyzer/src/error/codes.dart'; |
39 import 'package:analyzer/src/generated/engine.dart'; | 40 import 'package:analyzer/src/generated/engine.dart'; |
| 41 import 'package:analyzer/src/generated/error_verifier.dart'; |
40 import 'package:analyzer/src/generated/java_core.dart'; | 42 import 'package:analyzer/src/generated/java_core.dart'; |
41 import 'package:analyzer/src/generated/parser.dart'; | 43 import 'package:analyzer/src/generated/parser.dart'; |
42 import 'package:analyzer/src/generated/sdk.dart'; | 44 import 'package:analyzer/src/generated/sdk.dart'; |
43 import 'package:analyzer/src/generated/source.dart'; | 45 import 'package:analyzer/src/generated/source.dart'; |
44 import 'package:analyzer/src/generated/utilities_dart.dart'; | 46 import 'package:analyzer/src/generated/utilities_dart.dart'; |
45 import 'package:analyzer/src/task/dart.dart'; | 47 import 'package:analyzer/src/task/dart.dart'; |
46 import 'package:path/path.dart'; | 48 import 'package:path/path.dart'; |
47 | 49 |
48 /** | 50 /** |
49 * A predicate is a one-argument function that returns a boolean value. | 51 * A predicate is a one-argument function that returns a boolean value. |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 errorCode == | 282 errorCode == |
281 StaticWarningCode | 283 StaticWarningCode |
282 .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR || | 284 .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR || |
283 errorCode == | 285 errorCode == |
284 StaticWarningCode | 286 StaticWarningCode |
285 .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) { | 287 .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) { |
286 // make class abstract | 288 // make class abstract |
287 _addFix_makeEnclosingClassAbstract(); | 289 _addFix_makeEnclosingClassAbstract(); |
288 _addFix_createNoSuchMethod(); | 290 _addFix_createNoSuchMethod(); |
289 // implement methods | 291 // implement methods |
290 // TODO(scheglov) Fix another way to get unimplemented methods. | 292 _addFix_createMissingOverrides(); |
291 // AnalysisErrorWithProperties does not work with the new analysis driver. | |
292 if (error is AnalysisErrorWithProperties) { | |
293 AnalysisErrorWithProperties errorWithProperties = | |
294 error as AnalysisErrorWithProperties; | |
295 List<ExecutableElement> missingOverrides = errorWithProperties | |
296 .getProperty(ErrorProperty.UNIMPLEMENTED_METHODS); | |
297 _addFix_createMissingOverrides(missingOverrides); | |
298 } | |
299 } | 293 } |
300 if (errorCode == StaticWarningCode.CAST_TO_NON_TYPE || | 294 if (errorCode == StaticWarningCode.CAST_TO_NON_TYPE || |
301 errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME || | 295 errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME || |
302 errorCode == StaticWarningCode.UNDEFINED_CLASS) { | 296 errorCode == StaticWarningCode.UNDEFINED_CLASS) { |
303 _addFix_importLibrary_withType(); | 297 _addFix_importLibrary_withType(); |
304 _addFix_createClass(); | 298 _addFix_createClass(); |
305 _addFix_undefinedClass_useSimilar(); | 299 _addFix_undefinedClass_useSimilar(); |
306 } | 300 } |
307 if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) { | 301 if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) { |
308 _addFix_createConstructor_forUninitializedFinalFields(); | 302 _addFix_createConstructor_forUninitializedFinalFields(); |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 sb.append(prefix); | 1266 sb.append(prefix); |
1273 } | 1267 } |
1274 // insert source | 1268 // insert source |
1275 _insertBuilder(sb, unitElement); | 1269 _insertBuilder(sb, unitElement); |
1276 // add linked positions | 1270 // add linked positions |
1277 _addLinkedPosition('NAME', sb, rf.rangeNode(node)); | 1271 _addLinkedPosition('NAME', sb, rf.rangeNode(node)); |
1278 // add proposal | 1272 // add proposal |
1279 _addFix(DartFixKind.CREATE_LOCAL_VARIABLE, [name]); | 1273 _addFix(DartFixKind.CREATE_LOCAL_VARIABLE, [name]); |
1280 } | 1274 } |
1281 | 1275 |
1282 void _addFix_createMissingOverrides(List<ExecutableElement> elements) { | 1276 void _addFix_createMissingOverrides() { |
1283 elements = elements.toList(); | 1277 // prepare target |
1284 int numElements = elements.length; | 1278 ClassDeclaration targetClass = node.parent as ClassDeclaration; |
| 1279 ClassElement targetClassElement = targetClass.element; |
| 1280 utils.targetClassElement = targetClassElement; |
| 1281 List<ExecutableElement> elements = ErrorVerifier |
| 1282 .computeMissingOverrides( |
| 1283 context.analysisOptions.strongMode, |
| 1284 context.typeProvider, |
| 1285 context.typeSystem, |
| 1286 new InheritanceManager(unitLibraryElement), |
| 1287 targetClassElement) |
| 1288 .toList(); |
1285 // sort by name, getters before setters | 1289 // sort by name, getters before setters |
1286 elements.sort((Element a, Element b) { | 1290 elements.sort((Element a, Element b) { |
1287 int names = compareStrings(a.displayName, b.displayName); | 1291 int names = compareStrings(a.displayName, b.displayName); |
1288 if (names != 0) { | 1292 if (names != 0) { |
1289 return names; | 1293 return names; |
1290 } | 1294 } |
1291 if (a.kind == ElementKind.GETTER) { | 1295 if (a.kind == ElementKind.GETTER) { |
1292 return -1; | 1296 return -1; |
1293 } | 1297 } |
1294 return 1; | 1298 return 1; |
1295 }); | 1299 }); |
1296 // prepare target | |
1297 ClassDeclaration targetClass = node.parent as ClassDeclaration; | |
1298 utils.targetClassElement = targetClass.element; | |
1299 // prepare SourceBuilder | 1300 // prepare SourceBuilder |
1300 int insertOffset = targetClass.end - 1; | 1301 int insertOffset = targetClass.end - 1; |
1301 SourceBuilder sb = new SourceBuilder(file, insertOffset); | 1302 SourceBuilder sb = new SourceBuilder(file, insertOffset); |
1302 // EOL management | 1303 // EOL management |
1303 bool isFirst = true; | 1304 bool isFirst = true; |
1304 void addEolIfNotFirst() { | 1305 void addEolIfNotFirst() { |
1305 if (!isFirst || utils.isClassWithEmptyBody(targetClass)) { | 1306 if (!isFirst || utils.isClassWithEmptyBody(targetClass)) { |
1306 sb.append(eol); | 1307 sb.append(eol); |
1307 } | 1308 } |
1308 isFirst = false; | 1309 isFirst = false; |
1309 } | 1310 } |
1310 | 1311 |
1311 // merge getter/setter pairs into fields | 1312 // merge getter/setter pairs into fields |
1312 String prefix = utils.getIndent(1); | 1313 String prefix = utils.getIndent(1); |
| 1314 int numElements = elements.length; |
1313 for (int i = 0; i < elements.length; i++) { | 1315 for (int i = 0; i < elements.length; i++) { |
1314 ExecutableElement element = elements[i]; | 1316 ExecutableElement element = elements[i]; |
1315 if (element.kind == ElementKind.GETTER && i + 1 < elements.length) { | 1317 if (element.kind == ElementKind.GETTER && i + 1 < elements.length) { |
1316 ExecutableElement nextElement = elements[i + 1]; | 1318 ExecutableElement nextElement = elements[i + 1]; |
1317 if (nextElement.kind == ElementKind.SETTER) { | 1319 if (nextElement.kind == ElementKind.SETTER) { |
1318 // remove this and the next elements, adjust iterator | 1320 // remove this and the next elements, adjust iterator |
1319 elements.removeAt(i + 1); | 1321 elements.removeAt(i + 1); |
1320 elements.removeAt(i); | 1322 elements.removeAt(i); |
1321 i--; | 1323 i--; |
1322 numElements--; | 1324 numElements--; |
(...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2939 } | 2941 } |
2940 } | 2942 } |
2941 } | 2943 } |
2942 | 2944 |
2943 void _updateList(Iterable<Element> elements) { | 2945 void _updateList(Iterable<Element> elements) { |
2944 for (Element element in elements) { | 2946 for (Element element in elements) { |
2945 _update(element); | 2947 _update(element); |
2946 } | 2948 } |
2947 } | 2949 } |
2948 } | 2950 } |
OLD | NEW |