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

New syntax fro patterns

上级 691c79c4
......@@ -43,12 +43,12 @@ comparison
;
namedInfixOrTypeExpression
: elvisOperation (inOperation elvisOperation)*
: elvisOperation (isOperation isRHS)?
: elvisOperation (typeOperation type)?
: elvisExpression (inOperation elvisExpression)*
: elvisExpression (isOperation isRHS)?
: elvisExpression (typeOperation type)?
;
elvisOperation
elvisExpression
: infixFunctionCall ("?:" infixFunctionCall)*
;
......@@ -170,7 +170,7 @@ postfixUnaryOperation
: typeArguments? valueArguments
: typeArguments
: arrayAccess
: memberAccessOperation atomicExpression
: memberAccessOperation postfixUnaryOperation // TODO: Review
;
memberAccessOperation
......
......@@ -15,6 +15,7 @@ whenConditionIf
whenCondition
: expression
// : "." atomicExpression typeArguments? valueArguments?
: ("in" | "!in") expression
: ("is" | "!is") isRHS
;
......@@ -22,17 +23,18 @@ whenCondition
pattern
: attributes pattern
: type // '[a] T' is a type-pattern 'T' with an attribute '[a]', not a type-pattern '[a] T'
// this makes sense because is-chack may be different for a type with attributes
// this makes sense because is-check may be different for a type with attributes
: tuplePattern
: decomposerPattern
: constantPattern
: bindingPattern
: expressionPattern
: "*" // wildcard pattern
;
decomposerPattern
: type
: qualifiedName typeParameters? (tuplePattern)?
// TODO : typeParameters will be consumed by the expression
: elvisExpression typeParameters? '@' tuplePattern
;
constantPattern
......@@ -44,7 +46,7 @@ tuplePattern
;
bindingPattern
: "?" SimpleName? binding?
: "val" SimpleName binding?
;
binding
......@@ -52,13 +54,5 @@ binding
: "!is" pattern
: "in" expression
: "!in" expression
: "=" expression
;
qualifiedName
: ("namespace" ".")? SimpleName{","}
;
expressionPattern
: "=" expression
: ":" type
;
\ No newline at end of file
......@@ -114,6 +114,7 @@ public interface JetNodeTypes {
JetNodeType TYPE_PATTERN = new JetNodeType("TYPE_PATTERN");
JetNodeType EXPRESSION_PATTERN = new JetNodeType("EXPRESSION_PATTERN");
JetNodeType BINDING_PATTERN = new JetNodeType("BINDING_PATTERN");
JetNodeType WILDCARD_PATTERN = new JetNodeType("WILDCARD_PATTERN");
JetNodeType WHEN = new JetNodeType("WHEN", JetWhenExpression.class);
JetNodeType WHEN_ENTRY = new JetNodeType("WHEN_ENTRY", JetWhenEntry.class);
JetNodeType WHEN_CONDITION = new JetNodeType("WHEN_CONDITION");
......
......@@ -171,7 +171,6 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
private final JetParsing myJetParsing;
private TokenSet expressionFollow = null;
private TokenSet decomposerExpressionFollow = null;
public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
......@@ -181,6 +180,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
private TokenSet getDecomposerExpressionFollow() {
// TODO : memoize
if (decomposerExpressionFollow == null) {
List<IElementType> elvisFollow = new ArrayList<IElementType>();
Precedence precedence = Precedence.ELVIS;
while (precedence != null) {
......@@ -190,7 +190,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
precedence = precedence.higher;
}
return TokenSet.orSet(EXPRESSION_FOLLOW, TokenSet.create(elvisFollow.toArray(new IElementType[elvisFollow.size()])));
decomposerExpressionFollow = TokenSet.orSet(EXPRESSION_FOLLOW, TokenSet.create(elvisFollow.toArray(new IElementType[elvisFollow.size()])));
}
return decomposerExpressionFollow;
}
/*
......@@ -690,13 +692,12 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseTuplePattern(TUPLE_PATTERN_ENTRY);
pattern.done(TUPLE_PATTERN);
}
else if (at(QUEST)) {
else if (at(MUL)) {
advance(); // MUL
pattern.done(WILDCARD_PATTERN);
} else if (at(VAL_KEYWORD)) {
parseBindingPattern();
pattern.done(BINDING_PATTERN);
} else if (at(EQ)) {
advance(); // EQ
parseExpression();
pattern.done(EXPRESSION_PATTERN);
} else if (parseLiteralConstant()) {
pattern.done(EXPRESSION_PATTERN);
} else {
......@@ -741,7 +742,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
/*
* bindingPattern
* : "?" SimpleName? binding?
* : "val" SimpleName binding?
* ;
*
* binding
......@@ -749,15 +750,15 @@ public class JetExpressionParsing extends AbstractJetParsing {
* : "!is" pattern
* : "in" expression
* : "!in" expression
* : "=" expression
* : ":" type
* ;
*/
private void parseBindingPattern() {
assert _at(QUEST);
assert _at(VAL_KEYWORD);
advance(); // QUEST
advance(); // VAL_KEYWORD
consumeIf(IDENTIFIER);
expect(IDENTIFIER, "Expecting an identifier");
if (at(IS_KEYWORD) || at(NOT_IS)) {
advance(); // IS_KEYWORD or NOT_IS
......@@ -767,12 +768,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // IN_KEYWORD ot NOT_IN
parseExpression();
} else if (at(EQ)) {
} else if (at(COLON)) {
advance(); // EQ
parseExpression();
myJetParsing.parseTypeRef();
}
}
/*
* arrayAccess
* : "[" expression{","} "]"
......
fun foo() {
when (e) {
is [a] =2 => d
is [a] val a => d
is [a] val a is foo => d
is [a] * => d
is [a] 2 => d
is [a] T => d
is [a] T @ () => d
......
......@@ -27,7 +27,7 @@ JetFile: AttributesOnPatterns.jet
WHEN_CONDITION
PsiElement(is)('is')
PsiWhiteSpace(' ')
EXPRESSION_PATTERN
BINDING_PATTERN
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
......@@ -37,9 +37,61 @@ JetFile: AttributesOnPatterns.jet
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION
PsiElement(is)('is')
PsiWhiteSpace(' ')
BINDING_PATTERN
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION
PsiElement(is)('is')
PsiWhiteSpace(' ')
WILDCARD_PATTERN
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(MUL)('*')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
......
......@@ -26,10 +26,9 @@ fun foo() {
is 'c' => foo
is "sadfsa" => foo
is """ddd""" => foo
is ? => foo
is ? is Foo => foo
is ?a is Foo => foo
is (?a is Foo, b) => foo
is * => foo
is val a is Foo => foo
is (val a is Foo, b) => foo
}
when (when(when (e) {
......@@ -43,21 +42,22 @@ fun foo() {
fun foo() {
when (val a = e) {
is Tree => c
is Tree @ (null, ?r) => c
is Tree @ (null, val r) => c
is a @ (a, b) => c
is a @ (a, b) => c
is a.a @ (a, b) => c
is a.a @ (foo = a, bar = b) => c
is namespace.a.a @ (a, b) => c
is a @ (?a is T, b) => c
is a @ (val a is T, b) => c
is a @ (b, 1) => c
in 1..2 => dsf
!in 2 => sd
!is t => d
is {(foo) : Bar} => fgpp
is (1, ?a is Foo, ?, ? is Foo, bar) => d
is (Foo, ?a in 1..2, ?, ? !is Foo, ?bar = foo.bar<a>(a)) => d
is (1, val a is Foo, *, Foo, bar) => d
is (Foo, val a in 1..2, *, val _ !is Foo, val bar is foo.bar<a> @ (a)) => d
is (Int, Int) => 2
is val a : Foo => 2
else => foo
else continue
}
......@@ -66,11 +66,11 @@ fun foo() {
fun foo() {
when (val a = e) {
is Tree,
is Tree @ (null, ?r),
is Tree @ (null, val r),
is a @ (a, b) => c
1, foo(), bar, 2 + 3,
is a @ (a, b) => c
is a.a @ (=a + 3, b) => c
is a.a @ (val b, b) if (b == a + 3) => c
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册