Supported propagation of vararg mark.

#KT-2776 in progress
This commit is contained in:
Evgeny Gerashchenko
2012-11-22 17:18:10 +04:00
parent 4df311366d
commit dd671313c5
18 changed files with 287 additions and 2 deletions
@@ -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;
}
}
}
@@ -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
}
}
@@ -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);
}
}
@@ -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>)
}
}
@@ -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
}
}
@@ -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);
}
}
@@ -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)
}
}
@@ -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");
@@ -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");