提交 d4b1658b 编写于 作者: A Andrey Breslav

Autocasts & binding patterns in 'when'-expressions

上级 75365016
......@@ -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,96 +1088,102 @@ 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) {
pattern.accept(new JetVisitor() {
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 visitTypePattern(JetTypePattern typePattern) {
JetTypeReference typeReference = typePattern.getTypeReference();
if (typeReference != null) {
JetType type = typeResolver.resolveType(scope, typeReference);
checkTypeCompatibility(type, subjectType, typePattern);
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 visitWildcardPattern(JetWildcardPattern pattern) {
// Nothing
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 visitExpressionPattern(JetExpressionPattern pattern) {
JetType type = getType(scope, pattern.getExpression(), false);
checkTypeCompatibility(type, subjectType, pattern);
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) {
JetTypeReference typeReference = typePattern.getTypeReference();
if (typeReference != null) {
JetType type = typeResolver.resolveType(scope, typeReference);
checkTypeCompatibility(type, subjectType, typePattern);
if (subjectVariable != null) {
result[0] = dataFlowInfo.isInstanceOf(subjectVariable, type);
}
}
}
@Override
......@@ -1202,7 +1191,7 @@ public class JetTypeInferrer {
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
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(' ')
......
......@@ -327,17 +327,19 @@ JetFile: When.jet
PsiElement(is)('is')
PsiWhiteSpace(' ')
BINDING_PATTERN
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PROPERTY
PsiElement(val)('val')
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('_')
PsiWhiteSpace(' ')
PsiElement(NOT_IS)('!is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('_')
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')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('bar')
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册