Call with closure is available inside the by clause in nested expressions, see the test
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -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;
|
||||
}
|
||||
}
|
||||
+3
-25
@@ -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;
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
@@ -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)('}')
|
||||
Reference in New Issue
Block a user