Special diagnostics when no type arguments passed on teh right-hand side of 'is' expression
Example: if (a is Map) // ERROR: Say 'Map<*, *>' if you don't want to pass type arguments
This commit is contained in:
@@ -91,6 +91,7 @@ public interface Errors {
|
||||
SimpleDiagnosticFactory<JetNullableType> REDUNDANT_NULLABLE = SimpleDiagnosticFactory.create(WARNING, NULLABLE_TYPE);
|
||||
DiagnosticFactory1<JetNullableType, JetType> BASE_WITH_NULLABLE_UPPER_BOUND = DiagnosticFactory1.create(WARNING, NULLABLE_TYPE);
|
||||
DiagnosticFactory1<JetElement, Integer> WRONG_NUMBER_OF_TYPE_ARGUMENTS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory2<JetUserType, Integer, String> NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory1<JetTypeProjection, ClassifierDescriptor> CONFLICTING_PROJECTION = DiagnosticFactory1.create(ERROR, VARIANCE_IN_PROJECTION);
|
||||
DiagnosticFactory1<JetTypeProjection, ClassifierDescriptor> REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, VARIANCE_IN_PROJECTION);
|
||||
|
||||
|
||||
+2
@@ -419,6 +419,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH, "Type inference failed. Expected type mismatch: found: {0} required: {1}", RENDER_TYPE, RENDER_TYPE);
|
||||
|
||||
MAP.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type argument} expected", null);
|
||||
MAP.put(NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type argument} expected. " +
|
||||
"Use ''{1}'' if you don''t want to pass type parameters", null, TO_STRING);
|
||||
|
||||
MAP.put(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED,
|
||||
"This expression is treated as an argument to the function call on the previous line. " +
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||
@@ -142,7 +143,12 @@ public class TypeResolver {
|
||||
else {
|
||||
if (actualArgumentCount != expectedArgumentCount) {
|
||||
if (actualArgumentCount == 0) {
|
||||
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount));
|
||||
if (rhsOfIsExpression(type)) {
|
||||
trace.report(NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION.on(type, expectedArgumentCount, allStarProjectionsString(typeConstructor)));
|
||||
}
|
||||
else {
|
||||
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount));
|
||||
}
|
||||
}
|
||||
else {
|
||||
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type.getTypeArgumentList(), expectedArgumentCount));
|
||||
@@ -233,6 +239,19 @@ public class TypeResolver {
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private static boolean rhsOfIsExpression(@NotNull JetUserType type) {
|
||||
// Look for the FIRST expression containing this type
|
||||
JetExpression outerExpression = PsiTreeUtil.getParentOfType(type, JetExpression.class);
|
||||
if (outerExpression instanceof JetIsExpression) {
|
||||
JetIsExpression isExpression = (JetIsExpression) outerExpression;
|
||||
// If this expression is JetIsExpression, and the type is the outermost on the RHS
|
||||
if (type.getParent() == isExpression.getTypeRef()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private JetScope getScopeForTypeParameter(final TypeParameterDescriptor typeParameterDescriptor, boolean checkBounds) {
|
||||
if (checkBounds) {
|
||||
return typeParameterDescriptor.getUpperBoundsAsType().getMemberScope();
|
||||
@@ -317,4 +336,15 @@ public class TypeResolver {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String allStarProjectionsString(@NotNull TypeConstructor constructor) {
|
||||
int size = constructor.getParameters().size();
|
||||
assert size != 0 : "No projections possible for a nilary type constructor" + constructor;
|
||||
ClassifierDescriptor declarationDescriptor = constructor.getDeclarationDescriptor();
|
||||
assert declarationDescriptor != null : "No declaration descriptor for type constructor " + constructor;
|
||||
String name = declarationDescriptor.getName().getName();
|
||||
|
||||
return TypeUtils.getTypeNameAndStarProjectionsString(name, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,4 +497,18 @@ public class TypeUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getTypeNameAndStarProjectionsString(@NotNull String name, int size) {
|
||||
StringBuilder builder = new StringBuilder(name);
|
||||
builder.append("<");
|
||||
for (int i = 0; i < size; i++) {
|
||||
builder.append("*");
|
||||
if (i == size - 1) break;
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(">");
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package p
|
||||
|
||||
public fun foo(a: Any) {
|
||||
a is Map<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>
|
||||
a is <!NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION!>Map<!>
|
||||
a is Map<out Any?, Any?>
|
||||
a is Map<*, *>
|
||||
a is Map<<!SYNTAX!><!>>
|
||||
a is <!CANNOT_CHECK_FOR_ERASED!>List<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>><!>
|
||||
a is <!NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION!>List<!>
|
||||
a is Int
|
||||
|
||||
(a <!USELESS_CAST!>as<!> <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) is Int
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,16 @@
|
||||
*/
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
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 java.io.File;
|
||||
import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
||||
@InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class})
|
||||
@@ -1766,6 +1769,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/generics/Projections.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("RawTypeInIsExpression.kt")
|
||||
public void testRawTypeInIsExpression() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/generics/RawTypeInIsExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("RecursiveUpperBoundCheck.kt")
|
||||
public void testRecursiveUpperBoundCheck() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundCheck.kt");
|
||||
|
||||
+4
-1
@@ -15,13 +15,16 @@
|
||||
*/
|
||||
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 java.io.File;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest;
|
||||
|
||||
/** 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})
|
||||
|
||||
Reference in New Issue
Block a user