diff --git a/grammar/src/class_members.grm b/grammar/src/class_members.grm
index e1a7ee6db69..6a30c8064ef 100644
--- a/grammar/src/class_members.grm
+++ b/grammar/src/class_members.grm
@@ -84,7 +84,7 @@ functionBody
;
property
- : modifiers ("val" | "var") attributes (type ".")? SimpleName (":" type)? ("=" expression)?
+ : modifiers ("val" | "var") attributes (type ".")? SimpleName (":" type)? ("=" expression SEMI?)?
(getter? setter? | setter? getter?) SEMI?
;
diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
index 57a2a2e11c2..bfbebfdd8cd 100644
--- a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
+++ b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
@@ -574,7 +574,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
declType = myJetParsing.parseFunction();
}
else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
- declType = myJetParsing.parseProperty();
+ declType = myJetParsing.parseProperty(true);
}
else if (keywordToken == TYPE_KEYWORD) {
declType = myJetParsing.parseTypeDef();
diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java
index a1ac47b8641..c9d19c9e847 100644
--- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java
+++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java
@@ -696,14 +696,15 @@ public class JetParsing extends AbstractJetParsing {
/*
* property
- * : modifiers ("val" | "var") attributes (type ".")? SimpleName (":" type)? ("=" expression)?
+ * : modifiers ("val" | "var") attributes (type ".")? SimpleName (":" type)? ("=" expression SEMI?)?
* (getter? setter? | setter? getter?) SEMI?
* ;
*/
public JetNodeType parseProperty() {
- // TODO: var foo : Int { get; private set }
- // TODO: accessors for local variables
+ return parseProperty(false);
+ }
+ public JetNodeType parseProperty(boolean local) {
assert at(VAL_KEYWORD) || at(VAR_KEYWORD);
advance(); // VAL_KEYWORD or VAR_KEYWORD
@@ -749,20 +750,23 @@ public class JetParsing extends AbstractJetParsing {
if (at(EQ)) {
advance(); // EQ
myExpressionParsing.parseExpression();
+ consumeIf(SEMICOLON);
+ }
+ if (!local) {
+ if (parsePropertyGetterOrSetter()) {
+ parsePropertyGetterOrSetter();
+ }
+ consumeIf(SEMICOLON);
}
- if (parsePropertyGetterOrSetter()) {
- parsePropertyGetterOrSetter();
- }
-
- consumeIf(SEMICOLON);
return PROPERTY;
}
/*
* getter
- * : modifiers
+ * : modifiers ("get" | "set")
+ * :
* ( "get" "(" ")"
* |
* "set" "(" modifiers parameter ")"
@@ -782,6 +786,11 @@ public class JetParsing extends AbstractJetParsing {
boolean setter = at(SET_KEYWORD);
advance(); // GET_KEYWORD or SET_KEYWORD
+ if (!at(LPAR)) {
+ getterOrSetter.done(PROPERTY_ACCESSOR);
+ return true;
+ }
+
myBuilder.disableEols();
expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
if (setter) {
diff --git a/idea/testData/psi/Precedence.jet b/idea/testData/psi/Precedence.jet
index bab05d3a74e..3f0eef4ff7a 100644
--- a/idea/testData/psi/Precedence.jet
+++ b/idea/testData/psi/Precedence.jet
@@ -2,6 +2,9 @@ fun foo() {
b().x
x++ . 4
++ -- ! a
+ f(foo(x))
+ f(foo(x))
+ f(foo(x))
f(foo(x)))
f(foo(x))
f((foo(x))
@@ -9,6 +12,7 @@ fun foo() {
a + b
a + b * c
a + (b * c)
+ (a + b) * c
a + b > c * c
a + b in c * d
a.b
@@ -20,6 +24,7 @@ fun foo() {
a+b..b-1
1..2 foo 2..3
1 foo 2 ?: 1 bar 3
+ a b c d e f g
a ?: b in b?: c
a : b < b : c
a < b == b > c
diff --git a/idea/testData/psi/Precedence.txt b/idea/testData/psi/Precedence.txt
index 72896914205..ca76a855907 100644
--- a/idea/testData/psi/Precedence.txt
+++ b/idea/testData/psi/Precedence.txt
@@ -43,6 +43,96 @@ JetFile: Precedence.jet
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ PsiElement(IDENTIFIER)('f')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ CALL_EXPRESSION
+ PsiElement(IDENTIFIER)('foo')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('a')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('a')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('b')
+ PsiElement(GT)('>')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(RPAR)(')')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ PsiElement(IDENTIFIER)('f')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('foo')
+ PsiElement(LT)('<')
+ PsiElement(IDENTIFIER)('a')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('1')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('b')
+ PsiElement(GT)('>')
+ TUPLE
+ PsiElement(LPAR)('(')
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(RPAR)(')')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ PsiElement(IDENTIFIER)('f')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('foo')
+ PsiElement(LT)('<')
+ PsiElement(IDENTIFIER)('a')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ TUPLE
+ PsiElement(LPAR)('(')
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('a')
+ PsiWhiteSpace(' ')
+ PsiElement(PLUS)('+')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('1')
+ PsiElement(RPAR)(')')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('b')
+ PsiElement(GT)('>')
+ TUPLE
+ PsiElement(LPAR)('(')
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(RPAR)(')')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('f')
VALUE_ARGUMENT_LIST
@@ -165,6 +255,21 @@ JetFile: Precedence.jet
PsiElement(IDENTIFIER)('c')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
+ BINARY_EXPRESSION
+ TUPLE
+ PsiElement(LPAR)('(')
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('a')
+ PsiWhiteSpace(' ')
+ PsiElement(PLUS)('+')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('b')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiElement(MUL)('*')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('c')
+ PsiWhiteSpace('\n ')
BINARY_EXPRESSION
BINARY_EXPRESSION
PsiElement(IDENTIFIER)('a')
@@ -299,6 +404,23 @@ JetFile: Precedence.jet
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace('\n ')
+ BINARY_EXPRESSION
+ BINARY_EXPRESSION
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('a')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('b')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('c')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('d')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('e')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('f')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('g')
+ PsiWhiteSpace('\n ')
BINARY_EXPRESSION
BINARY_EXPRESSION
PsiElement(IDENTIFIER)('a')
diff --git a/idea/testData/psi/Properties.jet b/idea/testData/psi/Properties.jet
index e7ff0ab2829..d8ffd4e646b 100644
--- a/idea/testData/psi/Properties.jet
+++ b/idea/testData/psi/Properties.jet
@@ -34,3 +34,39 @@ val {foo.bar.() : ()}.foo : bar = foo
val {foo.bar.() : ()}.foo : bar = foo
[a] public get() {}
+
+val foo get
+val foo set
+
+var foo
+ get
+ private set
+
+val foo.bar
+ get() {}
+ set
+
+val foo.bar
+ get
+ set(sad) = foo
+
+val foo = 5; get
+val foo =1; get set
+
+var foo = 5
+ get
+ private set
+
+val foo.bar = 5
+ get() {}
+ set
+
+val foo.bar = 5
+ get
+ set(sad) = foo
+
+fun foo() {
+ val foo = 5
+ get() = 5
+ set(int : x) = 5
+}
\ No newline at end of file
diff --git a/idea/testData/psi/Properties.txt b/idea/testData/psi/Properties.txt
index ee4d60f8e21..9771e28117e 100644
--- a/idea/testData/psi/Properties.txt
+++ b/idea/testData/psi/Properties.txt
@@ -445,4 +445,237 @@ JetFile: Properties.jet
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
- PsiElement(RBRACE)('}')
\ No newline at end of file
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace(' ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace('\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace(' ')
+ PROPERTY_ACCESSOR
+ PsiElement(set)('set')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(var)('var')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ MODIFIER_LIST
+ PsiElement(private)('private')
+ PsiWhiteSpace(' ')
+ PsiElement(set)('set')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('foo')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('bar')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(set)('set')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('foo')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('bar')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(set)('set')
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('sad')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiElement(SEMICOLON)(';')
+ PsiWhiteSpace(' ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace('\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('1')
+ PsiElement(SEMICOLON)(';')
+ PsiWhiteSpace(' ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace(' ')
+ PROPERTY_ACCESSOR
+ PsiElement(set)('set')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(var)('var')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ MODIFIER_LIST
+ PsiElement(private)('private')
+ PsiWhiteSpace(' ')
+ PsiElement(set)('set')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('foo')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('bar')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(set)('set')
+ PsiWhiteSpace('\n\n')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ PsiElement(IDENTIFIER)('foo')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('bar')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(get)('get')
+ PsiWhiteSpace('\n ')
+ PROPERTY_ACCESSOR
+ PsiElement(set)('set')
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('sad')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ TYPE_PARAMETER_LIST
+
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiWhiteSpace('\n ')
+ BINARY_EXPRESSION
+ CALL_EXPRESSION
+ PsiElement(IDENTIFIER)('get')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiWhiteSpace('\n ')
+ BINARY_EXPRESSION
+ CALL_EXPRESSION
+ PsiElement(IDENTIFIER)('set')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ PsiElement(IDENTIFIER)('int')
+ PsiWhiteSpace(' ')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('5')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
\ No newline at end of file
diff --git a/idea/testData/psi/Properties_ERR.txt b/idea/testData/psi/Properties_ERR.txt
index 5f7311ac4d4..73b24eb8f56 100644
--- a/idea/testData/psi/Properties_ERR.txt
+++ b/idea/testData/psi/Properties_ERR.txt
@@ -157,15 +157,13 @@ JetFile: Properties_ERR.jet
PsiWhiteSpace('\n ')
PROPERTY_ACCESSOR
PsiElement(set)('set')
- PsiErrorElement:Expecting '('
-
- VALUE_PARAMETER
-
- PsiElement(RPAR)(')')
- PsiWhiteSpace(' ')
- BLOCK
- PsiElement(LBRACE)('{')
- PsiElement(RBRACE)('}')
+ PsiErrorElement:Expecting namespace or top level declaration
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiErrorElement:Expecting namespace or top level declaration
+ PsiElement(LBRACE)('{')
+ PsiErrorElement:Expecting namespace or top level declaration
+ PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(IDENTIFIER)('dfget')