Disallowed using type parameter as reified type argument.

#KT-3050 fixed
This commit is contained in:
Evgeny Gerashchenko
2013-09-26 03:12:14 +04:00
parent 2c877f080e
commit 48625dd7b6
15 changed files with 147 additions and 10 deletions
@@ -345,6 +345,8 @@ public interface Errors {
DiagnosticFactory0<JetExpression> DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<PsiElement, TypeParameterDescriptor> TYPE_PARAMETER_AS_REIFIED = DiagnosticFactory1.create(ERROR);
// Type inference
DiagnosticFactory0<JetParameter> CANNOT_INFER_PARAMETER_TYPE = DiagnosticFactory0.create(ERROR);
@@ -441,6 +441,8 @@ public class DefaultErrorMessages {
"This expression is treated as an argument to the function call on the previous line. " +
"Separate it with a semicolon (;) if it is not intended to be an argument.");
MAP.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead.", NAME);
MAP.put(NOT_AN_ANNOTATION_CLASS, "''{0}'' is not an annotation class", TO_STRING);
MAP.put(ANNOTATION_CLASS_WITH_BODY, "Body is not allowed for annotation class");
MAP.put(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member");
@@ -7,7 +7,7 @@ import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImp
public class CompositeExtension implements CallResolverExtension {
private final CallResolverExtension[] delegates = new CallResolverExtension[]{
new NeedSyntheticCallResolverExtension()};
new NeedSyntheticCallResolverExtension(), new TypeParameterAsReifiedCheck()};
@Override
public <F extends CallableDescriptor> void run(
@@ -0,0 +1,34 @@
package org.jetbrains.jet.lang.resolve.calls;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Map;
public class TypeParameterAsReifiedCheck implements CallResolverExtension {
@Override
public <F extends CallableDescriptor> void run(
@NotNull OverloadResolutionResultsImpl<F> results, @NotNull BasicCallResolutionContext context
) {
if (results.isSuccess()) {
Map<TypeParameterDescriptor, JetType> typeArguments = results.getResultingCall().getTypeArguments();
for (Map.Entry<TypeParameterDescriptor, JetType> entry : typeArguments.entrySet()) {
TypeParameterDescriptor parameter = entry.getKey();
JetType argument = entry.getValue();
if (parameter.isReified() && argument.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
JetExpression callee = context.call.getCalleeExpression();
PsiElement element = callee != null ? callee : context.call.getCallElement();
context.trace.report(Errors.TYPE_PARAMETER_AS_REIFIED.on(element, typeArguments.keySet().iterator().next()));
}
}
}
}
}
@@ -33,9 +33,9 @@ trait WriteOnlyArray<in T> : ISized {
}
class MutableArray<T>(length: Int, init : (Int) -> T) : ReadOnlyArray<T>, WriteOnlyArray<T> {
private val array = Array<T>(length, init)
private val array = Array<Any?>(length, init)
override fun get(index : Int) : T = array[index]
override fun get(index : Int) : T = array[index] as T
override fun set(index : Int, value : T) : Unit { array[index] = value }
override val size : Int
@@ -0,0 +1,11 @@
fun <reified T> T.plus(<!UNUSED_PARAMETER!>p<!>: T): T = this
fun <reified T> T.invoke(): T = this
fun <A> main(tp: A, any: Any) {
tp <!TYPE_PARAMETER_AS_REIFIED!>+<!> tp
any + any
<!TYPE_PARAMETER_AS_REIFIED!>tp<!>()
any()
}
@@ -0,0 +1,16 @@
class C<reified T>
fun <T> id(p: T): T = p
fun <A> main() {
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>C<!>()
val <!UNUSED_VARIABLE!>a<!>: C<A> = <!TYPE_PARAMETER_AS_REIFIED!>C<!>()
<!TYPE_PARAMETER_AS_REIFIED!>C<!><A>()
val <!UNUSED_VARIABLE!>b<!>: C<Int> = C()
C<Int>()
// TODO svtk, uncomment when extensions are called for nested calls!
//val < !UNUSED_VARIABLE!>с< !>: C<A> = id(< !TYPE_PARAMETER_AS_REIFIED!>C< !>())
}
@@ -0,0 +1,16 @@
fun <reified T> f(): T = throw UnsupportedOperationException()
fun <T> id(p: T): T = p
fun <A> main() {
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>f<!>()
val <!UNUSED_VARIABLE!>a<!>: A = <!TYPE_PARAMETER_AS_REIFIED!>f<!>()
<!TYPE_PARAMETER_AS_REIFIED!>f<!><A>()
val <!UNUSED_VARIABLE!>b<!>: Int = f()
f<Int>()
// TODO svtk, uncomment when extensions are called for nested calls!
//val < !UNUSED_VARIABLE!>с< !>: A = id(< !TYPE_PARAMETER_AS_REIFIED!>f< !>())
}
@@ -0,0 +1,15 @@
val <reified T> v: T
get() = throw UnsupportedOperationException()
fun <T> id(p: T): T = p
fun <A> main() {
val <!UNUSED_VARIABLE!>a<!> = <!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>v<!>
val <!UNUSED_VARIABLE!>b<!>: A = <!TYPE_PARAMETER_AS_REIFIED!>v<!>
val <!UNUSED_VARIABLE!>c<!>: Int = v
// TODO svtk, uncomment when extensions are called for nested calls!
//val < !UNUSED_VARIABLE!>d< !>: A = id(< !TYPE_PARAMETER_AS_REIFIED!>v< !>)
}
@@ -0,0 +1,4 @@
class C<reified T>
fun <A> main(<!UNUSED_PARAMETER!>p1<!>: C<A>, <!UNUSED_PARAMETER!>p2<!>: C<Int>) {
}
@@ -2802,6 +2802,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
}
@TestMetadata("compiler/testData/diagnostics/tests/generics")
@InnerTestClasses({Generics.TpAsReified.class})
public static class Generics extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInGenerics() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/generics"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -2852,6 +2853,45 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundWithTwoArguments.kt");
}
@TestMetadata("compiler/testData/diagnostics/tests/generics/tpAsReified")
public static class TpAsReified extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInTpAsReified() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/generics/tpAsReified"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("Conventions.kt")
public void testConventions() throws Exception {
doTest("compiler/testData/diagnostics/tests/generics/tpAsReified/Conventions.kt");
}
@TestMetadata("InConstructor.kt")
public void testInConstructor() throws Exception {
doTest("compiler/testData/diagnostics/tests/generics/tpAsReified/InConstructor.kt");
}
@TestMetadata("InFunction.kt")
public void testInFunction() throws Exception {
doTest("compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.kt");
}
@TestMetadata("InProperty.kt")
public void testInProperty() throws Exception {
doTest("compiler/testData/diagnostics/tests/generics/tpAsReified/InProperty.kt");
}
@TestMetadata("InType.kt")
public void testInType() throws Exception {
doTest("compiler/testData/diagnostics/tests/generics/tpAsReified/InType.kt");
}
}
public static Test innerSuite() {
TestSuite suite = new TestSuite("Generics");
suite.addTestSuite(Generics.class);
suite.addTestSuite(TpAsReified.class);
return suite;
}
}
@TestMetadata("compiler/testData/diagnostics/tests/incompleteCode")
@@ -5969,7 +6009,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
suite.addTest(Enum.innerSuite());
suite.addTestSuite(Extensions.class);
suite.addTest(FunctionLiterals.innerSuite());
suite.addTestSuite(Generics.class);
suite.addTest(Generics.innerSuite());
suite.addTest(IncompleteCode.innerSuite());
suite.addTest(Inference.innerSuite());
suite.addTestSuite(Infos.class);
-3
View File
@@ -6,9 +6,6 @@ public inline fun <T> Array<T>.isNotEmpty() : Boolean = !this.isEmpty()
/** Returns true if the array is empty */
public inline fun <T> Array<T>.isEmpty() : Boolean = this.size == 0
/** Returns the array if its not null or else returns an empty array */
public inline fun <T> Array<out T>?.orEmpty() : Array<out T> = if (this != null) this else array<T>()
public inline val BooleanArray.lastIndex : Int
get() = this.size - 1
+1 -1
View File
@@ -6,7 +6,7 @@ import java.util.Arrays
import jet.runtime.Intrinsic
// Array "constructor"
[Intrinsic("kotlin.arrays.array")] public inline fun <T> array(vararg t : T) : Array<T> = t
[Intrinsic("kotlin.arrays.array")] public inline fun <reified T> array(vararg t : T) : Array<T> = t
// "constructors" for primitive types array
[Intrinsic("kotlin.arrays.array")] public inline fun doubleArray(vararg content : Double) : DoubleArray = content
+1 -1
View File
@@ -8,7 +8,7 @@ import jet.runtime.Intrinsic
[Intrinsic("kotlin.javaClass.property")] public val <T> T.javaClass : Class<T>
get() = (this as java.lang.Object).getClass() as Class<T>
[Intrinsic("kotlin.javaClass.function")] fun <T> javaClass() : Class<T> = null as Class<T>
[Intrinsic("kotlin.javaClass.function")] fun <reified T> javaClass() : Class<T> = null as Class<T>
/**
@@ -102,7 +102,7 @@ class SyntaxHighligher() {
fun putAll(tokenSet: TokenSet?, style: String): Unit {
if (tokenSet != null) {
for (token in tokenSet.getTypes().orEmpty()) {
for (token in tokenSet.getTypes()) {
styleMap.put(token, style)
}
}