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.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
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(
|
||||
originalParam.getContainingDeclaration(),
|
||||
@@ -85,7 +89,7 @@ public class SignaturesPropagation {
|
||||
originalParam.isVar(),
|
||||
altType,
|
||||
originalParam.declaresDefaultValue(),
|
||||
originalParam.getVarargElementType()
|
||||
varargCheckResult.isVararg ? KotlinBuiltIns.getInstance().getArrayElementType(altType) : null
|
||||
));
|
||||
}
|
||||
|
||||
@@ -127,6 +131,49 @@ public class SignaturesPropagation {
|
||||
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
|
||||
private static JetType modifyTypeAccordingToSuperMethods(
|
||||
@@ -394,4 +441,14 @@ public class 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");
|
||||
}
|
||||
|
||||
public void testKotlinSignatureTwoSuperclassesVarargAndNot() throws Exception {
|
||||
String dir = PATH + "/kotlinSignature/";
|
||||
doTest(dir + "TwoSuperclassesVarargAndNot.txt",
|
||||
dir + "TwoSuperclassesVarargAndNot.java");
|
||||
}
|
||||
|
||||
//TODO: move to LoadJavaTestGenerated when possible
|
||||
public void testEnum() throws Exception {
|
||||
String dir = PATH + "/enum";
|
||||
|
||||
@@ -456,6 +456,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
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")
|
||||
public void testInheritNullability() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testNotNullToNullable() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testInheritNullability() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testNotNullToNullable() throws Exception {
|
||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.kt");
|
||||
|
||||
Reference in New Issue
Block a user