X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index 908fbf8..a838e7f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -9,6 +9,7 @@ package net.sourceforge.phpdt.internal.compiler.parser; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; @@ -73,42 +74,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI protected boolean diet = false; //tells the scanner to jump over some - // parts of the code/expressions like - // method bodies - //scanner token + /** + * the PHP token scanner + */ public Scanner scanner; - // private ArrayList phpList; - - // private int currentPHPString; - - // private boolean phpEnd; - - // private static HashMap keywordMap = null; - private String str; - - // current character - // char ch; - // current token int token; - // row counter for syntax errors: - //int rowCount; - // column counter for syntax errors: - //int columnCount; - //int chIndx; - // - // // current identifier - // String identifier; - // Long longNumber; - - // Double doubleNumber; - - // private String stringValue; - - /** Contains the current expression. */ - // private StringBuffer expression; - //private boolean phpMode; protected int modifiers; protected int modifiersSourceStart; @@ -116,28 +88,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI protected Parser(ProblemReporter problemReporter) { this.problemReporter = problemReporter; this.options = problemReporter.options; - // this.currentPHPString = 0; - // PHPParserSuperclass.fileToParse = fileToParse; - // this.phpList = null; - // this.indexManager = null; - this.str = ""; this.token = TokenNameEOF; - // this.chIndx = 0; - // this.rowCount = 1; - // this.columnCount = 0; - // this.phpEnd = false; - // getNextToken(); this.initializeScanner(); } public void setFileToParse(IFile fileToParse) { - // this.currentPHPString = 0; - // PHPParserSuperclass.fileToParse = fileToParse; - // this.phpList = null; - // this.indexManager = null; - this.str = ""; this.token = TokenNameEOF; - // this.phpEnd = false; this.initializeScanner(); } @@ -160,7 +116,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // PHPParserSuperclass.fileToParse = fileToParse; // this.phpList = null; this.includesList = null; - this.str = ""; +// this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; @@ -193,8 +149,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI */ private void throwSyntaxError(String error) { int problemStartPosition = scanner.getCurrentTokenStartPosition(); - int problemEndPosition = scanner.getCurrentTokenEndPosition(); - throwSyntaxError(error, problemStartPosition, problemEndPosition + 1); + int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1; + if (scanner.source.length <= problemEndPosition && problemEndPosition > 0) { + problemEndPosition = scanner.source.length - 1; + if (problemStartPosition > 0 && problemStartPosition >= problemEndPosition && problemEndPosition > 0) { + problemStartPosition = problemEndPosition - 1; + } + } + throwSyntaxError(error, problemStartPosition, problemEndPosition); } /** @@ -229,12 +191,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } - private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) { - if (referenceContext != null) { - problemReporter.phpParsingWarning(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, - compilationUnit.compilationResult); - } - } +// private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) { +// if (referenceContext != null) { +// problemReporter.phpParsingWarning(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, +// compilationUnit.compilationResult); +// } +// } /** * gets the next token from input @@ -262,7 +224,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } public void init(String s) { - this.str = s; +// this.str = s; this.token = TokenNameEOF; this.includesList = new ArrayList(); // this.chIndx = 0; @@ -285,7 +247,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI referenceContext = null; this.includesList = new ArrayList(); // this.indexManager = indexManager; - this.str = ""; +// this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; @@ -308,6 +270,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI */ public void parse(String s, HashMap variables) { fMethodVariables = variables; + fStackUnassigned = new ArrayList(); init(s); parse(); } @@ -354,30 +317,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("End-of-file not reached."); } break; - } catch (SyntaxError sytaxErr1) { + } catch (SyntaxError syntaxError) { + // syntaxError.printStackTrace(); break; - // // if an error occured, - // // try to find keywords 'abstract' 'final' 'class' or 'function' - // // to parse the rest of the string - // boolean tokenize = scanner.tokenizeStrings; - // if (!tokenize) { - // scanner.tokenizeStrings = true; - // } - // try { - // while (token != TokenNameEOF) { - // if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) { - // break; - // } - // getNextToken(); - // } - // if (token == TokenNameEOF) { - // break; - // } - // } catch (SyntaxError sytaxErr2) { - // break; - // } finally { - // scanner.tokenizeStrings = tokenize; - // } } } while (true); @@ -415,10 +357,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } catch (SyntaxError sytaxErr1) { return; } finally { - int sourceEnd = scanner.getCurrentTokenStartPosition(); + int sourceEnd = methodDecl.sourceEnd; if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { sourceEnd = methodDecl.declarationSourceStart + 1; } + methodDecl.sourceEnd = sourceEnd; methodDecl.declarationSourceEnd = sourceEnd; } } @@ -470,8 +413,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI try { statement = statement(); blockStatements.add(statement); - if (branchStatement && statement!=null) { - reportSyntaxError("Unreachable code", statement.sourceStart, statement.sourceEnd); + if (branchStatement && statement != null) { + // reportSyntaxError("Unreachable code", statement.sourceStart, statement.sourceEnd); + problemReporter.unreachableCode(new String(scanner.getCurrentIdentifierSource()), statement.sourceStart, + statement.sourceEnd, referenceContext, compilationUnit.compilationResult); } if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) @@ -525,7 +470,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI private boolean checkUnreachableStatements(Statement statement) { if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) { return true; - } else if (statement instanceof IfStatement && ((IfStatement)statement).checkUnreachable) { + } else if (statement instanceof IfStatement && ((IfStatement) statement).checkUnreachable) { return true; } return false; @@ -549,15 +494,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameLBRACE) { getNextToken(); } else { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("'{' expected in compound-statement."); } if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { - // methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("'}' expected in compound-statement."); } } @@ -718,7 +665,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI foreach_optional_arg(); if (token == TokenNameEQUAL_GREATER) { getNextToken(); - variable(); + variable(false, false); } if (token == TokenNameRPAREN) { getNextToken(); @@ -791,7 +738,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } return statement; } else if (token == TokenNameINLINE_HTML) { - getNextToken(); + if (scanner.phpExpressionTag) { + // start of block + getNextToken(); + expr(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("Missing '?>' for open PHP expression block (' sourceEnd) { sourceEnd = methodDecl.declarationSourceStart + 1; } methodDecl.declarationSourceEnd = sourceEnd; + methodDecl.sourceEnd = sourceEnd; } return statement; } else if (token == TokenNamedeclare) { @@ -903,6 +863,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token != TokenNameVariable) { throwSyntaxError("Variable expected in 'catch' statement."); } + addVariableSet(); getNextToken(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in 'catch' statement."); @@ -1034,6 +995,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token != TokenNameVariable) { throwSyntaxError("Variable expected in 'catch' statement."); } + addVariableSet(); getNextToken(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in 'catch' statement."); @@ -1059,7 +1021,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameAND) { getNextToken(); } - w_variable(); + w_variable(true); } private void foreach_optional_arg() { @@ -1075,8 +1037,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // global_var_list: // global_var_list ',' global_var //| global_var + HashSet set = peekVariableSet(); while (true) { - global_var(); + global_var(set); if (token != TokenNameCOMMA) { break; } @@ -1084,16 +1047,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } - private void global_var() { + private void global_var(HashSet set) { //global_var: // T_VARIABLE //| '$' r_variable //| '$' '{' expr '}' if (token == TokenNameVariable) { - VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR); if (fMethodVariables != null) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR); fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); } + addVariableSet(set); getNextToken(); } else if (token == TokenNameDOLLAR) { getNextToken(); @@ -1115,13 +1079,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // static_var_list ',' T_VARIABLE //| static_var_list ',' T_VARIABLE '=' static_scalar //| T_VARIABLE - //| T_VARIABLE '=' static_scalar + //| T_VARIABLE '=' static_scalar, + HashSet set = peekVariableSet(); while (true) { if (token == TokenNameVariable) { - VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR); if (fMethodVariables != null) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR); fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); } + addVariableSet(set); getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); @@ -1144,7 +1110,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // unset_variable: // variable while (true) { - variable(); + variable(false, false); if (token != TokenNameCOMMA) { break; } @@ -1275,19 +1241,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } - private void class_extends(TypeDeclaration typeDecl) { - // /* empty */ - // | T_EXTENDS interface_list - if (token == TokenNameextends) { - getNextToken(); - - if (token == TokenNameIdentifier) { - getNextToken(); - } else { - throwSyntaxError("Class name expected after keyword 'extends'."); - } - } - } +// private void class_extends(TypeDeclaration typeDecl) { +// // /* empty */ +// // | T_EXTENDS interface_list +// if (token == TokenNameextends) { +// getNextToken(); +// +// if (token == TokenNameIdentifier) { +// getNextToken(); +// } else { +// throwSyntaxError("Class name expected after keyword 'extends'."); +// } +// } +// } private void interface_extends_list(TypeDeclaration typeDecl) { // /* empty */ @@ -1418,11 +1384,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); functionDefinition(methodDecl); } finally { - int sourceEnd = scanner.getCurrentTokenStartPosition(); + int sourceEnd = methodDecl.sourceEnd; if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { sourceEnd = methodDecl.declarationSourceStart + 1; } methodDecl.declarationSourceEnd = sourceEnd; + methodDecl.sourceEnd = sourceEnd; } } else { if (!hasModifiers) { @@ -1607,15 +1574,23 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } } - functionDeclarator(methodDecl); - if (token == TokenNameSEMICOLON) { - if (!isAbstract) { - throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector)); + try { + pushFunctionVariableSet(); + functionDeclarator(methodDecl); + if (token == TokenNameSEMICOLON) { + if (!isAbstract) { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector)); + } + getNextToken(); + return; + } + functionBody(methodDecl); + } finally { + if (!fStackUnassigned.isEmpty()) { + fStackUnassigned.remove(fStackUnassigned.size() - 1); } - getNextToken(); - return; } - functionBody(methodDecl); } private void functionDeclarator(MethodDeclaration methodDecl) { @@ -1635,12 +1610,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameLPAREN) { getNextToken(); } else { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("'(' expected in function declaration."); } if (token != TokenNameRPAREN) { parameter_list(methodDecl); } if (token != TokenNameRPAREN) { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("')' expected in function declaration."); } else { methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1; @@ -1648,6 +1625,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } else { methodDecl.selector = "".toCharArray(); + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("Function name expected after keyword 'function'."); } } @@ -1672,6 +1650,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // static_scalar char[] typeIdentifier = null; if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) { + HashSet set = peekVariableSet(); while (true) { if (token == TokenNameIdentifier) { typeIdentifier = scanner.getCurrentIdentifierSource(); @@ -1691,6 +1670,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI info.typeIdentifier = typeIdentifier; fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); } + addVariableSet(set); getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); @@ -1794,13 +1774,38 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI 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); + HashSet assignedVariableSet = null; + try { + Block b = inner_statement_list(); + iState.thenStatement = b; + checkUnreachable(iState, b); + } finally { + assignedVariableSet = removeIfVariableSet(); + } if (token == TokenNameelseif) { - new_elseif_list(iState); - } - new_else_single(iState); + try { + pushIfVariableSet(); + new_elseif_list(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null) { + assignedVariableSet.addAll(set); + } + } + } + try { + pushIfVariableSet(); + new_else_single(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null) { + HashSet topSet = peekVariableSet(); + if (topSet != null) { + topSet.addAll(set); + topSet.addAll(assignedVariableSet); + } + } + } if (token != TokenNameendif) { throwSyntaxError("'endif' expected."); } @@ -1816,13 +1821,40 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI private void ifStatement(IfStatement iState) { // T_IF '(' expr ')' statement elseif_list else_single - Statement s = statement(); - iState.thenStatement = s; - checkUnreachable(iState, s); + HashSet assignedVariableSet = null; + try { + pushIfVariableSet(); + Statement s = statement(); + iState.thenStatement = s; + checkUnreachable(iState, s); + } finally { + assignedVariableSet = removeIfVariableSet(); + } + if (token == TokenNameelseif) { - elseif_list(iState); + try { + pushIfVariableSet(); + elseif_list(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null) { + assignedVariableSet.addAll(set); + } + } + } + try { + pushIfVariableSet(); + else_single(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null) { + HashSet topSet = peekVariableSet(); + if (topSet != null) { + topSet.addAll(set); + topSet.addAll(assignedVariableSet); + } + } } - else_single(iState); } private void elseif_list(IfStatement iState) { @@ -1943,14 +1975,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI int off = b.statements.length - 1; if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement) && !(b.statements[off] instanceof BreakStatement)) { - if (!(b.statements[off] instanceof IfStatement) || !((IfStatement)b.statements[off]).checkUnreachable) { + if (!(b.statements[off] instanceof IfStatement) || !((IfStatement) b.statements[off]).checkUnreachable) { iState.checkUnreachable = false; } - } + } } } else { if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) { - if (!(s instanceof IfStatement) || !((IfStatement)s).checkUnreachable) { + if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) { iState.checkUnreachable = false; } } @@ -2201,7 +2233,30 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } switch (token) { case TokenNameisset: + // T_ISSET '(' isset_variables ')' + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'isset'"); + } + getNextToken(); + isset_variables(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'isset'"); + } + getNextToken(); + break; case TokenNameempty: + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'empty'"); + } + getNextToken(); + variable(true, false); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'empty'"); + } + getNextToken(); + break; case TokenNameeval: case TokenNameinclude: case TokenNameinclude_once: @@ -2262,68 +2317,68 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | '`' encaps_list '`' // | common_scalar // | '`' encaps_list '`' - case TokenNameEncapsedString0: - scanner.encapsedStringStack.push(new Character('`')); - getNextToken(); - try { - if (token == TokenNameEncapsedString0) { - } else { - encaps_list(); - if (token != TokenNameEncapsedString0) { - throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); - } - } - } finally { - scanner.encapsedStringStack.pop(); - getNextToken(); - } - break; - // | '\'' encaps_list '\'' - case TokenNameEncapsedString1: - scanner.encapsedStringStack.push(new Character('\'')); - getNextToken(); - try { - exprSourceStart = scanner.getCurrentTokenStartPosition(); - if (token == TokenNameEncapsedString1) { - expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner - .getCurrentTokenEndPosition()); - } else { - encaps_list(); - if (token != TokenNameEncapsedString1) { - throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); - } else { - expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner - .getCurrentTokenEndPosition()); - } - } - } finally { - scanner.encapsedStringStack.pop(); - getNextToken(); - } - break; - //| '"' encaps_list '"' - case TokenNameEncapsedString2: - scanner.encapsedStringStack.push(new Character('"')); - getNextToken(); - try { - exprSourceStart = scanner.getCurrentTokenStartPosition(); - if (token == TokenNameEncapsedString2) { - expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner - .getCurrentTokenEndPosition()); - } else { - encaps_list(); - if (token != TokenNameEncapsedString2) { - throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); - } else { - expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner - .getCurrentTokenEndPosition()); - } - } - } finally { - scanner.encapsedStringStack.pop(); - getNextToken(); - } - break; + // case TokenNameEncapsedString0: + // scanner.encapsedStringStack.push(new Character('`')); + // getNextToken(); + // try { + // if (token == TokenNameEncapsedString0) { + // } else { + // encaps_list(); + // if (token != TokenNameEncapsedString0) { + // throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); + // } + // } + // } finally { + // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + // // | '\'' encaps_list '\'' + // case TokenNameEncapsedString1: + // scanner.encapsedStringStack.push(new Character('\'')); + // getNextToken(); + // try { + // exprSourceStart = scanner.getCurrentTokenStartPosition(); + // if (token == TokenNameEncapsedString1) { + // expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } else { + // encaps_list(); + // if (token != TokenNameEncapsedString1) { + // throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); + // } else { + // expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } + // } + // } finally { + // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + // //| '"' encaps_list '"' + // case TokenNameEncapsedString2: + // scanner.encapsedStringStack.push(new Character('"')); + // getNextToken(); + // try { + // exprSourceStart = scanner.getCurrentTokenStartPosition(); + // if (token == TokenNameEncapsedString2) { + // expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } else { + // encaps_list(); + // if (token != TokenNameEncapsedString2) { + // throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); + // } else { + // expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } + // } + // } finally { + // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; case TokenNameStringDoubleQuote: expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner .getCurrentTokenEndPosition()); @@ -2420,9 +2475,25 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI case TokenNameVariable: case TokenNameDOLLAR: boolean rememberedVar = false; - Expression lhs = variable(); + Expression lhs = variable(true, true); + if (lhs != null && lhs instanceof FieldReference && token != TokenNameEQUAL && token != TokenNamePLUS_EQUAL + && token != TokenNameMINUS_EQUAL && token != TokenNameMULTIPLY_EQUAL && token != TokenNameDIVIDE_EQUAL + && token != TokenNameDOT_EQUAL && token != TokenNameREMAINDER_EQUAL && token != TokenNameAND_EQUAL + && token != TokenNameOR_EQUAL && token != TokenNameXOR_EQUAL && token != TokenNameRIGHT_SHIFT_EQUAL + && token != TokenNameLEFT_SHIFT_EQUAL) { + FieldReference ref = (FieldReference) lhs; + if (!containsVariableSet(ref.token)) { + problemReporter.uninitializedLocalVariable(new String(ref.token), ref.sourceStart(), ref.sourceEnd(), referenceContext, + compilationUnit.compilationResult); + addVariableSet(ref.token); + } + } + switch (token) { case TokenNameEQUAL: + if (lhs != null && lhs instanceof FieldReference) { + addVariableSet(((FieldReference) lhs).token); + } getNextToken(); if (token == TokenNameAND) { getNextToken(); @@ -2446,7 +2517,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } } else { - Expression rhs = variable(); + Expression rhs = variable(false, false); if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) { // example: // $var = &$ref; @@ -2509,6 +2580,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI case TokenNameXOR_EQUAL: case TokenNameRIGHT_SHIFT_EQUAL: case TokenNameLEFT_SHIFT_EQUAL: + if (lhs != null && lhs instanceof FieldReference) { + addVariableSet(((FieldReference) lhs).token); + } getNextToken(); expr(); break; @@ -2531,6 +2605,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); break; } else { + // System.out.println(scanner.getCurrentTokenStartPosition()); + // System.out.println(scanner.getCurrentTokenEndPosition()); + throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "')."); } } @@ -2734,8 +2811,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // variable //| T_LIST '(' assignment_list ')' //| /* empty */ - if (token == TokenNameVariable || token == TokenNameDOLLAR) { - variable(); + if (token == TokenNameVariable) { + variable(true, false); + } else if (token == TokenNameDOLLAR) { + variable(false, false); } else { if (token == TokenNamelist) { getNextToken(); @@ -2776,17 +2855,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (true) { if (token == TokenNameAND) { getNextToken(); - variable(); + variable(true, false); } else { expr(); if (token == TokenNameAND) { getNextToken(); - variable(); + variable(true, false); } else if (token == TokenNameEQUAL_GREATER) { getNextToken(); if (token == TokenNameAND) { getNextToken(); - variable(); + variable(true, false); } else { expr(); } @@ -2812,7 +2891,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // } while (true); // } - private Expression variable_without_objects() { + private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) { // variable_without_objects: // reference_variable // | simple_indirect_reference reference_variable @@ -2822,10 +2901,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (token == TokenNameDOLLAR) { getNextToken(); } - return reference_variable(); + return reference_variable(lefthandside, ignoreVar); } - private Expression function_call() { + private Expression function_call(boolean lefthandside, boolean ignoreVar) { // function_call: // T_STRING '(' function_call_parameter_list ')' //| class_constant '(' function_call_parameter_list ')' @@ -2855,12 +2934,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); } else { // static member: - variable_without_objects(); + variable_without_objects(true, false); } break; } } else { - ref = variable_without_objects(); + ref = variable_without_objects(lefthandside, ignoreVar); } if (token != TokenNameLPAREN) { if (defineName != null) { @@ -2931,7 +3010,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (true) { if (token == TokenNameAND) { getNextToken(); - w_variable(); + w_variable(true); } else { // if (token == TokenNameIdentifier || token == // TokenNameVariable @@ -2968,35 +3047,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'::' expected after class name (static_member)."); } getNextToken(); - variable_without_objects(); + variable_without_objects(false, false); } - private Expression base_variable_with_function_calls() { + private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) { // base_variable_with_function_calls: // base_variable //| function_call - boolean functionCall = false; if (Scanner.TRACE) { System.out.println("TRACE: base_variable_with_function_calls()"); } - // if (token == TokenNameIdentifier) { - // functionCall = true; - // } else if (token == TokenNameVariable) { - // int tempToken = token; - // int tempPosition = scanner.currentPosition; - // getNextToken(); - // if (token == TokenNameLPAREN) { - // functionCall = true; - // } - // token = tempToken; - // scanner.currentPosition = tempPosition; - // scanner.phpMode = true; - // } - // if (functionCall) { - return function_call(); - // } else { - // base_variable(); - // } + return function_call(lefthandside, ignoreVar); } private Expression base_variable() { @@ -3014,7 +3075,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (token == TokenNameDOLLAR) { getNextToken(); } - reference_variable(); + reference_variable(false, false); } return ref; } @@ -3024,7 +3085,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // // '$' // //| simple_indirect_reference '$' // } - private Expression reference_variable() { + private Expression reference_variable(boolean lefthandside, boolean ignoreVar) { // reference_variable: // reference_variable '[' dim_offset ']' // | reference_variable '{' expr '}' @@ -3033,7 +3094,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (Scanner.TRACE) { System.out.println("TRACE: reference_variable()"); } - ref = compound_variable(); + ref = compound_variable(lefthandside, ignoreVar); while (true) { if (token == TokenNameLBRACE) { ref = null; @@ -3044,6 +3105,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } getNextToken(); } else if (token == TokenNameLBRACKET) { + if (ref != null && ref instanceof FieldReference) { + FieldReference fref = (FieldReference) ref; + addVariableSet(fref.token); + } ref = null; getNextToken(); if (token != TokenNameRBRACKET) { @@ -3061,7 +3126,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return ref; } - private Expression compound_variable() { + private Expression compound_variable(boolean lefthandside, boolean ignoreVar) { // compound_variable: // T_VARIABLE // | '$' '{' expr '}' @@ -3069,6 +3134,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI System.out.println("TRACE: compound_variable()"); } if (token == TokenNameVariable) { + if (!lefthandside) { + if (!containsVariableSet()) { + // reportSyntaxError("The local variable " + new String(scanner.getCurrentIdentifierSource()) + // + " may not have been initialized"); + problemReporter.uninitializedLocalVariable(new String(scanner.getCurrentIdentifierSource()), scanner + .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), referenceContext, + compilationUnit.compilationResult); + } + } else { + if (!ignoreVar) { + addVariableSet(); + } + } FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); getNextToken(); return ref; @@ -3089,11 +3167,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); } return null; - } + } // private void dim_offset() { // // dim_offset: // // /* empty */ - // private void dim_offset() { - // // dim_offset: - // // /* empty */ // // | expr // expr(); // } @@ -3105,7 +3180,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI System.out.println("TRACE: object_property()"); } if (token == TokenNameVariable || token == TokenNameDOLLAR) { - variable_without_objects(); + variable_without_objects(false, false); } else { object_dim_list(); } @@ -3171,23 +3246,23 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } private void r_variable() { - variable(); + variable(false, false); } - private void w_variable() { - variable(); + private void w_variable(boolean lefthandside) { + variable(lefthandside, false); } private void rw_variable() { - variable(); + variable(false, false); } - private Expression variable() { + private Expression variable(boolean lefthandside, boolean ignoreVar) { // variable: // base_variable_with_function_calls T_OBJECT_OPERATOR // object_property method_or_not variable_properties // | base_variable_with_function_calls - Expression ref = base_variable_with_function_calls(); + Expression ref = base_variable_with_function_calls(lefthandside, ignoreVar); if (token == TokenNameMINUS_GREATER) { ref = null; getNextToken(); @@ -3262,276 +3337,276 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); } - private void encaps_list() { - // encaps_list encaps_var - // | encaps_list T_STRING - // | encaps_list T_NUM_STRING - // | encaps_list T_ENCAPSED_AND_WHITESPACE - // | encaps_list T_CHARACTER - // | encaps_list T_BAD_CHARACTER - // | encaps_list '[' - // | encaps_list ']' - // | encaps_list '{' - // | encaps_list '}' - // | encaps_list T_OBJECT_OPERATOR - // | /* empty */ - while (true) { - switch (token) { - case TokenNameSTRING: - getNextToken(); - break; - case TokenNameLBRACE: - // scanner.encapsedStringStack.pop(); - getNextToken(); - break; - case TokenNameRBRACE: - // scanner.encapsedStringStack.pop(); - getNextToken(); - break; - case TokenNameLBRACKET: - // scanner.encapsedStringStack.pop(); - getNextToken(); - break; - case TokenNameRBRACKET: - // scanner.encapsedStringStack.pop(); - getNextToken(); - break; - case TokenNameMINUS_GREATER: - // scanner.encapsedStringStack.pop(); - getNextToken(); - break; - case TokenNameVariable: - case TokenNameDOLLAR_LBRACE: - case TokenNameLBRACE_DOLLAR: - encaps_var(); - break; - default: - char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue(); - if (encapsedChar == '$') { - scanner.encapsedStringStack.pop(); - encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue(); - switch (encapsedChar) { - case '`': - if (token == TokenNameEncapsedString0) { - return; - } - token = TokenNameSTRING; - continue; - case '\'': - if (token == TokenNameEncapsedString1) { - return; - } - token = TokenNameSTRING; - continue; - case '"': - if (token == TokenNameEncapsedString2) { - return; - } - token = TokenNameSTRING; - continue; - } - } - return; - } - } - } + // private void encaps_list() { + // // encaps_list encaps_var + // // | encaps_list T_STRING + // // | encaps_list T_NUM_STRING + // // | encaps_list T_ENCAPSED_AND_WHITESPACE + // // | encaps_list T_CHARACTER + // // | encaps_list T_BAD_CHARACTER + // // | encaps_list '[' + // // | encaps_list ']' + // // | encaps_list '{' + // // | encaps_list '}' + // // | encaps_list T_OBJECT_OPERATOR + // // | /* empty */ + // while (true) { + // switch (token) { + // case TokenNameSTRING: + // getNextToken(); + // break; + // case TokenNameLBRACE: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameRBRACE: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameLBRACKET: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameRBRACKET: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameMINUS_GREATER: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameVariable: + // case TokenNameDOLLAR_LBRACE: + // case TokenNameLBRACE_DOLLAR: + // encaps_var(); + // break; + // default: + // char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue(); + // if (encapsedChar == '$') { + // scanner.encapsedStringStack.pop(); + // encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue(); + // switch (encapsedChar) { + // case '`': + // if (token == TokenNameEncapsedString0) { + // return; + // } + // token = TokenNameSTRING; + // continue; + // case '\'': + // if (token == TokenNameEncapsedString1) { + // return; + // } + // token = TokenNameSTRING; + // continue; + // case '"': + // if (token == TokenNameEncapsedString2) { + // return; + // } + // token = TokenNameSTRING; + // continue; + // } + // } + // return; + // } + // } + // } - private void encaps_var() { - // T_VARIABLE - // | T_VARIABLE '[' encaps_var_offset ']' - // | T_VARIABLE T_OBJECT_OPERATOR T_STRING - // | T_DOLLAR_OPEN_CURLY_BRACES expr '}' - // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' - // | T_CURLY_OPEN variable '}' - switch (token) { - case TokenNameVariable: - getNextToken(); - if (token == TokenNameLBRACKET) { - getNextToken(); - expr(); //encaps_var_offset(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("']' expected after variable."); - } - // scanner.encapsedStringStack.pop(); - getNextToken(); - // } - } else if (token == TokenNameMINUS_GREATER) { - getNextToken(); - if (token != TokenNameIdentifier) { - throwSyntaxError("Identifier expected after '->'."); - } - // scanner.encapsedStringStack.pop(); - getNextToken(); - } - // else { - // // scanner.encapsedStringStack.pop(); - // int tempToken = TokenNameSTRING; - // if (!scanner.encapsedStringStack.isEmpty() - // && (token == TokenNameEncapsedString0 - // || token == TokenNameEncapsedString1 - // || token == TokenNameEncapsedString2 || token == - // TokenNameERROR)) { - // char encapsedChar = ((Character) - // scanner.encapsedStringStack.peek()) - // .charValue(); - // switch (token) { - // case TokenNameEncapsedString0 : - // if (encapsedChar == '`') { - // tempToken = TokenNameEncapsedString0; - // } - // break; - // case TokenNameEncapsedString1 : - // if (encapsedChar == '\'') { - // tempToken = TokenNameEncapsedString1; - // } - // break; - // case TokenNameEncapsedString2 : - // if (encapsedChar == '"') { - // tempToken = TokenNameEncapsedString2; - // } - // break; - // case TokenNameERROR : - // if (scanner.source[scanner.currentPosition - 1] == '\\') { - // scanner.currentPosition--; - // getNextToken(); - // } - // break; - // } - // } - // token = tempToken; - // } - break; - case TokenNameDOLLAR_LBRACE: - getNextToken(); - if (token == TokenNameDOLLAR_LBRACE) { - encaps_var(); - } else if (token == TokenNameIdentifier) { - getNextToken(); - if (token == TokenNameLBRACKET) { - getNextToken(); - // if (token == TokenNameRBRACKET) { - // getNextToken(); - // } else { - expr(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("']' expected after '${'."); - } - getNextToken(); - // } - } - } else { - expr(); - } - if (token != TokenNameRBRACE) { - throwSyntaxError("'}' expected."); - } - getNextToken(); - break; - case TokenNameLBRACE_DOLLAR: - getNextToken(); - if (token == TokenNameLBRACE_DOLLAR) { - encaps_var(); - } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { - getNextToken(); - if (token == TokenNameLBRACKET) { - getNextToken(); - // if (token == TokenNameRBRACKET) { - // getNextToken(); - // } else { - expr(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("']' expected."); - } - getNextToken(); - // } - } else if (token == TokenNameMINUS_GREATER) { - getNextToken(); - if (token != TokenNameIdentifier && token != TokenNameVariable) { - throwSyntaxError("String or Variable token expected."); - } - getNextToken(); - if (token == TokenNameLBRACKET) { - getNextToken(); - // if (token == TokenNameRBRACKET) { - // getNextToken(); - // } else { - expr(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("']' expected after '${'."); - } - getNextToken(); - // } - } - } - // if (token != TokenNameRBRACE) { - // throwSyntaxError("'}' expected after '{$'."); - // } - // // scanner.encapsedStringStack.pop(); - // getNextToken(); - } else { - expr(); - if (token != TokenNameRBRACE) { - throwSyntaxError("'}' expected."); - } - // scanner.encapsedStringStack.pop(); - getNextToken(); - } - break; - } - } + // private void encaps_var() { + // // T_VARIABLE + // // | T_VARIABLE '[' encaps_var_offset ']' + // // | T_VARIABLE T_OBJECT_OPERATOR T_STRING + // // | T_DOLLAR_OPEN_CURLY_BRACES expr '}' + // // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' + // // | T_CURLY_OPEN variable '}' + // switch (token) { + // case TokenNameVariable: + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // expr(); //encaps_var_offset(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected after variable."); + // } + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // // } + // } else if (token == TokenNameMINUS_GREATER) { + // getNextToken(); + // if (token != TokenNameIdentifier) { + // throwSyntaxError("Identifier expected after '->'."); + // } + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // // else { + // // // scanner.encapsedStringStack.pop(); + // // int tempToken = TokenNameSTRING; + // // if (!scanner.encapsedStringStack.isEmpty() + // // && (token == TokenNameEncapsedString0 + // // || token == TokenNameEncapsedString1 + // // || token == TokenNameEncapsedString2 || token == + // // TokenNameERROR)) { + // // char encapsedChar = ((Character) + // // scanner.encapsedStringStack.peek()) + // // .charValue(); + // // switch (token) { + // // case TokenNameEncapsedString0 : + // // if (encapsedChar == '`') { + // // tempToken = TokenNameEncapsedString0; + // // } + // // break; + // // case TokenNameEncapsedString1 : + // // if (encapsedChar == '\'') { + // // tempToken = TokenNameEncapsedString1; + // // } + // // break; + // // case TokenNameEncapsedString2 : + // // if (encapsedChar == '"') { + // // tempToken = TokenNameEncapsedString2; + // // } + // // break; + // // case TokenNameERROR : + // // if (scanner.source[scanner.currentPosition - 1] == '\\') { + // // scanner.currentPosition--; + // // getNextToken(); + // // } + // // break; + // // } + // // } + // // token = tempToken; + // // } + // break; + // case TokenNameDOLLAR_LBRACE: + // getNextToken(); + // if (token == TokenNameDOLLAR_LBRACE) { + // encaps_var(); + // } else if (token == TokenNameIdentifier) { + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // // if (token == TokenNameRBRACKET) { + // // getNextToken(); + // // } else { + // expr(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected after '${'."); + // } + // getNextToken(); + // // } + // } + // } else { + // expr(); + // } + // if (token != TokenNameRBRACE) { + // throwSyntaxError("'}' expected."); + // } + // getNextToken(); + // break; + // case TokenNameLBRACE_DOLLAR: + // getNextToken(); + // if (token == TokenNameLBRACE_DOLLAR) { + // encaps_var(); + // } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // // if (token == TokenNameRBRACKET) { + // // getNextToken(); + // // } else { + // expr(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected."); + // } + // getNextToken(); + // // } + // } else if (token == TokenNameMINUS_GREATER) { + // getNextToken(); + // if (token != TokenNameIdentifier && token != TokenNameVariable) { + // throwSyntaxError("String or Variable token expected."); + // } + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // // if (token == TokenNameRBRACKET) { + // // getNextToken(); + // // } else { + // expr(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected after '${'."); + // } + // getNextToken(); + // // } + // } + // } + // // if (token != TokenNameRBRACE) { + // // throwSyntaxError("'}' expected after '{$'."); + // // } + // // // scanner.encapsedStringStack.pop(); + // // getNextToken(); + // } else { + // expr(); + // if (token != TokenNameRBRACE) { + // throwSyntaxError("'}' expected."); + // } + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + // } + // } - private void encaps_var_offset() { - // T_STRING - // | T_NUM_STRING - // | T_VARIABLE - switch (token) { - case TokenNameSTRING: - getNextToken(); - break; - case TokenNameIntegerLiteral: - getNextToken(); - break; - case TokenNameVariable: - getNextToken(); - break; - case TokenNameIdentifier: - getNextToken(); - break; - default: - throwSyntaxError("Variable or String token expected."); - break; - } - } +// private void encaps_var_offset() { +// // T_STRING +// // | T_NUM_STRING +// // | T_VARIABLE +// switch (token) { +// case TokenNameSTRING: +// getNextToken(); +// break; +// case TokenNameIntegerLiteral: +// getNextToken(); +// break; +// case TokenNameVariable: +// getNextToken(); +// break; +// case TokenNameIdentifier: +// getNextToken(); +// break; +// default: +// throwSyntaxError("Variable or String token expected."); +// break; +// } +// } private void internal_functions_in_yacc() { // int start = 0; switch (token) { - case TokenNameisset: - // T_ISSET '(' isset_variables ')' - getNextToken(); - if (token != TokenNameLPAREN) { - throwSyntaxError("'(' expected after keyword 'isset'"); - } - getNextToken(); - isset_variables(); - if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected after keyword 'isset'"); - } - getNextToken(); - break; - case TokenNameempty: - // T_EMPTY '(' variable ')' - getNextToken(); - if (token != TokenNameLPAREN) { - throwSyntaxError("'(' expected after keyword 'empty'"); - } - getNextToken(); - variable(); - if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected after keyword 'empty'"); - } - getNextToken(); - break; + // case TokenNameisset: + // // T_ISSET '(' isset_variables ')' + // getNextToken(); + // if (token != TokenNameLPAREN) { + // throwSyntaxError("'(' expected after keyword 'isset'"); + // } + // getNextToken(); + // isset_variables(); + // if (token != TokenNameRPAREN) { + // throwSyntaxError("')' expected after keyword 'isset'"); + // } + // getNextToken(); + // break; + // case TokenNameempty: + // // T_EMPTY '(' variable ')' + // getNextToken(); + // if (token != TokenNameLPAREN) { + // throwSyntaxError("'(' expected after keyword 'empty'"); + // } + // getNextToken(); + // variable(false); + // if (token != TokenNameRPAREN) { + // throwSyntaxError("')' expected after keyword 'empty'"); + // } + // getNextToken(); + // break; case TokenNameinclude: //T_INCLUDE expr checkFileName(token); @@ -3564,6 +3639,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } + /** + * Parse and check the include file name + * + * @param includeToken + */ private void checkFileName(int includeToken) { // expr int start = scanner.getCurrentTokenStartPosition(); @@ -3626,19 +3706,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI IPath path = PHPFileUtil.determineFilePath(includeNameString, file, project); if (path == null) { - // reportSyntaxError("File: " + expression.toStringExpression() + " doesn't exist in project: " - // + project.getLocation().toString(), literal.sourceStart, literal.sourceEnd); + // SyntaxError: "File: << >> doesn't exist in project." String[] args = { expression.toStringExpression(), project.getLocation().toString() }; problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext, compilationUnit.compilationResult); } else { try { - // String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString(); - // String filePath = file.getRawLocation().toString(); String filePath = path.toString(); String ext = file.getRawLocation().getFileExtension(); int fileExtensionLength = ext == null ? 0 : ext.length() + 1; - int length; impt.tokens = CharOperation.splitOn('/', filePath.toCharArray(), 0, filePath.length() - fileExtensionLength); impt.setFile(PHPFileUtil.createFile(path, project)); @@ -3658,7 +3734,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("Variable expected after keyword 'isset'"); } while (true) { - variable(); + variable(true, false); if (token == TokenNameCOMMA) { getNextToken(); } else { @@ -3763,33 +3839,39 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'`' expected at end of static string."); } break; - case TokenNameEncapsedString1: - try { - scanner.currentCharacter = scanner.source[scanner.currentPosition++]; - while (scanner.currentCharacter != '\'') { - if (scanner.currentCharacter == '\\') { - scanner.currentPosition++; - } - scanner.currentCharacter = scanner.source[scanner.currentPosition++]; - } - getNextToken(); - } catch (IndexOutOfBoundsException e) { - throwSyntaxError("'\'' expected at end of static string."); - } + // case TokenNameEncapsedString1: + // try { + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // while (scanner.currentCharacter != '\'') { + // if (scanner.currentCharacter == '\\') { + // scanner.currentPosition++; + // } + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // } + // getNextToken(); + // } catch (IndexOutOfBoundsException e) { + // throwSyntaxError("'\'' expected at end of static string."); + // } + // break; + // case TokenNameEncapsedString2: + // try { + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // while (scanner.currentCharacter != '"') { + // if (scanner.currentCharacter == '\\') { + // scanner.currentPosition++; + // } + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // } + // getNextToken(); + // } catch (IndexOutOfBoundsException e) { + // throwSyntaxError("'\"' expected at end of static string."); + // } + // break; + case TokenNameStringSingleQuote: + getNextToken(); break; - case TokenNameEncapsedString2: - try { - scanner.currentCharacter = scanner.source[scanner.currentPosition++]; - while (scanner.currentCharacter != '"') { - if (scanner.currentCharacter == '\\') { - scanner.currentPosition++; - } - scanner.currentCharacter = scanner.source[scanner.currentPosition++]; - } - getNextToken(); - } catch (IndexOutOfBoundsException e) { - throwSyntaxError("'\"' expected at end of static string."); - } + case TokenNameStringDoubleQuote: + getNextToken(); break; case TokenNamePLUS: getNextToken(); @@ -3852,110 +3934,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } - public void reportSyntaxError() { //int act, int currentKind, int - // stateStackTop) { - /* remember current scanner position */ - int startPos = scanner.startPosition; - int currentPos = scanner.currentPosition; - // String[] expectings; - // String tokenName = name[symbol_index[currentKind]]; - //fetch all "accurate" possible terminals that could recover the error - // int start, end = start = asi(stack[stateStackTop]); - // while (asr[end] != 0) - // end++; - // int length = end - start; - // expectings = new String[length]; - // if (length != 0) { - // char[] indexes = new char[length]; - // System.arraycopy(asr, start, indexes, 0, length); - // for (int i = 0; i < length; i++) { - // expectings[i] = name[symbol_index[indexes[i]]]; - // } - // } - //if the pb is an EOF, try to tell the user that they are some - // if (tokenName.equals(UNEXPECTED_EOF)) { - // if (!this.checkAndReportBracketAnomalies(problemReporter())) { - // char[] tokenSource; - // try { - // tokenSource = this.scanner.getCurrentTokenSource(); - // } catch (Exception e) { - // tokenSource = new char[] {}; - // } - // problemReporter().parseError( - // this.scanner.startPosition, - // this.scanner.currentPosition - 1, - // tokenSource, - // tokenName, - // expectings); - // } - // } else { //the next test is HEAVILY grammar DEPENDENT. - // if ((length == 14) - // && (expectings[0] == "=") //$NON-NLS-1$ - // && (expectings[1] == "*=") //$NON-NLS-1$ - // && (expressionPtr > -1)) { - // switch(currentKind) { - // case TokenNameSEMICOLON: - // case TokenNamePLUS: - // case TokenNameMINUS: - // case TokenNameDIVIDE: - // case TokenNameREMAINDER: - // case TokenNameMULTIPLY: - // case TokenNameLEFT_SHIFT: - // case TokenNameRIGHT_SHIFT: - //// case TokenNameUNSIGNED_RIGHT_SHIFT: - // case TokenNameLESS: - // case TokenNameGREATER: - // case TokenNameLESS_EQUAL: - // case TokenNameGREATER_EQUAL: - // case TokenNameEQUAL_EQUAL: - // case TokenNameNOT_EQUAL: - // case TokenNameXOR: - // case TokenNameAND: - // case TokenNameOR: - // case TokenNameOR_OR: - // case TokenNameAND_AND: - // // the ; is not the expected token ==> it ends a statement when an - // expression is not ended - // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]); - // break; - // case TokenNameRBRACE : - // problemReporter().missingSemiColon(expressionStack[expressionPtr]); - // break; - // default: - // char[] tokenSource; - // try { - // tokenSource = this.scanner.getCurrentTokenSource(); - // } catch (Exception e) { - // tokenSource = new char[] {}; - // } - // problemReporter().parseError( - // this.scanner.startPosition, - // this.scanner.currentPosition - 1, - // tokenSource, - // tokenName, - // expectings); - // this.checkAndReportBracketAnomalies(problemReporter()); - // } - // } else { - char[] tokenSource; - try { - tokenSource = this.scanner.getCurrentTokenSource(); - } catch (Exception e) { - tokenSource = new char[] {}; - } - // problemReporter().parseError( - // this.scanner.startPosition, - // this.scanner.currentPosition - 1, - // tokenSource, - // tokenName, - // expectings); - this.checkAndReportBracketAnomalies(problemReporter()); - // } - // } - /* reset scanner where it was */ - scanner.startPosition = startPos; - scanner.currentPosition = currentPos; - } +// public void reportSyntaxError() { //int act, int currentKind, int +// // stateStackTop) { +// /* remember current scanner position */ +// int startPos = scanner.startPosition; +// int currentPos = scanner.currentPosition; +// +// this.checkAndReportBracketAnomalies(problemReporter()); +// /* reset scanner where it was */ +// scanner.startPosition = startPos; +// scanner.currentPosition = currentPos; +// } public static final int RoundBracket = 0; @@ -3976,6 +3965,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI HashMap fMethodVariables = null; + ArrayList fStackUnassigned = new ArrayList(); + //ast stack final static int AstStackIncrement = 100; @@ -4017,398 +4008,397 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /* * Reconsider the entire source looking for inconsistencies in {} () [] */ - public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) { - scanner.wasAcr = false; - boolean anomaliesDetected = false; - try { - char[] source = scanner.source; - int[] leftCount = { 0, 0, 0 }; - int[] rightCount = { 0, 0, 0 }; - int[] depths = { 0, 0, 0 }; - int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] }; - int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] }; - int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] }; - int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] }; - scanner.currentPosition = scanner.initialPosition; //starting - // point - // (first-zero-based - // char) - while (scanner.currentPosition < scanner.eofPosition) { //loop for - // jumping - // over - // comments - try { - // ---------Consume white space and handles - // startPosition--------- - boolean isWhiteSpace; - do { - scanner.startPosition = scanner.currentPosition; - // if (((scanner.currentCharacter = - // source[scanner.currentPosition++]) == '\\') && - // (source[scanner.currentPosition] == 'u')) { - // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace(); - // } else { - if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { - if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { - // only record line positions we have not - // recorded yet - scanner.pushLineSeparator(); - } - } - isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter); - // } - } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition)); - // -------consume token until } is found--------- - switch (scanner.currentCharacter) { - case '{': { - int index = leftCount[CurlyBracket]++; - if (index == leftPositions[CurlyBracket].length) { - System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index); - System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index); - } - leftPositions[CurlyBracket][index] = scanner.startPosition; - leftDepths[CurlyBracket][index] = depths[CurlyBracket]++; - } - break; - case '}': { - int index = rightCount[CurlyBracket]++; - if (index == rightPositions[CurlyBracket].length) { - System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index); - System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index); - } - rightPositions[CurlyBracket][index] = scanner.startPosition; - rightDepths[CurlyBracket][index] = --depths[CurlyBracket]; - } - break; - case '(': { - int index = leftCount[RoundBracket]++; - if (index == leftPositions[RoundBracket].length) { - System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index); - System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index); - } - leftPositions[RoundBracket][index] = scanner.startPosition; - leftDepths[RoundBracket][index] = depths[RoundBracket]++; - } - break; - case ')': { - int index = rightCount[RoundBracket]++; - if (index == rightPositions[RoundBracket].length) { - System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index); - System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index); - } - rightPositions[RoundBracket][index] = scanner.startPosition; - rightDepths[RoundBracket][index] = --depths[RoundBracket]; - } - break; - case '[': { - int index = leftCount[SquareBracket]++; - if (index == leftPositions[SquareBracket].length) { - System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index); - System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index); - } - leftPositions[SquareBracket][index] = scanner.startPosition; - leftDepths[SquareBracket][index] = depths[SquareBracket]++; - } - break; - case ']': { - int index = rightCount[SquareBracket]++; - if (index == rightPositions[SquareBracket].length) { - System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index); - System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index); - } - rightPositions[SquareBracket][index] = scanner.startPosition; - rightDepths[SquareBracket][index] = --depths[SquareBracket]; - } - break; - case '\'': { - if (scanner.getNextChar('\\')) { - scanner.scanEscapeCharacter(); - } else { // consume next character - scanner.unicodeAsBackSlash = false; - // if (((scanner.currentCharacter = - // source[scanner.currentPosition++]) == - // '\\') && - // (source[scanner.currentPosition] == - // 'u')) { - // scanner.getNextUnicodeChar(); - // } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - // } - } - scanner.getNextChar('\''); - break; - } - case '"': - // consume next character - scanner.unicodeAsBackSlash = false; - // if (((scanner.currentCharacter = - // source[scanner.currentPosition++]) == '\\') && - // (source[scanner.currentPosition] == 'u')) { - // scanner.getNextUnicodeChar(); - // } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - // } - while (scanner.currentCharacter != '"') { - if (scanner.currentCharacter == '\r') { - if (source[scanner.currentPosition] == '\n') - scanner.currentPosition++; - break; // the string cannot go further that - // the line - } - if (scanner.currentCharacter == '\n') { - break; // the string cannot go further that - // the line - } - if (scanner.currentCharacter == '\\') { - scanner.scanEscapeCharacter(); - } - // consume next character - scanner.unicodeAsBackSlash = false; - // if (((scanner.currentCharacter = - // source[scanner.currentPosition++]) == '\\') - // && (source[scanner.currentPosition] == 'u')) - // { - // scanner.getNextUnicodeChar(); - // } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - // } - } - break; - case '/': { - int test; - if ((test = scanner.getNextChar('/', '*')) == 0) { //line - // comment - //get the next char - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') - && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement - // ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 - || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 - || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 - || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error - // don't - // care of the - // value - scanner.currentCharacter = 'A'; - } //something different from \n and \r - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') { - //get the next char - scanner.startPosition = scanner.currentPosition; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') - && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement - // ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 - || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 - || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 - || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error - // don't - // care of the - // value - scanner.currentCharacter = 'A'; - } //something different from \n - // and \r - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - } - if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { - if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { - // only record line positions we - // have not recorded yet - scanner.pushLineSeparator(); - if (this.scanner.taskTags != null) { - this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner - .getCurrentTokenEndPosition()); - } - } - } - break; - } - if (test > 0) { //traditional and annotation - // comment - boolean star = false; - // consume next character - scanner.unicodeAsBackSlash = false; - // if (((scanner.currentCharacter = - // source[scanner.currentPosition++]) == - // '\\') && - // (source[scanner.currentPosition] == - // 'u')) { - // scanner.getNextUnicodeChar(); - // } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - // } - if (scanner.currentCharacter == '*') { - star = true; - } - //get the next char - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') - && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement - // ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 - || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 - || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 - || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error - // don't - // care of the - // value - scanner.currentCharacter = 'A'; - } //something different from * and / - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - //loop until end of comment */ - while ((scanner.currentCharacter != '/') || (!star)) { - star = scanner.currentCharacter == '*'; - //get next char - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') - && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement - // ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 - || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 - || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 - || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error - // don't - // care of the - // value - scanner.currentCharacter = 'A'; - } //something different from * and - // / - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - } - if (this.scanner.taskTags != null) { - this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition()); - } - break; - } - break; - } - default: - if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) { - scanner.scanIdentifierOrKeyword(false); - break; - } - if (Character.isDigit(scanner.currentCharacter)) { - scanner.scanNumber(false); - break; - } - } - //-----------------end switch while - // try-------------------- - } catch (IndexOutOfBoundsException e) { - break; // read until EOF - } catch (InvalidInputException e) { - return false; // no clue - } - } - if (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = - scanner.getLineEnds(); - } - // check placement anomalies against other kinds of brackets - for (int kind = 0; kind < BracketKinds; kind++) { - for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) { - int start = leftPositions[kind][leftIndex]; // deepest - // first - // find matching closing bracket - int depth = leftDepths[kind][leftIndex]; - int end = -1; - for (int i = 0; i < rightCount[kind]; i++) { - int pos = rightPositions[kind][i]; - // want matching bracket further in source with same - // depth - if ((pos > start) && (depth == rightDepths[kind][i])) { - end = pos; - break; - } - } - if (end < 0) { // did not find a good closing match - problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); - return true; - } - // check if even number of opening/closing other brackets - // in between this pair of brackets - int balance = 0; - for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) { - for (int i = 0; i < leftCount[otherKind]; i++) { - int pos = leftPositions[otherKind][i]; - if ((pos > start) && (pos < end)) - balance++; - } - for (int i = 0; i < rightCount[otherKind]; i++) { - int pos = rightPositions[otherKind][i]; - if ((pos > start) && (pos < end)) - balance--; - } - if (balance != 0) { - problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket - // anomaly - return true; - } - } - } - // too many opening brackets ? - for (int i = rightCount[kind]; i < leftCount[kind]; i++) { - anomaliesDetected = true; - problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, - compilationUnit.compilationResult); - } - // too many closing brackets ? - for (int i = leftCount[kind]; i < rightCount[kind]; i++) { - anomaliesDetected = true; - problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult); - } - if (anomaliesDetected) - return true; - } - return anomaliesDetected; - } catch (ArrayStoreException e) { // jdk1.2.2 jit bug - return anomaliesDetected; - } catch (NullPointerException e) { // jdk1.2.2 jit bug - return anomaliesDetected; - } - } +// public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) { +// scanner.wasAcr = false; +// boolean anomaliesDetected = false; +// try { +// char[] source = scanner.source; +// int[] leftCount = { 0, 0, 0 }; +// int[] rightCount = { 0, 0, 0 }; +// int[] depths = { 0, 0, 0 }; +// int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] }; +// int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] }; +// int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] }; +// int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] }; +// scanner.currentPosition = scanner.initialPosition; //starting +// // point +// // (first-zero-based +// // char) +// while (scanner.currentPosition < scanner.eofPosition) { //loop for +// // jumping +// // over +// // comments +// try { +// // ---------Consume white space and handles +// // startPosition--------- +// boolean isWhiteSpace; +// do { +// scanner.startPosition = scanner.currentPosition; +// // if (((scanner.currentCharacter = +// // source[scanner.currentPosition++]) == '\\') && +// // (source[scanner.currentPosition] == 'u')) { +// // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace(); +// // } else { +// if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { +// if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { +// // only record line positions we have not +// // recorded yet +// scanner.pushLineSeparator(); +// } +// } +// isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter); +// // } +// } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition)); +// // -------consume token until } is found--------- +// switch (scanner.currentCharacter) { +// case '{': { +// int index = leftCount[CurlyBracket]++; +// if (index == leftPositions[CurlyBracket].length) { +// System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index); +// System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index); +// } +// leftPositions[CurlyBracket][index] = scanner.startPosition; +// leftDepths[CurlyBracket][index] = depths[CurlyBracket]++; +// } +// break; +// case '}': { +// int index = rightCount[CurlyBracket]++; +// if (index == rightPositions[CurlyBracket].length) { +// System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index); +// System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index); +// } +// rightPositions[CurlyBracket][index] = scanner.startPosition; +// rightDepths[CurlyBracket][index] = --depths[CurlyBracket]; +// } +// break; +// case '(': { +// int index = leftCount[RoundBracket]++; +// if (index == leftPositions[RoundBracket].length) { +// System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index); +// System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index); +// } +// leftPositions[RoundBracket][index] = scanner.startPosition; +// leftDepths[RoundBracket][index] = depths[RoundBracket]++; +// } +// break; +// case ')': { +// int index = rightCount[RoundBracket]++; +// if (index == rightPositions[RoundBracket].length) { +// System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index); +// System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index); +// } +// rightPositions[RoundBracket][index] = scanner.startPosition; +// rightDepths[RoundBracket][index] = --depths[RoundBracket]; +// } +// break; +// case '[': { +// int index = leftCount[SquareBracket]++; +// if (index == leftPositions[SquareBracket].length) { +// System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index); +// System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index); +// } +// leftPositions[SquareBracket][index] = scanner.startPosition; +// leftDepths[SquareBracket][index] = depths[SquareBracket]++; +// } +// break; +// case ']': { +// int index = rightCount[SquareBracket]++; +// if (index == rightPositions[SquareBracket].length) { +// System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index); +// System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index); +// } +// rightPositions[SquareBracket][index] = scanner.startPosition; +// rightDepths[SquareBracket][index] = --depths[SquareBracket]; +// } +// break; +// case '\'': { +// if (scanner.getNextChar('\\')) { +// scanner.scanEscapeCharacter(); +// } else { // consume next character +// scanner.unicodeAsBackSlash = false; +// // if (((scanner.currentCharacter = +// // source[scanner.currentPosition++]) == +// // '\\') && +// // (source[scanner.currentPosition] == +// // 'u')) { +// // scanner.getNextUnicodeChar(); +// // } else { +// if (scanner.withoutUnicodePtr != 0) { +// scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; +// } +// // } +// } +// scanner.getNextChar('\''); +// break; +// } +// case '"': +// // consume next character +// scanner.unicodeAsBackSlash = false; +// // if (((scanner.currentCharacter = +// // source[scanner.currentPosition++]) == '\\') && +// // (source[scanner.currentPosition] == 'u')) { +// // scanner.getNextUnicodeChar(); +// // } else { +// if (scanner.withoutUnicodePtr != 0) { +// scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; +// } +// // } +// while (scanner.currentCharacter != '"') { +// if (scanner.currentCharacter == '\r') { +// if (source[scanner.currentPosition] == '\n') +// scanner.currentPosition++; +// break; // the string cannot go further that +// // the line +// } +// if (scanner.currentCharacter == '\n') { +// break; // the string cannot go further that +// // the line +// } +// if (scanner.currentCharacter == '\\') { +// scanner.scanEscapeCharacter(); +// } +// // consume next character +// scanner.unicodeAsBackSlash = false; +// // if (((scanner.currentCharacter = +// // source[scanner.currentPosition++]) == '\\') +// // && (source[scanner.currentPosition] == 'u')) +// // { +// // scanner.getNextUnicodeChar(); +// // } else { +// if (scanner.withoutUnicodePtr != 0) { +// scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; +// } +// // } +// } +// break; +// case '/': { +// int test; +// if ((test = scanner.getNextChar('/', '*')) == 0) { //line +// // comment +// //get the next char +// if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') +// && (source[scanner.currentPosition] == 'u')) { +// //-------------unicode traitement +// // ------------ +// int c1 = 0, c2 = 0, c3 = 0, c4 = 0; +// scanner.currentPosition++; +// while (source[scanner.currentPosition] == 'u') { +// scanner.currentPosition++; +// } +// if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 +// || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 +// || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 +// || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error +// // don't +// // care of the +// // value +// scanner.currentCharacter = 'A'; +// } //something different from \n and \r +// else { +// scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); +// } +// } +// while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') { +// //get the next char +// scanner.startPosition = scanner.currentPosition; +// if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') +// && (source[scanner.currentPosition] == 'u')) { +// //-------------unicode traitement +// // ------------ +// int c1 = 0, c2 = 0, c3 = 0, c4 = 0; +// scanner.currentPosition++; +// while (source[scanner.currentPosition] == 'u') { +// scanner.currentPosition++; +// } +// if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 +// || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 +// || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 +// || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error +// // don't +// // care of the +// // value +// scanner.currentCharacter = 'A'; +// } //something different from \n +// // and \r +// else { +// scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); +// } +// } +// } +// if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { +// if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { +// // only record line positions we +// // have not recorded yet +// scanner.pushLineSeparator(); +// if (this.scanner.taskTags != null) { +// this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner +// .getCurrentTokenEndPosition()); +// } +// } +// } +// break; +// } +// if (test > 0) { //traditional and annotation +// // comment +// boolean star = false; +// // consume next character +// scanner.unicodeAsBackSlash = false; +// // if (((scanner.currentCharacter = +// // source[scanner.currentPosition++]) == +// // '\\') && +// // (source[scanner.currentPosition] == +// // 'u')) { +// // scanner.getNextUnicodeChar(); +// // } else { +// if (scanner.withoutUnicodePtr != 0) { +// scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; +// } +// // } +// if (scanner.currentCharacter == '*') { +// star = true; +// } +// //get the next char +// if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') +// && (source[scanner.currentPosition] == 'u')) { +// //-------------unicode traitement +// // ------------ +// int c1 = 0, c2 = 0, c3 = 0, c4 = 0; +// scanner.currentPosition++; +// while (source[scanner.currentPosition] == 'u') { +// scanner.currentPosition++; +// } +// if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 +// || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 +// || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 +// || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error +// // don't +// // care of the +// // value +// scanner.currentCharacter = 'A'; +// } //something different from * and / +// else { +// scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); +// } +// } +// //loop until end of comment */ +// while ((scanner.currentCharacter != '/') || (!star)) { +// star = scanner.currentCharacter == '*'; +// //get next char +// if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') +// && (source[scanner.currentPosition] == 'u')) { +// //-------------unicode traitement +// // ------------ +// int c1 = 0, c2 = 0, c3 = 0, c4 = 0; +// scanner.currentPosition++; +// while (source[scanner.currentPosition] == 'u') { +// scanner.currentPosition++; +// } +// if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 +// || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 +// || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 +// || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error +// // don't +// // care of the +// // value +// scanner.currentCharacter = 'A'; +// } //something different from * and +// // / +// else { +// scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); +// } +// } +// } +// if (this.scanner.taskTags != null) { +// this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition()); +// } +// break; +// } +// break; +// } +// default: +// if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) { +// scanner.scanIdentifierOrKeyword(false); +// break; +// } +// if (Character.isDigit(scanner.currentCharacter)) { +// scanner.scanNumber(false); +// break; +// } +// } +// //-----------------end switch while +// // try-------------------- +// } catch (IndexOutOfBoundsException e) { +// break; // read until EOF +// } catch (InvalidInputException e) { +// return false; // no clue +// } +// } +// if (scanner.recordLineSeparator) { +// compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); +// } +// // check placement anomalies against other kinds of brackets +// for (int kind = 0; kind < BracketKinds; kind++) { +// for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) { +// int start = leftPositions[kind][leftIndex]; // deepest +// // first +// // find matching closing bracket +// int depth = leftDepths[kind][leftIndex]; +// int end = -1; +// for (int i = 0; i < rightCount[kind]; i++) { +// int pos = rightPositions[kind][i]; +// // want matching bracket further in source with same +// // depth +// if ((pos > start) && (depth == rightDepths[kind][i])) { +// end = pos; +// break; +// } +// } +// if (end < 0) { // did not find a good closing match +// problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); +// return true; +// } +// // check if even number of opening/closing other brackets +// // in between this pair of brackets +// int balance = 0; +// for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) { +// for (int i = 0; i < leftCount[otherKind]; i++) { +// int pos = leftPositions[otherKind][i]; +// if ((pos > start) && (pos < end)) +// balance++; +// } +// for (int i = 0; i < rightCount[otherKind]; i++) { +// int pos = rightPositions[otherKind][i]; +// if ((pos > start) && (pos < end)) +// balance--; +// } +// if (balance != 0) { +// problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket +// // anomaly +// return true; +// } +// } +// } +// // too many opening brackets ? +// for (int i = rightCount[kind]; i < leftCount[kind]; i++) { +// anomaliesDetected = true; +// problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, +// compilationUnit.compilationResult); +// } +// // too many closing brackets ? +// for (int i = leftCount[kind]; i < rightCount[kind]; i++) { +// anomaliesDetected = true; +// problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult); +// } +// if (anomaliesDetected) +// return true; +// } +// return anomaliesDetected; +// } catch (ArrayStoreException e) { // jdk1.2.2 jit bug +// return anomaliesDetected; +// } catch (NullPointerException e) { // jdk1.2.2 jit bug +// return anomaliesDetected; +// } +// } protected void pushOnAstLengthStack(int pos) { try { @@ -4461,7 +4451,6 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI String ext = file.getRawLocation().getFileExtension(); int fileExtensionLength = ext == null ? 0 : ext.length() + 1; ImportReference impt; - int length; char[][] tokens; if (filePath.startsWith(projectPath)) { tokens = CharOperation @@ -4480,4 +4469,111 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI //endPosition is just before the ; } + + public final static String[] GLOBALS = { + "$this", + "$_COOKIE", + "$_ENV", + "$_FILES", + "$_GET", + "$GLOBALS", + "$_POST", + "$_REQUEST", + "$_SESSION", + "$_SERVER" }; + + /** + * + */ + private void pushFunctionVariableSet() { + HashSet set = new HashSet(); + if (fStackUnassigned.isEmpty()) { + for (int i = 0; i < GLOBALS.length; i++) { + set.add(GLOBALS[i]); + } + } + fStackUnassigned.add(set); + } + + private void pushIfVariableSet() { + if (!fStackUnassigned.isEmpty()) { + HashSet set = new HashSet(); + fStackUnassigned.add(set); + } + } + + private HashSet removeIfVariableSet() { + if (!fStackUnassigned.isEmpty()) { + return (HashSet) fStackUnassigned.remove(fStackUnassigned.size() - 1); + } + return null; + } + + /** + * Returns the set of assigned variables returns null if no Set is defined at the current scanner position + */ + private HashSet peekVariableSet() { + if (!fStackUnassigned.isEmpty()) { + return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1); + } + return null; + } + + /** + * add the current identifier source to the set of assigned variables + * + * @param set + */ + private void addVariableSet(HashSet set) { + if (set != null) { + set.add(new String(scanner.getCurrentTokenSource())); + } + } + + /** + * add the current identifier source to the set of assigned variables + * + */ + private void addVariableSet() { + HashSet set = peekVariableSet(); + if (set != null) { + set.add(new String(scanner.getCurrentTokenSource())); + } + } + + /** + * add the current identifier source to the set of assigned variables + * + */ + private void addVariableSet(char[] token) { + HashSet set = peekVariableSet(); + if (set != null) { + set.add(new String(token)); + } + } + + /** + * check if the current identifier source is in the set of assigned variables Returns true, if no set is defined for the + * current scanner position + * + */ + private boolean containsVariableSet() { + return containsVariableSet(scanner.getCurrentTokenSource()); + } + + private boolean containsVariableSet(char[] token) { + + if (!fStackUnassigned.isEmpty()) { + HashSet set; + String str = new String(token); + for (int i = 0; i < fStackUnassigned.size(); i++) { + set = (HashSet) fStackUnassigned.get(i); + if (set.contains(str)) { + return true; + } + } + return false; + } + return true; + } } \ No newline at end of file