Report an error when variance is specified for a function or property type parameter
This commit is contained in:
@@ -187,6 +187,8 @@ public interface Errors {
|
|||||||
DiagnosticFactory2<JetSimpleNameExpression, JetTypeConstraint, JetTypeParameterListOwner> NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER =
|
DiagnosticFactory2<JetSimpleNameExpression, JetTypeConstraint, JetTypeParameterListOwner> NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER =
|
||||||
DiagnosticFactory2.create(ERROR);
|
DiagnosticFactory2.create(ERROR);
|
||||||
|
|
||||||
|
SimpleDiagnosticFactory<JetTypeParameter> VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER = SimpleDiagnosticFactory.create(ERROR, VARIANCE_MODIFIER);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
SimpleDiagnosticFactory<PsiElement> PACKAGE_MEMBER_CANNOT_BE_PROTECTED = SimpleDiagnosticFactory.create(ERROR);
|
SimpleDiagnosticFactory<PsiElement> PACKAGE_MEMBER_CANNOT_BE_PROTECTED = SimpleDiagnosticFactory.create(ERROR);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.psi.*;
|
|||||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -182,6 +183,27 @@ public class PositioningStrategies {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final PositioningStrategy<JetModifierListOwner> VARIANCE_MODIFIER = modifierSetPosition(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD);
|
||||||
|
|
||||||
|
public static PositioningStrategy<JetModifierListOwner> modifierSetPosition(final JetKeywordToken... tokens) {
|
||||||
|
return new PositioningStrategy<JetModifierListOwner>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<TextRange> mark(@NotNull JetModifierListOwner modifierListOwner) {
|
||||||
|
JetModifierList modifierList = modifierListOwner.getModifierList();
|
||||||
|
assert modifierList != null : "No modifier list, but modifier has been found by the analyzer";
|
||||||
|
|
||||||
|
for (JetKeywordToken token : tokens) {
|
||||||
|
ASTNode node = modifierList.getModifierNode(token);
|
||||||
|
if (node != null) {
|
||||||
|
return markNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("None of the modifiers is found: " + Arrays.asList(tokens));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static final PositioningStrategy<JetArrayAccessExpression> ARRAY_ACCESS = new PositioningStrategy<JetArrayAccessExpression>() {
|
public static final PositioningStrategy<JetArrayAccessExpression> ARRAY_ACCESS = new PositioningStrategy<JetArrayAccessExpression>() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+2
@@ -319,6 +319,8 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(AUTOCAST_IMPOSSIBLE, "Automatic cast to ''{0}'' is impossible, because ''{1}'' could have changed since the is-check", RENDER_TYPE,
|
MAP.put(AUTOCAST_IMPOSSIBLE, "Automatic cast to ''{0}'' is impossible, because ''{1}'' could have changed since the is-check", RENDER_TYPE,
|
||||||
NAME);
|
NAME);
|
||||||
|
|
||||||
|
MAP.put(VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER, "Variance annotations are only allowed for type parameters of classes and traits");
|
||||||
|
|
||||||
MAP.put(TYPE_MISMATCH_IN_FOR_LOOP, "The loop iterates over values of type {0} but the parameter is declared to be {1}", RENDER_TYPE,
|
MAP.put(TYPE_MISMATCH_IN_FOR_LOOP, "The loop iterates over values of type {0} but the parameter is declared to be {1}", RENDER_TYPE,
|
||||||
RENDER_TYPE);
|
RENDER_TYPE);
|
||||||
MAP.put(TYPE_MISMATCH_IN_CONDITION, "Condition must be of type jet.Boolean, but is of type {0}", RENDER_TYPE);
|
MAP.put(TYPE_MISMATCH_IN_CONDITION, "Condition must be of type jet.Boolean, but is of type {0}", RENDER_TYPE);
|
||||||
|
|||||||
@@ -522,6 +522,11 @@ public class DescriptorResolver {
|
|||||||
int index,
|
int index,
|
||||||
BindingTrace trace
|
BindingTrace trace
|
||||||
) {
|
) {
|
||||||
|
if (typeParameter.getVariance() != Variance.INVARIANT) {
|
||||||
|
assert !(containingDescriptor instanceof ClassifierDescriptor) : "This method is intended for functions/properties";
|
||||||
|
trace.report(VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER.on(typeParameter));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Annotations are not resolved!
|
// TODO: Annotations are not resolved!
|
||||||
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
containingDescriptor,
|
containingDescriptor,
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
fun <<!VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER!>in<!> T> f() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <<!VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER!>out<!> T> g() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <<!VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER!>out<!> T, <!VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER!>in<!> X, Y> h() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val <<!VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER!>out<!> T> T.x: Int
|
||||||
|
get() = 1
|
||||||
|
|
||||||
|
val <<!VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER!>in<!> T> T.y: Int
|
||||||
|
get() = 1
|
||||||
@@ -22,7 +22,7 @@ fun test() {
|
|||||||
|
|
||||||
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
||||||
|
|
||||||
fun <in T, C: MutableCollection<in T>> Array<T>.toCollection(result: C) : C {
|
fun <T, C: MutableCollection<in T>> Array<T>.toCollection(result: C) : C {
|
||||||
for (element in this) result.add(element)
|
for (element in this) result.add(element)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ fun test() {
|
|||||||
|
|
||||||
//from library
|
//from library
|
||||||
fun arrayList<T>(vararg <!UNUSED_PARAMETER!>values<!>: T) : ArrayList<T> {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
fun arrayList<T>(vararg <!UNUSED_PARAMETER!>values<!>: T) : ArrayList<T> {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun <in T> Iterable<T>.plus(<!UNUSED_PARAMETER!>elements<!>: Iterable<T>): List<T> {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
fun <T> Iterable<T>.plus(<!UNUSED_PARAMETER!>elements<!>: Iterable<T>): List<T> {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
@@ -35,7 +35,7 @@ fun <T, R, C: MutableCollection<in R>> Collection<T>.mapTo(result: C, transform
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <in T, C: MutableCollection<in T>> Array<T>.toCollection(result: C) : C {
|
fun <T, C: MutableCollection<in T>> Array<T>.toCollection(result: C) : C {
|
||||||
for (element in this) result.add(element)
|
for (element in this) result.add(element)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ fun assertEquals(<!UNUSED_PARAMETER!>expected<!>: Any?, <!UNUSED_PARAMETER!>actu
|
|||||||
|
|
||||||
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
||||||
|
|
||||||
fun <in T, C: MutableCollection<in T>> Array<T>.toCollection(result: C) : C {
|
fun <T, C: MutableCollection<in T>> Array<T>.toCollection(result: C) : C {
|
||||||
for (element in this) result.add(element)
|
for (element in this) result.add(element)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
fun <in T> f() = 1
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace test
|
|
||||||
|
|
||||||
internal final fun </*0*/ in T : jet.Any?>f(): jet.Int
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
fun <out T> f() = 1
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace test
|
|
||||||
|
|
||||||
internal final fun </*0*/ out T : jet.Any?>f(): jet.Int
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
fun <in P, Q : P> funParamReferencesParam() = 1
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace test
|
|
||||||
|
|
||||||
internal final fun </*0*/ in P : jet.Any?, /*1*/ Q : P>funParamReferencesParam(): jet.Int
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
fun <P, in Q> funTwoTypeParams() = 1
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace test
|
|
||||||
|
|
||||||
internal final fun </*0*/ P : jet.Any?, /*1*/ in Q : jet.Any?>funTwoTypeParams(): jet.Int
|
|
||||||
@@ -1462,6 +1462,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.kt");
|
doTest("compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("VarianceOnFunctionAndPropertyTypeParameters.kt")
|
||||||
|
public void testVarianceOnFunctionAndPropertyTypeParameters() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/declarationChecks/VarianceOnFunctionAndPropertyTypeParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations")
|
@TestMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations")
|
||||||
public static class MultiDeclarations extends AbstractDiagnosticsTestWithEagerResolve {
|
public static class MultiDeclarations extends AbstractDiagnosticsTestWithEagerResolve {
|
||||||
public void testAllFilesPresentInMultiDeclarations() throws Exception {
|
public void testAllFilesPresentInMultiDeclarations() throws Exception {
|
||||||
|
|||||||
@@ -347,16 +347,6 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunGenericParam.kt");
|
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunGenericParam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("FunInParam.kt")
|
|
||||||
public void testFunInParam() throws Exception {
|
|
||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunInParam.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("FunOutParam.kt")
|
|
||||||
public void testFunOutParam() throws Exception {
|
|
||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunOutParam.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("FunParamParam.kt")
|
@TestMetadata("FunParamParam.kt")
|
||||||
public void testFunParamParam() throws Exception {
|
public void testFunParamParam() throws Exception {
|
||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamParam.kt");
|
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamParam.kt");
|
||||||
@@ -372,11 +362,6 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam.kt");
|
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("FunParamReferencesParam2.kt")
|
|
||||||
public void testFunParamReferencesParam2() throws Exception {
|
|
||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam2.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("FunParamTwoUpperBounds.kt")
|
@TestMetadata("FunParamTwoUpperBounds.kt")
|
||||||
public void testFunParamTwoUpperBounds() throws Exception {
|
public void testFunParamTwoUpperBounds() throws Exception {
|
||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt");
|
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt");
|
||||||
@@ -412,11 +397,6 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams.kt");
|
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("FunTwoTypeParams2.kt")
|
|
||||||
public void testFunTwoTypeParams2() throws Exception {
|
|
||||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams2.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadKotlin/fun/genericWithoutTypeVariables")
|
@TestMetadata("compiler/testData/loadKotlin/fun/genericWithoutTypeVariables")
|
||||||
|
|||||||
+1
-24
@@ -15,16 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.jet.lang.resolve.lazy;
|
package org.jetbrains.jet.lang.resolve.lazy;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.test.InnerTestClasses;
|
import org.jetbrains.jet.test.InnerTestClasses;
|
||||||
import org.jetbrains.jet.test.TestMetadata;
|
import org.jetbrains.jet.test.TestMetadata;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest;
|
import java.io.File;
|
||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
||||||
@InnerTestClasses({LazyResolveNamespaceComparingTestGenerated.LoadKotlin.class, LazyResolveNamespaceComparingTestGenerated.LoadJava.class, LazyResolveNamespaceComparingTestGenerated.NamespaceComparator.class})
|
@InnerTestClasses({LazyResolveNamespaceComparingTestGenerated.LoadKotlin.class, LazyResolveNamespaceComparingTestGenerated.LoadJava.class, LazyResolveNamespaceComparingTestGenerated.NamespaceComparator.class})
|
||||||
@@ -349,16 +346,6 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunGenericParam.kt");
|
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunGenericParam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("FunInParam.kt")
|
|
||||||
public void testFunInParam() throws Exception {
|
|
||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunInParam.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("FunOutParam.kt")
|
|
||||||
public void testFunOutParam() throws Exception {
|
|
||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunOutParam.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("FunParamParam.kt")
|
@TestMetadata("FunParamParam.kt")
|
||||||
public void testFunParamParam() throws Exception {
|
public void testFunParamParam() throws Exception {
|
||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamParam.kt");
|
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamParam.kt");
|
||||||
@@ -374,11 +361,6 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam.kt");
|
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("FunParamReferencesParam2.kt")
|
|
||||||
public void testFunParamReferencesParam2() throws Exception {
|
|
||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam2.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("FunParamTwoUpperBounds.kt")
|
@TestMetadata("FunParamTwoUpperBounds.kt")
|
||||||
public void testFunParamTwoUpperBounds() throws Exception {
|
public void testFunParamTwoUpperBounds() throws Exception {
|
||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt");
|
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt");
|
||||||
@@ -414,11 +396,6 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams.kt");
|
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("FunTwoTypeParams2.kt")
|
|
||||||
public void testFunTwoTypeParams2() throws Exception {
|
|
||||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams2.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadKotlin/fun/genericWithoutTypeVariables")
|
@TestMetadata("compiler/testData/loadKotlin/fun/genericWithoutTypeVariables")
|
||||||
|
|||||||
Reference in New Issue
Block a user