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 SUPERTYE_QUALIFIER = new JetNodeType("SUPERTYE_QUALIFIER");
JetNodeType LONG_CONSTANT = new JetNodeType("LONG_CONSTANT"); JetNodeType LONG_CONSTANT = new JetNodeType("LONG_CONSTANT");
JetNodeType TUPLE = new JetNodeType("TUPLE"); JetNodeType TUPLE = new JetNodeType("TUPLE");
JetNodeType ARROW_TUPLE = new JetNodeType("ARROW_TUPLE");
JetNodeType MAP_LITERAL_ENTRY = new JetNodeType("MAP_LITERAL_ENTRY"); JetNodeType MAP_LITERAL_ENTRY = new JetNodeType("MAP_LITERAL_ENTRY");
JetNodeType MAP_LITERAL = new JetNodeType("MAP_LITERAL"); JetNodeType MAP_LITERAL = new JetNodeType("MAP_LITERAL");
JetNodeType RANGE_LITERAL = new JetNodeType("RANGE_LITERAL"); JetNodeType RANGE_LITERAL = new JetNodeType("RANGE_LITERAL");
@@ -153,6 +153,7 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
if (at(token)) advance(); // token if (at(token)) advance(); // token
} }
// TODO: Migrate to predicates
protected void skipUntil(TokenSet tokenSet) { protected void skipUntil(TokenSet tokenSet) {
boolean stopAtEolOrSemi = tokenSet.contains(EOL_OR_SEMICOLON); boolean stopAtEolOrSemi = tokenSet.contains(EOL_OR_SEMICOLON);
while (!eof() && !tokenSet.contains(tt()) && !(stopAtEolOrSemi && at(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()) { while (!eof()) {
if (pattern.processToken( if (pattern.processToken(
myBuilder.getCurrentOffset(), myBuilder.getCurrentOffset(),
openAngleBrackets == 0 pattern.isTopLevel(openAngleBrackets, openBrackets, openBraces, openParentheses))) {
&& openBrackets == 0
&& openBraces == 0
&& openParentheses == 0)) {
break; break;
} }
if (at(LPAR)) { 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> * top-level occurrence of a token from the <code>stopSet</code>
* *
* Returns -1 if no occurrence is found * Returns -1 if no occurrence is found
*
* TODO: Migrate to predictaes
*/ */
protected int findLastBefore(TokenSet lookFor, TokenSet stopAt, boolean dontStopRightAfterOccurrence) { protected int findLastBefore(TokenSet lookFor, TokenSet stopAt, boolean dontStopRightAfterOccurrence) {
return matchTokenStreamPredicate(new LastBefore(new AtSet(lookFor), new AtSet(stopAt), 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 { public abstract class AbstractTokenStreamPattern implements TokenStreamPattern {
protected int lastOccurrence = -1; protected int lastOccurrence = -1;
@Override @Override
public int result() { public int result() {
return lastOccurrence; 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"}) @SuppressWarnings({"UnusedDeclaration"})
private enum Priority { private enum Precedence {
MEMBER_ACCESS(DOT, HASH, SAFE_ACCESS) { MEMBER_ACCESS(DOT, HASH, SAFE_ACCESS) {
@Override @Override
public void parseHigherPriority(JetExpressionParsing parsing) { public void parseHigherPrecedence(JetExpressionParsing parsing) {
parsing.parseAtomicExpression(); parsing.parseAtomicExpression();
} }
}, },
@@ -34,14 +34,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // attributes PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // attributes
@Override @Override
public void parseHigherPriority(JetExpressionParsing parsing) { public void parseHigherPrecedence(JetExpressionParsing parsing) {
throw new IllegalStateException("Don't call this method"); throw new IllegalStateException("Don't call this method");
} }
}, },
MULTIPLICATIVE(MUL, DIV, PERC) { MULTIPLICATIVE(MUL, DIV, PERC) {
@Override @Override
public void parseHigherPriority(JetExpressionParsing parsing) { public void parseHigherPrecedence(JetExpressionParsing parsing) {
parsing.parsePrefixExpression(); parsing.parsePrefixExpression();
} }
}, },
@@ -56,26 +56,27 @@ public class JetExpressionParsing extends AbstractJetParsing {
CONJUNCTION(ANDAND), CONJUNCTION(ANDAND),
DISJUNCTION(OROR), DISJUNCTION(OROR),
MATCH(MATCH_KEYWORD), MATCH(MATCH_KEYWORD),
// TODO: don't build a binary tree, build a tuple
ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ),
ARROW(JetTokens.ARROW), ARROW(JetTokens.ARROW),
ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ)
; ;
static { static {
Priority[] values = Priority.values(); Precedence[] values = Precedence.values();
for (Priority priority : values) { for (Precedence precedence : values) {
int ordinal = priority.ordinal(); int ordinal = precedence.ordinal();
priority.higher = ordinal > 0 ? values[ordinal - 1] : null; precedence.higher = ordinal > 0 ? values[ordinal - 1] : null;
} }
} }
private Priority higher; private Precedence higher;
private final TokenSet operations; private final TokenSet operations;
Priority(IElementType... operations ) { Precedence(IElementType... operations) {
this.operations = TokenSet.create(operations); this.operations = TokenSet.create(operations);
} }
public void parseHigherPriority(JetExpressionParsing parsing) { public void parseHigherPrecedence(JetExpressionParsing parsing) {
assert higher != null; assert higher != null;
parsing.parseBinaryExpression(higher); parsing.parseBinaryExpression(higher);
} }
@@ -107,18 +108,23 @@ public class JetExpressionParsing extends AbstractJetParsing {
* ; * ;
*/ */
public void parseExpression() { 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(); PsiBuilder.Marker expression = mark();
priority.parseHigherPriority(this); precedence.parseHigherPrecedence(this);
while (!myBuilder.eolInLastWhitespace() && atSet(priority.getOperations())) { while (!myBuilder.eolInLastWhitespace() && atSet(precedence.getOperations())) {
advance(); // operation advance(); // operation
priority.parseHigherPriority(this); precedence.parseHigherPrecedence(this);
expression.done(BINARY_EXPRESSION); expression.done(BINARY_EXPRESSION);
expression = expression.precede(); expression = expression.precede();
} }
@@ -126,6 +132,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
expression.drop(); expression.drop();
} }
/*
* operation? expression
*/
private void parsePrefixExpression() { private void parsePrefixExpression() {
// System.out.println("pre at " + tt()); // System.out.println("pre at " + tt());
if (at(LBRACKET)) { if (at(LBRACKET)) {
@@ -135,7 +144,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
parsePostfixExpression(); parsePostfixExpression();
attributes.done(ANNOTATED_EXPRESSION); attributes.done(ANNOTATED_EXPRESSION);
} }
} else if (atSet(Priority.PREFIX.getOperations())) { } else if (atSet(Precedence.PREFIX.getOperations())) {
PsiBuilder.Marker expression = mark(); PsiBuilder.Marker expression = mark();
advance(); // operation advance(); // operation
parsePostfixExpression(); parsePostfixExpression();
@@ -145,17 +154,20 @@ public class JetExpressionParsing extends AbstractJetParsing {
} }
} }
/*
* expression operation?
*/
private void parsePostfixExpression() { private void parsePostfixExpression() {
// System.out.println("post at " + tt()); // System.out.println("post at " + tt());
PsiBuilder.Marker expression = mark(); PsiBuilder.Marker expression = mark();
parseBinaryExpression(Priority.MEMBER_ACCESS); parseBinaryExpression(Precedence.MEMBER_ACCESS);
if (myBuilder.eolInLastWhitespace()) { if (myBuilder.eolInLastWhitespace()) {
expression.drop(); expression.drop();
} else if (at(LBRACKET)) { } else if (at(LBRACKET)) {
parseArrayAccess(); parseArrayAccess();
expression.done(ARRAY_ACCESS_EXPRESSION); expression.done(ARRAY_ACCESS_EXPRESSION);
} else if (atSet(Priority.POSTFIX.getOperations())) { } else if (atSet(Precedence.POSTFIX.getOperations())) {
advance(); // operation advance(); // operation
expression.done(POSTFIX_EXPRESSION); expression.done(POSTFIX_EXPRESSION);
} else if (at(LPAR)) { } else if (at(LPAR)) {
@@ -171,7 +183,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* : tupleLiteral // or parenthesized expression * : tupleLiteral // or parenthesized expression
* : "this" ("<" type ">")? * : "this" ("<" type ">")?
* : "typeof" "(" expression ")" * : "typeof" "(" expression ")"
* : "new" constructorInvocation // TODO: Do we need "new"?, see factory methods * : "new" constructorInvocation
* : objectLiteral * : objectLiteral
* : jump * : jump
* : if * : if
@@ -347,7 +359,12 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // LBRACE 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) { if (doubleArrowPos >= 0) {
boolean dontExpectParameters = false; boolean dontExpectParameters = false;
@@ -460,7 +477,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
public void parseExpressions() { public void parseExpressions() {
while (!eof() && !at(RBRACE)) { while (!eof() && !at(RBRACE)) {
parseExpression(); 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 @Override
public boolean eolInLastWhitespace() { public boolean eolInLastWhitespace() {
return myEOLInLastWhitespace; return myEOLInLastWhitespace || eof();
} }
} }
@@ -7,10 +7,8 @@ public interface TokenStreamPattern {
/** /**
* Called on each token * Called on each token
* *
*
*
* @param offset * @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 * @return <code>true</code> to stop
*/ */
boolean processToken(int offset, boolean topLevel); 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 * @return the position where the predicate has matched, -1 if no match was found
*/ */
int result(); 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 ') PsiWhiteSpace('\n\n ')
FUNCTION_LITERAL FUNCTION_LITERAL
PsiElement(LBRACE)('{') PsiElement(LBRACE)('{')
BODY VALUE_PARAMETER_LIST
TUPLE PsiElement(LPAR)('(')
PsiElement(LPAR)('(') VALUE_PARAMETER
PsiElement(IDENTIFIER)('a') PsiElement(IDENTIFIER)('a')
PsiErrorElement:Expecting ')' PsiErrorElement:Expecting ')
<empty list> <empty list>
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiErrorElement:Expecting an expression PsiElement(DOUBLE_ARROW)('=>')
PsiElement(DOUBLE_ARROW)('=>') PsiWhiteSpace(' ')
PsiWhiteSpace(' ') BODY
PsiElement(IDENTIFIER)('a') PsiElement(IDENTIFIER)('a')
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')