| Index: editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/internal/corext/codemanipulation/StubUtility.java
|
| diff --git a/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/internal/corext/codemanipulation/StubUtility.java b/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/internal/corext/codemanipulation/StubUtility.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b5e6a28c9c8d9a99b28edcfe11cb0756bb3a2641
|
| --- /dev/null
|
| +++ b/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/internal/corext/codemanipulation/StubUtility.java
|
| @@ -0,0 +1,186 @@
|
| +/*
|
| + * Copyright (c) 2012, the Dart project authors.
|
| + *
|
| + * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
|
| + * in compliance with the License. You may obtain a copy of the License at
|
| + *
|
| + * http://www.eclipse.org/legal/epl-v10.html
|
| + *
|
| + * Unless required by applicable law or agreed to in writing, software distributed under the License
|
| + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
| + * or implied. See the License for the specific language governing permissions and limitations under
|
| + * the License.
|
| + */
|
| +
|
| +package com.google.dart.tools.internal.corext.codemanipulation;
|
| +
|
| +import static com.google.dart.tools.core.dom.PropertyDescriptorHelper.DART_INVOCATION_ARGS;
|
| +import static com.google.dart.tools.core.dom.PropertyDescriptorHelper.DART_NAMED_EXPRESSION_EXPRESSION;
|
| +import static com.google.dart.tools.core.dom.PropertyDescriptorHelper.getLocationInParent;
|
| +
|
| +import com.google.common.collect.Lists;
|
| +import com.google.common.collect.Sets;
|
| +import com.google.dart.compiler.ast.DartBinaryExpression;
|
| +import com.google.dart.compiler.ast.DartExpression;
|
| +import com.google.dart.compiler.ast.DartIdentifier;
|
| +import com.google.dart.compiler.ast.DartInvocation;
|
| +import com.google.dart.compiler.ast.DartMethodInvocation;
|
| +import com.google.dart.compiler.ast.DartNamedExpression;
|
| +import com.google.dart.compiler.ast.DartPropertyAccess;
|
| +import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
|
| +import com.google.dart.compiler.parser.Token;
|
| +import com.google.dart.compiler.resolver.MethodElement;
|
| +import com.google.dart.compiler.resolver.VariableElement;
|
| +import com.google.dart.compiler.type.Type;
|
| +import com.google.dart.compiler.type.TypeKind;
|
| +import com.google.dart.compiler.util.apache.StringUtils;
|
| +import com.google.dart.tools.core.dom.StructuralPropertyDescriptor;
|
| +import com.google.dart.tools.internal.corext.refactoring.code.ExtractUtils;
|
| +
|
| +import java.util.Collection;
|
| +import java.util.List;
|
| +import java.util.Set;
|
| +
|
| +/**
|
| + * @coverage dart.editor.ui.corext
|
| + */
|
| +public class StubUtility {
|
| + private static final String[] KNOWN_METHOD_NAME_PREFIXES = {"get", "is", "to"};
|
| +
|
| + public static String[] getVariableNameSuggestions(Type expectedType,
|
| + DartExpression assignedExpression, Set<String> excluded) {
|
| + Set<String> res = Sets.newLinkedHashSet();
|
| + // use expression
|
| + if (assignedExpression != null) {
|
| + String nameFromExpression = getBaseNameFromExpression(assignedExpression);
|
| + if (nameFromExpression != null) {
|
| + addAll(excluded, res, getVariableNameSuggestions(nameFromExpression));
|
| + }
|
| +
|
| + String nameFromParent = getBaseNameFromLocationInParent(assignedExpression);
|
| + if (nameFromParent != null) {
|
| + addAll(excluded, res, getVariableNameSuggestions(nameFromParent));
|
| + }
|
| + }
|
| + // use type
|
| + if (expectedType != null && TypeKind.of(expectedType) != TypeKind.DYNAMIC) {
|
| + String typeName = ExtractUtils.getTypeSource(expectedType);
|
| + if ("int".equals(typeName)) {
|
| + addSingleCharacterName(excluded, res, 'i');
|
| + } else if ("double".equals(typeName)) {
|
| + addSingleCharacterName(excluded, res, 'd');
|
| + } else {
|
| + typeName = StringUtils.substringBefore(typeName, "<");
|
| + addAll(excluded, res, getVariableNameSuggestions(typeName));
|
| + }
|
| + res.remove(typeName);
|
| + }
|
| + // done
|
| + return res.toArray(new String[res.size()]);
|
| + }
|
| +
|
| + /**
|
| + * Adds "toAdd" items which are not excluded.
|
| + */
|
| + private static void addAll(Set<String> excluded, Set<String> result, Collection<String> toAdd) {
|
| + for (String item : toAdd) {
|
| + // add name based on "item", but not "excluded"
|
| + for (int suffix = 1;; suffix++) {
|
| + // prepare name, just "item" or "item2", "item3", etc
|
| + String name = item;
|
| + if (suffix > 1) {
|
| + name += suffix;
|
| + }
|
| + // add once found not excluded
|
| + if (!excluded.contains(name)) {
|
| + result.add(name);
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + private static void addSingleCharacterName(Set<String> excluded, Set<String> result, char c) {
|
| + while (c < 'z') {
|
| + String name = String.valueOf(c);
|
| + // may be done
|
| + if (!excluded.contains(name)) {
|
| + result.add(name);
|
| + break;
|
| + }
|
| + // next character
|
| + c = (char) (c + 1);
|
| + }
|
| + }
|
| +
|
| + private static String getBaseNameFromExpression(DartExpression expression) {
|
| + String name = null;
|
| + if (expression instanceof DartBinaryExpression) {
|
| + DartBinaryExpression binaryExpression = (DartBinaryExpression) expression;
|
| + if (binaryExpression.getOperator() == Token.AS) {
|
| + expression = binaryExpression.getArg1();
|
| + }
|
| + }
|
| + if (expression instanceof DartIdentifier) {
|
| + DartIdentifier node = (DartIdentifier) expression;
|
| + return node.getName();
|
| + } else if (expression instanceof DartPropertyAccess) {
|
| + DartPropertyAccess node = (DartPropertyAccess) expression;
|
| + return node.getName().getName();
|
| + } else if (expression instanceof DartMethodInvocation) {
|
| + name = ((DartMethodInvocation) expression).getFunctionName().getName();
|
| + } else if (expression instanceof DartUnqualifiedInvocation) {
|
| + name = ((DartUnqualifiedInvocation) expression).getTarget().getName();
|
| + }
|
| + if (name != null) {
|
| + for (int i = 0; i < KNOWN_METHOD_NAME_PREFIXES.length; i++) {
|
| + String curr = KNOWN_METHOD_NAME_PREFIXES[i];
|
| + if (name.startsWith(curr)) {
|
| + if (name.equals(curr)) {
|
| + return null; // don't suggest 'get' as variable name
|
| + } else if (Character.isUpperCase(name.charAt(curr.length()))) {
|
| + return name.substring(curr.length());
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return name;
|
| + }
|
| +
|
| + private static String getBaseNameFromLocationInParent(DartExpression expression) {
|
| + StructuralPropertyDescriptor location = getLocationInParent(expression);
|
| + // value in named expression
|
| + if (location == DART_NAMED_EXPRESSION_EXPRESSION) {
|
| + return ((DartNamedExpression) expression.getParent()).getName().getName();
|
| + }
|
| + // positional argument
|
| + if (location == DART_INVOCATION_ARGS) {
|
| + DartInvocation invocation = (DartInvocation) expression.getParent();
|
| + MethodElement invocationElement = (MethodElement) invocation.getElement();
|
| + Object parameterId = expression.getInvocationParameterId();
|
| + if (parameterId instanceof Integer) {
|
| + int index = ((Integer) parameterId).intValue();
|
| + List<VariableElement> parameters = invocationElement.getParameters();
|
| + if (index < parameters.size()) {
|
| + return parameters.get(index).getName();
|
| + }
|
| + }
|
| + }
|
| + // unknown
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * @return all variants of names by removing leading words by one.
|
| + */
|
| + private static List<String> getVariableNameSuggestions(String name) {
|
| + List<String> result = Lists.newArrayList();
|
| + String[] parts = name.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
|
| + for (int i = 0; i < parts.length; i++) {
|
| + String suggestion = parts[i].toLowerCase() + StringUtils.join(parts, "", i + 1, parts.length);
|
| + result.add(suggestion);
|
| + }
|
| + return result;
|
| + }
|
| +
|
| +}
|
|
|