Disallowed using type parameter as reified type argument.
#KT-3050 fixed
This commit is contained in:
@@ -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);
|
||||
|
||||
+2
@@ -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(
|
||||
|
||||
+34
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user