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

Side by Side Diff: pkg/analysis_services/lib/src/correction/fix.dart

Issue 417263003: Use a Levenshtein calculating algorithm with a threshold. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes for review comments Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analysis_services/lib/src/correction/levenshtein.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 // 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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_services/lib/src/correction/levenshtein.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698