new "collecting" name validator

This commit is contained in:
Alexander Kirillin
2013-05-07 20:12:22 +04:00
parent 5499bea181
commit 1783f8df3a
5 changed files with 73 additions and 46 deletions
@@ -62,9 +62,10 @@ public class JetNameSuggester {
* 3. Method call expression according to method callee expression * 3. Method call expression according to method callee expression
* @param expression to suggest name for variable * @param expression to suggest name for variable
* @param validator to check scope for such names * @param validator to check scope for such names
* @param defaultName
* @return possible names * @return possible names
*/ */
public static String[] suggestNames(JetExpression expression, JetNameValidator validator) { public static String[] suggestNames(JetExpression expression, JetNameValidator validator, String defaultName) {
ArrayList<String> result = new ArrayList<String>(); ArrayList<String> result = new ArrayList<String>();
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) expression.getContainingFile()).getBindingContext(); BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) expression.getContainingFile()).getBindingContext();
@@ -74,13 +75,21 @@ public class JetNameSuggester {
} }
addNamesForExpression(result, expression, validator); addNamesForExpression(result, expression, validator);
if (result.isEmpty()) addName(result, "value", validator); if (result.isEmpty()) addName(result, defaultName, validator);
return ArrayUtil.toStringArray(result); return ArrayUtil.toStringArray(result);
} }
public static String[] suggestNames(JetType type, JetNameValidator validator, String defaultName) {
ArrayList<String> result = new ArrayList<String>();
addNamesForType(result, type, validator);
if (result.isEmpty()) addName(result, defaultName, validator);
return ArrayUtil.toStringArray(result);
}
private static void addNamesForType(ArrayList<String> result, JetType jetType, JetNameValidator validator) { private static void addNamesForType(ArrayList<String> result, JetType jetType, JetNameValidator validator) {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
JetTypeChecker typeChecker = JetTypeChecker.INSTANCE; JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
jetType = TypeUtils.makeNotNullable(jetType); // wipe out '?'
if (ErrorUtils.containsErrorType(jetType)) return; if (ErrorUtils.containsErrorType(jetType)) return;
if (typeChecker.equalTypes(builtIns.getBooleanType(), jetType)) { if (typeChecker.equalTypes(builtIns.getBooleanType(), jetType)) {
addName(result, "b", validator); addName(result, "b", validator);
@@ -17,20 +17,66 @@
package org.jetbrains.jet.plugin.refactoring; package org.jetbrains.jet.plugin.refactoring;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
/** /**
* User: Alefas * User: Alefas
* Date: 07.02.12 * Date: 07.02.12
*/ */
public interface JetNameValidator { public abstract class JetNameValidator {
private final Project project;
protected JetNameValidator(Project project) {
this.project = project;
}
public static JetNameValidator getEmptyValidator(final Project project) {
return new JetNameValidator(project) {
@Override
protected boolean validateInner(String name) {
return true;
}
};
}
public static JetNameValidator getCollectingValidator(final Project project) {
return new JetNameValidator(project) {
private final Set<String> suggestedSet = new HashSet<String>();
@Override
protected boolean validateInner(String name) {
return !suggestedSet.contains(name);
}
@Override
public String validateName(String name) {
String validatedName = super.validateName(name);
suggestedSet.add(validatedName);
return validatedName;
}
};
}
/** /**
* Validates name, and slightly improves it by adding number to name in case of conflicts * Validates name, and slightly improves it by adding number to name in case of conflicts
* @param name to check it in scope * @param name to check it in scope
* @return name or nameI, where I is number * @return name or nameI, where I is number
*/ */
@Nullable public String validateName(String name) {
String validateName(String name); if (validateInner(name)) return name;
int i = 1;
while (!validateInner(name + i)) {
++i;
}
Project getProject(); return name + i;
}
protected abstract boolean validateInner(String name);
public Project getProject() {
return project;
}
} }
@@ -16,17 +16,15 @@
package org.jetbrains.jet.plugin.refactoring; package org.jetbrains.jet.plugin.refactoring;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.codeInsight.TipsManager;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetVisitorVoid; import org.jetbrains.jet.lang.psi.JetVisitorVoid;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.plugin.codeInsight.TipsManager;
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
import java.util.Collection; import java.util.Collection;
@@ -35,41 +33,19 @@ import java.util.Collection;
* User: Alefas * User: Alefas
* Date: 07.02.12 * Date: 07.02.12
*/ */
public class JetNameValidatorImpl implements JetNameValidator { public class JetNameValidatorImpl extends JetNameValidator {
public static JetNameValidator getEmptyValidator(final Project project) {
return new JetNameValidator() {
@Override
public String validateName(String name) {
return name;
}
@Override
public Project getProject() {
return project;
}
};
}
private final PsiElement myContainer; private final PsiElement myContainer;
private PsiElement myAnchor; private final PsiElement myAnchor;
BindingContext myBindingContext; private BindingContext myBindingContext;
public JetNameValidatorImpl(PsiElement container, PsiElement anchor) { public JetNameValidatorImpl(PsiElement container, PsiElement anchor) {
super(container.getProject());
myContainer = container; myContainer = container;
myAnchor = anchor; myAnchor = anchor;
} }
@Nullable @Override
public String validateName(String name) { protected boolean validateInner(String name) {
if (validateInner(name)) return name;
int i = 1;
while (true) {
if (validateInner(name + i)) return name + i;
++i;
}
}
private boolean validateInner(String name) {
PsiElement sibling; PsiElement sibling;
if (myAnchor != null) { if (myAnchor != null) {
sibling = myAnchor; sibling = myAnchor;
@@ -119,8 +95,4 @@ public class JetNameValidatorImpl implements JetNameValidator {
sibling.accept(visitor); sibling.accept(visitor);
return result.get(); return result.get();
} }
public Project getProject() {
return myContainer.getProject();
}
} }
@@ -180,7 +180,7 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
calculateAnchor(commonParent, calculateAnchor(commonParent,
commonContainer, commonContainer,
allReplaces)); allReplaces));
String[] suggestedNames = JetNameSuggester.suggestNames(expression, validator); String[] suggestedNames = JetNameSuggester.suggestNames(expression, validator, "value");
final LinkedHashSet<String> suggestedNamesSet = new LinkedHashSet<String>(); final LinkedHashSet<String> suggestedNamesSet = new LinkedHashSet<String>();
Collections.addAll(suggestedNamesSet, suggestedNames); Collections.addAll(suggestedNamesSet, suggestedNames);
final Ref<JetProperty> propertyRef = new Ref<JetProperty>(); final Ref<JetProperty> propertyRef = new Ref<JetProperty>();
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.PluginTestCaseBase; import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester;
import org.jetbrains.jet.plugin.refactoring.JetNameValidatorImpl; import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil; import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil;
import java.util.Arrays; import java.util.Arrays;
@@ -96,7 +96,7 @@ public class JetNameSuggesterTest extends LightCodeInsightFixtureTestCase {
JetRefactoringUtil.selectExpression(myFixture.getEditor(), file, new JetRefactoringUtil.SelectExpressionCallback() { JetRefactoringUtil.selectExpression(myFixture.getEditor(), file, new JetRefactoringUtil.SelectExpressionCallback() {
@Override @Override
public void run(@Nullable JetExpression expression) { public void run(@Nullable JetExpression expression) {
String[] names = JetNameSuggester.suggestNames(expression, JetNameValidatorImpl.getEmptyValidator(getProject())); String[] names = JetNameSuggester.suggestNames(expression, JetNameValidator.getEmptyValidator(getProject()), "value");
Arrays.sort(names); Arrays.sort(names);
String result = StringUtil.join(names, "\n").trim(); String result = StringUtil.join(names, "\n").trim();
assertEquals(finalExpectedResultText, result); assertEquals(finalExpectedResultText, result);