Do not allow inference of type arguments on the rhs if there's no information available
This commit is contained in:
@@ -85,7 +85,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetNullableType> REDUNDANT_NULLABLE = DiagnosticFactory0.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);
|
||||
DiagnosticFactory2<JetTypeReference, Integer, String> NO_TYPE_ARGUMENTS_ON_RHS = 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);
|
||||
|
||||
|
||||
+1
-1
@@ -434,7 +434,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH, "Type inference failed. Expected type mismatch: found: {1} required: {0}", 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 arguments} 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 arguments} expected. " +
|
||||
MAP.put(NO_TYPE_ARGUMENTS_ON_RHS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type arguments} expected. " +
|
||||
"Use ''{1}'' if you don''t want to pass type arguments", null, TO_STRING);
|
||||
|
||||
MAP.put(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED,
|
||||
|
||||
@@ -79,17 +79,19 @@ public class PossiblyBareType {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType reconstruct(@NotNull JetType subjectType) {
|
||||
if (!isBare()) return getActualType();
|
||||
public TypeReconstructionResult reconstruct(@NotNull JetType subjectType) {
|
||||
if (!isBare()) return new TypeReconstructionResult(getActualType(), true);
|
||||
|
||||
JetType type = CastDiagnosticsUtil.findStaticallyKnownSubtype(
|
||||
TypeReconstructionResult reconstructionResult = CastDiagnosticsUtil.findStaticallyKnownSubtype(
|
||||
TypeUtils.makeNotNullable(subjectType),
|
||||
getBareTypeConstructor()
|
||||
);
|
||||
JetType type = reconstructionResult.getResultingType();
|
||||
// No need to make an absent type nullable
|
||||
if (type == null) return type;
|
||||
if (type == null) return reconstructionResult;
|
||||
|
||||
return TypeUtils.makeNullableAsSpecified(type, isBareTypeNullable());
|
||||
JetType resultingType = TypeUtils.makeNullableAsSpecified(type, isBareTypeNullable());
|
||||
return new TypeReconstructionResult(resultingType, reconstructionResult.isAllArgumentsInferred());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -112,7 +112,7 @@ public class CastDiagnosticsUtil {
|
||||
// NOTE: this does not account for 'as Array<List<T>>'
|
||||
if (allParametersReified(subtype)) return false;
|
||||
|
||||
JetType staticallyKnownSubtype = findStaticallyKnownSubtype(supertype, subtype.getConstructor());
|
||||
JetType staticallyKnownSubtype = findStaticallyKnownSubtype(supertype, subtype.getConstructor()).getResultingType();
|
||||
|
||||
// If the substitution failed, it means that the result is an impossible type, e.g. something like Out<in Foo>
|
||||
// In this case, we can't guarantee anything, so the cast is considered to be erased
|
||||
@@ -132,14 +132,14 @@ public class CastDiagnosticsUtil {
|
||||
* Example 1:
|
||||
* supertype = Collection<String>
|
||||
* subtype = List<...>
|
||||
* result = List<String>
|
||||
* result = List<String>, all arguments are inferred
|
||||
*
|
||||
* Example 2:
|
||||
* supertype = Any
|
||||
* subtype = List<...>
|
||||
* result = List<*>
|
||||
* result = List<*>, some arguments were not inferred, replaced with '*'
|
||||
*/
|
||||
public static JetType findStaticallyKnownSubtype(@NotNull JetType supertype, @NotNull TypeConstructor subtypeConstructor) {
|
||||
public static TypeReconstructionResult findStaticallyKnownSubtype(@NotNull JetType supertype, @NotNull TypeConstructor subtypeConstructor) {
|
||||
assert !supertype.isNullable() : "This method only makes sense for non-nullable types";
|
||||
|
||||
// Assume we are casting an expression of type Collection<Foo> to List<Bar>
|
||||
@@ -176,6 +176,7 @@ public class CastDiagnosticsUtil {
|
||||
|
||||
// If some of the parameters are not determined by unification, it means that these parameters are lost,
|
||||
// let's put stars instead, so that we can only cast to something like List<*>, e.g. (a: Any) as List<*>
|
||||
boolean allArgumentsInferred = true;
|
||||
for (TypeParameterDescriptor variable : variables) {
|
||||
TypeProjection value = substitution.get(variable.getTypeConstructor());
|
||||
if (value == null) {
|
||||
@@ -183,12 +184,15 @@ public class CastDiagnosticsUtil {
|
||||
variable.getTypeConstructor(),
|
||||
SubstitutionUtils.makeStarProjection(variable)
|
||||
);
|
||||
allArgumentsInferred = false;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we have values for all type parameters of List
|
||||
// Let's make a type by substituting them: List<T> -> List<Foo>
|
||||
return TypeSubstitutor.create(substitution).substitute(subtypeWithVariables, Variance.INVARIANT);
|
||||
JetType substituted = TypeSubstitutor.create(substitution).substitute(subtypeWithVariables, Variance.INVARIANT);
|
||||
|
||||
return new TypeReconstructionResult(substituted, allArgumentsInferred);
|
||||
}
|
||||
|
||||
private static boolean allParametersReified(JetType subtype) {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TypeReconstructionResult {
|
||||
private final JetType resultingType;
|
||||
private final boolean allArgumentsInferred;
|
||||
|
||||
public TypeReconstructionResult(@Nullable JetType resultingType, boolean allArgumentsInferred) {
|
||||
this.resultingType = resultingType;
|
||||
this.allArgumentsInferred = allArgumentsInferred;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetType getResultingType() {
|
||||
return resultingType;
|
||||
}
|
||||
|
||||
public boolean isAllArgumentsInferred() {
|
||||
return allArgumentsInferred;
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -62,7 +62,9 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.utils.ThrowingList;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
@@ -77,12 +79,14 @@ import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils.resolveSpecialConstructionAsCall;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
import static org.jetbrains.jet.lang.types.expressions.TypeReconstructionUtil.reconstructBareType;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.AS_KEYWORD;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.AS_SAFE;
|
||||
|
||||
@SuppressWarnings("SuspiciousMethodCalls")
|
||||
public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
private static final TokenSet BARE_TYPES_ALLOWED = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, NOT_IS);
|
||||
private static final TokenSet BARE_TYPES_ALLOWED = TokenSet.create(AS_KEYWORD, AS_SAFE);
|
||||
|
||||
private final PlatformToKotlinClassMap platformToKotlinClassMap;
|
||||
|
||||
@@ -192,10 +196,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||
JetType subjectType = typeInfo.getType();
|
||||
JetType targetType;
|
||||
if (subjectType != null) {
|
||||
targetType = possiblyBareTarget.reconstruct(subjectType);
|
||||
JetType targetType = reconstructBareType(right, possiblyBareTarget, subjectType, context.trace);
|
||||
|
||||
if (subjectType != null) {
|
||||
checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, subjectType);
|
||||
dataFlowInfo = typeInfo.getDataFlowInfo();
|
||||
if (operationType == AS_KEYWORD) {
|
||||
@@ -204,10 +207,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
dataFlowInfo = dataFlowInfo.establishSubtyping(value, targetType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Recovery: let's reconstruct as if we were casting from Any, to get some type there
|
||||
targetType = possiblyBareTarget.reconstruct(KotlinBuiltIns.getInstance().getAnyType());
|
||||
}
|
||||
|
||||
JetType result = operationType == AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
|
||||
return DataFlowUtils.checkType(result, expression, context, dataFlowInfo);
|
||||
}
|
||||
|
||||
+1
-4
@@ -283,10 +283,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, /*allowBareTypes=*/ true);
|
||||
PossiblyBareType possiblyBareTarget = context.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, typeReferenceAfterIs);
|
||||
JetType type = possiblyBareTarget.reconstruct(subjectType);
|
||||
if (possiblyBareTarget.isBare()) {
|
||||
context.trace.record(BindingContext.TYPE, typeReferenceAfterIs, type);
|
||||
}
|
||||
JetType type = TypeReconstructionUtil.reconstructBareType(typeReferenceAfterIs, possiblyBareTarget, subjectType, context.trace);
|
||||
if (!subjectType.isNullable() && type.isNullable()) {
|
||||
JetTypeElement element = typeReferenceAfterIs.getTypeElement();
|
||||
assert element instanceof JetNullableType : "element must be instance of " + JetNullableType.class.getName();
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.types.expressions;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.PossiblyBareType;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.NO_TYPE_ARGUMENTS_ON_RHS;
|
||||
|
||||
public class TypeReconstructionUtil {
|
||||
@NotNull
|
||||
public static JetType reconstructBareType(
|
||||
@NotNull JetTypeReference right,
|
||||
@NotNull PossiblyBareType possiblyBareTarget,
|
||||
@Nullable JetType subjectType,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
if (subjectType == null) {
|
||||
// Recovery: let's reconstruct as if we were casting from Any, to get some type there
|
||||
subjectType = KotlinBuiltIns.getInstance().getAnyType();
|
||||
}
|
||||
TypeReconstructionResult reconstructionResult = possiblyBareTarget.reconstruct(subjectType);
|
||||
if (!reconstructionResult.isAllArgumentsInferred()) {
|
||||
TypeConstructor typeConstructor = possiblyBareTarget.getBareTypeConstructor();
|
||||
trace.report(NO_TYPE_ARGUMENTS_ON_RHS.on(right,
|
||||
typeConstructor.getParameters().size(),
|
||||
allStarProjectionsString(typeConstructor)));
|
||||
}
|
||||
|
||||
JetType targetType = reconstructionResult.getResultingType();
|
||||
if (targetType != null) {
|
||||
if (possiblyBareTarget.isBare()) {
|
||||
trace.record(BindingContext.TYPE, right, targetType);
|
||||
}
|
||||
return targetType;
|
||||
}
|
||||
|
||||
return ErrorUtils.createErrorType("Failed to reconstruct type: " + right.getText());
|
||||
}
|
||||
|
||||
@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().asString();
|
||||
|
||||
return TypeUtils.getTypeNameAndStarProjectionsString(name, size);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
trait Tr
|
||||
trait G<T>
|
||||
|
||||
fun test(tr: Tr) {
|
||||
val v = tr as <!NO_TYPE_ARGUMENTS_ON_RHS!>G?<!>
|
||||
// If v is not nullable, there will be a warning on this line:
|
||||
v!!: G<*>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class G<T>
|
||||
|
||||
fun foo(p: <!UNRESOLVED_REFERENCE!>P<!>) {
|
||||
val v = <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>p<!> <!USELESS_CAST!>as<!> <!NO_TYPE_ARGUMENTS_ON_RHS!>G?<!>
|
||||
v!!: G<*>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
trait Tr
|
||||
trait G<T>
|
||||
|
||||
fun test(tr: Tr?) {
|
||||
val v = tr as <!NO_TYPE_ARGUMENTS_ON_RHS!>G<!>
|
||||
v: G<*>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
trait Tr<T>
|
||||
trait G<T> : Tr<T>
|
||||
|
||||
fun test(tr: Tr<String>?) {
|
||||
val v = tr as G?
|
||||
// If v is not nullable, there will be a warning on this line:
|
||||
v!!: G<String>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
trait Tr
|
||||
trait G<T>
|
||||
|
||||
fun test(tr: Tr?) {
|
||||
val v = tr as <!NO_TYPE_ARGUMENTS_ON_RHS!>G?<!>
|
||||
v!!: G<*>
|
||||
}
|
||||
@@ -2,6 +2,6 @@ trait Tr
|
||||
trait G<T>
|
||||
|
||||
fun test(tr: Tr) {
|
||||
val v = tr as G
|
||||
val v = tr as <!NO_TYPE_ARGUMENTS_ON_RHS!>G<!>
|
||||
v: G<*>
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
trait Tr
|
||||
trait G<T>
|
||||
|
||||
fun test(tr: Tr) = tr is G
|
||||
fun test(tr: Tr) = tr is <!NO_TYPE_ARGUMENTS_ON_RHS!>G<!>
|
||||
@@ -2,15 +2,13 @@ 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 <!NO_TYPE_ARGUMENTS_ON_RHS!>Map<!>
|
||||
a is Map<out Any?, Any?>
|
||||
a is Map<*, *>
|
||||
a is Map<<!SYNTAX!><!>>
|
||||
a is List<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>>
|
||||
a is <!NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION!>List<!>
|
||||
a is <!NO_TYPE_ARGUMENTS_ON_RHS!>List<!>
|
||||
a is Int
|
||||
|
||||
(a <!USELESS_CAST!>as<!> <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) is Int
|
||||
}
|
||||
|
||||
|
||||
(a as <!NO_TYPE_ARGUMENTS_ON_RHS!>Map<!>) is <!INCOMPATIBLE_TYPES!>Int<!>
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
public fun foo(a: Any, <!UNUSED_PARAMETER!>b<!>: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) {
|
||||
when (a) {
|
||||
is Map<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!> -> {}
|
||||
is <!NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION!>Map<!> -> {}
|
||||
is <!NO_TYPE_ARGUMENTS_ON_RHS!>Map<!> -> {}
|
||||
is Map<out Any?, Any?> -> {}
|
||||
is Map<*, *> -> {}
|
||||
is Map<<!SYNTAX!><!>> -> {}
|
||||
is List<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>> -> {}
|
||||
is <!NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION!>List<!> -> {}
|
||||
is <!NO_TYPE_ARGUMENTS_ON_RHS!>List<!> -> {}
|
||||
is Int -> {}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
@@ -1201,6 +1201,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/AsNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("AsNullableNotEnough.kt")
|
||||
public void testAsNullableNotEnough() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/AsNullableNotEnough.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("EitherAs.kt")
|
||||
public void testEitherAs() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/EitherAs.kt");
|
||||
@@ -1231,11 +1236,31 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/ErrorsInSubstitution.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FromErrorType.kt")
|
||||
public void testFromErrorType() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/FromErrorType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NullableAs.kt")
|
||||
public void testNullableAs() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/NullableAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NullableAsNotEnough.kt")
|
||||
public void testNullableAsNotEnough() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/NullableAsNotEnough.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NullableAsNullable.kt")
|
||||
public void testNullableAsNullable() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/NullableAsNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NullableAsNullableNotEnough.kt")
|
||||
public void testNullableAsNullableNotEnough() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/NullableAsNullableNotEnough.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("RedundantNullable.kt")
|
||||
public void testRedundantNullable() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt");
|
||||
|
||||
@@ -72,14 +72,17 @@ public abstract class AddStarProjectionsFix extends JetIntentionAction<JetUserTy
|
||||
return new JetSingleIntentionActionFactory() {
|
||||
@Override
|
||||
public IntentionAction createAction(Diagnostic diagnostic) {
|
||||
assert diagnostic.getFactory() == Errors.NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION;
|
||||
assert diagnostic.getFactory() == Errors.NO_TYPE_ARGUMENTS_ON_RHS;
|
||||
@SuppressWarnings("unchecked")
|
||||
DiagnosticWithParameters2<JetUserType, Integer, String> diagnosticWithParameters =
|
||||
(DiagnosticWithParameters2<JetUserType, Integer, String>) diagnostic;
|
||||
JetUserType userType = QuickFixUtil.getParentElementOfType(diagnostic, JetUserType.class);
|
||||
if (userType == null) return null;
|
||||
DiagnosticWithParameters2<JetTypeReference, Integer, String> diagnosticWithParameters =
|
||||
(DiagnosticWithParameters2<JetTypeReference, Integer, String>) diagnostic;
|
||||
JetTypeElement typeElement = diagnosticWithParameters.getPsiElement().getTypeElement();
|
||||
while (typeElement instanceof JetNullableType) {
|
||||
typeElement = ((JetNullableType) typeElement).getInnerType();
|
||||
}
|
||||
if (!(typeElement instanceof JetUserType)) return null;
|
||||
Integer size = diagnosticWithParameters.getA();
|
||||
return new AddStarProjectionsFix(userType, size) {};
|
||||
return new AddStarProjectionsFix((JetUserType) typeElement, size) {};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ public class QuickFixes {
|
||||
factories.put(ELSE_MISPLACED_IN_WHEN, MoveWhenElseBranchFix.createFactory());
|
||||
factories.put(NO_ELSE_IN_WHEN, AddWhenElseBranchFix.createFactory());
|
||||
|
||||
factories.put(NO_TYPE_ARGUMENTS_ON_RHS_OF_IS_EXPRESSION, AddStarProjectionsFix.createFactoryForIsExpression());
|
||||
factories.put(NO_TYPE_ARGUMENTS_ON_RHS, AddStarProjectionsFix.createFactoryForIsExpression());
|
||||
factories.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, AddStarProjectionsFix.createFactoryForJavaClass());
|
||||
|
||||
factories.put(TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER, RemovePsiElementSimpleFix.createRemoveTypeArgumentsFactory());
|
||||
|
||||
Reference in New Issue
Block a user