import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression;
+import net.sourceforge.phpeclipse.internal.compiler.ast.Block;
import net.sourceforge.phpeclipse.internal.compiler.ast.BreakStatement;
import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression;
return compilationUnit;
}
-// private boolean isVariable() {
-// return token == TokenNameVariable; // || token == TokenNamethis;
-// }
-
- private void statementList() {
+ private Block statementList() {
boolean branchStatement = false;
Statement statement;
int sourceStart;
int sourceEnd;
+ int blockStart = scanner.getCurrentTokenStartPosition();
+ ArrayList blockStatements = new ArrayList();
do {
try {
sourceStart = scanner.getCurrentTokenStartPosition();
- statement = statement(TokenNameEOF);
+ statement = statement();
+ blockStatements.add(statement);
if (branchStatement) {
sourceEnd = scanner.getCurrentTokenEndPosition();
reportSyntaxError("Unreachable code", sourceStart, sourceEnd);
|| (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
|| (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
|| (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
- return;
- }
- branchStatement = false;
- if (statement instanceof ReturnStatement ||statement instanceof ContinueStatement || statement instanceof BreakStatement) {
- branchStatement = true;
+ return createBlock(blockStart, blockStatements);
}
+ branchStatement = checkUnreachableStatements(statement);
+// return createBlock(blockStart, blockStatements);
} catch (SyntaxError sytaxErr1) {
// if an error occured,
// try to find keywords
|| (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
|| (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
|| (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
- return;
+ return createBlock(blockStart, blockStatements);
}
if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile
|| token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak
} while (true);
}
+ /**
+ * @param statement
+ * @return
+ */
+ private boolean checkUnreachableStatements(Statement statement) {
+ boolean branchStatement = false;
+ if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) {
+ branchStatement = true;
+ } else if (statement instanceof IfStatement && ((IfStatement)statement).checkUnreachable) {
+ branchStatement = true;
+ }
+ return branchStatement;
+ }
+
+ /**
+ * @param blockStart
+ * @param blockStatements
+ * @return
+ */
+ private Block createBlock(int blockStart, ArrayList blockStatements) {
+ int blockEnd = scanner.getCurrentTokenEndPosition();
+ Block b = Block.EmptyWith(blockStart, blockEnd);
+ b.statements = new Statement[blockStatements.size()];
+ blockStatements.toArray(b.statements);
+ return b;
+ }
+
private void functionBody(MethodDeclaration methodDecl) {
// '{' [statement-list] '}'
if (token == TokenNameLBRACE) {
}
}
- private Statement statement(int previousToken) {
+ private Statement statement() {
Statement statement = null;
Expression expression;
int sourceStart = scanner.getCurrentTokenStartPosition();
int sourceEnd;
if (token == TokenNameif) {
+ // T_IF '(' expr ')' statement elseif_list else_single
+ // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'if' condition.");
}
- ifStatement();
- return new IfStatement(expression, statement, sourceStart, scanner.getCurrentTokenEndPosition());
+ // create basic IfStatement
+ IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1);
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ ifStatementColon(ifStatement);
+ } else {
+ ifStatement(ifStatement);
+ }
+ return ifStatement;
} else if (token == TokenNameswitch) {
getNextToken();
if (token == TokenNameLPAREN) {
throwSyntaxError("'}' expected after 'do' keyword.");
}
} else {
- statement(TokenNameEOF);
+ statement();
}
if (token == TokenNamewhile) {
getNextToken();
sourceEnd = scanner.getCurrentTokenEndPosition();
getNextToken();
}
- return new BreakStatement(null,sourceStart, sourceEnd);
+ return new BreakStatement(null, sourceStart, sourceEnd);
} else if (token == TokenNamecontinue) {
expression = null;
getNextToken();
sourceEnd = scanner.getCurrentTokenEndPosition();
getNextToken();
}
- return new ContinueStatement(null,sourceStart, sourceEnd);
+ return new ContinueStatement(null, sourceStart, sourceEnd);
} else if (token == TokenNamereturn) {
expression = null;
getNextToken();
sourceEnd = scanner.getCurrentTokenEndPosition();
getNextToken();
}
- return new ReturnStatement(expression,sourceStart, sourceEnd);
+ return new ReturnStatement(expression, sourceStart, sourceEnd);
} else if (token == TokenNameecho) {
getNextToken();
expressionList();
} else if (token == TokenNameLBRACE) {
getNextToken();
if (token != TokenNameRBRACE) {
- statementList();
+ statement = statementList();
}
if (token == TokenNameRBRACE) {
getNextToken();
}
getNextToken();
} else {
- statement(TokenNameRPAREN);
+ statement();
}
}
} while (token == TokenNamecase || token == TokenNamedefault);
}
- // public void labeledStatement() {
- // if (token == TokenNamecase) {
- // getNextToken();
- // constant();
- // if (token == TokenNameDDOT) {
- // getNextToken();
- // statement();
- // } else {
- // throwSyntaxError("':' character after 'case' constant expected.");
- // }
- // return;
- // } else if (token == TokenNamedefault) {
- // getNextToken();
- // if (token == TokenNameDDOT) {
- // getNextToken();
- // statement();
- // } else {
- // throwSyntaxError("':' character after 'default' expected.");
- // }
- // return;
- // }
- // }
- // public void expressionStatement() {
- // }
- // private void inclusionStatement() {
- // }
- // public void compoundStatement() {
- // }
- // public void selectionStatement() {
- // }
- //
- // public void iterationStatement() {
- // }
- //
- // public void jumpStatement() {
- // }
- //
- // public void outputStatement() {
- // }
- //
- // public void scopeStatement() {
- // }
- //
- // public void flowStatement() {
- // }
- //
- // public void definitionStatement() {
- // }
- private void ifStatement() {
- // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
- if (token == TokenNameCOLON) {
- getNextToken();
- if (token != TokenNameendif) {
- statementList();
- switch (token) {
- case TokenNameelse:
- getNextToken();
- if (token == TokenNameCOLON) {
- getNextToken();
- if (token != TokenNameendif) {
- statementList();
- }
- } else {
- if (token == TokenNameif) { //'else if'
- getNextToken();
- elseifStatementList();
- } else {
- throwSyntaxError("':' expected after 'else'.");
- }
- }
- break;
- case TokenNameelseif:
- getNextToken();
- elseifStatementList();
- break;
- }
- }
- if (token != TokenNameendif) {
- throwSyntaxError("'endif' expected.");
- }
+ private void ifStatementColon(IfStatement iState) {
+ // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
+ Block b = inner_statement_list();
+ iState.thenStatement = b;
+ checkUnreachable(iState, b);
+ if (token == TokenNameelseif) {
+ new_elseif_list(iState);
+ }
+ new_else_single(iState);
+ if (token != TokenNameendif) {
+ throwSyntaxError("'endif' expected.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ reportSyntaxError("';' expected after if-statement.");
+ iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+ } else {
+ iState.sourceEnd = scanner.getCurrentTokenEndPosition();
getNextToken();
- if (token != TokenNameSEMICOLON) {
- throwSyntaxError("';' expected after if-statement.");
- }
+ }
+ }
+
+ private void ifStatement(IfStatement iState) {
+ // T_IF '(' expr ')' statement elseif_list else_single
+ Statement s = statement();
+ iState.thenStatement = s;
+ checkUnreachable(iState, s);
+ if (token == TokenNameelseif) {
+ elseif_list(iState);
+ }
+ else_single(iState);
+ }
+
+ private void elseif_list(IfStatement iState) {
+ // /* empty */
+ //| elseif_list T_ELSEIF '(' expr ')' statement
+ ArrayList conditionList = new ArrayList();
+ ArrayList statementList = new ArrayList();
+ Expression e;
+ Statement s;
+ while (token == TokenNameelseif) {
getNextToken();
- } else {
- // statement [else-statement]
- statement(TokenNameEOF);
- if (token == TokenNameelseif) {
+ if (token == TokenNameLPAREN) {
getNextToken();
- if (token == TokenNameLPAREN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'elseif' keyword.");
- }
- expr();
- if (token == TokenNameRPAREN) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'elseif' condition.");
- }
- ifStatement();
- } else if (token == TokenNameelse) {
+ } else {
+ throwSyntaxError("'(' expected after 'elseif' keyword.");
+ }
+ e = expr();
+ conditionList.add(e);
+ if (token == TokenNameRPAREN) {
getNextToken();
- statement(TokenNameEOF);
+ } else {
+ throwSyntaxError("')' expected after 'elseif' condition.");
}
+ s = statement();
+ statementList.add(s);
+ checkUnreachable(iState, s);
}
+ iState.elseifConditions = new Expression[conditionList.size()];
+ iState.elseifStatements = new Statement[statementList.size()];
+ conditionList.toArray(iState.elseifConditions);
+ statementList.toArray(iState.elseifStatements);
}
- private void elseifStatementList() {
- do {
- elseifStatement();
- switch (token) {
- case TokenNameelse:
+ private void new_elseif_list(IfStatement iState) {
+ // /* empty */
+ //| new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
+ ArrayList conditionList = new ArrayList();
+ ArrayList statementList = new ArrayList();
+ Expression e;
+ Block b;
+ while (token == TokenNameelseif) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
getNextToken();
- if (token == TokenNameCOLON) {
- getNextToken();
- if (token != TokenNameendif) {
- statementList();
- }
- return;
- } else {
- if (token == TokenNameif) { //'else if'
- getNextToken();
- } else {
- throwSyntaxError("':' expected after 'else'.");
- }
- }
- break;
- case TokenNameelseif:
+ } else {
+ throwSyntaxError("'(' expected after 'elseif' keyword.");
+ }
+ e = expr();
+ conditionList.add(e);
+ if (token == TokenNameRPAREN) {
getNextToken();
- break;
- default:
- return;
+ } else {
+ throwSyntaxError("')' expected after 'elseif' condition.");
}
- } while (true);
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("':' expected after 'elseif' keyword.");
+ }
+ b = inner_statement_list();
+ statementList.add(b);
+ checkUnreachable(iState, b);
+ }
+ iState.elseifConditions = new Expression[conditionList.size()];
+ iState.elseifStatements = new Statement[statementList.size()];
+ conditionList.toArray(iState.elseifConditions);
+ statementList.toArray(iState.elseifStatements);
}
- private void elseifStatement() {
- if (token == TokenNameLPAREN) {
+ private void else_single(IfStatement iState) {
+ // /* empty */
+ // T_ELSE statement
+ if (token == TokenNameelse) {
getNextToken();
- expr();
- if (token != TokenNameRPAREN) {
- throwSyntaxError("')' expected in else-if-statement.");
- }
+ Statement s = statement();
+ iState.elseStatement = s;
+ checkUnreachable(iState, s);
+ } else {
+ iState.checkUnreachable = false;
+ }
+ iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+ }
+
+ private void new_else_single(IfStatement iState) {
+ // /* empty */
+ //| T_ELSE ':' inner_statement_list
+ if (token == TokenNameelse) {
getNextToken();
- if (token != TokenNameCOLON) {
- throwSyntaxError("':' expected in else-if-statement.");
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("':' expected after 'else' keyword.");
}
- getNextToken();
- if (token != TokenNameendif) {
- statementList();
+ Block b = inner_statement_list();
+ iState.elseStatement = b;
+ checkUnreachable(iState, b);
+ } else {
+ iState.checkUnreachable = false;
+ }
+ }
+
+ private Block inner_statement_list() {
+ // inner_statement_list inner_statement
+ // /* empty */
+ return statementList();
+ }
+
+ /**
+ * @param iState
+ * @param b
+ */
+ private void checkUnreachable(IfStatement iState, Statement s) {
+ if (s instanceof Block) {
+ Block b = (Block) s;
+ if (b.statements == null || b.statements.length == 0) {
+ iState.checkUnreachable = false;
+ } else {
+ int off = b.statements.length - 1;
+ if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement)
+ && !(b.statements[off] instanceof BreakStatement)) {
+ iState.checkUnreachable = false;
+ }
+ }
+ } else {
+ if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) {
+ iState.checkUnreachable = false;
}
}
}
+ // private void elseifStatementList() {
+ // do {
+ // elseifStatement();
+ // switch (token) {
+ // case TokenNameelse:
+ // getNextToken();
+ // if (token == TokenNameCOLON) {
+ // getNextToken();
+ // if (token != TokenNameendif) {
+ // statementList();
+ // }
+ // return;
+ // } else {
+ // if (token == TokenNameif) { //'else if'
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("':' expected after 'else'.");
+ // }
+ // }
+ // break;
+ // case TokenNameelseif:
+ // getNextToken();
+ // break;
+ // default:
+ // return;
+ // }
+ // } while (true);
+ // }
+
+ // private void elseifStatement() {
+ // if (token == TokenNameLPAREN) {
+ // getNextToken();
+ // expr();
+ // if (token != TokenNameRPAREN) {
+ // throwSyntaxError("')' expected in else-if-statement.");
+ // }
+ // getNextToken();
+ // if (token != TokenNameCOLON) {
+ // throwSyntaxError("':' expected in else-if-statement.");
+ // }
+ // getNextToken();
+ // if (token != TokenNameendif) {
+ // statementList();
+ // }
+ // }
+ // }
+
private void switchStatement() {
if (token == TokenNameCOLON) {
// ':' [labeled-statement-list] 'endswitch' ';'
}
getNextToken();
} else {
- statement(TokenNameEOF);
+ statement();
}
}
}
getNextToken();
} else {
- statement(TokenNameEOF);
+ statement();
}
}
}
getNextToken();
} else {
- statement(TokenNameEOF);
+ statement();
}
}