| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library services.src.correction.fix; | 8 library services.src.correction.fix; |
| 9 | 9 |
| 10 import 'package:analysis_services/correction/change.dart'; | 10 import 'package:analysis_services/correction/change.dart'; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 /** | 30 /** |
| 31 * A predicate is a one-argument function that returns a boolean value. | 31 * A predicate is a one-argument function that returns a boolean value. |
| 32 */ | 32 */ |
| 33 typedef bool Predicate<E>(E argument); | 33 typedef bool Predicate<E>(E argument); |
| 34 | 34 |
| 35 | 35 |
| 36 /** | 36 /** |
| 37 * The computer for Dart fixes. | 37 * The computer for Dart fixes. |
| 38 */ | 38 */ |
| 39 class FixProcessor { | 39 class FixProcessor { |
| 40 static const int MAX_LEVENSHTEIN_DISTANCE = 3; |
| 41 |
| 40 final SearchEngine searchEngine; | 42 final SearchEngine searchEngine; |
| 41 final Source source; | 43 final Source source; |
| 42 final String file; | 44 final String file; |
| 43 final CompilationUnit unit; | 45 final CompilationUnit unit; |
| 44 final AnalysisError error; | 46 final AnalysisError error; |
| 45 CompilationUnitElement unitElement; | 47 CompilationUnitElement unitElement; |
| 46 LibraryElement unitLibraryElement; | 48 LibraryElement unitLibraryElement; |
| 47 | 49 |
| 48 final List<Edit> edits = <Edit>[]; | 50 final List<Edit> edits = <Edit>[]; |
| 49 final Map<String, LinkedPositionGroup> linkedPositionGroups = <String, | 51 final Map<String, LinkedPositionGroup> linkedPositionGroups = <String, |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 var instanceCreation = coveredNode as InstanceCreationExpression; | 1024 var instanceCreation = coveredNode as InstanceCreationExpression; |
| 1023 _addReplaceEdit(rf.rangeToken(instanceCreation.keyword), "const"); | 1025 _addReplaceEdit(rf.rangeToken(instanceCreation.keyword), "const"); |
| 1024 _addFix(FixKind.USE_CONST, []); | 1026 _addFix(FixKind.USE_CONST, []); |
| 1025 } | 1027 } |
| 1026 } | 1028 } |
| 1027 | 1029 |
| 1028 void _addFix_undefinedClass_useSimilar() { | 1030 void _addFix_undefinedClass_useSimilar() { |
| 1029 if (_mayBeTypeIdentifier(node)) { | 1031 if (_mayBeTypeIdentifier(node)) { |
| 1030 String name = (node as SimpleIdentifier).name; | 1032 String name = (node as SimpleIdentifier).name; |
| 1031 _ClosestElementFinder finder = | 1033 _ClosestElementFinder finder = |
| 1032 new _ClosestElementFinder(name, (Element element) => element is ClassE
lement); | 1034 new _ClosestElementFinder( |
| 1035 name, |
| 1036 (Element element) => element is ClassElement, |
| 1037 MAX_LEVENSHTEIN_DISTANCE); |
| 1033 // find closest element | 1038 // find closest element |
| 1034 { | 1039 { |
| 1035 // elements of this library | 1040 // elements of this library |
| 1036 for (CompilationUnitElement unit in unitLibraryElement.units) { | 1041 for (CompilationUnitElement unit in unitLibraryElement.units) { |
| 1037 finder._updateList(unit.types); | 1042 finder._updateList(unit.types); |
| 1038 } | 1043 } |
| 1039 // elements from imports | 1044 // elements from imports |
| 1040 for (ImportElement importElement in unitLibraryElement.imports) { | 1045 for (ImportElement importElement in unitLibraryElement.imports) { |
| 1041 if (importElement.prefix == null) { | 1046 if (importElement.prefix == null) { |
| 1042 Map<String, Element> namespace = getImportNamespace(importElement); | 1047 Map<String, Element> namespace = getImportNamespace(importElement); |
| 1043 finder._updateList(namespace.values); | 1048 finder._updateList(namespace.values); |
| 1044 } | 1049 } |
| 1045 } | 1050 } |
| 1046 } | 1051 } |
| 1047 // if we have close enough element, suggest to use it | 1052 // if we have close enough element, suggest to use it |
| 1048 if (finder != null && finder._distance < 5) { | 1053 if (finder._element != null) { |
| 1049 String closestName = finder._element.name; | 1054 String closestName = finder._element.name; |
| 1050 _addReplaceEdit(rf.rangeNode(node), closestName); | 1055 _addReplaceEdit(rf.rangeNode(node), closestName); |
| 1051 // add proposal | 1056 // add proposal |
| 1052 if (closestName != null) { | 1057 if (closestName != null) { |
| 1053 _addFix(FixKind.CHANGE_TO, [closestName]); | 1058 _addFix(FixKind.CHANGE_TO, [closestName]); |
| 1054 } | 1059 } |
| 1055 } | 1060 } |
| 1056 } | 1061 } |
| 1057 } | 1062 } |
| 1058 | 1063 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 // add proposal | 1105 // add proposal |
| 1101 _addFix(FixKind.CREATE_FUNCTION, [name]); | 1106 _addFix(FixKind.CREATE_FUNCTION, [name]); |
| 1102 } | 1107 } |
| 1103 | 1108 |
| 1104 void _addFix_undefinedFunction_useSimilar() { | 1109 void _addFix_undefinedFunction_useSimilar() { |
| 1105 if (node is SimpleIdentifier) { | 1110 if (node is SimpleIdentifier) { |
| 1106 String name = (node as SimpleIdentifier).name; | 1111 String name = (node as SimpleIdentifier).name; |
| 1107 _ClosestElementFinder finder = | 1112 _ClosestElementFinder finder = |
| 1108 new _ClosestElementFinder( | 1113 new _ClosestElementFinder( |
| 1109 name, | 1114 name, |
| 1110 (Element element) => element is FunctionElement); | 1115 (Element element) => element is FunctionElement, |
| 1116 MAX_LEVENSHTEIN_DISTANCE); |
| 1111 // this library | 1117 // this library |
| 1112 for (CompilationUnitElement unit in unitLibraryElement.units) { | 1118 for (CompilationUnitElement unit in unitLibraryElement.units) { |
| 1113 finder._updateList(unit.functions); | 1119 finder._updateList(unit.functions); |
| 1114 } | 1120 } |
| 1115 // imports | 1121 // imports |
| 1116 for (ImportElement importElement in unitLibraryElement.imports) { | 1122 for (ImportElement importElement in unitLibraryElement.imports) { |
| 1117 if (importElement.prefix == null) { | 1123 if (importElement.prefix == null) { |
| 1118 Map<String, Element> namespace = getImportNamespace(importElement); | 1124 Map<String, Element> namespace = getImportNamespace(importElement); |
| 1119 finder._updateList(namespace.values); | 1125 finder._updateList(namespace.values); |
| 1120 } | 1126 } |
| 1121 } | 1127 } |
| 1122 // if we have close enough element, suggest to use it | 1128 // if we have close enough element, suggest to use it |
| 1123 String closestName = null; | 1129 if (finder._element != null) { |
| 1124 if (finder != null && finder._distance < 5) { | 1130 String closestName = finder._element.name; |
| 1125 closestName = finder._element.name; | |
| 1126 _addReplaceEdit(rf.rangeNode(node), closestName); | 1131 _addReplaceEdit(rf.rangeNode(node), closestName); |
| 1127 _addFix(FixKind.CHANGE_TO, [closestName]); | 1132 _addFix(FixKind.CHANGE_TO, [closestName]); |
| 1128 } | 1133 } |
| 1129 } | 1134 } |
| 1130 } | 1135 } |
| 1131 | 1136 |
| 1132 void _addFix_undefinedMethod_create() { | 1137 void _addFix_undefinedMethod_create() { |
| 1133 if (node is SimpleIdentifier && node.parent is MethodInvocation) { | 1138 if (node is SimpleIdentifier && node.parent is MethodInvocation) { |
| 1134 String name = (node as SimpleIdentifier).name; | 1139 String name = (node as SimpleIdentifier).name; |
| 1135 MethodInvocation invocation = node.parent as MethodInvocation; | 1140 MethodInvocation invocation = node.parent as MethodInvocation; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 sb.endPosition(); | 1245 sb.endPosition(); |
| 1241 } | 1246 } |
| 1242 } | 1247 } |
| 1243 } | 1248 } |
| 1244 | 1249 |
| 1245 void _addFix_undefinedMethod_useSimilar() { | 1250 void _addFix_undefinedMethod_useSimilar() { |
| 1246 if (node is SimpleIdentifier && node.parent is MethodInvocation) { | 1251 if (node is SimpleIdentifier && node.parent is MethodInvocation) { |
| 1247 MethodInvocation invocation = node.parent as MethodInvocation; | 1252 MethodInvocation invocation = node.parent as MethodInvocation; |
| 1248 String name = (node as SimpleIdentifier).name; | 1253 String name = (node as SimpleIdentifier).name; |
| 1249 _ClosestElementFinder finder = | 1254 _ClosestElementFinder finder = |
| 1250 new _ClosestElementFinder(name, (Element element) { | 1255 new _ClosestElementFinder( |
| 1251 return element is MethodElement && !element.isOperator; | 1256 name, |
| 1252 }); | 1257 (Element element) => element is MethodElement && !element.isOperat
or, |
| 1258 MAX_LEVENSHTEIN_DISTANCE); |
| 1253 // unqualified invocation | 1259 // unqualified invocation |
| 1254 Expression target = invocation.realTarget; | 1260 Expression target = invocation.realTarget; |
| 1255 if (target == null) { | 1261 if (target == null) { |
| 1256 ClassDeclaration clazz = | 1262 ClassDeclaration clazz = |
| 1257 invocation.getAncestor((node) => node is ClassDeclaration); | 1263 invocation.getAncestor((node) => node is ClassDeclaration); |
| 1258 if (clazz != null) { | 1264 if (clazz != null) { |
| 1259 ClassElement classElement = clazz.element; | 1265 ClassElement classElement = clazz.element; |
| 1260 _updateFinderWithClassMembers(finder, classElement); | 1266 _updateFinderWithClassMembers(finder, classElement); |
| 1261 } | 1267 } |
| 1262 } else { | 1268 } else { |
| 1263 DartType type = target.bestType; | 1269 DartType type = target.bestType; |
| 1264 if (type is InterfaceType) { | 1270 if (type is InterfaceType) { |
| 1265 ClassElement classElement = type.element; | 1271 ClassElement classElement = type.element; |
| 1266 _updateFinderWithClassMembers(finder, classElement); | 1272 _updateFinderWithClassMembers(finder, classElement); |
| 1267 } | 1273 } |
| 1268 } | 1274 } |
| 1269 // if we have close enough element, suggest to use it | 1275 // if we have close enough element, suggest to use it |
| 1270 String closestName = null; | 1276 if (finder._element != null) { |
| 1271 if (finder != null && finder._distance < 5) { | 1277 String closestName = finder._element.name; |
| 1272 closestName = finder._element.name; | |
| 1273 _addReplaceEdit(rf.rangeNode(node), closestName); | 1278 _addReplaceEdit(rf.rangeNode(node), closestName); |
| 1274 _addFix(FixKind.CHANGE_TO, [closestName]); | 1279 _addFix(FixKind.CHANGE_TO, [closestName]); |
| 1275 } | 1280 } |
| 1276 } | 1281 } |
| 1277 } | 1282 } |
| 1278 | 1283 |
| 1279 void _addFix_useEffectiveIntegerDivision() { | 1284 void _addFix_useEffectiveIntegerDivision() { |
| 1280 for (AstNode n = node; n != null; n = n.parent) { | 1285 for (AstNode n = node; n != null; n = n.parent) { |
| 1281 if (n is MethodInvocation && | 1286 if (n is MethodInvocation && |
| 1282 n.offset == errorOffset && | 1287 n.offset == errorOffset && |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1916 } | 1921 } |
| 1917 | 1922 |
| 1918 /** | 1923 /** |
| 1919 * Helper for finding [Element] with name closest to the given. | 1924 * Helper for finding [Element] with name closest to the given. |
| 1920 */ | 1925 */ |
| 1921 class _ClosestElementFinder { | 1926 class _ClosestElementFinder { |
| 1922 final String _targetName; | 1927 final String _targetName; |
| 1923 final Predicate<Element> _predicate; | 1928 final Predicate<Element> _predicate; |
| 1924 | 1929 |
| 1925 Element _element = null; | 1930 Element _element = null; |
| 1926 int _distance = 1 << 10; | 1931 int _distance; |
| 1927 | 1932 |
| 1928 _ClosestElementFinder(this._targetName, this._predicate); | 1933 _ClosestElementFinder(this._targetName, this._predicate, this._distance); |
| 1929 | 1934 |
| 1930 void _update(Element element) { | 1935 void _update(Element element) { |
| 1931 if (_predicate(element)) { | 1936 if (_predicate(element)) { |
| 1932 int memberDistance = getLevenshteinDistance(element.name, _targetName); | 1937 int memberDistance = levenshtein(element.name, _targetName, _distance); |
| 1933 if (memberDistance < _distance) { | 1938 if (memberDistance < _distance) { |
| 1934 _element = element; | 1939 _element = element; |
| 1935 _distance = memberDistance; | 1940 _distance = memberDistance; |
| 1936 } | 1941 } |
| 1937 } | 1942 } |
| 1938 } | 1943 } |
| 1939 | 1944 |
| 1940 void _updateList(Iterable<Element> elements) { | 1945 void _updateList(Iterable<Element> elements) { |
| 1941 for (Element element in elements) { | 1946 for (Element element in elements) { |
| 1942 _update(element); | 1947 _update(element); |
| 1943 } | 1948 } |
| 1944 } | 1949 } |
| 1945 } | 1950 } |
| 1946 | 1951 |
| 1947 /** | 1952 /** |
| 1948 * Describes the location for a newly created [ConstructorDeclaration]. | 1953 * Describes the location for a newly created [ConstructorDeclaration]. |
| 1949 */ | 1954 */ |
| 1950 class _ConstructorLocation { | 1955 class _ConstructorLocation { |
| 1951 final String _prefix; | 1956 final String _prefix; |
| 1952 final int _offset; | 1957 final int _offset; |
| 1953 final String _suffix; | 1958 final String _suffix; |
| 1954 | 1959 |
| 1955 _ConstructorLocation(this._prefix, this._offset, this._suffix); | 1960 _ConstructorLocation(this._prefix, this._offset, this._suffix); |
| 1956 } | 1961 } |
| OLD | NEW |