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) { public static JetParsing createForByClause(final SemanticWhitespaceAwarePsiBuilder builder) {
JetParsing jetParsing = new JetParsing(builder); final SemanticWhitespaceAwarePsiBuilderForByClause builderForByClause = new SemanticWhitespaceAwarePsiBuilderForByClause(builder);
jetParsing.myExpressionParsing = new JetExpressionParsing(builder, jetParsing) { JetParsing jetParsing = new JetParsing(builderForByClause);
jetParsing.myExpressionParsing = new JetExpressionParsing(builderForByClause, jetParsing) {
@Override @Override
protected boolean parseCallWithClosure() { protected boolean parseCallWithClosure() {
if (builderForByClause.getStackSize() > 0) {
return super.parseCallWithClosure();
}
return false; return false;
} }
@@ -527,7 +531,7 @@ public class JetParsing extends AbstractJetParsing {
* ; * ;
*/ */
/*package*/ void parseClassBody() { /*package*/ void parseClassBody() {
// TODO : initializer? // TODO : anonymous initializer, like {...} in Java?
assert at(LBRACE); assert at(LBRACE);
PsiBuilder.Marker body = mark(); PsiBuilder.Marker body = mark();
@@ -1003,7 +1007,6 @@ public class JetParsing extends AbstractJetParsing {
if (at(BY_KEYWORD)) { if (at(BY_KEYWORD)) {
advance(); // 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(); createForByClause(myBuilder).myExpressionParsing.parseExpression();
delegator.done(DELEGATOR_BY); delegator.done(DELEGATOR_BY);
} }
@@ -1336,7 +1339,7 @@ public class JetParsing extends AbstractJetParsing {
int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(RBRACE, COLON), false); int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(RBRACE, COLON), false);
if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) { if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) {
PsiBuilder.Marker receiverType = mark(); PsiBuilder.Marker receiverType = mark();
// TODO : -1 is a hack // TODO : -1 is a hack?
createTruncatedBuilder(lastLPar - 1).parseTypeRef(); createTruncatedBuilder(lastLPar - 1).parseTypeRef();
receiverType.done(RECEIVER_TYPE); receiverType.done(RECEIVER_TYPE);
advance(); // DOT advance(); // DOT
@@ -6,6 +6,7 @@ import com.intellij.lang.PsiBuilder;
* @author abreslav * @author abreslav
*/ */
public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder { public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
// TODO: Wrong name, should be something like "EOL before current token"
boolean eolInLastWhitespace(); boolean eolInLastWhitespace();
void disableEols(); void disableEols();
void enableEols(); 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 * @author abreslav
*/ */
public class TruncatedSemanticWhitespaceAwarePsiBuilder extends PsiBuilderAdapter implements SemanticWhitespaceAwarePsiBuilder { public class TruncatedSemanticWhitespaceAwarePsiBuilder extends SemanticWhitespaceAwarePsiBuilderAdapter {
private final SemanticWhitespaceAwarePsiBuilder myBuilder;
private final int myEOFPosition; private final int myEOFPosition;
public TruncatedSemanticWhitespaceAwarePsiBuilder(SemanticWhitespaceAwarePsiBuilder myBuilder, int eofPosition) { public TruncatedSemanticWhitespaceAwarePsiBuilder(SemanticWhitespaceAwarePsiBuilder builder, int eofPosition) {
super(myBuilder); super(builder);
this.myBuilder = myBuilder;
this.myEOFPosition = eofPosition; 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 @Override
public boolean eof() { public boolean eof() {
if (super.eof()) return true; 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)('}')