| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 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. |
| 7 |
| 8 library services.src.correction.name_suggestion; |
| 9 |
| 10 import 'package:analysis_services/src/correction/strings.dart'; |
| 11 import 'package:analyzer/src/generated/ast.dart'; |
| 12 import 'package:analyzer/src/generated/element.dart'; |
| 13 |
| 14 |
| 15 List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to']; |
| 16 |
| 17 /** |
| 18 * Returns possible names for a [String] variable with [text] value. |
| 19 * |
| 20 * TODO(scheglov) rename |
| 21 */ |
| 22 List<String> getVariableNameSuggestions(String text, Set<String> excluded) { |
| 23 // filter out everything except of letters and white spaces |
| 24 { |
| 25 StringBuffer sb = new StringBuffer(); |
| 26 for (int i = 0; i < text.length; i++) { |
| 27 int c = text.codeUnitAt(i); |
| 28 if (isLetter(c) || isWhitespace(c)) { |
| 29 sb.writeCharCode(c); |
| 30 } |
| 31 } |
| 32 text = sb.toString(); |
| 33 } |
| 34 // make single camel-case text |
| 35 { |
| 36 List<String> words = text.split(' '); |
| 37 StringBuffer sb = new StringBuffer(); |
| 38 for (int i = 0; i < words.length; i++) { |
| 39 String word = words[i]; |
| 40 if (i > 0) { |
| 41 word = capitalize(word); |
| 42 } |
| 43 sb.write(word); |
| 44 } |
| 45 text = sb.toString(); |
| 46 } |
| 47 // split camel-case into separate suggested names |
| 48 Set<String> res = new Set(); |
| 49 _addAll(excluded, res, _getVariableNameSuggestions(text)); |
| 50 return new List.from(res); |
| 51 } |
| 52 |
| 53 /** |
| 54 * Returns possible names for a variable with given expected type and expression
. |
| 55 * |
| 56 * TODO(scheglov) rename |
| 57 */ |
| 58 List<String> getVariableNameSuggestions2(DartType expectedType, |
| 59 Expression assignedExpression, Set<String> excluded) { |
| 60 Set<String> res = new Set(); |
| 61 // use expression |
| 62 if (assignedExpression != null) { |
| 63 String nameFromExpression = _getBaseNameFromExpression(assignedExpression); |
| 64 if (nameFromExpression != null) { |
| 65 nameFromExpression = removeStart(nameFromExpression, '_'); |
| 66 _addAll(excluded, res, _getVariableNameSuggestions(nameFromExpression)); |
| 67 } |
| 68 String nameFromParent = |
| 69 _getBaseNameFromLocationInParent(assignedExpression); |
| 70 if (nameFromParent != null) { |
| 71 _addAll(excluded, res, _getVariableNameSuggestions(nameFromParent)); |
| 72 } |
| 73 } |
| 74 // use type |
| 75 if (expectedType != null && !expectedType.isDynamic) { |
| 76 String typeName = expectedType.name; |
| 77 if ('int' == typeName) { |
| 78 _addSingleCharacterName(excluded, res, 0x69); |
| 79 } else if ('double' == typeName) { |
| 80 _addSingleCharacterName(excluded, res, 0x64); |
| 81 } else if ('String' == typeName) { |
| 82 _addSingleCharacterName(excluded, res, 0x73); |
| 83 } else { |
| 84 _addAll(excluded, res, _getVariableNameSuggestions(typeName)); |
| 85 } |
| 86 res.remove(typeName); |
| 87 } |
| 88 // done |
| 89 return new List.from(res); |
| 90 } |
| 91 |
| 92 /** |
| 93 * Adds [toAdd] items which are not excluded. |
| 94 */ |
| 95 void _addAll(Set<String> excluded, Set<String> result, Iterable<String> toAdd) { |
| 96 for (String item in toAdd) { |
| 97 // add name based on "item", but not "excluded" |
| 98 for (int suffix = 1; ; suffix++) { |
| 99 // prepare name, just "item" or "item2", "item3", etc |
| 100 String name = item; |
| 101 if (suffix > 1) { |
| 102 name += suffix.toString(); |
| 103 } |
| 104 // add once found not excluded |
| 105 if (!excluded.contains(name)) { |
| 106 result.add(name); |
| 107 break; |
| 108 } |
| 109 } |
| 110 } |
| 111 } |
| 112 |
| 113 /** |
| 114 * Adds to [result] either [c] or the first ASCII character after it. |
| 115 */ |
| 116 void _addSingleCharacterName(Set<String> excluded, Set<String> result, int c) { |
| 117 while (c < 0x7A) { |
| 118 String name = new String.fromCharCode(c); |
| 119 // may be done |
| 120 if (!excluded.contains(name)) { |
| 121 result.add(name); |
| 122 break; |
| 123 } |
| 124 // next character |
| 125 c = c + 1; |
| 126 } |
| 127 } |
| 128 |
| 129 String _getBaseNameFromExpression(Expression expression) { |
| 130 String name = null; |
| 131 // e as Type |
| 132 if (expression is AsExpression) { |
| 133 AsExpression asExpression = expression as AsExpression; |
| 134 expression = asExpression.expression; |
| 135 } |
| 136 // analyze expressions |
| 137 if (expression is SimpleIdentifier) { |
| 138 SimpleIdentifier node = expression; |
| 139 return node.name; |
| 140 } else if (expression is PrefixedIdentifier) { |
| 141 PrefixedIdentifier node = expression; |
| 142 return node.identifier.name; |
| 143 } else if (expression is MethodInvocation) { |
| 144 name = expression.methodName.name; |
| 145 } else if (expression is InstanceCreationExpression) { |
| 146 InstanceCreationExpression creation = expression; |
| 147 ConstructorName constructorName = creation.constructorName; |
| 148 TypeName typeName = constructorName.type; |
| 149 if (typeName != null) { |
| 150 Identifier typeNameIdentifier = typeName.name; |
| 151 // new ClassName() |
| 152 if (typeNameIdentifier is SimpleIdentifier) { |
| 153 return typeNameIdentifier.name; |
| 154 } |
| 155 // new prefix.name(); |
| 156 if (typeNameIdentifier is PrefixedIdentifier) { |
| 157 PrefixedIdentifier prefixed = typeNameIdentifier; |
| 158 // new prefix.ClassName() |
| 159 if (prefixed.prefix.staticElement is PrefixElement) { |
| 160 return prefixed.identifier.name; |
| 161 } |
| 162 // new ClassName.constructorName() |
| 163 return prefixed.prefix.name; |
| 164 } |
| 165 } |
| 166 } |
| 167 // strip known prefixes |
| 168 if (name != null) { |
| 169 for (int i = 0; i < _KNOWN_METHOD_NAME_PREFIXES.length; i++) { |
| 170 String curr = _KNOWN_METHOD_NAME_PREFIXES[i]; |
| 171 if (name.startsWith(curr)) { |
| 172 if (name == curr) { |
| 173 return null; |
| 174 } else if (isUpperCase(name.codeUnitAt(curr.length))) { |
| 175 return name.substring(curr.length); |
| 176 } |
| 177 } |
| 178 } |
| 179 } |
| 180 // done |
| 181 return name; |
| 182 } |
| 183 |
| 184 String _getBaseNameFromLocationInParent(Expression expression) { |
| 185 // value in named expression |
| 186 if (expression.parent is NamedExpression) { |
| 187 NamedExpression namedExpression = expression.parent as NamedExpression; |
| 188 if (identical(namedExpression.expression, expression)) { |
| 189 return namedExpression.name.label.name; |
| 190 } |
| 191 } |
| 192 // positional argument |
| 193 { |
| 194 ParameterElement parameter = expression.propagatedParameterElement; |
| 195 if (parameter == null) { |
| 196 parameter = expression.staticParameterElement; |
| 197 } |
| 198 if (parameter != null) { |
| 199 return parameter.displayName; |
| 200 } |
| 201 } |
| 202 // unknown |
| 203 return null; |
| 204 } |
| 205 |
| 206 /** |
| 207 * REturns all variants of names by removing leading words one by one. |
| 208 */ |
| 209 List<String> _getVariableNameSuggestions(String name) { |
| 210 List<String> result = []; |
| 211 List<String> parts = |
| 212 name.split('(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])'); |
| 213 for (int i = 0; i < parts.length; i++) { |
| 214 var s1 = parts[i].toLowerCase(); |
| 215 var s2 = parts.skip(i + 1).join(); |
| 216 String suggestion = '$s1$s2'; |
| 217 result.add(suggestion); |
| 218 } |
| 219 return result; |
| 220 } |
| OLD | NEW |