From c5d1e04d41db6b19dadebda3c0c2e9bc8dc1a843 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 25 Feb 2013 15:10:58 +0400 Subject: [PATCH] EA-36903 - ISE: JavaTypeTransformer$.visitClassType Using error types as type arguments when there's an error in a type instantiation in Java code --- .../resolve/java/JavaTypeTransformer.java | 42 +++++++++++-------- .../errors/WrongNumberOfGenericParameters.txt | 17 ++++++++ .../test/WrongNumberOfGenericParameters.java | 16 +++++++ .../jet/jvm/compiler/LoadJavaCustomTest.java | 5 +++ 4 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 compiler/testData/loadJavaCustom/errors/WrongNumberOfGenericParameters.txt create mode 100644 compiler/testData/loadJavaCustom/errors/test/WrongNumberOfGenericParameters.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 9f840b63ed2..925de6daf4e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -39,6 +40,8 @@ import static org.jetbrains.jet.lang.resolve.java.TypeUsage.*; public class JavaTypeTransformer { + private static final Logger LOG = Logger.getInstance(JavaTypeTransformer.class); + private JavaSemanticServices javaSemanticServices; private JavaDescriptorResolver resolver; @Inject @@ -175,25 +178,30 @@ public class JavaTypeTransformer { PsiType[] psiArguments = classType.getParameters(); if (parameters.size() != psiArguments.length) { - throw new IllegalStateException( - "parameters = " + parameters.size() + ", actual arguments = " + psiArguments.length - + " in " + classType.getPresentableText() + "\n PsiClass: \n" + psiClass.getText()); - } - - for (int i = 0; i < parameters.size(); i++) { - PsiType psiArgument = psiArguments[i]; - TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + // Most of the time this means there is an error in the Java code + LOG.warn("parameters = " + parameters.size() + ", actual arguments = " + psiArguments.length + + " in " + classType.getPresentableText() + "\n PsiClass: \n" + psiClass.getText()); - TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT; - TypeProjection typeProjection = transformToTypeProjection( - psiArgument, typeParameterDescriptor, typeVariableResolver, howTheProjectionIsUsed); - - if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) { - // remove redundant 'out' and 'in' - arguments.add(new TypeProjection(Variance.INVARIANT, typeProjection.getType())); + for (TypeParameterDescriptor parameter : parameters) { + arguments.add(new TypeProjection(ErrorUtils.createErrorType(parameter.getName().getName()))); } - else { - arguments.add(typeProjection); + } + else { + for (int i = 0; i < parameters.size(); i++) { + PsiType psiArgument = psiArguments[i]; + TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + + TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT; + TypeProjection typeProjection = transformToTypeProjection( + psiArgument, typeParameterDescriptor, typeVariableResolver, howTheProjectionIsUsed); + + if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) { + // remove redundant 'out' and 'in' + arguments.add(new TypeProjection(Variance.INVARIANT, typeProjection.getType())); + } + else { + arguments.add(typeProjection); + } } } } diff --git a/compiler/testData/loadJavaCustom/errors/WrongNumberOfGenericParameters.txt b/compiler/testData/loadJavaCustom/errors/WrongNumberOfGenericParameters.txt new file mode 100644 index 00000000000..f20a39cf9b8 --- /dev/null +++ b/compiler/testData/loadJavaCustom/errors/WrongNumberOfGenericParameters.txt @@ -0,0 +1,17 @@ +package test + +public trait WrongNumberOfGenericParameters : java.lang.Object { + public abstract fun o0() : test.WrongNumberOfGenericParameters.One? + public abstract fun o2() : test.WrongNumberOfGenericParameters.One<[ERROR : T]>? + public abstract fun t1() : test.WrongNumberOfGenericParameters.Two? + public abstract fun z() : test.WrongNumberOfGenericParameters.Zero? + + public trait One : java.lang.Object { + } + + public trait Two : java.lang.Object { + } + + public trait Zero : java.lang.Object { + } +} diff --git a/compiler/testData/loadJavaCustom/errors/test/WrongNumberOfGenericParameters.java b/compiler/testData/loadJavaCustom/errors/test/WrongNumberOfGenericParameters.java new file mode 100644 index 00000000000..12c12f8b2c4 --- /dev/null +++ b/compiler/testData/loadJavaCustom/errors/test/WrongNumberOfGenericParameters.java @@ -0,0 +1,16 @@ +package test; + +public interface WrongNumberOfGenericParameters { + + interface Zero {} + interface One {} + + Zero z(); + + One o0(); + One o2(); + + // This does not produce the expected result, because IDEA thinks Two is a raw type + interface Two {} + Two t1(); +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java index 825072d9466..5267c940720 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaCustomTest.java @@ -187,6 +187,11 @@ public final class LoadJavaCustomTest extends KotlinTestWithEnvironment { doTestNoCompile(dir + "ReturnNotSubtype.txt", dir); } + public void testWrongNumberOfGenericParameters() throws Exception { + String dir = PATH + "/errors/"; + doTestNoCompile(dir + "WrongNumberOfGenericParameters.txt", dir); + } + public static class SubclassingKotlinInJavaTest extends KotlinTestWithEnvironmentManagement { public void testSubclassingKotlinInJava() throws Exception { doTest(PATH + "/" + getTestName(true));