X-Git-Url: http://secure.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 d3e2a3c..fb1b3cc 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 @@ -10,7 +10,6 @@ package net.sourceforge.phpdt.internal.compiler.parser; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Stack; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; @@ -195,8 +194,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); } /** @@ -310,7 +315,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI */ public void parse(String s, HashMap variables) { fMethodVariables = variables; - fStackUnassigned = new Stack(); + fStackUnassigned = new ArrayList(); init(s); parse(); } @@ -357,30 +362,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); @@ -418,10 +402,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; } } @@ -474,9 +459,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI statement = statement(); blockStatements.add(statement); if (branchStatement && statement != null) { -// reportSyntaxError("Unreachable code", statement.sourceStart, statement.sourceEnd); - problemReporter.unreachableCode(new String(scanner.getCurrentIdentifierSource()),statement.sourceStart, statement.sourceEnd, - referenceContext, compilationUnit.compilationResult); + // 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) @@ -554,15 +539,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."); } } @@ -723,7 +710,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI foreach_optional_arg(); if (token == TokenNameEQUAL_GREATER) { getNextToken(); - variable(false); + variable(false, false); } if (token == TokenNameRPAREN) { getNextToken(); @@ -796,7 +783,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) { @@ -1129,7 +1129,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI 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) { @@ -1153,7 +1153,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // unset_variable: // variable while (true) { - variable(false); + variable(false, false); if (token != TokenNameCOMMA) { break; } @@ -1427,11 +1427,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) { @@ -1617,10 +1618,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } try { - pushVariableSet(); + pushFunctionVariableSet(); functionDeclarator(methodDecl); if (token == TokenNameSEMICOLON) { if (!isAbstract) { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector)); } getNextToken(); @@ -1628,7 +1630,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } functionBody(methodDecl); } finally { - fStackUnassigned.pop(); + if (!fStackUnassigned.isEmpty()) { + fStackUnassigned.remove(fStackUnassigned.size() - 1); + } } } @@ -1649,12 +1653,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; @@ -1662,6 +1668,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } else { methodDecl.selector = "".toCharArray(); + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; throwSyntaxError("Function name expected after keyword 'function'."); } } @@ -1810,13 +1817,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); + 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); + } + } } - new_else_single(iState); if (token != TokenNameendif) { throwSyntaxError("'endif' expected."); } @@ -1832,13 +1864,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) { @@ -2217,7 +2276,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: @@ -2278,68 +2360,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()); @@ -2436,17 +2518,28 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI case TokenNameVariable: case TokenNameDOLLAR: boolean rememberedVar = false; -// char[] lhsVar = null; -// if (token==TokenNameVariable) { -// lhsVar = scanner.getCurrentTokenSource(); -// } - Expression lhs = variable(true); + 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 (lhsVar != null) { -// addVariableSet(lhsVar); -// } + if (lhs != null && lhs instanceof FieldReference) { + addVariableSet(((FieldReference) lhs).token); + } + // if (lhsVar != null) { + // addVariableSet(lhsVar); + // } getNextToken(); if (token == TokenNameAND) { getNextToken(); @@ -2470,7 +2563,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } } else { - Expression rhs = variable(false); + Expression rhs = variable(false, false); if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) { // example: // $var = &$ref; @@ -2533,6 +2626,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; @@ -2555,6 +2651,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) + "')."); } } @@ -2759,9 +2858,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI //| T_LIST '(' assignment_list ')' //| /* empty */ if (token == TokenNameVariable) { - variable(true); + variable(true, false); } else if (token == TokenNameDOLLAR) { - variable(false); + variable(false, false); } else { if (token == TokenNamelist) { getNextToken(); @@ -2802,17 +2901,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (true) { if (token == TokenNameAND) { getNextToken(); - variable(false); + variable(true, false); } else { expr(); if (token == TokenNameAND) { getNextToken(); - variable(false); + variable(true, false); } else if (token == TokenNameEQUAL_GREATER) { getNextToken(); if (token == TokenNameAND) { getNextToken(); - variable(false); + variable(true, false); } else { expr(); } @@ -2838,7 +2937,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // } while (true); // } - private Expression variable_without_objects(boolean lefthandside) { + private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) { // variable_without_objects: // reference_variable // | simple_indirect_reference reference_variable @@ -2848,10 +2947,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (token == TokenNameDOLLAR) { getNextToken(); } - return reference_variable(lefthandside); + return reference_variable(lefthandside, ignoreVar); } - private Expression function_call(boolean lefthandside) { + private Expression function_call(boolean lefthandside, boolean ignoreVar) { // function_call: // T_STRING '(' function_call_parameter_list ')' //| class_constant '(' function_call_parameter_list ')' @@ -2881,12 +2980,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); } else { // static member: - variable_without_objects(false); + variable_without_objects(true, false); } break; } } else { - ref = variable_without_objects(lefthandside); + ref = variable_without_objects(lefthandside, ignoreVar); } if (token != TokenNameLPAREN) { if (defineName != null) { @@ -2957,7 +3056,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (true) { if (token == TokenNameAND) { getNextToken(); - w_variable(false); + w_variable(true); } else { // if (token == TokenNameIdentifier || token == // TokenNameVariable @@ -2994,10 +3093,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'::' expected after class name (static_member)."); } getNextToken(); - variable_without_objects(false); + variable_without_objects(false, false); } - private Expression base_variable_with_function_calls(boolean lefthandside) { + private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) { // base_variable_with_function_calls: // base_variable //| function_call @@ -3019,7 +3118,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // scanner.phpMode = true; // } // if (functionCall) { - return function_call(lefthandside); + return function_call(lefthandside, ignoreVar); // } else { // base_variable(); // } @@ -3040,7 +3139,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (token == TokenNameDOLLAR) { getNextToken(); } - reference_variable(false); + reference_variable(false, false); } return ref; } @@ -3050,7 +3149,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // // '$' // //| simple_indirect_reference '$' // } - private Expression reference_variable(boolean lefthandside) { + private Expression reference_variable(boolean lefthandside, boolean ignoreVar) { // reference_variable: // reference_variable '[' dim_offset ']' // | reference_variable '{' expr '}' @@ -3059,7 +3158,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (Scanner.TRACE) { System.out.println("TRACE: reference_variable()"); } - ref = compound_variable(lefthandside); + ref = compound_variable(lefthandside, ignoreVar); while (true) { if (token == TokenNameLBRACE) { ref = null; @@ -3070,6 +3169,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) { @@ -3087,7 +3190,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return ref; } - private Expression compound_variable(boolean lefthandside) { + private Expression compound_variable(boolean lefthandside, boolean ignoreVar) { // compound_variable: // T_VARIABLE // | '$' '{' expr '}' @@ -3097,13 +3200,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI 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); + // 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 { - addVariableSet(); + if (!ignoreVar) { + addVariableSet(); + } } FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); getNextToken(); @@ -3125,11 +3231,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(); // } @@ -3141,7 +3244,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI System.out.println("TRACE: object_property()"); } if (token == TokenNameVariable || token == TokenNameDOLLAR) { - variable_without_objects(false); + variable_without_objects(false, false); } else { object_dim_list(); } @@ -3207,23 +3310,23 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } private void r_variable() { - variable(false); + variable(false, false); } private void w_variable(boolean lefthandside) { - variable(lefthandside); + variable(lefthandside, false); } private void rw_variable() { - variable(false); + variable(false, false); } - private Expression variable(boolean lefthandside) { + 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(lefthandside); + Expression ref = base_variable_with_function_calls(lefthandside, ignoreVar); if (token == TokenNameMINUS_GREATER) { ref = null; getNextToken(); @@ -3298,223 +3401,223 @@ 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 @@ -3542,32 +3645,32 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI 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(false); - 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); @@ -3694,7 +3797,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("Variable expected after keyword 'isset'"); } while (true) { - variable(false); + variable(true, false); if (token == TokenNameCOMMA) { getNextToken(); } else { @@ -3799,33 +3902,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(); @@ -4012,7 +4121,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI HashMap fMethodVariables = null; - Stack fStackUnassigned = new Stack(); + ArrayList fStackUnassigned = new ArrayList(); //ast stack final static int AstStackIncrement = 100; @@ -4528,25 +4637,41 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI "$_POST", "$_REQUEST", "$_SESSION", - "$_SERVER" - }; + "$_SERVER" }; + /** - * + * */ - private void pushVariableSet() { - HashSet set =new HashSet(); - for (int i = 0; i < GLOBALS.length; i++) { - set.add(GLOBALS[i]); + private void pushFunctionVariableSet() { + HashSet set = new HashSet(); + if (fStackUnassigned.isEmpty()) { + for (int i = 0; i < GLOBALS.length; i++) { + set.add(GLOBALS[i]); + } } - fStackUnassigned.push(set); + 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.peek(); + return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1); } return null; } @@ -4590,9 +4715,33 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI * */ private boolean containsVariableSet() { - HashSet set = peekVariableSet(); - if (set != null) { - return set.contains(new String(scanner.getCurrentTokenSource())); + return containsVariableSet(scanner.getCurrentTokenSource()); + // if (!fStackUnassigned.isEmpty()) { + // HashSet set; + // String str = new String(scanner.getCurrentTokenSource()); + // for (int i = 0; i < fStackUnassigned.size(); i++) { + // set = (HashSet) fStackUnassigned.get(i); + // if (set.contains(str)) { + // return true; + // } + // } + // return false; + // } + // return true; + } + + 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; }