Supported checking for changing signature in submethods.

#KT-2776 in progress
This commit is contained in:
Evgeny Gerashchenko
2012-11-26 17:25:50 +04:00
parent dd671313c5
commit 8d7de5d063
20 changed files with 295 additions and 6 deletions
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.ArrayList;
@@ -43,7 +44,6 @@ import java.util.Map;
*/
public class AlternativeMethodSignatureData extends ElementAlternativeSignatureData {
private final JetNamedFunction altFunDeclaration;
private final PsiMethodWrapper method;
private JavaDescriptorResolver.ValueParameterDescriptors altValueParameters;
private JetType altReturnType;
@@ -56,18 +56,17 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
@NotNull PsiMethodWrapper method,
@NotNull JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors,
@Nullable JetType originalReturnType,
@NotNull List<TypeParameterDescriptor> methodTypeParameters
@NotNull List<TypeParameterDescriptor> methodTypeParameters,
boolean hasSuperMethods
) {
String signature = method.getSignatureAnnotation().signature();
if (signature.isEmpty()) {
setAnnotated(false);
altFunDeclaration = null;
this.method = null;
return;
}
setAnnotated(true);
this.method = method;
Project project = method.getPsiMethod().getProject();
altFunDeclaration = JetPsiFactory.createFunction(project, signature);
@@ -89,6 +88,10 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
computeTypeParameters(methodTypeParameters);
computeValueParameters(valueParameterDescriptors);
if (hasSuperMethods) {
checkSameParameterTypes(valueParameterDescriptors, methodTypeParameters);
}
if (originalReturnType != null) {
altReturnType = computeReturnType(originalReturnType, altFunDeclaration.getReturnTypeRef(), originalToAltTypeParameters);
}
@@ -98,6 +101,32 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
}
}
private void checkSameParameterTypes(
@NotNull JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors,
@NotNull List<TypeParameterDescriptor> methodTypeParameters
) {
for (ValueParameterDescriptor parameter : valueParameterDescriptors.getDescriptors()) {
int index = parameter.getIndex();
ValueParameterDescriptor altParameter = altValueParameters.getDescriptors().get(index);
if (!TypeUtils.equalTypes(parameter.getType(), altParameter.getType())) {
throw new AlternativeSignatureMismatchException(
"Parameter type changed for method which overrides another: " + altParameter.getType()
+ ", was: " + parameter.getType());
}
}
// don't check receiver
for (TypeParameterDescriptor parameter : methodTypeParameters) {
int index = parameter.getIndex();
if (!TypeUtils.equalTypes(altTypeParameters.get(index).getUpperBoundsAsType(), parameter.getUpperBoundsAsType())) {
throw new AlternativeSignatureMismatchException(
"Type parameter's upper bound changed for method which overrides another: "
+ altTypeParameters.get(index).getUpperBoundsAsType() + ", was: " + parameter.getUpperBoundsAsType());
}
}
}
@NotNull
public JavaDescriptorResolver.ValueParameterDescriptors getValueParameters() {
checkForErrors();
@@ -192,7 +192,7 @@ public final class JavaConstructorResolver {
AlternativeMethodSignatureData alternativeMethodSignatureData =
new AlternativeMethodSignatureData(constructor, valueParameterDescriptors, null,
Collections.<TypeParameterDescriptor>emptyList());
Collections.<TypeParameterDescriptor>emptyList(), false);
if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) {
valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
}
@@ -156,7 +156,8 @@ public final class JavaFunctionResolver {
// TODO consider better place for this check
AlternativeMethodSignatureData alternativeMethodSignatureData =
new AlternativeMethodSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters);
new AlternativeMethodSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters,
!superFunctions.isEmpty());
if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) {
valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
returnType = alternativeMethodSignatureData.getReturnType();
@@ -0,0 +1,20 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
import java.util.*;
public interface ChangeProjectionKind1 {
public interface Super {
@KotlinSignature("fun foo(p: MutableList<in String>)")
void foo(List<String> p);
}
public interface Sub extends Super {
@ExpectLoadError("Variance mismatch, actual: in, in alternative signature: ")
@KotlinSignature("fun foo(p: MutableList<String>)")
void foo(List<String> p);
}
}
@@ -0,0 +1,12 @@
package test
public trait ChangeProjectionKind1: Object {
public trait Super: Object {
public fun foo(p0: MutableList<in String>)
}
public trait Sub: Super {
override fun foo(p0: MutableList<in String>)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.ChangeProjectionKind1 : java.lang.Object {
public abstract trait test.ChangeProjectionKind1.Sub : test.ChangeProjectionKind1.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.MutableList<in jet.String>): jet.Tuple0
}
public abstract trait test.ChangeProjectionKind1.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.MutableList<in jet.String>): jet.Tuple0
}
}
@@ -0,0 +1,20 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
import java.util.*;
public interface ChangeProjectionKind2 {
public interface Super {
@KotlinSignature("fun foo(p: MutableList<String>)")
void foo(List<String> p);
}
public interface Sub extends Super {
@ExpectLoadError("Parameter type changed for method which overrides another: MutableList<in String>, was: MutableList<String>")
@KotlinSignature("fun foo(p: MutableList<in String>)")
void foo(List<String> p);
}
}
@@ -0,0 +1,12 @@
package test
public trait ChangeProjectionKind2: Object {
public trait Super: Object {
public fun foo(p0: MutableList<String>)
}
public trait Sub: Super {
override fun foo(p0: MutableList<String>)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.ChangeProjectionKind2 : java.lang.Object {
public abstract trait test.ChangeProjectionKind2.Sub : test.ChangeProjectionKind2.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.MutableList<jet.String>): jet.Tuple0
}
public abstract trait test.ChangeProjectionKind2.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.MutableList<jet.String>): jet.Tuple0
}
}
@@ -0,0 +1,20 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
import java.util.*;
public interface MutableToReadOnly {
public interface Super {
@KotlinSignature("fun foo(p: MutableList<String>)")
void foo(List<String> p);
}
public interface Sub extends Super {
@ExpectLoadError("Parameter type changed for method which overrides another: List<String>, was: MutableList<String>")
@KotlinSignature("fun foo(p: List<String>)")
void foo(List<String> p);
}
}
@@ -0,0 +1,12 @@
package test
public trait MutableToReadOnly: Object {
public trait Super: Object {
public fun foo(p0: MutableList<String>)
}
public trait Sub: Super {
override fun foo(p0: MutableList<String>)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.MutableToReadOnly : java.lang.Object {
public abstract trait test.MutableToReadOnly.Sub : test.MutableToReadOnly.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.MutableList<jet.String>): jet.Tuple0
}
public abstract trait test.MutableToReadOnly.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.MutableList<jet.String>): jet.Tuple0
}
}
@@ -0,0 +1,19 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
public interface NullableToNotNullKotlinSignature {
public interface Super {
@KotlinSignature("fun foo(p: String?)")
void foo(String p);
}
public interface Sub extends Super {
@ExpectLoadError("Parameter type changed for method which overrides another: String, was: String?")
@KotlinSignature("fun foo(p: String)")
void foo(String p);
}
}
@@ -0,0 +1,12 @@
package test
public trait NullableToNotNullKotlinSignature: Object {
public trait Super: Object {
public fun foo(p0: String?)
}
public trait Sub: Super {
override fun foo(p0: String?)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.NullableToNotNullKotlinSignature : java.lang.Object {
public abstract trait test.NullableToNotNullKotlinSignature.Sub : test.NullableToNotNullKotlinSignature.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.String?): jet.Tuple0
}
public abstract trait test.NullableToNotNullKotlinSignature.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.String?): jet.Tuple0
}
}
@@ -0,0 +1,20 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
import java.util.*;
public interface ReadOnlyToMutable {
public interface Super {
@KotlinSignature("fun foo(p: List<String>)")
void foo(List<String> p);
}
public interface Sub extends Super {
@ExpectLoadError("Parameter type changed for method which overrides another: MutableList<String>, was: List<String>")
@KotlinSignature("fun foo(p: MutableList<String>)")
void foo(List<String> p);
}
}
@@ -0,0 +1,12 @@
package test
public trait ReadOnlyToMutable: Object {
public trait Super: Object {
public fun foo(p0: List<String>)
}
public trait Sub: Super {
override fun foo(p0: List<String>)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.ReadOnlyToMutable : java.lang.Object {
public abstract trait test.ReadOnlyToMutable.Sub : test.ReadOnlyToMutable.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.List<jet.String>): jet.Tuple0
}
public abstract trait test.ReadOnlyToMutable.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.List<jet.String>): jet.Tuple0
}
}
@@ -451,6 +451,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/kotlinSignature/propagation/parameter"), "java", true);
}
@TestMetadata("ChangeProjectionKind1.java")
public void testChangeProjectionKind1() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/ChangeProjectionKind1.java");
}
@TestMetadata("ChangeProjectionKind2.java")
public void testChangeProjectionKind2() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/ChangeProjectionKind2.java");
}
@TestMetadata("InheritMutability.java")
public void testInheritMutability() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.java");
@@ -491,6 +501,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritVarargNotNull.java");
}
@TestMetadata("MutableToReadOnly.java")
public void testMutableToReadOnly() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/MutableToReadOnly.java");
}
@TestMetadata("NotNullToNullable.java")
public void testNotNullToNullable() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.java");
@@ -501,6 +516,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NullableToNotNull.java");
}
@TestMetadata("NullableToNotNullKotlinSignature.java")
public void testNullableToNotNullKotlinSignature() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NullableToNotNullKotlinSignature.java");
}
@TestMetadata("ReadOnlyToMutable.java")
public void testReadOnlyToMutable() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/ReadOnlyToMutable.java");
}
}
@TestMetadata("compiler/testData/loadJava/kotlinSignature/propagation/return")
@@ -1341,6 +1341,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/kotlinSignature/propagation/parameter"), "kt", true);
}
@TestMetadata("ChangeProjectionKind1.kt")
public void testChangeProjectionKind1() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/ChangeProjectionKind1.kt");
}
@TestMetadata("ChangeProjectionKind2.kt")
public void testChangeProjectionKind2() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/ChangeProjectionKind2.kt");
}
@TestMetadata("InheritMutability.kt")
public void testInheritMutability() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.kt");
@@ -1381,6 +1391,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritVarargNotNull.kt");
}
@TestMetadata("MutableToReadOnly.kt")
public void testMutableToReadOnly() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/MutableToReadOnly.kt");
}
@TestMetadata("NotNullToNullable.kt")
public void testNotNullToNullable() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.kt");
@@ -1391,6 +1406,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NullableToNotNull.kt");
}
@TestMetadata("NullableToNotNullKotlinSignature.kt")
public void testNullableToNotNullKotlinSignature() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NullableToNotNullKotlinSignature.kt");
}
@TestMetadata("ReadOnlyToMutable.kt")
public void testReadOnlyToMutable() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/ReadOnlyToMutable.kt");
}
}
@TestMetadata("compiler/testData/loadJava/kotlinSignature/propagation/return")