Call with closure is available inside the by clause in nested expressions, see the test

This commit is contained in:
Andrey Breslav
2011-01-03 17:10:15 +03:00
parent fc669d18b9
commit c4fa51c16e
7 changed files with 434 additions and 30 deletions
@@ -46,10 +46,14 @@ public class JetParsing extends AbstractJetParsing {
}
public static JetParsing createForByClause(final SemanticWhitespaceAwarePsiBuilder builder) {
JetParsing jetParsing = new JetParsing(builder);
jetParsing.myExpressionParsing = new JetExpressionParsing(builder, jetParsing) {
final SemanticWhitespaceAwarePsiBuilderForByClause builderForByClause = new SemanticWhitespaceAwarePsiBuilderForByClause(builder);
JetParsing jetParsing = new JetParsing(builderForByClause);
jetParsing.myExpressionParsing = new JetExpressionParsing(builderForByClause, jetParsing) {
@Override
protected boolean parseCallWithClosure() {
if (builderForByClause.getStackSize() > 0) {
return super.parseCallWithClosure();
}
return false;
}
@@ -527,7 +531,7 @@ public class JetParsing extends AbstractJetParsing {
* ;
*/
/*package*/ void parseClassBody() {
// TODO : initializer?
// TODO : anonymous initializer, like {...} in Java?
assert at(LBRACE);
PsiBuilder.Marker body = mark();
@@ -1003,7 +1007,6 @@ public class JetParsing extends AbstractJetParsing {
if (at(BY_KEYWORD)) {
advance(); // BY_KEYWORD
// TODO: discuss: in nested expressions (including method bodies) one cannot use foo {bar} either, but this is required only for the top level
createForByClause(myBuilder).myExpressionParsing.parseExpression();
delegator.done(DELEGATOR_BY);
}
@@ -1336,7 +1339,7 @@ public class JetParsing extends AbstractJetParsing {
int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(RBRACE, COLON), false);
if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) {
PsiBuilder.Marker receiverType = mark();
// TODO : -1 is a hack
// TODO : -1 is a hack?
createTruncatedBuilder(lastLPar - 1).parseTypeRef();
receiverType.done(RECEIVER_TYPE);
advance(); // DOT
@@ -6,6 +6,7 @@ import com.intellij.lang.PsiBuilder;
* @author abreslav
*/
public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
// TODO: Wrong name, should be something like "EOL before current token"
boolean eolInLastWhitespace();
void disableEols();
void enableEols();
@@ -0,0 +1,36 @@
package org.jetbrains.jet.lang.parsing;
/**
* @author abreslav
*/
public class SemanticWhitespaceAwarePsiBuilderAdapter extends PsiBuilderAdapter implements SemanticWhitespaceAwarePsiBuilder {
private final SemanticWhitespaceAwarePsiBuilder myBuilder;
public SemanticWhitespaceAwarePsiBuilderAdapter(SemanticWhitespaceAwarePsiBuilder builder) {
super(builder);
this.myBuilder = builder;
}
@Override
public boolean eolInLastWhitespace() {
return myBuilder.eolInLastWhitespace();
}
@Override
public void disableEols() {
myBuilder.disableEols();
}
@Override
public void enableEols() {
myBuilder.enableEols();
}
@Override
public void restoreEolsState() {
myBuilder.restoreEolsState();
}
}
@@ -0,0 +1,37 @@
package org.jetbrains.jet.lang.parsing;
import com.intellij.psi.tree.IElementType;
/**
* @author abreslav
*/
public class SemanticWhitespaceAwarePsiBuilderForByClause extends SemanticWhitespaceAwarePsiBuilderAdapter {
private int stackSize = 0;
public SemanticWhitespaceAwarePsiBuilderForByClause(SemanticWhitespaceAwarePsiBuilder builder) {
super(builder);
}
@Override
public void disableEols() {
super.disableEols();
stackSize++;
}
@Override
public void enableEols() {
super.enableEols();
stackSize++;
}
@Override
public void restoreEolsState() {
super.restoreEolsState();
stackSize--;
}
public int getStackSize() {
return stackSize;
}
}
@@ -5,38 +5,16 @@ import com.intellij.psi.tree.IElementType;
/**
* @author abreslav
*/
public class TruncatedSemanticWhitespaceAwarePsiBuilder extends PsiBuilderAdapter implements SemanticWhitespaceAwarePsiBuilder {
public class TruncatedSemanticWhitespaceAwarePsiBuilder extends SemanticWhitespaceAwarePsiBuilderAdapter {
private final SemanticWhitespaceAwarePsiBuilder myBuilder;
private final int myEOFPosition;
public TruncatedSemanticWhitespaceAwarePsiBuilder(SemanticWhitespaceAwarePsiBuilder myBuilder, int eofPosition) {
super(myBuilder);
this.myBuilder = myBuilder;
public TruncatedSemanticWhitespaceAwarePsiBuilder(SemanticWhitespaceAwarePsiBuilder builder, int eofPosition) {
super(builder);
this.myEOFPosition = eofPosition;
}
@Override
public boolean eolInLastWhitespace() {
return myBuilder.eolInLastWhitespace();
}
@Override
public void disableEols() {
myBuilder.disableEols();;
}
@Override
public void enableEols() {
myBuilder.enableEols();
}
@Override
public void restoreEolsState() {
myBuilder.restoreEolsState();
}
@Override
public boolean eof() {
if (super.eof()) return true;
+23
View File
@@ -0,0 +1,23 @@
class A : b by a {
this() {}
}
class A : b by a + b() * 5 {
this() {}
}
class A : b by (a) {
this() {}
}
class A : b by (a {}) {
this() {}
}
class A : b by a[a {}] {
this() {}
}
class A : b by a(a {}) {
this() {}
}
class A : b by object {
fun f() = a {}
} {
this() {}
}
+326
View File
@@ -0,0 +1,326 @@
JetFile: ByCaluses.jet
NAMESPACE
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
BINARY_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(PLUS)('+')
PsiWhiteSpace(' ')
BINARY_EXPRESSION
CALL_EXPRESSION
PsiElement(IDENTIFIER)('b')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(MUL)('*')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('5')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
TUPLE
PsiElement(LPAR)('(')
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
TUPLE
PsiElement(LPAR)('(')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BODY
<empty list>
PsiElement(RBRACE)('}')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
ARRAY_ACCESS_EXPRESSION
PsiElement(IDENTIFIER)('a')
INDICES
PsiElement(LBRACKET)('[')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BODY
<empty list>
PsiElement(RBRACE)('}')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('a')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
CALL_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BODY
<empty list>
PsiElement(RBRACE)('}')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATION_SPECIFIER
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
OBJECT_LITERAL
PsiElement(object)('object')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BODY
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')