Supported propagation of vararg mark.
#KT-2776 in progress
This commit is contained in:
+59
-2
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -75,7 +76,10 @@ public class SignaturesPropagation {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
JetType altType = modifyTypeAccordingToSuperMethods(originalParam.getType(), typesFromSuperMethods, false, reportError);
|
VarargCheckResult varargCheckResult =
|
||||||
|
checkVarargInSuperFunctions(originalParam, superFunctions, reportError);
|
||||||
|
|
||||||
|
JetType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, typesFromSuperMethods, false, reportError);
|
||||||
|
|
||||||
resultParameters.add(new ValueParameterDescriptorImpl(
|
resultParameters.add(new ValueParameterDescriptorImpl(
|
||||||
originalParam.getContainingDeclaration(),
|
originalParam.getContainingDeclaration(),
|
||||||
@@ -85,7 +89,7 @@ public class SignaturesPropagation {
|
|||||||
originalParam.isVar(),
|
originalParam.isVar(),
|
||||||
altType,
|
altType,
|
||||||
originalParam.declaresDefaultValue(),
|
originalParam.declaresDefaultValue(),
|
||||||
originalParam.getVarargElementType()
|
varargCheckResult.isVararg ? KotlinBuiltIns.getInstance().getArrayElementType(altType) : null
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +131,49 @@ public class SignaturesPropagation {
|
|||||||
return superFunctions;
|
return superFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static VarargCheckResult checkVarargInSuperFunctions(
|
||||||
|
@NotNull ValueParameterDescriptor originalParam,
|
||||||
|
@NotNull List<FunctionDescriptor> superFunctions,
|
||||||
|
@NotNull Function1<String, Void> reportError
|
||||||
|
) {
|
||||||
|
boolean someSupersVararg = false;
|
||||||
|
boolean someSupersNotVararg = false;
|
||||||
|
for (FunctionDescriptor superFunction : superFunctions) {
|
||||||
|
if (superFunction.getValueParameters().get(originalParam.getIndex()).getVarargElementType() != null) {
|
||||||
|
someSupersVararg = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
someSupersNotVararg = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JetType originalVarargElementType = originalParam.getVarargElementType();
|
||||||
|
JetType originalType = originalParam.getType();
|
||||||
|
|
||||||
|
if (someSupersVararg && someSupersNotVararg) {
|
||||||
|
reportError.invoke("Incompatible super methods: some have vararg parameter, some have not");
|
||||||
|
return new VarargCheckResult(originalType, originalVarargElementType != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (someSupersVararg && originalVarargElementType == null) {
|
||||||
|
assert KotlinBuiltIns.getInstance().isArray(originalType);
|
||||||
|
|
||||||
|
// convert to vararg; replace Array<out Foo>? with Array<Foo>
|
||||||
|
JetType varargElementType = KotlinBuiltIns.getInstance().getArrayElementType(originalType);
|
||||||
|
return new VarargCheckResult(KotlinBuiltIns.getInstance().getArrayType(varargElementType), true);
|
||||||
|
}
|
||||||
|
else if (someSupersNotVararg && originalVarargElementType != null) {
|
||||||
|
assert KotlinBuiltIns.getInstance().isArray(originalType);
|
||||||
|
|
||||||
|
// convert to non-vararg; replace Array<Foo> with Array<out Foo>?
|
||||||
|
return new VarargCheckResult(
|
||||||
|
TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getArrayType(Variance.OUT_VARIANCE, originalVarargElementType)),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VarargCheckResult(originalType, originalVarargElementType != null);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static JetType modifyTypeAccordingToSuperMethods(
|
private static JetType modifyTypeAccordingToSuperMethods(
|
||||||
@@ -394,4 +441,14 @@ public class SignaturesPropagation {
|
|||||||
|
|
||||||
private SignaturesPropagation() {
|
private SignaturesPropagation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class VarargCheckResult {
|
||||||
|
public final JetType parameterType;
|
||||||
|
public final boolean isVararg;
|
||||||
|
|
||||||
|
private VarargCheckResult(JetType parameterType, boolean isVararg) {
|
||||||
|
this.parameterType = parameterType;
|
||||||
|
this.isVararg = isVararg;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
public interface InheritNotVararg {
|
||||||
|
|
||||||
|
public interface Super {
|
||||||
|
void foo(String[] p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super {
|
||||||
|
void foo(String... p);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait InheritNotVararg: Object {
|
||||||
|
|
||||||
|
public trait Super: Object {
|
||||||
|
public fun foo(p0: Array<out String?>?)
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Sub: Super {
|
||||||
|
override fun foo(p0: Array<out String?>?)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.InheritNotVararg : java.lang.Object {
|
||||||
|
public abstract trait test.InheritNotVararg.Sub : test.InheritNotVararg.Super {
|
||||||
|
public abstract override /*1*/ fun foo(/*0*/ p0: jet.Array<out jet.String?>?): jet.Tuple0
|
||||||
|
}
|
||||||
|
public abstract trait test.InheritNotVararg.Super : java.lang.Object {
|
||||||
|
public abstract fun foo(/*0*/ p0: jet.Array<out jet.String?>?): jet.Tuple0
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
|
|
||||||
|
public interface InheritNotVarargNotNull {
|
||||||
|
|
||||||
|
public interface Super {
|
||||||
|
@KotlinSignature("fun foo(p: Array<out String>)")
|
||||||
|
void foo(String[] p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super {
|
||||||
|
void foo(String... p);
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait InheritNotVarargNotNull: Object {
|
||||||
|
|
||||||
|
public trait Super: Object {
|
||||||
|
public fun foo(p0: Array<out String>)
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Sub: Super {
|
||||||
|
override fun foo(p0: Array<out String>)
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.InheritNotVarargNotNull : java.lang.Object {
|
||||||
|
public abstract trait test.InheritNotVarargNotNull.Sub : test.InheritNotVarargNotNull.Super {
|
||||||
|
public abstract override /*1*/ fun foo(/*0*/ p0: jet.Array<out jet.String>): jet.Tuple0
|
||||||
|
}
|
||||||
|
public abstract trait test.InheritNotVarargNotNull.Super : java.lang.Object {
|
||||||
|
public abstract fun foo(/*0*/ p0: jet.Array<out jet.String>): jet.Tuple0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
public interface InheritVararg {
|
||||||
|
|
||||||
|
public interface Super {
|
||||||
|
void foo(String... p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super {
|
||||||
|
void foo(String[] p);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait InheritVararg: Object {
|
||||||
|
|
||||||
|
public trait Super: Object {
|
||||||
|
public fun foo(vararg p0: String?)
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Sub: Super {
|
||||||
|
override fun foo(vararg p0: String?)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.InheritVararg : java.lang.Object {
|
||||||
|
public abstract trait test.InheritVararg.Sub : test.InheritVararg.Super {
|
||||||
|
public abstract override /*1*/ fun foo(/*0*/ vararg p0: jet.String? /*jet.Array<jet.String?>*/): jet.Tuple0
|
||||||
|
}
|
||||||
|
public abstract trait test.InheritVararg.Super : java.lang.Object {
|
||||||
|
public abstract fun foo(/*0*/ vararg p0: jet.String? /*jet.Array<jet.String?>*/): jet.Tuple0
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
|
|
||||||
|
public interface InheritVarargNotNull {
|
||||||
|
|
||||||
|
public interface Super {
|
||||||
|
@KotlinSignature("fun foo(vararg p: String)")
|
||||||
|
void foo(String... p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super {
|
||||||
|
void foo(String[] p);
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait InheritVarargNotNull: Object {
|
||||||
|
|
||||||
|
public trait Super: Object {
|
||||||
|
public fun foo(vararg p0: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Sub: Super {
|
||||||
|
override fun foo(vararg p0: String)
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.InheritVarargNotNull : java.lang.Object {
|
||||||
|
public abstract trait test.InheritVarargNotNull.Sub : test.InheritVarargNotNull.Super {
|
||||||
|
public abstract override /*1*/ fun foo(/*0*/ vararg p0: jet.String /*jet.Array<jet.String>*/): jet.Tuple0
|
||||||
|
}
|
||||||
|
public abstract trait test.InheritVarargNotNull.Super : java.lang.Object {
|
||||||
|
public abstract fun foo(/*0*/ vararg p0: jet.String /*jet.Array<jet.String>*/): jet.Tuple0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.String;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
|
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
|
||||||
|
|
||||||
|
public interface TwoSuperclassesVarargAndNot {
|
||||||
|
public interface Super1 {
|
||||||
|
void foo(String... s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Super2 {
|
||||||
|
void foo(String[] s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super1, Super2 {
|
||||||
|
@ExpectLoadError("Incompatible projection kinds in type arguments of super methods' return types: [String?, out String?]|" +
|
||||||
|
"Incompatible super methods: some have vararg parameter, some have not|" +
|
||||||
|
"Incompatible types in superclasses: [Array<String?>, Array<out String?>?]")
|
||||||
|
void foo(String[] s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.TwoSuperclassesVarargAndNot : java.lang.Object {
|
||||||
|
public abstract trait test.TwoSuperclassesVarargAndNot.Sub : test.TwoSuperclassesVarargAndNot.Super1, test.TwoSuperclassesVarargAndNot.Super2 {
|
||||||
|
public abstract override /*1*/ fun foo(/*0*/ p0: jet.Array<out jet.String?>?): jet.Tuple0
|
||||||
|
public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ vararg p0: jet.String? /*jet.Array<jet.String?>*/): jet.Tuple0
|
||||||
|
}
|
||||||
|
public abstract trait test.TwoSuperclassesVarargAndNot.Super1 : java.lang.Object {
|
||||||
|
public abstract fun foo(/*0*/ vararg p0: jet.String? /*jet.Array<jet.String?>*/): jet.Tuple0
|
||||||
|
}
|
||||||
|
public abstract trait test.TwoSuperclassesVarargAndNot.Super2 : java.lang.Object {
|
||||||
|
public abstract fun foo(/*0*/ p0: jet.Array<out jet.String?>?): jet.Tuple0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -98,6 +98,12 @@ public final class LoadJavaCustomTest extends KotlinTestWithEnvironment {
|
|||||||
dir + "TwoSuperclassesInconsistentGenericTypes.java");
|
dir + "TwoSuperclassesInconsistentGenericTypes.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKotlinSignatureTwoSuperclassesVarargAndNot() throws Exception {
|
||||||
|
String dir = PATH + "/kotlinSignature/";
|
||||||
|
doTest(dir + "TwoSuperclassesVarargAndNot.txt",
|
||||||
|
dir + "TwoSuperclassesVarargAndNot.java");
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: move to LoadJavaTestGenerated when possible
|
//TODO: move to LoadJavaTestGenerated when possible
|
||||||
public void testEnum() throws Exception {
|
public void testEnum() throws Exception {
|
||||||
String dir = PATH + "/enum";
|
String dir = PATH + "/enum";
|
||||||
|
|||||||
@@ -456,6 +456,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.java");
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritNotVararg.java")
|
||||||
|
public void testInheritNotVararg() throws Exception {
|
||||||
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNotVararg.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritNotVarargNotNull.java")
|
||||||
|
public void testInheritNotVarargNotNull() throws Exception {
|
||||||
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNotVarargNotNull.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("InheritNullability.java")
|
@TestMetadata("InheritNullability.java")
|
||||||
public void testInheritNullability() throws Exception {
|
public void testInheritNullability() throws Exception {
|
||||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNullability.java");
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNullability.java");
|
||||||
@@ -471,6 +481,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritReadOnliness.java");
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritReadOnliness.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritVararg.java")
|
||||||
|
public void testInheritVararg() throws Exception {
|
||||||
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritVararg.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritVarargNotNull.java")
|
||||||
|
public void testInheritVarargNotNull() throws Exception {
|
||||||
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritVarargNotNull.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NotNullToNullable.java")
|
@TestMetadata("NotNullToNullable.java")
|
||||||
public void testNotNullToNullable() throws Exception {
|
public void testNotNullToNullable() throws Exception {
|
||||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.java");
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.java");
|
||||||
|
|||||||
+20
@@ -1346,6 +1346,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.kt");
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritNotVararg.kt")
|
||||||
|
public void testInheritNotVararg() throws Exception {
|
||||||
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNotVararg.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritNotVarargNotNull.kt")
|
||||||
|
public void testInheritNotVarargNotNull() throws Exception {
|
||||||
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNotVarargNotNull.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("InheritNullability.kt")
|
@TestMetadata("InheritNullability.kt")
|
||||||
public void testInheritNullability() throws Exception {
|
public void testInheritNullability() throws Exception {
|
||||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNullability.kt");
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNullability.kt");
|
||||||
@@ -1361,6 +1371,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritReadOnliness.kt");
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritReadOnliness.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritVararg.kt")
|
||||||
|
public void testInheritVararg() throws Exception {
|
||||||
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritVararg.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InheritVarargNotNull.kt")
|
||||||
|
public void testInheritVarargNotNull() throws Exception {
|
||||||
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritVarargNotNull.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NotNullToNullable.kt")
|
@TestMetadata("NotNullToNullable.kt")
|
||||||
public void testNotNullToNullable() throws Exception {
|
public void testNotNullToNullable() throws Exception {
|
||||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.kt");
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user