KT-657 Semantic checks for when without condition
This commit is contained in:
@@ -14,7 +14,6 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.*;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
@@ -2753,7 +2752,6 @@ If finally block is present, its last expression is the value of try expression.
|
||||
}
|
||||
|
||||
private StackValue generateWhenCondition(Type subjectType, int subjectLocal, JetWhenCondition condition, @Nullable Label nextEntry) {
|
||||
StackValue conditionValue;
|
||||
if (condition instanceof JetWhenConditionInRange) {
|
||||
JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition;
|
||||
JetExpression rangeExpression = conditionInRange.getRangeExpression();
|
||||
@@ -2768,16 +2766,22 @@ If finally block is present, its last expression is the value of try expression.
|
||||
}
|
||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
}
|
||||
else if (condition instanceof JetWhenConditionIsPattern) {
|
||||
JetPattern pattern;
|
||||
boolean isNegated;
|
||||
if (condition instanceof JetWhenConditionIsPattern) {
|
||||
JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition;
|
||||
JetPattern pattern = patternCondition.getPattern();
|
||||
conditionValue = generatePatternMatch(pattern, patternCondition.isNegated(),
|
||||
subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType), nextEntry);
|
||||
pattern = patternCondition.getPattern();
|
||||
isNegated = patternCondition.isNegated();
|
||||
}
|
||||
else if (condition instanceof JetWhenConditionWithExpression) {
|
||||
pattern = ((JetWhenConditionWithExpression) condition).getPattern();
|
||||
isNegated = false;
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("unsupported kind of when condition");
|
||||
}
|
||||
return conditionValue;
|
||||
return generatePatternMatch(pattern, isNegated,
|
||||
subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType), nextEntry);
|
||||
}
|
||||
|
||||
private boolean isIntRangeExpr(JetExpression rangeExpression) {
|
||||
|
||||
@@ -139,6 +139,7 @@ public interface JetNodeTypes {
|
||||
|
||||
JetNodeType WHEN_CONDITION_IN_RANGE = new JetNodeType("WHEN_CONDITION_IN_RANGE", JetWhenConditionInRange.class);
|
||||
JetNodeType WHEN_CONDITION_IS_PATTERN = new JetNodeType("WHEN_CONDITION_IS_PATTERN", JetWhenConditionIsPattern.class);
|
||||
JetNodeType WHEN_CONDITION_EXPRESSION = new JetNodeType("WHEN_CONDITION_WITH_EXPRESSION", JetWhenConditionWithExpression.class);
|
||||
|
||||
JetNodeType NAMESPACE_HEADER = new JetNodeType("NAMESPACE_HEADER", JetNamespaceHeader.class);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,14 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionExpression(JetWhenConditionWithExpression condition) {
|
||||
JetExpressionPattern pattern = condition.getPattern();
|
||||
if (pattern != null) {
|
||||
pattern.accept(patternVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
||||
|
||||
@@ -320,6 +320,7 @@ public interface Errors {
|
||||
ParameterizedDiagnosticFactory2<JetType, Integer> TYPE_MISMATCH_IN_TUPLE_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "Type mismatch: subject is of type {0} but the pattern is of type Tuple{1}"); // TODO: message
|
||||
ParameterizedDiagnosticFactory2<JetType, JetType> TYPE_MISMATCH_IN_BINDING_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "{0} must be a supertype of {1}. Use 'is' to match against {0}");
|
||||
ParameterizedDiagnosticFactory2<JetType, JetType> INCOMPATIBLE_TYPES = ParameterizedDiagnosticFactory2.create(ERROR, "Incompatible types: {0} and {1}");
|
||||
SimpleDiagnosticFactory EXPECTED_CONDITION = SimpleDiagnosticFactory.create(ERROR, "Expected condition of Boolean type");
|
||||
|
||||
ParameterizedDiagnosticFactory1<JetType> CANNOT_CHECK_FOR_ERASED = ParameterizedDiagnosticFactory1.create(ERROR, "Cannot check for instance of erased type: {0}");
|
||||
ParameterizedDiagnosticFactory2<JetType, JetType> UNCHECKED_CAST = ParameterizedDiagnosticFactory2.create(WARNING, "Unchecked cast: {0} to {1}");
|
||||
|
||||
@@ -844,7 +844,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
parseExpression();
|
||||
}
|
||||
expressionPattern.done(EXPRESSION_PATTERN);
|
||||
condition.done(WHEN_CONDITION_IS_PATTERN);
|
||||
condition.done(WHEN_CONDITION_EXPRESSION);
|
||||
}
|
||||
myBuilder.restoreNewlinesState();
|
||||
}
|
||||
|
||||
@@ -359,6 +359,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
|
||||
public R visitWhenConditionInRange(JetWhenConditionInRange condition, D data) {
|
||||
return visitJetElement(condition, data);
|
||||
}
|
||||
|
||||
public R visitWhenConditionExpression(JetWhenConditionWithExpression condition, D data) {
|
||||
return visitJetElement(condition, data);
|
||||
}
|
||||
|
||||
public R visitTypePattern(JetTypePattern pattern, D data) {
|
||||
return visitPattern(pattern, data);
|
||||
|
||||
@@ -358,6 +358,10 @@ public class JetVisitorVoid extends PsiElementVisitor {
|
||||
visitJetElement(condition);
|
||||
}
|
||||
|
||||
public void visitWhenConditionExpression(JetWhenConditionWithExpression condition) {
|
||||
visitJetElement(condition);
|
||||
}
|
||||
|
||||
public void visitTypePattern(JetTypePattern pattern) {
|
||||
visitPattern(pattern);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class JetWhenConditionWithExpression extends JetWhenCondition {
|
||||
public JetWhenConditionWithExpression(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@IfNotParsed
|
||||
public JetExpressionPattern getPattern() {
|
||||
return findChildByClass(JetExpressionPattern.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull JetVisitorVoid visitor) {
|
||||
visitor.visitWhenConditionExpression(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitWhenConditionExpression(this, data);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -814,7 +814,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return DataFlowUtils.checkType(result, expression, contextWithExpectedType);
|
||||
}
|
||||
|
||||
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
||||
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
||||
String name = "contains";
|
||||
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||
OverloadResolutionResults<FunctionDescriptor> functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
@Nullable
|
||||
JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ExpressionTypingContext context);
|
||||
|
||||
void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context);
|
||||
void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context);
|
||||
|
||||
void checkStatementType(@NotNull JetExpression expression, ExpressionTypingContext context);
|
||||
}
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetType, Expre
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
||||
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
||||
basic.checkInExpression(callElement, operationSign, left, right, context);
|
||||
}
|
||||
|
||||
|
||||
+51
-38
@@ -38,7 +38,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetPattern pattern = expression.getPattern();
|
||||
if (pattern != null) {
|
||||
WritableScopeImpl scopeToExtend = newWritableScopeImpl(context).setDebugName("Scope extended in 'is'");
|
||||
DataFlowInfo newDataFlowInfo = checkPatternType(pattern, knownType, scopeToExtend, context, DataFlowValueFactory.INSTANCE.createDataFlowValue(leftHandSide, knownType, context.trace.getBindingContext()));
|
||||
DataFlowInfo newDataFlowInfo = checkPatternType(pattern, knownType, false, scopeToExtend, context, DataFlowValueFactory.INSTANCE.createDataFlowValue(leftHandSide, knownType, context.trace.getBindingContext()));
|
||||
context.patternsToDataFlowInfo.put(pattern, newDataFlowInfo);
|
||||
context.patternsToBoundVariableLists.put(pattern, scopeToExtend.getDeclaredVariables());
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
final JetExpression subjectExpression = expression.getSubjectExpression();
|
||||
|
||||
final JetType subjectType = subjectExpression != null ? context.getServices().safeGetType(context.scope, subjectExpression, TypeUtils.NO_EXPECTED_TYPE) : ErrorUtils.createErrorType("Unknown type");
|
||||
final DataFlowValue variableDescriptor = subjectExpression != null ? DataFlowValueFactory.INSTANCE.createDataFlowValue(subjectExpression, subjectType, context.trace.getBindingContext()) : null;
|
||||
final DataFlowValue variableDescriptor = subjectExpression != null ? DataFlowValueFactory.INSTANCE.createDataFlowValue(subjectExpression, subjectType, context.trace.getBindingContext()) : DataFlowValue.NULL;
|
||||
|
||||
// TODO : exhaustive patterns
|
||||
|
||||
@@ -70,14 +70,14 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
newDataFlowInfo = context.dataFlowInfo;
|
||||
JetWhenCondition condition = conditions[0];
|
||||
if (condition != null) {
|
||||
newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, scopeToExtend, context, variableDescriptor);
|
||||
newDataFlowInfo = checkWhenCondition(subjectExpression, subjectExpression == null, subjectType, condition, scopeToExtend, context, variableDescriptor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
scopeToExtend = newWritableScopeImpl(context); // We don't write to this scope
|
||||
newDataFlowInfo = null;
|
||||
for (JetWhenCondition condition : conditions) {
|
||||
DataFlowInfo dataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, newWritableScopeImpl(context), context, variableDescriptor);
|
||||
DataFlowInfo dataFlowInfo = checkWhenCondition(subjectExpression, subjectExpression == null, subjectType, condition, newWritableScopeImpl(context), context, variableDescriptor);
|
||||
if (newDataFlowInfo == null) {
|
||||
newDataFlowInfo = dataFlowInfo;
|
||||
}
|
||||
@@ -113,47 +113,59 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataFlowInfo checkWhenCondition(@Nullable final JetExpression subjectExpression, final JetType subjectType, JetWhenCondition condition, final WritableScope scopeToExtend, final ExpressionTypingContext context, final DataFlowValue... subjectVariables) {
|
||||
private DataFlowInfo checkWhenCondition(@Nullable final JetExpression subjectExpression, final boolean expectedCondition, final JetType subjectType, JetWhenCondition condition, final WritableScope scopeToExtend, final ExpressionTypingContext context, final DataFlowValue... subjectVariables) {
|
||||
final DataFlowInfo[] newDataFlowInfo = new DataFlowInfo[]{context.dataFlowInfo};
|
||||
condition.accept(new JetVisitorVoid() {
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
||||
JetExpression rangeExpression = condition.getRangeExpression();
|
||||
if (rangeExpression != null) {
|
||||
assert subjectExpression != null;
|
||||
facade.checkInExpression(condition, condition.getOperationReference(), subjectExpression, rangeExpression, context);
|
||||
if (rangeExpression == null) return;
|
||||
if (expectedCondition) {
|
||||
context.trace.report(EXPECTED_CONDITION.on(condition));
|
||||
facade.getType(rangeExpression, context);
|
||||
return;
|
||||
}
|
||||
facade.checkInExpression(condition, condition.getOperationReference(), subjectExpression, rangeExpression, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
||||
JetPattern pattern = condition.getPattern();
|
||||
if (expectedCondition) {
|
||||
context.trace.report(EXPECTED_CONDITION.on(condition));
|
||||
}
|
||||
if (pattern != null) {
|
||||
newDataFlowInfo[0] = checkPatternType(pattern, subjectType, scopeToExtend, context, subjectVariables);
|
||||
newDataFlowInfo[0] = checkPatternType(pattern, subjectType, subjectExpression == null, scopeToExtend, context, subjectVariables);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionExpression(JetWhenConditionWithExpression condition) {
|
||||
JetPattern pattern = condition.getPattern();
|
||||
if (pattern != null) {
|
||||
newDataFlowInfo[0] = checkPatternType(pattern, subjectType, subjectExpression == null, scopeToExtend, context, subjectVariables);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [OperatorConventions] : " + element);
|
||||
context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName()));
|
||||
}
|
||||
});
|
||||
return newDataFlowInfo[0];
|
||||
}
|
||||
|
||||
private DataFlowInfo checkPatternType(@NotNull JetPattern pattern, @NotNull final JetType subjectType, @NotNull final WritableScope scopeToExtend, final ExpressionTypingContext context, @NotNull final DataFlowValue... subjectVariables) {
|
||||
private DataFlowInfo checkPatternType(@NotNull JetPattern pattern, @NotNull final JetType subjectType, final boolean conditionExpected, @NotNull final WritableScope scopeToExtend, final ExpressionTypingContext context, @NotNull final DataFlowValue... subjectVariables) {
|
||||
final Ref<DataFlowInfo> result = new Ref<DataFlowInfo>(context.dataFlowInfo);
|
||||
pattern.accept(new JetVisitorVoid() {
|
||||
@Override
|
||||
public void visitTypePattern(JetTypePattern typePattern) {
|
||||
JetTypeReference typeReference = typePattern.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
JetType type = context.getTypeResolver().resolveType(context.scope, typeReference);
|
||||
checkTypeCompatibility(type, subjectType, typePattern);
|
||||
result.set(context.dataFlowInfo.establishSubtyping(subjectVariables, type));
|
||||
}
|
||||
if (typeReference == null) return;
|
||||
JetType type = context.getTypeResolver().resolveType(context.scope, typeReference);
|
||||
checkTypeCompatibility(type, subjectType, typePattern);
|
||||
result.set(context.dataFlowInfo.establishSubtyping(subjectVariables, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,25 +174,23 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
TypeConstructor typeConstructor = subjectType.getConstructor();
|
||||
if (!JetStandardClasses.getTuple(entries.size()).getTypeConstructor().equals(typeConstructor)
|
||||
|| typeConstructor.getParameters().size() != entries.size()) {
|
||||
// context.trace.getErrorHandler().genericError(pattern.getNode(), "Type mismatch: subject is of type " + subjectType + " but the pattern is of type Tuple" + entries.size());
|
||||
context.trace.report(TYPE_MISMATCH_IN_TUPLE_PATTERN.on(pattern, subjectType, entries.size()));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
for (int i = 0, entriesSize = entries.size(); i < entriesSize; i++) {
|
||||
JetTuplePatternEntry entry = entries.get(i);
|
||||
JetType type = subjectType.getArguments().get(i).getType();
|
||||
for (int i = 0, entriesSize = entries.size(); i < entriesSize; i++) {
|
||||
JetTuplePatternEntry entry = entries.get(i);
|
||||
JetType type = subjectType.getArguments().get(i).getType();
|
||||
|
||||
// TODO : is a name always allowed, ie for tuple patterns, not decomposer arg lists?
|
||||
ASTNode nameLabelNode = entry.getNameLabelNode();
|
||||
if (nameLabelNode != null) {
|
||||
// TODO : is a name always allowed, ie for tuple patterns, not decomposer arg lists?
|
||||
ASTNode nameLabelNode = entry.getNameLabelNode();
|
||||
if (nameLabelNode != null) {
|
||||
// context.trace.getErrorHandler().genericError(nameLabelNode, "Unsupported [OperatorConventions]");
|
||||
context.trace.report(UNSUPPORTED.on(nameLabelNode, getClass().getCanonicalName()));
|
||||
}
|
||||
context.trace.report(UNSUPPORTED.on(nameLabelNode, getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
JetPattern entryPattern = entry.getPattern();
|
||||
if (entryPattern != null) {
|
||||
result.set(result.get().and(checkPatternType(entryPattern, type, scopeToExtend, context)));
|
||||
}
|
||||
JetPattern entryPattern = entry.getPattern();
|
||||
if (entryPattern != null) {
|
||||
result.set(result.get().and(checkPatternType(entryPattern, type, false, scopeToExtend, context)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +204,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
result.set(checkPatternType(pattern.getArgumentList(), selectorReturnType == null
|
||||
? ErrorUtils.createErrorType("No type")
|
||||
: selectorReturnType, scopeToExtend, context));
|
||||
: selectorReturnType, false, scopeToExtend, context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,10 +216,16 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
@Override
|
||||
public void visitExpressionPattern(JetExpressionPattern pattern) {
|
||||
JetExpression expression = pattern.getExpression();
|
||||
if (expression != null) {
|
||||
JetType type = facade.getType(expression, context.replaceScope(scopeToExtend));
|
||||
checkTypeCompatibility(type, subjectType, pattern);
|
||||
if (expression == null) return;
|
||||
JetType type = facade.getType(expression, context.replaceScope(scopeToExtend));
|
||||
if (conditionExpected) {
|
||||
JetType booleanType = context.semanticServices.getStandardLibrary().getBooleanType();
|
||||
if (type != null && !context.semanticServices.getTypeChecker().equalTypes(booleanType, type)) {
|
||||
context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(pattern, type));
|
||||
}
|
||||
return;
|
||||
}
|
||||
checkTypeCompatibility(type, subjectType, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,7 +237,6 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
scopeToExtend.addVariableDescriptor(variableDescriptor);
|
||||
if (propertyTypeRef != null) {
|
||||
if (!context.semanticServices.getTypeChecker().isSubtypeOf(subjectType, type)) {
|
||||
// context.trace.getErrorHandler().genericError(propertyTypeRef.getNode(), type + " must be a supertype of " + subjectType + ". Use 'is' to match against " + type);
|
||||
context.trace.report(TYPE_MISMATCH_IN_BINDING_PATTERN.on(propertyTypeRef, type, subjectType));
|
||||
}
|
||||
}
|
||||
@@ -232,7 +247,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
DataFlowValue[] newSubjectVariables = new DataFlowValue[oldLength + 1];
|
||||
System.arraycopy(subjectVariables, 0, newSubjectVariables, 0, oldLength);
|
||||
newSubjectVariables[oldLength] = DataFlowValueFactory.INSTANCE.createDataFlowValue(variableDescriptor);
|
||||
result.set(checkWhenCondition(null, subjectType, condition, scopeToExtend, context, newSubjectVariables));
|
||||
result.set(checkWhenCondition(null, false, subjectType, condition, scopeToExtend, context, newSubjectVariables));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +260,6 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
return;
|
||||
}
|
||||
if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) {
|
||||
// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType);
|
||||
context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType));
|
||||
return;
|
||||
}
|
||||
@@ -257,7 +271,6 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [OperatorConventions]");
|
||||
context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//KT-657 Semantic checks for when without condition
|
||||
package kt657
|
||||
|
||||
fun foo() =
|
||||
when {
|
||||
cond1() -> 12
|
||||
cond2() -> 2
|
||||
<!TYPE_MISMATCH_IN_CONDITION!>4<!> -> 34
|
||||
<!TYPE_MISMATCH_IN_CONDITION!>#(1, 2)<!> -> 3
|
||||
<!EXPECTED_CONDITION!>in 1..10<!> -> 34
|
||||
<!TYPE_MISMATCH_IN_CONDITION!>4<!> -> 38
|
||||
<!EXPECTED_CONDITION!>is val a in 1..10<!> -> 23
|
||||
<!EXPECTED_CONDITION!>is Int<!> -> 33
|
||||
<!EXPECTED_CONDITION!>is <!TYPE_MISMATCH_IN_TUPLE_PATTERN!>#(val a, 3)<!><!> -> 2
|
||||
<!EXPECTED_CONDITION!>!is <!TYPE_MISMATCH_IN_TUPLE_PATTERN!>#(*, 1100)<!><!> -> 3
|
||||
<!EXPECTED_CONDITION!>is *<!> -> 34
|
||||
}
|
||||
|
||||
fun cond1() = false
|
||||
|
||||
fun cond2() = true
|
||||
@@ -23,7 +23,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -38,7 +38,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -57,7 +57,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -81,7 +81,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -111,7 +111,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -146,7 +146,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -166,7 +166,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -189,7 +189,7 @@ JetFile: CallsInWhen.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
|
||||
@@ -309,7 +309,7 @@ JetFile: NewlinesInParentheses.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
|
||||
@@ -1068,7 +1068,7 @@ JetFile: ShortAnnotations.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
|
||||
@@ -762,7 +762,7 @@ JetFile: When.jet
|
||||
PsiElement(IDENTIFIER)('Bar')
|
||||
PsiWhiteSpace(' ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
||||
<empty list>
|
||||
@@ -1086,13 +1086,13 @@ JetFile: When.jet
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -1102,13 +1102,13 @@ JetFile: When.jet
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
BINARY_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
@@ -1228,7 +1228,7 @@ JetFile: When.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('3')
|
||||
@@ -1242,7 +1242,7 @@ JetFile: When.jet
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -1263,7 +1263,7 @@ JetFile: When.jet
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -1276,7 +1276,7 @@ JetFile: When.jet
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
@@ -1297,7 +1297,7 @@ JetFile: When.jet
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
BINARY_WITH_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
|
||||
@@ -81,7 +81,7 @@ JetFile: When_ERR.jet
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
||||
<empty list>
|
||||
@@ -163,7 +163,7 @@ JetFile: When_ERR.jet
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
||||
<empty list>
|
||||
|
||||
@@ -433,7 +433,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('EQ')
|
||||
@@ -444,7 +444,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(true)('true')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('LS')
|
||||
@@ -471,7 +471,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('GT')
|
||||
@@ -708,7 +708,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('EQ')
|
||||
@@ -719,7 +719,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(false)('false')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('LS')
|
||||
@@ -748,7 +748,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('GT')
|
||||
@@ -886,7 +886,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('EQ')
|
||||
@@ -900,7 +900,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(false)('false')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('LS')
|
||||
@@ -986,7 +986,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('GT')
|
||||
@@ -1257,7 +1257,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('EQ')
|
||||
@@ -1268,7 +1268,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(IDENTIFIER)('node')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('LS')
|
||||
@@ -1290,7 +1290,7 @@ JetFile: BinaryTree.jet
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
EXPRESSION_PATTERN
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('GT')
|
||||
|
||||
Reference in New Issue
Block a user