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.create(ERROR);
|
||||
|
||||
SimpleDiagnosticFactory<JetTypeParameter> VARIANCE_ON_FUNCTION_OR_PROPERTY_PARAMETER = SimpleDiagnosticFactory.create(ERROR, VARIANCE_MODIFIER);
|
||||
|
||||
// Members
|
||||
|
||||
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.JetTokens;
|
||||
|
||||
import java.util.Arrays;
|
||||
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>() {
|
||||
@NotNull
|
||||
@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,
|
||||
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,
|
||||
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,
|
||||
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!
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
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 <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)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -12,4 +12,4 @@ fun test() {
|
||||
|
||||
//from library
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
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 <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)
|
||||
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");
|
||||
}
|
||||
|
||||
@TestMetadata("VarianceOnFunctionAndPropertyTypeParameters.kt")
|
||||
public void testVarianceOnFunctionAndPropertyTypeParameters() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/VarianceOnFunctionAndPropertyTypeParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations")
|
||||
public static class MultiDeclarations extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
public void testAllFilesPresentInMultiDeclarations() throws Exception {
|
||||
|
||||
@@ -347,16 +347,6 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
||||
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")
|
||||
public void testFunParamParam() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@TestMetadata("FunParamReferencesParam2.kt")
|
||||
public void testFunParamReferencesParam2() throws Exception {
|
||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunParamTwoUpperBounds.kt")
|
||||
public void testFunParamTwoUpperBounds() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@TestMetadata("FunTwoTypeParams2.kt")
|
||||
public void testFunTwoTypeParams2() throws Exception {
|
||||
doTest("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams2.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadKotlin/fun/genericWithoutTypeVariables")
|
||||
|
||||
+1
-24
@@ -15,16 +15,13 @@
|
||||
*/
|
||||
package org.jetbrains.jet.lang.resolve.lazy;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import java.io.File;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
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 */
|
||||
@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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testFunParamParam() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@TestMetadata("FunParamReferencesParam2.kt")
|
||||
public void testFunParamReferencesParam2() throws Exception {
|
||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunParamReferencesParam2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunParamTwoUpperBounds.kt")
|
||||
public void testFunParamTwoUpperBounds() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@TestMetadata("FunTwoTypeParams2.kt")
|
||||
public void testFunTwoTypeParams2() throws Exception {
|
||||
doTestSinglePackage("compiler/testData/loadKotlin/fun/genericWithTypeVariables/FunTwoTypeParams2.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadKotlin/fun/genericWithoutTypeVariables")
|
||||
|
||||
Reference in New Issue
Block a user