Name suggester: Improve name suggestion strategy for type parameters
This commit is contained in:
+4
-1
@@ -330,17 +330,20 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
val validator = CollectingValidator { scope.getClassifier(Name.identifier(it)) == null }
|
||||
val parameterNames = JetNameSuggester.suggestNamesForTypeParameters(typeParameterCount, validator)
|
||||
val typeParameters = typeParameterCount.indices.map {
|
||||
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
fakeFunction,
|
||||
Annotations.EMPTY,
|
||||
false,
|
||||
Variance.INVARIANT,
|
||||
Name.identifier(validator.validateName("T")),
|
||||
Name.identifier(parameterNames[it]),
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
return fakeFunction.initialize(null, null, typeParameters, Collections.emptyList(), null, null, Visibilities.INTERNAL)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
@@ -96,6 +97,16 @@ public class JetNameSuggester {
|
||||
return ArrayUtil.toStringArray(result);
|
||||
}
|
||||
|
||||
private static final String[] COMMON_TYPE_PARAMETER_NAMES = {"T", "U", "V", "W", "X", "Y", "Z"};
|
||||
|
||||
public static @NotNull String[] suggestNamesForTypeParameters(int count, @NotNull JetNameValidator validator) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
result.add(validator.validateNameWithVariants(COMMON_TYPE_PARAMETER_NAMES));
|
||||
}
|
||||
return ArrayUtil.toStringArray(result);
|
||||
}
|
||||
|
||||
private static void addNamesForType(ArrayList<String> result, JetType jetType, JetNameValidator validator) {
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
JetTypeChecker typeChecker = JetTypeChecker.DEFAULT;
|
||||
|
||||
@@ -35,6 +35,23 @@ public abstract class JetNameValidator {
|
||||
return name + i
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates name using set of variants which are tried in succession (and extended with suffixes if necessary)
|
||||
* For example, when given sequence of a, b, c possible names are tried out in the following order: a, b, c, a1, b1, c1, a2, b2, c2, ...
|
||||
* @param names to check it in scope
|
||||
* @return name or nameI, where name is one of variants and I is a number
|
||||
*/
|
||||
public fun validateNameWithVariants(vararg names: String): String {
|
||||
var i = 0
|
||||
while (true) {
|
||||
for (name in names) {
|
||||
val candidate = if (i > 0) name + i else name
|
||||
if (validateInner(candidate)) return candidate
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun validateInner(name: String): Boolean
|
||||
}
|
||||
|
||||
@@ -48,12 +65,12 @@ public open class CollectingValidator(
|
||||
): JetNameValidator() {
|
||||
private val suggestedSet = HashSet(existingNames)
|
||||
|
||||
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
|
||||
override fun validateInner(name: String): Boolean {
|
||||
if (name !in suggestedSet && filter(name)) {
|
||||
suggestedSet.add(name)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// "Create function 'foo'" "true"
|
||||
|
||||
class B<T>(val t: T) {
|
||||
fun <T1, T2> foo(arg: T1, arg1: T2): T1 {
|
||||
fun <U, V> foo(arg: U, arg1: V): U {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// "Create function 'foo'" "true"
|
||||
|
||||
class B<T>(val t: T) {
|
||||
fun <T1> foo(i: Int, arg: T1): Int {
|
||||
fun <U> foo(i: Int, arg: U): Int {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// "Create function 'foo'" "true"
|
||||
|
||||
class B<T>(val t: T) {
|
||||
fun <T1, T2> foo(arg: T1, arg1: T2): T1 {
|
||||
fun <U, V> foo(arg: U, arg1: V): U {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@ class A<T>(val items: List<T>) {
|
||||
}
|
||||
}
|
||||
|
||||
fun <E, T, T1> List<E>.foo(arg: T, arg1: T1): T {
|
||||
fun <E, T, U> List<E>.foo(arg: T, arg1: U): T {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
+1
-1
@@ -6,6 +6,6 @@ class A<T>(val items: List<T>) {
|
||||
}
|
||||
}
|
||||
|
||||
fun <E, T, T1> List<E>.foo(arg: T, arg1: T1): T {
|
||||
fun <E, T, U> List<E>.foo(arg: T, arg1: U): T {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
+1
-1
@@ -4,6 +4,6 @@ fun test(): Int {
|
||||
return foo<String, Int>(2, "2")
|
||||
}
|
||||
|
||||
fun <T, T1> foo(arg: T1, arg1: T): T1 {
|
||||
fun <T, U> foo(arg: U, arg1: T): U {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
+1
-1
@@ -4,6 +4,6 @@ fun test(): Int {
|
||||
return foo<String, Int, Boolean>(2, "2")
|
||||
}
|
||||
|
||||
fun <T, T1, T2> foo(arg: T1, arg1: T): T1 {
|
||||
fun <T, U, V> foo(arg: U, arg1: T): U {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
+1
-1
@@ -4,6 +4,6 @@ fun test(): Int {
|
||||
return foo<String, Int>(2, "2")
|
||||
}
|
||||
|
||||
fun <T, T1> foo(arg: T1, arg1: T): T1 {
|
||||
fun <T, U> foo(arg: U, arg1: T): U {
|
||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
Reference in New Issue
Block a user