From 06ab4e1c9a0725aeefc332f17f343e0e77692147 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 23 Sep 2014 16:17:33 +0400 Subject: [PATCH] Name Validator: Add filtering to collecting validator --- .../quickfix/AddFunctionParametersFix.java | 4 +-- .../ChangeFunctionLiteralSignatureFix.java | 4 +-- .../CreateFunctionFromUsageFix.kt | 30 ++++--------------- .../plugin/refactoring/JetNameValidator.kt | 15 +++++++--- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java index 73866eb0370..5ccee80a718 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java @@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage; -import org.jetbrains.jet.plugin.refactoring.CollectingValidator; +import org.jetbrains.jet.plugin.refactoring.SimpleCollectingValidator; import org.jetbrains.jet.plugin.refactoring.JetNameValidator; import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureConfiguration; import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureData; @@ -117,7 +117,7 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix { public void configure(@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext) { List parameters = functionDescriptor.getValueParameters(); List arguments = callElement.getValueArguments(); - JetNameValidator validator = new CollectingValidator(); + JetNameValidator validator = new SimpleCollectingValidator(); for (int i = 0; i < arguments.size(); i ++) { ValueArgument argument = arguments.get(i); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralSignatureFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralSignatureFix.java index b287e71a028..a0171613b31 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralSignatureFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralSignatureFix.java @@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage; -import org.jetbrains.jet.plugin.refactoring.CollectingValidator; +import org.jetbrains.jet.plugin.refactoring.SimpleCollectingValidator; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; import org.jetbrains.jet.plugin.refactoring.JetNameValidator; import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureConfiguration; @@ -62,7 +62,7 @@ public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFi runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() { @Override public void configure(@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext) { - JetNameValidator validator = new CollectingValidator(); + JetNameValidator validator = new SimpleCollectingValidator(); changeSignatureData.clearParameters(); for (JetType type : parameterTypes) { String name = JetNameSuggester.suggestNames(type, validator, "param")[0]; diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createFunction/CreateFunctionFromUsageFix.kt b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createFunction/CreateFunctionFromUsageFix.kt index 21151966728..b968bc022d2 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createFunction/CreateFunctionFromUsageFix.kt +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/createFromUsage/createFunction/CreateFunctionFromUsageFix.kt @@ -67,6 +67,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils import org.jetbrains.jet.plugin.quickfix.QuickFixUtil import org.jetbrains.jet.plugin.quickfix.createFromUsage.CreateFromUsageFixBase import org.jetbrains.jet.plugin.refactoring.EmptyValidator +import org.jetbrains.jet.plugin.refactoring.CollectingValidator private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList" private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt" @@ -244,9 +245,8 @@ private class ParameterNameExpression( } // ensure there are no conflicts - return names.map { name -> - LookupElementBuilder.create(getNextAvailableName(name, parameterNames, null)) - }.copyToArray() + val validator = CollectingValidator(parameterNames) + return names.map { LookupElementBuilder.create(validator.validateName(it)) }.copyToArray() } } @@ -318,24 +318,6 @@ private class TypeParameterListExpression(private val typeParameterNamesFromRece override fun calculateLookupItems(context: ExpressionContext?) = array() } -/** - * Returns the given name, appended with a number if it is one of the existingNames or already exists in - * scope. For example, given "foo", returns the next non-conflicting name in the list "foo", - * "foo1", "foo2", etc. - */ -private fun getNextAvailableName(name: String, existingNames: Collection, scope: JetScope?): String { - return if (isConflictingName(name, existingNames, scope)) { - "$name${stream(1) { it + 1 } first { !isConflictingName("$name$it", existingNames, scope) }}" - } - else { - name - } -} - -private fun isConflictingName(name: String, existingNames: Collection, scope: JetScope?): Boolean { - return name in existingNames || scope?.getClassifier(Name.identifier(name)) != null -} - public class CreateFunctionFromUsageFix internal ( element: PsiElement, private val ownerType: TypeOrExpressionThereof, @@ -552,10 +534,8 @@ public class CreateFunctionFromUsageFix internal ( returnType.typeCandidates!!.stream().flatMapTo(allTypeParametersNotInScope) { it.typeParameters.stream() } } - val typeParameterNames = ArrayList() - allTypeParametersNotInScope.mapTo(typeParameterNames) { typeParameter -> - getNextAvailableName(typeParameter.getName().asString(), typeParameterNames, scope) - } + val validator = CollectingValidator { scope.getClassifier(Name.identifier(it)) == null } + val typeParameterNames = allTypeParametersNotInScope.map { validator.validateName(it.getName().asString()) } val typeParameterNameMap = HashMap() for ((key, value) in allTypeParametersNotInScope.zip(typeParameterNames)) { diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.kt index 1e6c98449ce..bb162b8e7be 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidator.kt @@ -17,6 +17,7 @@ package org.jetbrains.jet.plugin.refactoring import java.util.HashSet +import java.util.Collections public abstract class JetNameValidator { /** @@ -41,14 +42,20 @@ public object EmptyValidator : JetNameValidator() { override fun validateInner(name: String): Boolean = true } -public class CollectingValidator: JetNameValidator() { - private val suggestedSet = HashSet() +public open class CollectingValidator( + existingNames: Collection = Collections.emptySet(), + val filter: (String) -> Boolean = { true } +): JetNameValidator() { + private val suggestedSet = HashSet(existingNames) - override fun validateInner(name: String): Boolean = !suggestedSet.contains(name) + override fun validateInner(name: String): Boolean = name !in suggestedSet && filter(name) override fun validateName(name: String): String { val validatedName = super.validateName(name) suggestedSet.add(validatedName) return validatedName } -} \ No newline at end of file +} + +// TODO: To be used from Java +public class SimpleCollectingValidator : CollectingValidator() \ No newline at end of file