Autocasts & binding patterns in 'when'-expressions
This commit is contained in:
@@ -641,6 +641,8 @@ public class JetControlFlowProcessor {
|
||||
JetWhenCondition condition = whenEntry.getCondition();
|
||||
if (condition != null) {
|
||||
condition.accept(new JetVisitor() {
|
||||
private final JetVisitor conditionVisitor = this;
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionWithExpression(JetWhenConditionWithExpression condition) {
|
||||
value(condition.getExpression(), false, inCondition); // TODO : inCondition?
|
||||
@@ -689,6 +691,14 @@ public class JetControlFlowProcessor {
|
||||
pattern.getArgumentList().accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBindingPattern(JetBindingPattern pattern) {
|
||||
JetWhenCondition condition = pattern.getCondition();
|
||||
if (condition != null) {
|
||||
condition.accept(conditionVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
||||
|
||||
@@ -886,22 +886,37 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
private void parseBindingPattern() {
|
||||
assert _at(VAL_KEYWORD);
|
||||
|
||||
PsiBuilder.Marker declaration = mark();
|
||||
|
||||
advance(); // VAL_KEYWORD
|
||||
|
||||
expect(IDENTIFIER, "Expecting an identifier");
|
||||
|
||||
if (at(IS_KEYWORD) || at(NOT_IS)) {
|
||||
advance(); // IS_KEYWORD or NOT_IS
|
||||
|
||||
parsePattern();
|
||||
} else if (at(IN_KEYWORD) || at(NOT_IN)) {
|
||||
advance(); // IN_KEYWORD ot NOT_IN
|
||||
|
||||
parseExpression();
|
||||
} else if (at(COLON)) {
|
||||
if (at(COLON)) {
|
||||
advance(); // EQ
|
||||
|
||||
myJetParsing.parseTypeRef();
|
||||
declaration.done(PROPERTY);
|
||||
}
|
||||
else {
|
||||
declaration.done(PROPERTY);
|
||||
PsiBuilder.Marker subCondition = mark();
|
||||
if (at(IS_KEYWORD) || at(NOT_IS)) {
|
||||
|
||||
advance(); // IS_KEYWORD or NOT_IS
|
||||
|
||||
parsePattern();
|
||||
subCondition.done(WHEN_CONDITION_IS_PATTERN);
|
||||
} else if (at(IN_KEYWORD) || at(NOT_IN)) {
|
||||
PsiBuilder.Marker mark = mark();
|
||||
advance(); // IN_KEYWORD ot NOT_IN
|
||||
mark.done(OPERATION_REFERENCE);
|
||||
|
||||
parseExpression();
|
||||
subCondition.done(WHEN_CONDITION_IN_RANGE);
|
||||
} else {
|
||||
subCondition.drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -12,10 +13,18 @@ public class JetBindingPattern extends JetPattern {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public boolean isVar() {
|
||||
return findChildByType(JetTokens.VAR_KEYWORD) != null;
|
||||
@NotNull
|
||||
public JetProperty getVariableDeclaration() {
|
||||
return (JetProperty) findChildByType(JetNodeTypes.PROPERTY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetWhenCondition getCondition() {
|
||||
return findChildByClass(JetWhenCondition.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull JetVisitor visitor) {
|
||||
visitor.visitBindingPattern(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,4 +397,8 @@ public class JetVisitor extends PsiElementVisitor {
|
||||
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
|
||||
visitNamedDeclaration(declaration);
|
||||
}
|
||||
|
||||
public void visitBindingPattern(JetBindingPattern pattern) {
|
||||
visitPattern(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,9 +413,14 @@ public class ClassDescriptorResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
|
||||
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property) {
|
||||
JetType type = getVariableType(scope, property, false); // For a local variable the type must not be deferred
|
||||
|
||||
return resolveLocalVariableDescriptorWithType(containingDeclaration, property, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VariableDescriptor resolveLocalVariableDescriptorWithType(DeclarationDescriptor containingDeclaration, JetProperty property, JetType type) {
|
||||
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
|
||||
containingDeclaration,
|
||||
AnnotationResolver.INSTANCE.resolveAnnotations(property.getModifierList()),
|
||||
|
||||
@@ -160,7 +160,7 @@ public class ErrorUtils {
|
||||
}
|
||||
|
||||
private static JetType createErrorType(String debugMessage, JetScope memberScope) {
|
||||
return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.<Annotation>emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.<TypeParameterDescriptor>emptyList(), Collections.<JetType>emptyList()), memberScope);
|
||||
return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.<Annotation>emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.<TypeParameterDescriptor>emptyList(), Collections.singleton(JetStandardClasses.getAnyType())), memberScope);
|
||||
}
|
||||
|
||||
public static JetType createWrongVarianceErrorType(TypeProjection value) {
|
||||
|
||||
@@ -104,7 +104,7 @@ public class JetTypeChecker {
|
||||
}
|
||||
commonSupertypes = computeCommonRawSupertypes(merge);
|
||||
}
|
||||
assert !commonSupertypes.isEmpty() : types;
|
||||
assert !commonSupertypes.isEmpty() : commonSupertypes + " <- " + types;
|
||||
Map.Entry<TypeConstructor, Set<JetType>> entry = commonSupertypes.entrySet().iterator().next();
|
||||
JetType result = computeSupertypeProjections(entry.getKey(), entry.getValue());
|
||||
|
||||
|
||||
@@ -378,23 +378,6 @@ public class JetTypeInferrer {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void collectAllReturnTypes(JetWhenExpression whenExpression, JetScope scope, List<JetType> result) {
|
||||
for (JetWhenEntry entry : whenExpression.getEntries()) {
|
||||
JetWhenExpression subWhen = entry.getSubWhen();
|
||||
if (subWhen != null) {
|
||||
collectAllReturnTypes(subWhen, scope, result);
|
||||
} else {
|
||||
JetExpression resultExpression = entry.getExpression();
|
||||
if (resultExpression != null) {
|
||||
JetType type = getType(scope, resultExpression, true);
|
||||
if (type != null) {
|
||||
result.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType resolveCall(
|
||||
@NotNull JetScope scope,
|
||||
@@ -1105,77 +1088,91 @@ public class JetTypeInferrer {
|
||||
// TODO :change scope according to the bound value in the when header
|
||||
final JetExpression subjectExpression = expression.getSubjectExpression();
|
||||
|
||||
JetType subjectType = null;
|
||||
if (subjectExpression != null) {
|
||||
subjectType = getType(scope, subjectExpression, false);
|
||||
}
|
||||
final JetType subjectType = subjectExpression != null ? safeGetType(scope, subjectExpression, false) : ErrorUtils.createErrorType("Unknown type");
|
||||
final VariableDescriptor variableDescriptor = subjectExpression != null ? getVariableDescriptorFromSimpleName(subjectExpression) : null;
|
||||
|
||||
// TODO : exhaustive patterns
|
||||
|
||||
Set<JetType> expressionTypes = Sets.newHashSet();
|
||||
for (JetWhenEntry whenEntry : expression.getEntries()) {
|
||||
final JetType finalSubjectType = subjectType != null ? subjectType : ErrorUtils.createErrorType("Unknown type");
|
||||
JetWhenCondition condition = whenEntry.getCondition();
|
||||
WritableScope scopeToExtend = new WritableScopeImpl(scope, scope.getContainingDeclaration(), trace.getErrorHandler());
|
||||
DataFlowInfo newDataFlowInfo = dataFlowInfo;
|
||||
if (condition != null) {
|
||||
condition.accept(new JetVisitor() {
|
||||
@Override
|
||||
public void visitWhenConditionWithExpression(JetWhenConditionWithExpression condition) {
|
||||
JetExpression conditionExpression = condition.getExpression();
|
||||
if (conditionExpression != null) {
|
||||
JetType type = getType(scope, conditionExpression, false);
|
||||
if (type != null && finalSubjectType != null) {
|
||||
if (TypeUtils.intersect(semanticServices.getTypeChecker(), Sets.newHashSet(finalSubjectType, type)) == null) {
|
||||
trace.getErrorHandler().genericError(conditionExpression.getNode(), "This condition can never hold");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
||||
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
|
||||
JetScope compositeScope = new ScopeWithReceiver(scope, finalSubjectType, semanticServices.getTypeChecker());
|
||||
if (callSuffixExpression != null) {
|
||||
JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false);
|
||||
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression");
|
||||
checkNullSafety(finalSubjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
||||
JetExpression rangeExpression = condition.getRangeExpression();
|
||||
if (rangeExpression != null) {
|
||||
checkInExpression(condition.getOperationReference(), subjectExpression, rangeExpression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
||||
JetPattern pattern = condition.getPattern();
|
||||
if (pattern != null) {
|
||||
checkPatternType(pattern, finalSubjectType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer] : " + element);
|
||||
}
|
||||
});
|
||||
newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, variableDescriptor, condition, scopeToExtend);
|
||||
}
|
||||
JetWhenExpression subWhen = whenEntry.getSubWhen();
|
||||
JetExpression bodyExpression = subWhen == null ? whenEntry.getExpression() : subWhen;
|
||||
if (bodyExpression != null) {
|
||||
JetType type = getType(scopeToExtend, bodyExpression, false, newDataFlowInfo);
|
||||
if (type != null) {
|
||||
expressionTypes.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<JetType> expressionTypes = new ArrayList<JetType>();
|
||||
collectAllReturnTypes(expression, scope, expressionTypes);
|
||||
if (!expressionTypes.isEmpty()) {
|
||||
result = semanticServices.getTypeChecker().commonSupertype(expressionTypes);
|
||||
}
|
||||
else {
|
||||
else if (expression.getEntries().isEmpty()) {
|
||||
trace.getErrorHandler().genericError(expression.getNode(), "Entries required for when-expression"); // TODO : Scope, and maybe this should not an error
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPatternType(@NotNull JetPattern pattern, @NotNull final JetType subjectType) {
|
||||
private DataFlowInfo checkWhenCondition(@Nullable final JetExpression subjectExpression, final JetType subjectType, final VariableDescriptor variableDescriptor, JetWhenCondition condition, final WritableScope scopeToExtend) {
|
||||
final DataFlowInfo[] newDataFlowInfo = new DataFlowInfo[]{dataFlowInfo};
|
||||
condition.accept(new JetVisitor() {
|
||||
@Override
|
||||
public void visitWhenConditionWithExpression(JetWhenConditionWithExpression condition) {
|
||||
JetExpression conditionExpression = condition.getExpression();
|
||||
if (conditionExpression != null) {
|
||||
JetType type = getType(scope, conditionExpression, false);
|
||||
if (type != null && subjectType != null) {
|
||||
if (TypeUtils.intersect(semanticServices.getTypeChecker(), Sets.newHashSet(subjectType, type)) == null) {
|
||||
trace.getErrorHandler().genericError(conditionExpression.getNode(), "This condition can never hold");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
||||
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
|
||||
JetScope compositeScope = new ScopeWithReceiver(scope, subjectType, semanticServices.getTypeChecker());
|
||||
if (callSuffixExpression != null) {
|
||||
JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false);
|
||||
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression");
|
||||
checkNullSafety(subjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
||||
JetExpression rangeExpression = condition.getRangeExpression();
|
||||
if (rangeExpression != null) {
|
||||
assert subjectExpression != null;
|
||||
checkInExpression(condition.getOperationReference(), subjectExpression, rangeExpression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
||||
JetPattern pattern = condition.getPattern();
|
||||
if (pattern != null) {
|
||||
newDataFlowInfo[0] = checkPatternType(variableDescriptor, pattern, subjectType, scopeToExtend);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer] : " + element);
|
||||
}
|
||||
});
|
||||
return newDataFlowInfo[0];
|
||||
}
|
||||
|
||||
private DataFlowInfo checkPatternType(@Nullable final VariableDescriptor subjectVariable, @NotNull JetPattern pattern, @NotNull final JetType subjectType, @NotNull final WritableScope scopeToExtend) {
|
||||
final DataFlowInfo[] result = new DataFlowInfo[] {dataFlowInfo};
|
||||
pattern.accept(new JetVisitor() {
|
||||
@Override
|
||||
public void visitTypePattern(JetTypePattern typePattern) {
|
||||
@@ -1183,26 +1180,18 @@ public class JetTypeInferrer {
|
||||
if (typeReference != null) {
|
||||
JetType type = typeResolver.resolveType(scope, typeReference);
|
||||
checkTypeCompatibility(type, subjectType, typePattern);
|
||||
if (subjectVariable != null) {
|
||||
result[0] = dataFlowInfo.isInstanceOf(subjectVariable, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWildcardPattern(JetWildcardPattern pattern) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpressionPattern(JetExpressionPattern pattern) {
|
||||
JetType type = getType(scope, pattern.getExpression(), false);
|
||||
checkTypeCompatibility(type, subjectType, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTuplePattern(JetTuplePattern pattern) {
|
||||
List<JetTuplePatternEntry> entries = pattern.getEntries();
|
||||
TypeConstructor typeConstructor = subjectType.getConstructor();
|
||||
if (!JetStandardClasses.getTuple(entries.size()).getTypeConstructor().equals(typeConstructor)
|
||||
|| typeConstructor.getParameters().size() != entries.size()) {
|
||||
|| typeConstructor.getParameters().size() != entries.size()) {
|
||||
trace.getErrorHandler().genericError(pattern.getNode(), "Type mismatch: subject is of type " + subjectType + " but the pattern is of type Tuple" + entries.size()); // TODO : message
|
||||
}
|
||||
else {
|
||||
@@ -1218,7 +1207,7 @@ public class JetTypeInferrer {
|
||||
|
||||
JetPattern entryPattern = entry.getPattern();
|
||||
if (entryPattern != null) {
|
||||
checkPatternType(entryPattern, type);
|
||||
result[0] = checkPatternType(null, entryPattern, type, scopeToExtend);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1228,10 +1217,41 @@ public class JetTypeInferrer {
|
||||
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
|
||||
JetType selectorReturnType = getSelectorReturnType(subjectType, pattern.getDecomposerExpression());
|
||||
|
||||
checkPatternType(pattern.getArgumentList(), selectorReturnType == null ? ErrorUtils.createErrorType("No type") : selectorReturnType);
|
||||
result[0] = checkPatternType(null, pattern.getArgumentList(), selectorReturnType == null ? ErrorUtils.createErrorType("No type") : selectorReturnType, scopeToExtend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWildcardPattern(JetWildcardPattern pattern) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpressionPattern(JetExpressionPattern pattern) {
|
||||
JetType type = getType(scope, pattern.getExpression(), false);
|
||||
checkTypeCompatibility(type, subjectType, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBindingPattern(JetBindingPattern pattern) {
|
||||
JetProperty variableDeclaration = pattern.getVariableDeclaration();
|
||||
JetTypeReference propertyTypeRef = variableDeclaration.getPropertyTypeRef();
|
||||
JetType type = propertyTypeRef == null ? subjectType : typeResolver.resolveType(scope, propertyTypeRef);
|
||||
VariableDescriptor variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptorWithType(scope.getContainingDeclaration(), variableDeclaration, type);
|
||||
scopeToExtend.addVariableDescriptor(variableDescriptor);
|
||||
if (propertyTypeRef != null) {
|
||||
if (!semanticServices.getTypeChecker().isSubtypeOf(subjectType, type)) {
|
||||
trace.getErrorHandler().genericError(propertyTypeRef.getNode(), type + " must be a supertype of " + subjectType + ". Use 'is' to match against " + type);
|
||||
}
|
||||
}
|
||||
|
||||
JetWhenCondition condition = pattern.getCondition();
|
||||
if (condition != null) {
|
||||
result[0] = checkWhenCondition(null, subjectType, variableDescriptor, condition, scopeToExtend);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) {
|
||||
// TODO : Take auto casts into account?
|
||||
if (type == null) {
|
||||
return;
|
||||
}
|
||||
@@ -1245,6 +1265,7 @@ public class JetTypeInferrer {
|
||||
trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer]");
|
||||
}
|
||||
});
|
||||
return result[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1667,6 +1688,9 @@ public class JetTypeInferrer {
|
||||
trace.recordAutoCast(receiverExpression, possibleType);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
errorHandler.closeAndReturnCurrentRegion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1789,6 +1813,7 @@ public class JetTypeInferrer {
|
||||
@Override
|
||||
public void visitIsExpression(JetIsExpression expression) {
|
||||
// TODO : patterns and everything
|
||||
// TODO : Unify with WhenExpression
|
||||
JetType knownType = getType(scope, expression.getLeftHandSide(), false);
|
||||
JetPattern pattern = expression.getPattern();
|
||||
if (pattern instanceof JetTypePattern) {
|
||||
|
||||
@@ -53,3 +53,25 @@ fun f10(a : A?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f11(a : A?) {
|
||||
when (a) {
|
||||
is B => <info descr="Automatically cast to B">a</info>.bar()
|
||||
is A => a.foo()
|
||||
is Any => a.foo()
|
||||
is Any? => a.<error>bar</error>()
|
||||
else => a?.foo()
|
||||
}
|
||||
}
|
||||
|
||||
fun f12(a : A?) {
|
||||
when (a) {
|
||||
is B => <info descr="Automatically cast to B">a</info>.bar()
|
||||
is A => a.foo()
|
||||
is Any => a.foo();
|
||||
is Any? => a.<error>bar</error>()
|
||||
is val c : <error>B</error> => c.foo()
|
||||
is val c is C => c.foo()
|
||||
else => a?.foo()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,10 @@ JetFile: AttributesOnPatterns.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -58,17 +59,19 @@ JetFile: AttributesOnPatterns.jet
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
|
||||
+127
-108
@@ -327,17 +327,19 @@ JetFile: When.jet
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -352,17 +354,19 @@ JetFile: When.jet
|
||||
PsiElement(LPAR)('(')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
@@ -473,9 +477,10 @@ JetFile: When.jet
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('r')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('r')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
@@ -686,17 +691,19 @@ JetFile: When.jet
|
||||
PsiElement(LPAR)('(')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('T')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('T')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
@@ -833,17 +840,19 @@ JetFile: When.jet
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
@@ -888,19 +897,22 @@ JetFile: When.jet
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
BINARY_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
WHEN_CONDITION_IN_RANGE
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(RANGE)('..')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
BINARY_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(RANGE)('..')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
@@ -910,55 +922,59 @@ JetFile: When.jet
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('_')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('_')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(NOT_IS)('!is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(NOT_IS)('!is')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
DECOMPOSER_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(DOT)('.')
|
||||
CALL_EXPRESSION
|
||||
WHEN_CONDITION_IS_PATTERN
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
DECOMPOSER_PATTERN
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
TYPE_ARGUMENT_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PROJECTION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(DOT)('.')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
TYPE_ARGUMENT_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PROJECTION
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(AT)('@')
|
||||
PsiWhiteSpace(' ')
|
||||
DECOMPOSER_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(AT)('@')
|
||||
PsiWhiteSpace(' ')
|
||||
DECOMPOSER_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
TYPE_PATTERN
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
@@ -998,16 +1014,17 @@ JetFile: When.jet
|
||||
PsiElement(is)('is')
|
||||
PsiWhiteSpace(' ')
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -1088,9 +1105,10 @@ JetFile: When.jet
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('r')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('r')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
@@ -1208,9 +1226,10 @@ JetFile: When.jet
|
||||
PsiElement(LPAR)('(')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
BINDING_PATTERN
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
TUPLE_PATTERN_ENTRY
|
||||
|
||||
Reference in New Issue
Block a user