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);
|
DiagnosticFactory0<JetNullableType> REDUNDANT_NULLABLE = DiagnosticFactory0.create(WARNING, NULLABLE_TYPE);
|
||||||
DiagnosticFactory1<JetNullableType, JetType> BASE_WITH_NULLABLE_UPPER_BOUND = DiagnosticFactory1.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);
|
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> CONFLICTING_PROJECTION = DiagnosticFactory1.create(ERROR, VARIANCE_IN_PROJECTION);
|
||||||
DiagnosticFactory1<JetTypeProjection, ClassifierDescriptor> REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, 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(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(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);
|
"Use ''{1}'' if you don''t want to pass type arguments", null, TO_STRING);
|
||||||
|
|
||||||
MAP.put(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED,
|
MAP.put(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED,
|
||||||
|
|||||||
@@ -79,17 +79,19 @@ public class PossiblyBareType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType reconstruct(@NotNull JetType subjectType) {
|
public TypeReconstructionResult reconstruct(@NotNull JetType subjectType) {
|
||||||
if (!isBare()) return getActualType();
|
if (!isBare()) return new TypeReconstructionResult(getActualType(), true);
|
||||||
|
|
||||||
JetType type = CastDiagnosticsUtil.findStaticallyKnownSubtype(
|
TypeReconstructionResult reconstructionResult = CastDiagnosticsUtil.findStaticallyKnownSubtype(
|
||||||
TypeUtils.makeNotNullable(subjectType),
|
TypeUtils.makeNotNullable(subjectType),
|
||||||
getBareTypeConstructor()
|
getBareTypeConstructor()
|
||||||
);
|
);
|
||||||
|
JetType type = reconstructionResult.getResultingType();
|
||||||
// No need to make an absent type nullable
|
// 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
|
@Override
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class CastDiagnosticsUtil {
|
|||||||
// NOTE: this does not account for 'as Array<List<T>>'
|
// NOTE: this does not account for 'as Array<List<T>>'
|
||||||
if (allParametersReified(subtype)) return false;
|
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>
|
// 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
|
// 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:
|
* Example 1:
|
||||||
* supertype = Collection<String>
|
* supertype = Collection<String>
|
||||||
* subtype = List<...>
|
* subtype = List<...>
|
||||||
* result = List<String>
|
* result = List<String>, all arguments are inferred
|
||||||
*
|
*
|
||||||
* Example 2:
|
* Example 2:
|
||||||
* supertype = Any
|
* supertype = Any
|
||||||
* subtype = List<...>
|
* 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";
|
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>
|
// 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,
|
// 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<*>
|
// 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) {
|
for (TypeParameterDescriptor variable : variables) {
|
||||||
TypeProjection value = substitution.get(variable.getTypeConstructor());
|
TypeProjection value = substitution.get(variable.getTypeConstructor());
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
@@ -183,12 +184,15 @@ public class CastDiagnosticsUtil {
|
|||||||
variable.getTypeConstructor(),
|
variable.getTypeConstructor(),
|
||||||
SubstitutionUtils.makeStarProjection(variable)
|
SubstitutionUtils.makeStarProjection(variable)
|
||||||
);
|
);
|
||||||
|
allArgumentsInferred = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point we have values for all type parameters of List
|
// At this point we have values for all type parameters of List
|
||||||
// Let's make a type by substituting them: List<T> -> List<Foo>
|
// 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) {
|
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.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.utils.ThrowingList;
|
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.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
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.createCallForSpecialConstruction;
|
||||||
import static org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils.resolveSpecialConstructionAsCall;
|
import static org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils.resolveSpecialConstructionAsCall;
|
||||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*;
|
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")
|
@SuppressWarnings("SuspiciousMethodCalls")
|
||||||
public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
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;
|
private final PlatformToKotlinClassMap platformToKotlinClassMap;
|
||||||
|
|
||||||
@@ -192,10 +196,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||||
JetType subjectType = typeInfo.getType();
|
JetType subjectType = typeInfo.getType();
|
||||||
JetType targetType;
|
JetType targetType = reconstructBareType(right, possiblyBareTarget, subjectType, context.trace);
|
||||||
if (subjectType != null) {
|
|
||||||
targetType = possiblyBareTarget.reconstruct(subjectType);
|
|
||||||
|
|
||||||
|
if (subjectType != null) {
|
||||||
checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, subjectType);
|
checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, subjectType);
|
||||||
dataFlowInfo = typeInfo.getDataFlowInfo();
|
dataFlowInfo = typeInfo.getDataFlowInfo();
|
||||||
if (operationType == AS_KEYWORD) {
|
if (operationType == AS_KEYWORD) {
|
||||||
@@ -204,10 +207,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
dataFlowInfo = dataFlowInfo.establishSubtyping(value, targetType);
|
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;
|
JetType result = operationType == AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
|
||||||
return DataFlowUtils.checkType(result, expression, context, dataFlowInfo);
|
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);
|
TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, /*allowBareTypes=*/ true);
|
||||||
PossiblyBareType possiblyBareTarget = context.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, typeReferenceAfterIs);
|
PossiblyBareType possiblyBareTarget = context.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, typeReferenceAfterIs);
|
||||||
JetType type = possiblyBareTarget.reconstruct(subjectType);
|
JetType type = TypeReconstructionUtil.reconstructBareType(typeReferenceAfterIs, possiblyBareTarget, subjectType, context.trace);
|
||||||
if (possiblyBareTarget.isBare()) {
|
|
||||||
context.trace.record(BindingContext.TYPE, typeReferenceAfterIs, type);
|
|
||||||
}
|
|
||||||
if (!subjectType.isNullable() && type.isNullable()) {
|
if (!subjectType.isNullable() && type.isNullable()) {
|
||||||
JetTypeElement element = typeReferenceAfterIs.getTypeElement();
|
JetTypeElement element = typeReferenceAfterIs.getTypeElement();
|
||||||
assert element instanceof JetNullableType : "element must be instance of " + JetNullableType.class.getName();
|
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>
|
trait G<T>
|
||||||
|
|
||||||
fun test(tr: Tr) {
|
fun test(tr: Tr) {
|
||||||
val v = tr as G
|
val v = tr as <!NO_TYPE_ARGUMENTS_ON_RHS!>G<!>
|
||||||
v: G<*>
|
v: G<*>
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
trait Tr
|
trait Tr
|
||||||
trait G<T>
|
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) {
|
public fun foo(a: Any) {
|
||||||
a is Map<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>
|
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<out Any?, Any?>
|
||||||
a is Map<*, *>
|
a is Map<*, *>
|
||||||
a is Map<<!SYNTAX!><!>>
|
a is Map<<!SYNTAX!><!>>
|
||||||
a is List<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>>
|
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 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<!>) {
|
public fun foo(a: Any, <!UNUSED_PARAMETER!>b<!>: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) {
|
||||||
when (a) {
|
when (a) {
|
||||||
is Map<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!> -> {}
|
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<out Any?, Any?> -> {}
|
||||||
is Map<*, *> -> {}
|
is Map<*, *> -> {}
|
||||||
is Map<<!SYNTAX!><!>> -> {}
|
is Map<<!SYNTAX!><!>> -> {}
|
||||||
is List<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>> -> {}
|
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 -> {}
|
is Int -> {}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1201,6 +1201,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/cast/bare/AsNullable.kt");
|
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")
|
@TestMetadata("EitherAs.kt")
|
||||||
public void testEitherAs() throws Exception {
|
public void testEitherAs() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/cast/bare/EitherAs.kt");
|
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");
|
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")
|
@TestMetadata("NullableAs.kt")
|
||||||
public void testNullableAs() throws Exception {
|
public void testNullableAs() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/cast/bare/NullableAs.kt");
|
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")
|
@TestMetadata("RedundantNullable.kt")
|
||||||
public void testRedundantNullable() throws Exception {
|
public void testRedundantNullable() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt");
|
doTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt");
|
||||||
|
|||||||
@@ -72,14 +72,17 @@ public abstract class AddStarProjectionsFix extends JetIntentionAction<JetUserTy
|
|||||||
return new JetSingleIntentionActionFactory() {
|
return new JetSingleIntentionActionFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IntentionAction createAction(Diagnostic diagnostic) {
|
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")
|
@SuppressWarnings("unchecked")
|
||||||
DiagnosticWithParameters2<JetUserType, Integer, String> diagnosticWithParameters =
|
DiagnosticWithParameters2<JetTypeReference, Integer, String> diagnosticWithParameters =
|
||||||
(DiagnosticWithParameters2<JetUserType, Integer, String>) diagnostic;
|
(DiagnosticWithParameters2<JetTypeReference, Integer, String>) diagnostic;
|
||||||
JetUserType userType = QuickFixUtil.getParentElementOfType(diagnostic, JetUserType.class);
|
JetTypeElement typeElement = diagnosticWithParameters.getPsiElement().getTypeElement();
|
||||||
if (userType == null) return null;
|
while (typeElement instanceof JetNullableType) {
|
||||||
|
typeElement = ((JetNullableType) typeElement).getInnerType();
|
||||||
|
}
|
||||||
|
if (!(typeElement instanceof JetUserType)) return null;
|
||||||
Integer size = diagnosticWithParameters.getA();
|
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(ELSE_MISPLACED_IN_WHEN, MoveWhenElseBranchFix.createFactory());
|
||||||
factories.put(NO_ELSE_IN_WHEN, AddWhenElseBranchFix.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(WRONG_NUMBER_OF_TYPE_ARGUMENTS, AddStarProjectionsFix.createFactoryForJavaClass());
|
||||||
|
|
||||||
factories.put(TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER, RemovePsiElementSimpleFix.createRemoveTypeArgumentsFactory());
|
factories.put(TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER, RemovePsiElementSimpleFix.createRemoveTypeArgumentsFactory());
|
||||||
|
|||||||
Reference in New Issue
Block a user