Minor fixes. The semantic newline problem is still there

This commit is contained in:
Andrey Breslav
2010-12-30 13:32:19 +03:00
parent 477d7c0a98
commit aaa3e9e1c2
8 changed files with 472 additions and 435 deletions
@@ -64,6 +64,7 @@ public interface JetNodeTypes {
JetNodeType SUPERTYE_QUALIFIER = new JetNodeType("SUPERTYE_QUALIFIER");
JetNodeType LONG_CONSTANT = new JetNodeType("LONG_CONSTANT");
JetNodeType TUPLE = new JetNodeType("TUPLE");
JetNodeType ARROW_TUPLE = new JetNodeType("ARROW_TUPLE");
JetNodeType MAP_LITERAL_ENTRY = new JetNodeType("MAP_LITERAL_ENTRY");
JetNodeType MAP_LITERAL = new JetNodeType("MAP_LITERAL");
JetNodeType RANGE_LITERAL = new JetNodeType("RANGE_LITERAL");
@@ -153,6 +153,7 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
if (at(token)) advance(); // token
}
// TODO: Migrate to predicates
protected void skipUntil(TokenSet tokenSet) {
boolean stopAtEolOrSemi = tokenSet.contains(EOL_OR_SEMICOLON);
while (!eof() && !tokenSet.contains(tt()) && !(stopAtEolOrSemi && at(EOL_OR_SEMICOLON))) {
@@ -183,10 +184,7 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
while (!eof()) {
if (pattern.processToken(
myBuilder.getCurrentOffset(),
openAngleBrackets == 0
&& openBrackets == 0
&& openBraces == 0
&& openParentheses == 0)) {
pattern.isTopLevel(openAngleBrackets, openBrackets, openBraces, openParentheses))) {
break;
}
if (at(LPAR)) {
@@ -224,6 +222,8 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
* top-level occurrence of a token from the <code>stopSet</code>
*
* Returns -1 if no occurrence is found
*
* TODO: Migrate to predictaes
*/
protected int findLastBefore(TokenSet lookFor, TokenSet stopAt, boolean dontStopRightAfterOccurrence) {
return matchTokenStreamPredicate(new LastBefore(new AtSet(lookFor), new AtSet(stopAt), dontStopRightAfterOccurrence));
@@ -5,11 +5,16 @@ package org.jetbrains.jet.lang.parsing;
*/
public abstract class AbstractTokenStreamPattern implements TokenStreamPattern {
protected int lastOccurrence = -1;
protected int lastOccurrence = -1;
@Override
public int result() {
return lastOccurrence;
}
@Override
public int result() {
return lastOccurrence;
}
@Override
public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
return openBraces == 0 && openBrackets == 0 && openParentheses == 0 && openAngleBrackets == 0;
}
}
@@ -21,10 +21,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
@SuppressWarnings({"UnusedDeclaration"})
private enum Priority {
private enum Precedence {
MEMBER_ACCESS(DOT, HASH, SAFE_ACCESS) {
@Override
public void parseHigherPriority(JetExpressionParsing parsing) {
public void parseHigherPrecedence(JetExpressionParsing parsing) {
parsing.parseAtomicExpression();
}
},
@@ -34,14 +34,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // attributes
@Override
public void parseHigherPriority(JetExpressionParsing parsing) {
public void parseHigherPrecedence(JetExpressionParsing parsing) {
throw new IllegalStateException("Don't call this method");
}
},
MULTIPLICATIVE(MUL, DIV, PERC) {
@Override
public void parseHigherPriority(JetExpressionParsing parsing) {
public void parseHigherPrecedence(JetExpressionParsing parsing) {
parsing.parsePrefixExpression();
}
},
@@ -56,26 +56,27 @@ public class JetExpressionParsing extends AbstractJetParsing {
CONJUNCTION(ANDAND),
DISJUNCTION(OROR),
MATCH(MATCH_KEYWORD),
// TODO: don't build a binary tree, build a tuple
ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ),
ARROW(JetTokens.ARROW),
ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ)
;
static {
Priority[] values = Priority.values();
for (Priority priority : values) {
int ordinal = priority.ordinal();
priority.higher = ordinal > 0 ? values[ordinal - 1] : null;
Precedence[] values = Precedence.values();
for (Precedence precedence : values) {
int ordinal = precedence.ordinal();
precedence.higher = ordinal > 0 ? values[ordinal - 1] : null;
}
}
private Priority higher;
private Precedence higher;
private final TokenSet operations;
Priority(IElementType... operations ) {
Precedence(IElementType... operations) {
this.operations = TokenSet.create(operations);
}
public void parseHigherPriority(JetExpressionParsing parsing) {
public void parseHigherPrecedence(JetExpressionParsing parsing) {
assert higher != null;
parsing.parseBinaryExpression(higher);
}
@@ -107,18 +108,23 @@ public class JetExpressionParsing extends AbstractJetParsing {
* ;
*/
public void parseExpression() {
parseBinaryExpression(Priority.ASSIGNMENT);
parseBinaryExpression(Precedence.ASSIGNMENT);
}
private void parseBinaryExpression(Priority priority) {
// System.out.println(priority.name() + " at " + tt());
/*
* expression (operation expression)*
*
* see the precedence table
*/
private void parseBinaryExpression(Precedence precedence) {
// System.out.println(precedence.name() + " at " + tt());
PsiBuilder.Marker expression = mark();
priority.parseHigherPriority(this);
precedence.parseHigherPrecedence(this);
while (!myBuilder.eolInLastWhitespace() && atSet(priority.getOperations())) {
while (!myBuilder.eolInLastWhitespace() && atSet(precedence.getOperations())) {
advance(); // operation
priority.parseHigherPriority(this);
precedence.parseHigherPrecedence(this);
expression.done(BINARY_EXPRESSION);
expression = expression.precede();
}
@@ -126,6 +132,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
expression.drop();
}
/*
* operation? expression
*/
private void parsePrefixExpression() {
// System.out.println("pre at " + tt());
if (at(LBRACKET)) {
@@ -135,7 +144,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
parsePostfixExpression();
attributes.done(ANNOTATED_EXPRESSION);
}
} else if (atSet(Priority.PREFIX.getOperations())) {
} else if (atSet(Precedence.PREFIX.getOperations())) {
PsiBuilder.Marker expression = mark();
advance(); // operation
parsePostfixExpression();
@@ -145,17 +154,20 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
}
/*
* expression operation?
*/
private void parsePostfixExpression() {
// System.out.println("post at " + tt());
PsiBuilder.Marker expression = mark();
parseBinaryExpression(Priority.MEMBER_ACCESS);
parseBinaryExpression(Precedence.MEMBER_ACCESS);
if (myBuilder.eolInLastWhitespace()) {
expression.drop();
} else if (at(LBRACKET)) {
parseArrayAccess();
expression.done(ARRAY_ACCESS_EXPRESSION);
} else if (atSet(Priority.POSTFIX.getOperations())) {
} else if (atSet(Precedence.POSTFIX.getOperations())) {
advance(); // operation
expression.done(POSTFIX_EXPRESSION);
} else if (at(LPAR)) {
@@ -171,7 +183,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* : tupleLiteral // or parenthesized expression
* : "this" ("<" type ">")?
* : "typeof" "(" expression ")"
* : "new" constructorInvocation // TODO: Do we need "new"?, see factory methods
* : "new" constructorInvocation
* : objectLiteral
* : jump
* : if
@@ -347,7 +359,12 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // LBRACE
int doubleArrowPos = matchTokenStreamPredicate(new FirstBefore(new At(DOUBLE_ARROW), new At(RBRACE)));
int doubleArrowPos = matchTokenStreamPredicate(new FirstBefore(new At(DOUBLE_ARROW), new At(RBRACE)) {
@Override
public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
return openBraces == 0;
}
});
if (doubleArrowPos >= 0) {
boolean dontExpectParameters = false;
@@ -460,7 +477,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
public void parseExpressions() {
while (!eof() && !at(RBRACE)) {
parseExpression();
consumeIf(SEMICOLON);
if (at(SEMICOLON)) {
advance(); // SEMICOLON
} else if (at(RBRACE)) {
break;
} else if (!myBuilder.eolInLastWhitespace()) {
errorUntil("Unexpected tokens (use ';' to separate expressions on the same line", TokenSet.create(EOL_OR_SEMICOLON));
}
}
}
@@ -37,6 +37,6 @@ public class SemanticWhitespaceAwarePsiBuilderImpl extends PsiBuilderAdapter imp
@Override
public boolean eolInLastWhitespace() {
return myEOLInLastWhitespace;
return myEOLInLastWhitespace || eof();
}
}
@@ -7,10 +7,8 @@ public interface TokenStreamPattern {
/**
* Called on each token
*
*
*
* @param offset
* @param topLevel indicates if no brackets (of types () [] {} <>) are currently unmatched
* @param topLevel see {@link #isTopLevel(int, int, int, int)}
* @return <code>true</code> to stop
*/
boolean processToken(int offset, boolean topLevel);
@@ -19,4 +17,10 @@ public interface TokenStreamPattern {
* @return the position where the predicate has matched, -1 if no match was found
*/
int result();
/*
* Decides if the combination of open bracet counts makes a "top level position"
* Straightforward meaning would be: if all counts are zero, then it's a top level
*/
boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses);
}
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -42,16 +42,16 @@ JetFile: FunctionLiterals_ERR.jet
PsiWhiteSpace('\n\n ')
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BODY
TUPLE
PsiElement(LPAR)('(')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiErrorElement:Expecting ')'
<empty list>
PsiWhiteSpace(' ')
PsiErrorElement:Expecting an expression
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting ')
<empty list>
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
BODY
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')