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 ad67bec..b1ddd61 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 @@ -8,6 +8,7 @@ package net.sourceforge.phpdt.internal.compiler.parser; import java.util.ArrayList; +import java.util.HashMap; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; @@ -27,39 +28,43 @@ import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaratio import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression; import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpeclipse.internal.compiler.ast.EmptyStatement; import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression; import net.sourceforge.phpeclipse.internal.compiler.ast.Expression; import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldReference; import net.sourceforge.phpeclipse.internal.compiler.ast.IfStatement; import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; +import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression; import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression; +import net.sourceforge.phpeclipse.internal.compiler.ast.OperatorIds; import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference; import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral; import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralDQ; import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralSQ; import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; +import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; -public class Parser //extends PHPParserSuperclass - implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation { - //internal data for the automat +public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation { protected final static int StackIncrement = 255; - + protected int stateStackTop; - protected int[] stack = new int[StackIncrement]; + // protected int[] stack = new int[StackIncrement]; public int firstToken; // handle for multiple parsing goals public int lastAct; //handle for multiple parsing goals - protected RecoveredElement currentElement; + // protected RecoveredElement currentElement; public static boolean VERBOSE_RECOVERY = false; @@ -70,11 +75,11 @@ public class Parser //extends PHPParserSuperclass //scanner token public Scanner scanner; - private ArrayList phpList; + // private ArrayList phpList; - private int currentPHPString; + // private int currentPHPString; - private boolean phpEnd; + // private boolean phpEnd; // private static HashMap keywordMap = null; private String str; @@ -92,11 +97,11 @@ public class Parser //extends PHPParserSuperclass // // // current identifier // String identifier; - Long longNumber; + // Long longNumber; - Double doubleNumber; + // Double doubleNumber; - private String stringValue; + // private String stringValue; /** Contains the current expression. */ // private StringBuffer expression; @@ -105,33 +110,31 @@ public class Parser //extends PHPParserSuperclass protected int modifiersSourceStart; - // protected IdentifierIndexManager indexManager; - protected Parser(ProblemReporter problemReporter) { this.problemReporter = problemReporter; this.options = problemReporter.options; - this.currentPHPString = 0; + // this.currentPHPString = 0; // PHPParserSuperclass.fileToParse = fileToParse; - this.phpList = null; + // this.phpList = null; // this.indexManager = null; this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; - this.phpEnd = false; + // this.phpEnd = false; // getNextToken(); this.initializeScanner(); } public void setFileToParse(IFile fileToParse) { - this.currentPHPString = 0; + // this.currentPHPString = 0; // PHPParserSuperclass.fileToParse = fileToParse; - this.phpList = null; + // this.phpList = null; // this.indexManager = null; this.str = ""; this.token = TokenNameEOF; - this.phpEnd = false; + // this.phpEnd = false; this.initializeScanner(); } @@ -150,16 +153,16 @@ public class Parser //extends PHPParserSuperclass // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i])); // } // } - this.currentPHPString = 0; + // this.currentPHPString = 0; // PHPParserSuperclass.fileToParse = fileToParse; - this.phpList = null; + // this.phpList = null; this.includesList = null; this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; - this.phpEnd = false; + // this.phpEnd = false; // getNextToken(); this.initializeScanner(); } @@ -167,9 +170,7 @@ public class Parser //extends PHPParserSuperclass public void initializeScanner() { this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options .getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false, - this.options.taskTags/* taskTags */, - this.options.taskPriorites/* taskPriorities */, - true/*isTaskCaseSensitive*/); + this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */, true/* isTaskCaseSensitive */); } /** @@ -205,8 +206,10 @@ public class Parser //extends PHPParserSuperclass // throw new SyntaxError(startRow, 0, " ", error); // } private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) { - problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, - compilationUnit.compilationResult); + if (referenceContext != null) { + problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + compilationUnit.compilationResult); + } throw new SyntaxError(1, 0, " ", error); } @@ -215,15 +218,19 @@ public class Parser //extends PHPParserSuperclass int problemEndPosition = scanner.getCurrentTokenEndPosition(); reportSyntaxError(error, problemStartPosition, problemEndPosition + 1); } - + private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { - problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, - compilationUnit.compilationResult); + if (referenceContext != null) { + problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + compilationUnit.compilationResult); + } } private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) { - problemReporter.phpParsingWarning(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, - compilationUnit.compilationResult); + if (referenceContext != null) { + problemReporter.phpParsingWarning(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + compilationUnit.compilationResult); + } } /** @@ -254,14 +261,16 @@ public class Parser //extends PHPParserSuperclass public void init(String s) { this.str = s; this.token = TokenNameEOF; + this.includesList = new ArrayList(); // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; - this.phpEnd = false; + // this.phpEnd = false; // this.phpMode = false; /* scanner initialization */ scanner.setSource(s.toCharArray()); scanner.setPHPMode(false); + astPtr = 0; } protected void initialize(boolean phpMode) { @@ -271,22 +280,31 @@ public class Parser //extends PHPParserSuperclass protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) { compilationUnit = null; referenceContext = null; - includesList = new ArrayList(); + this.includesList = new ArrayList(); // this.indexManager = indexManager; this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; - this.phpEnd = false; + // this.phpEnd = false; // this.phpMode = phpMode; scanner.setPHPMode(phpMode); + astPtr = 0; } /** * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>' */ public void parse(String s) { + parse(s, null); + } + + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>' + */ + public void parse(String s, HashMap variables) { + fMethodVariables = variables; init(s); parse(); } @@ -295,6 +313,13 @@ public class Parser //extends PHPParserSuperclass * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>' */ protected void parse() { + if (scanner.compilationUnit != null) { + IResource resource = scanner.compilationUnit.getResource(); + if (resource != null && resource instanceof IFile) { + // set the package name + consumePackageDeclarationName((IFile) resource); + } + } getNextToken(); do { try { @@ -327,58 +352,95 @@ public class Parser //extends PHPParserSuperclass } break; } catch (SyntaxError sytaxErr1) { - // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), - // ERROR); - // setMarker(sytaxErr1.getMessage(), - // scanner.getCurrentTokenStartPosition(), - // scanner.getCurrentTokenEndPosition(), ERROR); - try { - // if an error occured, - // try to find keywords 'class' or 'function' - // to parse the rest of the string - while (token != TokenNameEOF && token != TokenNameERROR) { - if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) { - break; - } - getNextToken(); - } - if (token == TokenNameEOF || token == TokenNameERROR) { - break; - } - } catch (SyntaxError sytaxErr2) { - // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), - // ERROR); - // setMarker(sytaxErr2.getMessage(), - // scanner.getCurrentTokenStartPosition(), - // scanner.getCurrentTokenEndPosition(), ERROR); - break; - } + 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); endParse(0); } + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>' + */ + public void parseFunction(String s, HashMap variables) { + init(s); + scanner.phpMode = true; + parseFunction(variables); + } + + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>' + */ + protected void parseFunction(HashMap variables) { + getNextToken(); + boolean hasModifiers = member_modifiers(); + if (token == TokenNamefunction) { + if (!hasModifiers) { + checkAndSetModifiers(AccPublic); + } + this.fMethodVariables = variables; + + MethodDeclaration methodDecl = new MethodDeclaration(null); + methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + methodDecl.modifiers = this.modifiers; + methodDecl.type = MethodDeclaration.METHOD_DEFINITION; + try { + getNextToken(); + functionDefinition(methodDecl); + } catch (SyntaxError sytaxErr1) { + return; + } finally { + int sourceEnd = scanner.getCurrentTokenStartPosition(); + if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + sourceEnd = methodDecl.declarationSourceStart + 1; + } + methodDecl.declarationSourceEnd = sourceEnd; + } + } + } + protected CompilationUnitDeclaration endParse(int act) { this.lastAct = act; - if (currentElement != null) { - currentElement.topElement().updateParseTree(); - if (VERBOSE_RECOVERY) { - System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$ - System.out.println("--------------------------"); //$NON-NLS-1$ - System.out.println(compilationUnit); - System.out.println("----------------------------------"); //$NON-NLS-1$ - } - } else { - if (diet & VERBOSE_RECOVERY) { - System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$ - System.out.println("--------------------------"); //$NON-NLS-1$ - System.out.println(compilationUnit); - System.out.println("----------------------------------"); //$NON-NLS-1$ - } + // if (currentElement != null) { + // currentElement.topElement().updateParseTree(); + // if (VERBOSE_RECOVERY) { + // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$ + // System.out.println("--------------------------"); //$NON-NLS-1$ + // System.out.println(compilationUnit); + // System.out.println("----------------------------------"); //$NON-NLS-1$ + // } + // } else { + if (diet & VERBOSE_RECOVERY) { + System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$ + System.out.println("--------------------------"); //$NON-NLS-1$ + System.out.println(compilationUnit); + System.out.println("----------------------------------"); //$NON-NLS-1$ } + // } if (scanner.recordLineSeparator) { compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); } @@ -396,203 +458,54 @@ public class Parser //extends PHPParserSuperclass return compilationUnit; } - // public PHPOutlineInfo parseInfo(Object parent, String s) { - // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent); - // // Stack stack = new Stack(); - // // stack.push(outlineInfo.getDeclarations()); - // this.str = s; - // this.token = TokenNameEOF; - // // this.chIndx = 0; - // // this.rowCount = 1; - // // this.columnCount = 0; - // this.phpEnd = false; - // this.phpMode = false; - // scanner.setSource(s.toCharArray()); - // scanner.setPHPMode(false); - // - // getNextToken(); - // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false); - // - // return outlineInfo; - // } private boolean isVariable() { return token == TokenNameVariable; // || token == TokenNamethis; } - // private void parseDeclarations(PHPOutlineInfo outlineInfo, - // OutlineableWithChildren current, boolean goBack) { - // char[] ident; - // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek(); - // PHPSegmentWithChildren temp; - // int counter = 0; - // IPreferenceStore store = - // PHPeclipsePlugin.getDefault().getPreferenceStore(); - // try { - // while (token != TokenNameEOF && token != TokenNameERROR) { - // if (token == TokenNameVariable) { - // ident = scanner.getCurrentIdentifierSource(); - // outlineInfo.addVariable(new String(ident)); - // getNextToken(); - // } else if (token == TokenNamevar) { - // getNextToken(); - // if (token == TokenNameVariable - // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) { - // ident = scanner.getCurrentIdentifierSource(); - // //substring(1) added because PHPVarDeclaration doesn't - // // need the $ anymore - // String variableName = new String(ident).substring(1); - // outlineInfo.addVariable(variableName); - // getNextToken(); - // if (token != TokenNameSEMICOLON) { - // getNextToken(); - // ident = scanner.getCurrentTokenSource(); - // if (token > TokenNameKEYWORD) { - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - ident.length, - // scanner.getCurrentTokenStartPosition(), new String(ident))); - // } else { - // switch (token) { - // case TokenNameVariable : - // case TokenNamethis : - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - - // // ident.length, - // scanner.getCurrentTokenStartPosition(), new String( - // ident))); - // break; - // case TokenNameIdentifier : - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - - // // ident.length, - // scanner.getCurrentTokenStartPosition(), new String( - // ident))); - // break; - // case TokenNameDoubleLiteral : - // current.add(new PHPVarDeclaration(current, variableName - // + doubleNumber, - // // chIndx - - // // ident.length, - // scanner.getCurrentTokenStartPosition(), new String( - // ident))); - // break; - // case TokenNameIntegerLiteral : - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - - // // ident.length, - // scanner.getCurrentTokenStartPosition(), new String( - // ident))); - // break; - // case TokenNameStringInterpolated : - // case TokenNameStringLiteral : - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - - // // ident.length, - // scanner.getCurrentTokenStartPosition(), new String( - // ident))); - // break; - // case TokenNameStringConstant : - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - - // // ident.length, - // scanner.getCurrentTokenStartPosition(), new String( - // ident))); - // break; - // default : - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - - // // ident.length - // scanner.getCurrentTokenStartPosition())); - // break; - // } - // } - // } else { - // ident = scanner.getCurrentIdentifierSource(); - // current.add(new PHPVarDeclaration(current, variableName, - // // chIndx - ident.length - // scanner.getCurrentTokenStartPosition())); - // } - // } - // } else if (token == TokenNamefunction) { - // getNextToken(); - // if (token == TokenNameAND) { - // getNextToken(); - // } - // if (token == TokenNameIdentifier - // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) { - // ident = scanner.getCurrentIdentifierSource(); - // outlineInfo.addVariable(new String(ident)); - // temp = new PHPFunctionDeclaration(current, new String(ident), - // // chIndx - ident.length - // scanner.getCurrentTokenStartPosition()); - // current.add(temp); - // getNextToken(); - // parseDeclarations(outlineInfo, temp, true); - // } - // } else if (token == TokenNameclass) { - // getNextToken(); - // if (token == TokenNameIdentifier - // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) { - // ident = scanner.getCurrentIdentifierSource(); - // outlineInfo.addVariable(new String(ident)); - // temp = new PHPClassDeclaration(current, new String(ident), - // // chIndx - ident.len - // scanner.getCurrentTokenStartPosition()); - // current.add(temp); - // // stack.push(temp); - // getNextToken(); - // //skip tokens for classname, extends and others until - // // we have the opening '{' - // while (token != TokenNameLBRACE && token != TokenNameEOF - // && token != TokenNameERROR) { - // getNextToken(); - // } - // parseDeclarations(outlineInfo, temp, true); - // // stack.pop(); - // } - // } else if ((token == TokenNameLBRACE) - // || (token == TokenNameDOLLAR_LBRACE)) { - // getNextToken(); - // counter++; - // } else if (token == TokenNameRBRACE) { - // getNextToken(); - // --counter; - // if (counter == 0 && goBack) { - // return; - // } - // } else if (token == TokenNamerequire || token == TokenNamerequire_once - // || token == TokenNameinclude || token == TokenNameinclude_once) { - // ident = scanner.getCurrentTokenSource(); - // getNextToken(); - // int startPosition = scanner.getCurrentTokenStartPosition(); - // expr(); - // char[] expr = scanner.getCurrentTokenSource(startPosition); - // outlineInfo.addVariable(new String(ident)); - // current.add(new PHPReqIncDeclaration(current, new String(ident), - // // chIndx - ident.length, - // startPosition, new String(expr))); - // getNextToken(); - // } else { - // getNextToken(); - // } - // } - // } catch (SyntaxError sytaxErr) { - // // try { - // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR); - // // setMarker(sytaxErr.getMessage(), - // // scanner.getCurrentTokenStartPosition(), - // // scanner.getCurrentTokenEndPosition(), ERROR); - // // } catch (CoreException e) { - // // } - // } - // } private void statementList() { do { - statement(TokenNameEOF); - if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) - || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) - || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) - || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) { - return; + try { + statement(TokenNameEOF); + if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) + || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) + || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) + || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) { + return; + } + } catch (SyntaxError sytaxErr1) { + // if an error occured, + // try to find keywords + // to parse the rest of the string + boolean tokenize = scanner.tokenizeStrings; + if (!tokenize) { + scanner.tokenizeStrings = true; + } + try { + while (token != TokenNameEOF) { + if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) + || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) + || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) + || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) { + return; + } + if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile + || token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak + || token == TokenNamereturn || token == TokenNameexit || token == TokenNameecho || token == TokenNameglobal + || token == TokenNamestatic || token == TokenNameunset || token == TokenNamefunction || token == TokenNamedeclare + || token == TokenNametry || token == TokenNamecatch || token == TokenNamethrow || token == TokenNamefinal + || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) { + break; + } + // System.out.println(scanner.toStringAction(token)); + getNextToken(); + // System.out.println(scanner.toStringAction(token)); + } + if (token == TokenNameEOF) { + throw sytaxErr1; + } + } finally { + scanner.tokenizeStrings = tokenize; + } } } while (true); } @@ -608,7 +521,7 @@ public class Parser //extends PHPParserSuperclass statementList(); } if (token == TokenNameRBRACE) { - methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + // methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected in compound-statement."); @@ -861,8 +774,17 @@ public class Parser //extends PHPParserSuperclass MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult); methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); methodDecl.modifiers = AccDefault; - getNextToken(); - functionDefinition(methodDecl); + methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION; + try { + getNextToken(); + functionDefinition(methodDecl); + } finally { + int sourceEnd = scanner.getCurrentTokenStartPosition(); + if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + sourceEnd = methodDecl.declarationSourceStart + 1; + } + methodDecl.declarationSourceEnd = sourceEnd; + } return statement; } else if (token == TokenNamedeclare) { //T_DECLARE '(' declare_list ')' declare_statement @@ -928,18 +850,18 @@ public class Parser //extends PHPParserSuperclass } return statement; } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) { - TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); - typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); - typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); - typeDecl.name = new char[] { ' ' }; - // default super class - typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0); - compilationUnit.types.add(typeDecl); try { + TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); + typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + typeDecl.name = new char[] { ' ' }; + // default super class + typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0); + compilationUnit.types.add(typeDecl); pushOnAstStack(typeDecl); unticked_class_declaration_statement(typeDecl); - // classBody(typeDecl); } finally { + // reduce stack: astPtr--; astLengthPtr--; } @@ -965,10 +887,14 @@ public class Parser //extends PHPParserSuperclass getNextToken(); return statement; } else { - if (token != TokenNameINLINE_HTML && token != TokenNameEOF) { - throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); + if (token == TokenNameRBRACE) { + reportSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); + } else { + if (token != TokenNameINLINE_HTML && token != TokenNameEOF) { + throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); + } + getNextToken(); } - getNextToken(); } } // may be null @@ -1083,14 +1009,18 @@ public class Parser //extends PHPParserSuperclass //| '$' r_variable //| '$' '{' expr '}' if (token == TokenNameVariable) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR); + if (fMethodVariables != null) { + fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } getNextToken(); } else if (token == TokenNameDOLLAR) { getNextToken(); - if (token == TokenNameLPAREN) { + if (token == TokenNameLBRACE) { getNextToken(); expr(); - if (token != TokenNameLPAREN) { - throwSyntaxError("')' expected in global variable."); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in global variable."); } getNextToken(); } else { @@ -1107,6 +1037,10 @@ public class Parser //extends PHPParserSuperclass //| T_VARIABLE '=' static_scalar while (true) { if (token == TokenNameVariable) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR); + if (fMethodVariables != null) { + fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); @@ -1272,8 +1206,8 @@ public class Parser //extends PHPParserSuperclass throwSyntaxError("Class name expected after keyword 'extends'."); } } - } - + } + private void interface_extends_list(TypeDeclaration typeDecl) { // /* empty */ // | T_EXTENDS interface_list @@ -1287,7 +1221,7 @@ public class Parser //extends PHPParserSuperclass // /* empty */ // | T_IMPLEMENTS interface_list if (token == TokenNameimplements) { - getNextToken(); + getNextToken(); interface_list(); } } @@ -1328,10 +1262,43 @@ public class Parser //extends PHPParserSuperclass // } private void class_statement_list(ArrayList list) { do { - class_statement(list); - } while (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic - || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar - || token == TokenNameconst); + try { + class_statement(list); + if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic + || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar + || token == TokenNameconst) { + continue; + } + if (token == TokenNameRBRACE) { + break; + } + throwSyntaxError("'}' at end of class statement."); + } catch (SyntaxError sytaxErr1) { + boolean tokenize = scanner.tokenizeStrings; + if (!tokenize) { + scanner.tokenizeStrings = true; + } + try { + // if an error occured, + // try to find keywords + // to parse the rest of the string + while (token != TokenNameEOF) { + if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic + || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar + || token == TokenNameconst) { + break; + } + // System.out.println(scanner.toStringAction(token)); + getNextToken(); + } + if (token == TokenNameEOF) { + throw sytaxErr1; + } + } finally { + scanner.tokenizeStrings = tokenize; + } + } + } while (true); } private void class_statement(ArrayList list) { @@ -1365,8 +1332,17 @@ public class Parser //extends PHPParserSuperclass MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult); methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); methodDecl.modifiers = this.modifiers; - getNextToken(); - functionDefinition(methodDecl); + methodDecl.type = MethodDeclaration.METHOD_DEFINITION; + try { + getNextToken(); + functionDefinition(methodDecl); + } finally { + int sourceEnd = scanner.getCurrentTokenStartPosition(); + if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + sourceEnd = methodDecl.declarationSourceStart + 1; + } + methodDecl.declarationSourceEnd = sourceEnd; + } } else { if (!hasModifiers) { throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations."); @@ -1496,8 +1472,11 @@ public class Parser //extends PHPParserSuperclass fieldDeclaration.declarationSourceStart = declarationSourceStart; fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); fieldDeclaration.modifiersSourceStart = declarationSourceStart; - // fieldDeclaration.type list.add(fieldDeclaration); + if (fTypeVariables != null) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_CLASS_UNIT); + fTypeVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); @@ -1524,7 +1503,9 @@ public class Parser //extends PHPParserSuperclass private void functionDefinition(MethodDeclaration methodDecl) { boolean isAbstract = false; if (astPtr == 0) { - compilationUnit.types.add(methodDecl); + if (compilationUnit != null) { + compilationUnit.types.add(methodDecl); + } } else { ASTNode node = astStack[astPtr]; if (node instanceof TypeDeclaration) { @@ -1533,9 +1514,9 @@ public class Parser //extends PHPParserSuperclass typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl }; } else { AbstractMethodDeclaration[] newMethods; - System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 1, + System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 0, typeDecl.methods.length); - newMethods[0] = methodDecl; + newMethods[typeDecl.methods.length] = methodDecl; typeDecl.methods = newMethods; } if ((typeDecl.modifiers & AccAbstract) == AccAbstract) { @@ -1568,8 +1549,6 @@ public class Parser //extends PHPParserSuperclass if (token > TokenNameKEYWORD) { problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); - // reportSyntaxWarning("Don't use keyword for function declaration [" + scanner.toStringAction(token) + "].", - // scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition()); } getNextToken(); if (token == TokenNameLPAREN) { @@ -1578,7 +1557,7 @@ public class Parser //extends PHPParserSuperclass throwSyntaxError("'(' expected in function declaration."); } if (token != TokenNameRPAREN) { - parameter_list(); + parameter_list(methodDecl); } if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in function declaration."); @@ -1593,13 +1572,13 @@ public class Parser //extends PHPParserSuperclass } // - private void parameter_list() { + private void parameter_list(MethodDeclaration methodDecl) { // non_empty_parameter_list // | /* empty */ - non_empty_parameter_list(true); + non_empty_parameter_list(methodDecl, true); } - private void non_empty_parameter_list(boolean empty_allowed) { + private void non_empty_parameter_list(MethodDeclaration methodDecl, boolean empty_allowed) { // optional_class_type T_VARIABLE // | optional_class_type '&' T_VARIABLE // | optional_class_type '&' T_VARIABLE '=' static_scalar @@ -1610,15 +1589,27 @@ public class Parser //extends PHPParserSuperclass // static_scalar // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' // static_scalar + char[] typeIdentifier = null; if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) { while (true) { if (token == TokenNameIdentifier) { + typeIdentifier = scanner.getCurrentIdentifierSource(); getNextToken(); } if (token == TokenNameAND) { getNextToken(); } if (token == TokenNameVariable) { + if (fMethodVariables != null) { + VariableInfo info; + if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) { + info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_FUNCTION_DEFINITION); + } else { + info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_METHOD_DEFINITION); + } + info.typeIdentifier = typeIdentifier; + fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); @@ -1644,31 +1635,31 @@ public class Parser //extends PHPParserSuperclass //| T_STRING } - private void parameterDeclaration() { - //variable - //variable-reference - if (token == TokenNameAND) { - getNextToken(); - if (isVariable()) { - getNextToken(); - } else { - throwSyntaxError("Variable expected after reference operator '&'."); - } - } - //variable '=' constant - if (token == TokenNameVariable) { - getNextToken(); - if (token == TokenNameEQUAL) { - getNextToken(); - static_scalar(); - } - return; - } - // if (token == TokenNamethis) { - // throwSyntaxError("Reserved word '$this' not allowed in parameter - // declaration."); - // } - } + // private void parameterDeclaration() { + // //variable + // //variable-reference + // if (token == TokenNameAND) { + // getNextToken(); + // if (isVariable()) { + // getNextToken(); + // } else { + // throwSyntaxError("Variable expected after reference operator '&'."); + // } + // } + // //variable '=' constant + // if (token == TokenNameVariable) { + // getNextToken(); + // if (token == TokenNameEQUAL) { + // getNextToken(); + // static_scalar(); + // } + // return; + // } + // // if (token == TokenNamethis) { + // // throwSyntaxError("Reserved word '$this' not allowed in parameter + // // declaration."); + // // } + // } private void labeledStatementList() { if (token != TokenNamecase && token != TokenNamedefault) { @@ -2001,450 +1992,532 @@ public class Parser //extends PHPParserSuperclass expression.sourceStart = exprSourceStart; // default, may be overwritten expression.sourceEnd = exprSourceEnd; - // internal_functions_in_yacc - // | T_CLONE expr - // | T_PRINT expr - // | '(' expr ')' - // | '@' expr - // | '+' expr - // | '-' expr - // | '!' expr - // | '~' expr - // | T_INC rw_variable - // | T_DEC rw_variable - // | T_INT_CAST expr - // | T_DOUBLE_CAST expr - // | T_STRING_CAST expr - // | T_ARRAY_CAST expr - // | T_OBJECT_CAST expr - // | T_BOOL_CAST expr - // | T_UNSET_CAST expr - // | T_EXIT exit_expr - // | scalar - // | T_ARRAY '(' array_pair_list ')' - // | '`' encaps_list '`' - // | T_LIST '(' assignment_list ')' '=' expr - // | T_NEW class_name_reference ctor_arguments - // | variable '=' expr - // | variable '=' '&' variable - // | variable '=' '&' T_NEW class_name_reference ctor_arguments - // | variable T_PLUS_EQUAL expr - // | variable T_MINUS_EQUAL expr - // | variable T_MUL_EQUAL expr - // | variable T_DIV_EQUAL expr - // | variable T_CONCAT_EQUAL expr - // | variable T_MOD_EQUAL expr - // | variable T_AND_EQUAL expr - // | variable T_OR_EQUAL expr - // | variable T_XOR_EQUAL expr - // | variable T_SL_EQUAL expr - // | variable T_SR_EQUAL expr - // | rw_variable T_INC - // | rw_variable T_DEC - // | expr T_BOOLEAN_OR expr - // | expr T_BOOLEAN_AND expr - // | expr T_LOGICAL_OR expr - // | expr T_LOGICAL_AND expr - // | expr T_LOGICAL_XOR expr - // | expr '|' expr - // | expr '&' expr - // | expr '^' expr - // | expr '.' expr - // | expr '+' expr - // | expr '-' expr - // | expr '*' expr - // | expr '/' expr - // | expr '%' expr - // | expr T_SL expr - // | expr T_SR expr - // | expr T_IS_IDENTICAL expr - // | expr T_IS_NOT_IDENTICAL expr - // | expr T_IS_EQUAL expr - // | expr T_IS_NOT_EQUAL expr - // | expr '<' expr - // | expr T_IS_SMALLER_OR_EQUAL expr - // | expr '>' expr - // | expr T_IS_GREATER_OR_EQUAL expr - // | expr T_INSTANCEOF class_name_reference - // | expr '?' expr ':' expr - if (Scanner.TRACE) { - System.out.println("TRACE: expr_without_variable() PART 1"); - } - switch (token) { - case TokenNameisset: - case TokenNameempty: - case TokenNameeval: - case TokenNameinclude: - case TokenNameinclude_once: - case TokenNamerequire: - case TokenNamerequire_once: - internal_functions_in_yacc(); - break; - // | '(' expr ')' - case TokenNameLPAREN: - getNextToken(); - expr(); - if (token == TokenNameRPAREN) { - getNextToken(); - } else { - throwSyntaxError("')' expected in expression."); + try { + // internal_functions_in_yacc + // | T_CLONE expr + // | T_PRINT expr + // | '(' expr ')' + // | '@' expr + // | '+' expr + // | '-' expr + // | '!' expr + // | '~' expr + // | T_INC rw_variable + // | T_DEC rw_variable + // | T_INT_CAST expr + // | T_DOUBLE_CAST expr + // | T_STRING_CAST expr + // | T_ARRAY_CAST expr + // | T_OBJECT_CAST expr + // | T_BOOL_CAST expr + // | T_UNSET_CAST expr + // | T_EXIT exit_expr + // | scalar + // | T_ARRAY '(' array_pair_list ')' + // | '`' encaps_list '`' + // | T_LIST '(' assignment_list ')' '=' expr + // | T_NEW class_name_reference ctor_arguments + // | variable '=' expr + // | variable '=' '&' variable + // | variable '=' '&' T_NEW class_name_reference ctor_arguments + // | variable T_PLUS_EQUAL expr + // | variable T_MINUS_EQUAL expr + // | variable T_MUL_EQUAL expr + // | variable T_DIV_EQUAL expr + // | variable T_CONCAT_EQUAL expr + // | variable T_MOD_EQUAL expr + // | variable T_AND_EQUAL expr + // | variable T_OR_EQUAL expr + // | variable T_XOR_EQUAL expr + // | variable T_SL_EQUAL expr + // | variable T_SR_EQUAL expr + // | rw_variable T_INC + // | rw_variable T_DEC + // | expr T_BOOLEAN_OR expr + // | expr T_BOOLEAN_AND expr + // | expr T_LOGICAL_OR expr + // | expr T_LOGICAL_AND expr + // | expr T_LOGICAL_XOR expr + // | expr '|' expr + // | expr '&' expr + // | expr '^' expr + // | expr '.' expr + // | expr '+' expr + // | expr '-' expr + // | expr '*' expr + // | expr '/' expr + // | expr '%' expr + // | expr T_SL expr + // | expr T_SR expr + // | expr T_IS_IDENTICAL expr + // | expr T_IS_NOT_IDENTICAL expr + // | expr T_IS_EQUAL expr + // | expr T_IS_NOT_EQUAL expr + // | expr '<' expr + // | expr T_IS_SMALLER_OR_EQUAL expr + // | expr '>' expr + // | expr T_IS_GREATER_OR_EQUAL expr + // | expr T_INSTANCEOF class_name_reference + // | expr '?' expr ':' expr + if (Scanner.TRACE) { + System.out.println("TRACE: expr_without_variable() PART 1"); } - break; - // | T_CLONE expr - // | T_PRINT expr - // | '@' expr - // | '+' expr - // | '-' expr - // | '!' expr - // | '~' expr - // | T_INT_CAST expr - // | T_DOUBLE_CAST expr - // | T_STRING_CAST expr - // | T_ARRAY_CAST expr - // | T_OBJECT_CAST expr - // | T_BOOL_CAST expr - // | T_UNSET_CAST expr - case TokenNameclone: - case TokenNameprint: - case TokenNameAT: - case TokenNamePLUS: - case TokenNameMINUS: - case TokenNameNOT: - case TokenNameTWIDDLE: - case TokenNameintCAST: - case TokenNamedoubleCAST: - case TokenNamestringCAST: - case TokenNamearrayCAST: - case TokenNameobjectCAST: - case TokenNameboolCAST: - case TokenNameunsetCAST: - getNextToken(); - expr(); - break; - case TokenNameexit: - getNextToken(); - exit_expr(); - break; - // scalar: - // T_STRING - //| T_STRING_VARNAME - //| class_constant - //| T_START_HEREDOC encaps_list T_END_HEREDOC - // | '`' encaps_list '`' - // | common_scalar - // | '`' encaps_list '`' - case TokenNameEncapsedString0: - scanner.encapsedStringStack.push(new Character('`')); - getNextToken(); - try { - if (token == TokenNameEncapsedString0) { + switch (token) { + case TokenNameisset: + case TokenNameempty: + case TokenNameeval: + case TokenNameinclude: + case TokenNameinclude_once: + case TokenNamerequire: + case TokenNamerequire_once: + internal_functions_in_yacc(); + break; + // | '(' expr ')' + case TokenNameLPAREN: + getNextToken(); + expr(); + if (token == TokenNameRPAREN) { + getNextToken(); } else { - encaps_list(); - if (token != TokenNameEncapsedString0) { - throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )"); - } + throwSyntaxError("')' expected in expression."); } - } finally { - scanner.encapsedStringStack.pop(); + break; + // | T_CLONE expr + // | T_PRINT expr + // | '@' expr + // | '+' expr + // | '-' expr + // | '!' expr + // | '~' expr + // | T_INT_CAST expr + // | T_DOUBLE_CAST expr + // | T_STRING_CAST expr + // | T_ARRAY_CAST expr + // | T_OBJECT_CAST expr + // | T_BOOL_CAST expr + // | T_UNSET_CAST expr + case TokenNameclone: + case TokenNameprint: + case TokenNameAT: + case TokenNamePLUS: + case TokenNameMINUS: + case TokenNameNOT: + case TokenNameTWIDDLE: + case TokenNameintCAST: + case TokenNamedoubleCAST: + case TokenNamestringCAST: + case TokenNamearrayCAST: + case TokenNameobjectCAST: + case TokenNameboolCAST: + case TokenNameunsetCAST: 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) + " )"); + expr(); + break; + case TokenNameexit: + getNextToken(); + exit_expr(); + break; + // scalar: + // T_STRING + //| T_STRING_VARNAME + //| class_constant + //| T_START_HEREDOC encaps_list T_END_HEREDOC + // | '`' 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(); } - } finally { - scanner.encapsedStringStack.pop(); + break; + //| '"' encaps_list '"' + case TokenNameEncapsedString2: + scanner.encapsedStringStack.push(new Character('"')); 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 { + 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()); - common_scalar(); - break; - case TokenNameStringSingleQuote: - expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner - .getCurrentTokenEndPosition()); - common_scalar(); - break; - case TokenNameIntegerLiteral: - case TokenNameDoubleLiteral: - case TokenNameStringInterpolated: - case TokenNameFILE: - case TokenNameLINE: - case TokenNameCLASS_C: - case TokenNameMETHOD_C: - case TokenNameFUNC_C: - common_scalar(); - break; - case TokenNameHEREDOC: - getNextToken(); - break; - case TokenNamearray: - // T_ARRAY '(' array_pair_list ')' - getNextToken(); - if (token == TokenNameLPAREN) { - getNextToken(); - if (token == TokenNameRPAREN) { + } finally { + scanner.encapsedStringStack.pop(); getNextToken(); - break; - } - array_pair_list(); - if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); - } - getNextToken(); - } else { - throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); - } - break; - case TokenNamelist: - // | T_LIST '(' assignment_list ')' '=' expr - getNextToken(); - if (token == TokenNameLPAREN) { - getNextToken(); - assignment_list(); - if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected after 'list' keyword."); - } - getNextToken(); - if (token != TokenNameEQUAL) { - throwSyntaxError("'=' expected after 'list' keyword."); } + break; + case TokenNameStringDoubleQuote: + expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition()); + common_scalar(); + break; + case TokenNameStringSingleQuote: + expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition()); + common_scalar(); + break; + case TokenNameIntegerLiteral: + case TokenNameDoubleLiteral: + case TokenNameStringInterpolated: + case TokenNameFILE: + case TokenNameLINE: + case TokenNameCLASS_C: + case TokenNameMETHOD_C: + case TokenNameFUNC_C: + common_scalar(); + break; + case TokenNameHEREDOC: getNextToken(); - expr(); - } else { - throwSyntaxError("'(' expected after 'list' keyword."); - } - break; - case TokenNamenew: - // | T_NEW class_name_reference ctor_arguments - getNextToken(); - class_name_reference(); - ctor_arguments(); - break; - // | T_INC rw_variable - // | T_DEC rw_variable - case TokenNamePLUS_PLUS: - case TokenNameMINUS_MINUS: - getNextToken(); - rw_variable(); - break; - // | variable '=' expr - // | variable '=' '&' variable - // | variable '=' '&' T_NEW class_name_reference ctor_arguments - // | variable T_PLUS_EQUAL expr - // | variable T_MINUS_EQUAL expr - // | variable T_MUL_EQUAL expr - // | variable T_DIV_EQUAL expr - // | variable T_CONCAT_EQUAL expr - // | variable T_MOD_EQUAL expr - // | variable T_AND_EQUAL expr - // | variable T_OR_EQUAL expr - // | variable T_XOR_EQUAL expr - // | variable T_SL_EQUAL expr - // | variable T_SR_EQUAL expr - // | rw_variable T_INC - // | rw_variable T_DEC - case TokenNameIdentifier: - case TokenNameVariable: - case TokenNameDOLLAR: - variable(); - switch (token) { - case TokenNameEQUAL: + break; + case TokenNamearray: + // T_ARRAY '(' array_pair_list ')' getNextToken(); - if (token == TokenNameAND) { + if (token == TokenNameLPAREN) { getNextToken(); - if (token == TokenNamenew) { - // | variable '=' '&' T_NEW class_name_reference - // ctor_arguments + if (token == TokenNameRPAREN) { getNextToken(); - class_name_reference(); - ctor_arguments(); - } else { - variable(); + break; + } + array_pair_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' or ',' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); } + getNextToken(); } else { + throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); + } + break; + case TokenNamelist: + // | T_LIST '(' assignment_list ')' '=' expr + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + assignment_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after 'list' keyword."); + } + getNextToken(); + if (token != TokenNameEQUAL) { + throwSyntaxError("'=' expected after 'list' keyword."); + } + getNextToken(); expr(); + } else { + throwSyntaxError("'(' expected after 'list' keyword."); } break; - case TokenNamePLUS_EQUAL: - case TokenNameMINUS_EQUAL: - case TokenNameMULTIPLY_EQUAL: - case TokenNameDIVIDE_EQUAL: - case TokenNameDOT_EQUAL: - case TokenNameREMAINDER_EQUAL: - case TokenNameAND_EQUAL: - case TokenNameOR_EQUAL: - case TokenNameXOR_EQUAL: - case TokenNameRIGHT_SHIFT_EQUAL: - case TokenNameLEFT_SHIFT_EQUAL: + case TokenNamenew: + // | T_NEW class_name_reference ctor_arguments getNextToken(); - expr(); + Expression typeRef = class_name_reference(); + ctor_arguments(); + if (typeRef != null) { + expression = typeRef; + } break; + // | T_INC rw_variable + // | T_DEC rw_variable case TokenNamePLUS_PLUS: case TokenNameMINUS_MINUS: getNextToken(); + rw_variable(); + break; + // | variable '=' expr + // | variable '=' '&' variable + // | variable '=' '&' T_NEW class_name_reference ctor_arguments + // | variable T_PLUS_EQUAL expr + // | variable T_MINUS_EQUAL expr + // | variable T_MUL_EQUAL expr + // | variable T_DIV_EQUAL expr + // | variable T_CONCAT_EQUAL expr + // | variable T_MOD_EQUAL expr + // | variable T_AND_EQUAL expr + // | variable T_OR_EQUAL expr + // | variable T_XOR_EQUAL expr + // | variable T_SL_EQUAL expr + // | variable T_SR_EQUAL expr + // | rw_variable T_INC + // | rw_variable T_DEC + case TokenNameIdentifier: + case TokenNameVariable: + case TokenNameDOLLAR: + boolean rememberedVar = false; + Expression lhs = variable(); + switch (token) { + case TokenNameEQUAL: + getNextToken(); + if (token == TokenNameAND) { + getNextToken(); + if (token == TokenNamenew) { + // | variable '=' '&' T_NEW class_name_reference + // ctor_arguments + getNextToken(); + SingleTypeReference classRef = class_name_reference(); + ctor_arguments(); + if (classRef != null) { + if (lhs != null && lhs instanceof FieldReference) { + // example: + // $var = & new Object(); + if (fMethodVariables != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = classRef; + lhsInfo.typeIdentifier = classRef.token; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } + } else { + Expression rhs = variable(); + if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) { + // example: + // $var = &$ref; + if (fMethodVariables != null) { + VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token); + if (rhsInfo != null && rhsInfo.reference != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = rhsInfo.reference; + lhsInfo.typeIdentifier = rhsInfo.typeIdentifier; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } + } + } else { + Expression rhs = expr(); + if (lhs != null && lhs instanceof FieldReference) { + if (rhs != null && rhs instanceof FieldReference) { + // example: + // $var = $ref; + if (fMethodVariables != null) { + VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token); + if (rhsInfo != null && rhsInfo.reference != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = rhsInfo.reference; + lhsInfo.typeIdentifier = rhsInfo.typeIdentifier; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } else if (rhs != null && rhs instanceof SingleTypeReference) { + // example: + // $var = new Object(); + if (fMethodVariables != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = (SingleTypeReference) rhs; + lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } + } + if (rememberedVar == false && lhs != null && lhs instanceof FieldReference) { + if (fMethodVariables != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + } + } + break; + case TokenNamePLUS_EQUAL: + case TokenNameMINUS_EQUAL: + case TokenNameMULTIPLY_EQUAL: + case TokenNameDIVIDE_EQUAL: + case TokenNameDOT_EQUAL: + case TokenNameREMAINDER_EQUAL: + case TokenNameAND_EQUAL: + case TokenNameOR_EQUAL: + case TokenNameXOR_EQUAL: + case TokenNameRIGHT_SHIFT_EQUAL: + case TokenNameLEFT_SHIFT_EQUAL: + getNextToken(); + expr(); + break; + case TokenNamePLUS_PLUS: + case TokenNameMINUS_MINUS: + getNextToken(); + break; + default: + if (!only_variable) { + throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "')."); + } + if (lhs != null) { + expression = lhs; + } + } break; default: - if (!only_variable) { - throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "')."); + if (token != TokenNameINLINE_HTML) { + if (token > TokenNameKEYWORD) { + getNextToken(); + break; + } else { + throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "')."); + } } + return expression; } - break; - default: - if (token != TokenNameINLINE_HTML) { - if (token > TokenNameKEYWORD) { + if (Scanner.TRACE) { + System.out.println("TRACE: expr_without_variable() PART 2"); + } + // | expr T_BOOLEAN_OR expr + // | expr T_BOOLEAN_AND expr + // | expr T_LOGICAL_OR expr + // | expr T_LOGICAL_AND expr + // | expr T_LOGICAL_XOR expr + // | expr '|' expr + // | expr '&' expr + // | expr '^' expr + // | expr '.' expr + // | expr '+' expr + // | expr '-' expr + // | expr '*' expr + // | expr '/' expr + // | expr '%' expr + // | expr T_SL expr + // | expr T_SR expr + // | expr T_IS_IDENTICAL expr + // | expr T_IS_NOT_IDENTICAL expr + // | expr T_IS_EQUAL expr + // | expr T_IS_NOT_EQUAL expr + // | expr '<' expr + // | expr T_IS_SMALLER_OR_EQUAL expr + // | expr '>' expr + // | expr T_IS_GREATER_OR_EQUAL expr + while (true) { + switch (token) { + case TokenNameOR_OR: getNextToken(); + expression = new OR_OR_Expression(expression, expr(), token); break; - } else { - throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "')."); + case TokenNameAND_AND: + getNextToken(); + expression = new AND_AND_Expression(expression, expr(), token); + break; + case TokenNameEQUAL_EQUAL: + getNextToken(); + expression = new EqualExpression(expression, expr(), token); + break; + case TokenNameand: + case TokenNameor: + case TokenNamexor: + case TokenNameAND: + case TokenNameOR: + case TokenNameXOR: + case TokenNameDOT: + case TokenNamePLUS: + case TokenNameMINUS: + case TokenNameMULTIPLY: + case TokenNameDIVIDE: + case TokenNameREMAINDER: + case TokenNameLEFT_SHIFT: + case TokenNameRIGHT_SHIFT: + case TokenNameEQUAL_EQUAL_EQUAL: + case TokenNameNOT_EQUAL_EQUAL: + case TokenNameNOT_EQUAL: + case TokenNameLESS: + case TokenNameLESS_EQUAL: + case TokenNameGREATER: + case TokenNameGREATER_EQUAL: + getNextToken(); + expression = new BinaryExpression(expression, expr(), token); + break; + // | expr T_INSTANCEOF class_name_reference + // | expr '?' expr ':' expr + case TokenNameinstanceof: + getNextToken(); + TypeReference classRef = class_name_reference(); + expression = new InstanceOfExpression(expression, classRef, OperatorIds.INSTANCEOF); + expression.sourceStart = exprSourceStart; + expression.sourceEnd = scanner.getCurrentTokenEndPosition(); + break; + case TokenNameQUESTION: + getNextToken(); + Expression valueIfTrue = expr(); + if (token != TokenNameCOLON) { + throwSyntaxError("':' expected in conditional expression."); + } + getNextToken(); + Expression valueIfFalse = expr(); + + expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse); + break; + default: + return expression; } } - return expression; - } - if (Scanner.TRACE) { - System.out.println("TRACE: expr_without_variable() PART 2"); - } - // | expr T_BOOLEAN_OR expr - // | expr T_BOOLEAN_AND expr - // | expr T_LOGICAL_OR expr - // | expr T_LOGICAL_AND expr - // | expr T_LOGICAL_XOR expr - // | expr '|' expr - // | expr '&' expr - // | expr '^' expr - // | expr '.' expr - // | expr '+' expr - // | expr '-' expr - // | expr '*' expr - // | expr '/' expr - // | expr '%' expr - // | expr T_SL expr - // | expr T_SR expr - // | expr T_IS_IDENTICAL expr - // | expr T_IS_NOT_IDENTICAL expr - // | expr T_IS_EQUAL expr - // | expr T_IS_NOT_EQUAL expr - // | expr '<' expr - // | expr T_IS_SMALLER_OR_EQUAL expr - // | expr '>' expr - // | expr T_IS_GREATER_OR_EQUAL expr - while (true) { - switch (token) { - case TokenNameOR_OR: - getNextToken(); - expression = new OR_OR_Expression(expression, expr(), token); - break; - case TokenNameAND_AND: - getNextToken(); - expression = new AND_AND_Expression(expression, expr(), token); - break; - case TokenNameEQUAL_EQUAL: - getNextToken(); - expression = new EqualExpression(expression, expr(), token); - break; - case TokenNameand: - case TokenNameor: - case TokenNamexor: - case TokenNameAND: - case TokenNameOR: - case TokenNameXOR: - case TokenNameDOT: - case TokenNamePLUS: - case TokenNameMINUS: - case TokenNameMULTIPLY: - case TokenNameDIVIDE: - case TokenNameREMAINDER: - case TokenNameLEFT_SHIFT: - case TokenNameRIGHT_SHIFT: - case TokenNameEQUAL_EQUAL_EQUAL: - case TokenNameNOT_EQUAL_EQUAL: - case TokenNameNOT_EQUAL: - case TokenNameLESS: - case TokenNameLESS_EQUAL: - case TokenNameGREATER: - case TokenNameGREATER_EQUAL: - getNextToken(); - expression = new BinaryExpression(expression, expr(), token); - break; - // | expr T_INSTANCEOF class_name_reference - // | expr '?' expr ':' expr - case TokenNameinstanceof: - getNextToken(); - class_name_reference(); - // TODO use InstanceofExpression - expression = new Expression(); - expression.sourceStart = exprSourceStart; - expression.sourceEnd = scanner.getCurrentTokenEndPosition(); - break; - case TokenNameQUESTION: + } catch (SyntaxError e) { + // try to find next token after expression with errors: + if (token == TokenNameSEMICOLON) { getNextToken(); - Expression valueIfTrue = expr(); - if (token != TokenNameCOLON) { - throwSyntaxError("':' expected in conditional expression."); - } + return expression; + } + if (token == TokenNameRBRACE || token == TokenNameRPAREN || token == TokenNameRBRACKET) { getNextToken(); - Expression valueIfFalse = expr(); - - expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse); - break; - default: return expression; } + throw e; } } - private void class_name_reference() { + private SingleTypeReference class_name_reference() { // class_name_reference: // T_STRING //| dynamic_class_name_reference + SingleTypeReference ref = null; if (Scanner.TRACE) { System.out.println("TRACE: class_name_reference()"); } if (token == TokenNameIdentifier) { + ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); getNextToken(); } else { + ref = null; dynamic_class_name_reference(); } + return ref; } private void dynamic_class_name_reference() { @@ -2602,7 +2675,7 @@ public class Parser //extends PHPParserSuperclass // } // } while (true); // } - private void variable_without_objects() { + private Expression variable_without_objects() { // variable_without_objects: // reference_variable // | simple_indirect_reference reference_variable @@ -2612,10 +2685,10 @@ public class Parser //extends PHPParserSuperclass while (token == TokenNameDOLLAR) { getNextToken(); } - reference_variable(); + return reference_variable(); } - private void function_call() { + private Expression function_call() { // function_call: // T_STRING '(' function_call_parameter_list ')' //| class_constant '(' function_call_parameter_list ')' @@ -2625,6 +2698,7 @@ public class Parser //extends PHPParserSuperclass char[] ident = null; int startPos = 0; int endPos = 0; + Expression ref = null; if (Scanner.TRACE) { System.out.println("TRACE: function_call()"); } @@ -2649,7 +2723,7 @@ public class Parser //extends PHPParserSuperclass break; } } else { - variable_without_objects(); + ref = variable_without_objects(); } if (token != TokenNameLPAREN) { if (defineName != null) { @@ -2679,13 +2753,13 @@ public class Parser //extends PHPParserSuperclass } } // TODO is this ok ? - return; + return ref; // throwSyntaxError("'(' expected in function call."); } getNextToken(); if (token == TokenNameRPAREN) { getNextToken(); - return; + return ref; } non_empty_function_call_parameter_list(); if (token != TokenNameRPAREN) { @@ -2698,6 +2772,7 @@ public class Parser //extends PHPParserSuperclass throwSyntaxError("')' expected in function call (" + functionName + ")."); } getNextToken(); + return ref; } // private void function_call_parameter_list() { @@ -2759,7 +2834,7 @@ public class Parser //extends PHPParserSuperclass variable_without_objects(); } - private void base_variable_with_function_calls() { + private Expression base_variable_with_function_calls() { // base_variable_with_function_calls: // base_variable //| function_call @@ -2781,17 +2856,18 @@ public class Parser //extends PHPParserSuperclass // scanner.phpMode = true; // } // if (functionCall) { - function_call(); + return function_call(); // } else { // base_variable(); // } } - private void base_variable() { + private Expression base_variable() { // base_variable: // reference_variable // | simple_indirect_reference reference_variable // | static_member + Expression ref = null; if (Scanner.TRACE) { System.out.println("TRACE: base_variable()"); } @@ -2803,6 +2879,7 @@ public class Parser //extends PHPParserSuperclass } reference_variable(); } + return ref; } // private void simple_indirect_reference() { @@ -2810,17 +2887,19 @@ public class Parser //extends PHPParserSuperclass // // '$' // //| simple_indirect_reference '$' // } - private void reference_variable() { + private Expression reference_variable() { // reference_variable: // reference_variable '[' dim_offset ']' // | reference_variable '{' expr '}' // | compound_variable + Expression ref = null; if (Scanner.TRACE) { System.out.println("TRACE: reference_variable()"); } - compound_variable(); + ref = compound_variable(); while (true) { if (token == TokenNameLBRACE) { + ref = null; getNextToken(); expr(); if (token != TokenNameRBRACE) { @@ -2828,6 +2907,7 @@ public class Parser //extends PHPParserSuperclass } getNextToken(); } else if (token == TokenNameLBRACKET) { + ref = null; getNextToken(); if (token != TokenNameRBRACKET) { expr(); @@ -2841,9 +2921,10 @@ public class Parser //extends PHPParserSuperclass break; } } + return ref; } - private void compound_variable() { + private Expression compound_variable() { // compound_variable: // T_VARIABLE // | '$' '{' expr '}' @@ -2851,14 +2932,17 @@ public class Parser //extends PHPParserSuperclass System.out.println("TRACE: compound_variable()"); } if (token == TokenNameVariable) { + FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); getNextToken(); + return ref; } else { // because of simple_indirect_reference while (token == TokenNameDOLLAR) { getNextToken(); } if (token != TokenNameLBRACE) { - throwSyntaxError("'{' expected after compound variable token '$'."); + reportSyntaxError("'{' expected after compound variable token '$'."); + return null; } getNextToken(); expr(); @@ -2867,6 +2951,7 @@ public class Parser //extends PHPParserSuperclass } getNextToken(); } + return null; } // private void dim_offset() { @@ -2960,44 +3045,20 @@ public class Parser //extends PHPParserSuperclass variable(); } - private void variable() { + private Expression variable() { // variable: // base_variable_with_function_calls T_OBJECT_OPERATOR // object_property method_or_not variable_properties // | base_variable_with_function_calls - base_variable_with_function_calls(); + Expression ref = base_variable_with_function_calls(); if (token == TokenNameMINUS_GREATER) { + ref = null; getNextToken(); object_property(); method_or_not(); variable_properties(); } - // if (token == TokenNameDOLLAR_LBRACE) { - // getNextToken(); - // expr(); - // ; - // if (token != TokenNameRBRACE) { - // throwSyntaxError("'}' expected after indirect variable token '${'."); - // } - // getNextToken(); - // } else { - // if (token == TokenNameVariable) { - // getNextToken(); - // if (token == TokenNameLBRACKET) { - // getNextToken(); - // expr(); - // if (token != TokenNameRBRACKET) { - // throwSyntaxError("']' expected in variable-list."); - // } - // getNextToken(); - // } else if (token == TokenNameEQUAL) { - // getNextToken(); - // static_scalar(); - // } - // } else { - // throwSyntaxError("$-variable expected in variable-list."); - // } - // } + return ref; } private void variable_properties() { @@ -3307,7 +3368,6 @@ public class Parser //extends PHPParserSuperclass private void internal_functions_in_yacc() { // int start = 0; - ImportReference impt = null; switch (token) { case TokenNameisset: // T_ISSET '(' isset_variables ')' @@ -3337,11 +3397,11 @@ public class Parser //extends PHPParserSuperclass break; case TokenNameinclude: //T_INCLUDE expr - checkFileName(token, impt); + checkFileName(token); break; case TokenNameinclude_once: // T_INCLUDE_ONCE expr - checkFileName(token, impt); + checkFileName(token); break; case TokenNameeval: // T_EVAL '(' expr ')' @@ -3358,16 +3418,16 @@ public class Parser //extends PHPParserSuperclass break; case TokenNamerequire: //T_REQUIRE expr - checkFileName(token, impt); + checkFileName(token); break; case TokenNamerequire_once: // T_REQUIRE_ONCE expr - checkFileName(token, impt); + checkFileName(token); break; } } - private void checkFileName(int includeToken, ImportReference impt) { + private void checkFileName(int includeToken) { // expr int start = scanner.getCurrentTokenStartPosition(); boolean hasLPAREN = false; @@ -3384,7 +3444,19 @@ public class Parser //extends PHPParserSuperclass throwSyntaxError("')' expected for keyword '" + scanner.toStringAction(includeToken) + "'"); } } - impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false); + char[] currTokenSource = scanner.getCurrentTokenSource(start); + IFile file = null; + if (scanner.compilationUnit != null) { + IResource resource = scanner.compilationUnit.getResource(); + if (resource != null && resource instanceof IFile) { + file = (IFile) resource; + } + } + char[][] tokens; + tokens = new char[1][]; + tokens[0] = currTokenSource; + + ImportReference impt = new ImportReference(tokens, currTokenSource, start, scanner.getCurrentTokenEndPosition(), false); impt.declarationSourceEnd = impt.sourceEnd; impt.declarationEnd = impt.declarationSourceEnd; //endPosition is just before the ; @@ -3409,26 +3481,32 @@ public class Parser //extends PHPParserSuperclass // assuming external include location return; } - if (scanner.compilationUnit != null) { - IResource resource = scanner.compilationUnit.getResource(); - // java.io.File f = new java.io.File(new String(compilationUnit.getFileName())); - // System.out.println(expression.toStringExpression()); - // } - if (resource != null && resource instanceof IFile) { - // check the filename: - // System.out.println(new String(compilationUnit.getFileName())+" - "+ expression.toStringExpression()); - IProject project = resource.getProject(); - if (project != null) { - IPath path = PHPFileUtil.determineFilePath(includeNameString, resource, project); - - if (path == null) { - // reportSyntaxError("File: " + expression.toStringExpression() + " doesn't exist in project: " - // + project.getLocation().toString(), literal.sourceStart, literal.sourceEnd); - String[] args = { expression.toStringExpression(), project.getLocation().toString() }; - problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext, - compilationUnit.compilationResult); - } else { - impt.setFile( PHPFileUtil.createFile(path, project) ); + if (file != null) { + // check the filename: + // System.out.println(new String(compilationUnit.getFileName())+" - "+ expression.toStringExpression()); + IProject project = file.getProject(); + if (project != null) { + 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); + 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)); + } catch (Exception e) { + // the file is outside of the workspace } } } @@ -3596,7 +3674,7 @@ public class Parser //extends PHPParserSuperclass } non_empty_static_array_pair_list(); if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected after keyword 'array'"); + throwSyntaxError("')' or ',' expected after keyword 'array'"); } getNextToken(); break; @@ -3754,6 +3832,13 @@ public class Parser //extends PHPParserSuperclass protected int nestedType, dimensions; + //variable set stack + final static int VariableStackIncrement = 10; + + HashMap fTypeVariables = null; + + HashMap fMethodVariables = null; + //ast stack final static int AstStackIncrement = 100; @@ -4231,4 +4316,31 @@ public class Parser //extends PHPParserSuperclass // modifiersFlag(int) this.scanner.commentPtr = -1; } + + protected void consumePackageDeclarationName(IFile file) { + // create a package name similar to java package names + String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString(); + String filePath = file.getRawLocation().toString(); + 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 + .splitOn('/', filePath.toCharArray(), projectPath.length() + 1, filePath.length() - fileExtensionLength); + } else { + String name = file.getName(); + tokens = new char[1][]; + tokens[0] = name.substring(0, ext.length() - fileExtensionLength).toCharArray(); + } + + this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true); + + impt.declarationSourceStart = 0; + impt.declarationSourceEnd = 0; + impt.declarationEnd = 0; + //endPosition is just before the ; + + } } \ No newline at end of file