X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index b7a1353..08ba9c4 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 @@ -14,6 +14,33 @@ import java.util.HashSet; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression; +import net.sourceforge.phpdt.internal.compiler.ast.ASTNode; +import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Block; +import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement; +import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement; +import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Expression; +import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.FieldReference; +import net.sourceforge.phpdt.internal.compiler.ast.IfStatement; +import net.sourceforge.phpdt.internal.compiler.ast.ImportReference; +import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression; +import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression; +import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds; +import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpdt.internal.compiler.ast.Statement; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ; +import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.TypeReference; import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions; import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; @@ -21,43 +48,17 @@ import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; import net.sourceforge.phpdt.internal.compiler.util.Util; -import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpdt.internal.core.util.PHPFileUtil; import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; -import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression; -import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode; -import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression; -import net.sourceforge.phpeclipse.internal.compiler.ast.Block; -import net.sourceforge.phpeclipse.internal.compiler.ast.BreakStatement; -import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression; -import net.sourceforge.phpeclipse.internal.compiler.ast.ContinueStatement; -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.ReturnStatement; -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 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 implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation { +public class Parser implements ITerminalSymbols, CompilerModifiers, + ParserBasicInformation { protected final static int StackIncrement = 255; protected int stateStackTop; @@ -92,44 +93,47 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI this.initializeScanner(); } - public void setFileToParse(IFile fileToParse) { - this.token = TokenNameEOF; - this.initializeScanner(); - } +// public void setFileToParse(IFile fileToParse) { +// this.token = TokenNameEOF; +// this.initializeScanner(); +// } /** * ClassDeclaration Constructor. - * + * * @param s * @param sess - * Description of Parameter + * Description of Parameter * @see */ - public Parser(IFile fileToParse) { - // if (keywordMap == null) { - // keywordMap = new HashMap(); - // for (int i = 0; i < PHP_KEYWORS.length; i++) { - // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i])); - // } - // } - // this.currentPHPString = 0; - // PHPParserSuperclass.fileToParse = fileToParse; - // this.phpList = null; - this.includesList = null; - // this.str = ""; - this.token = TokenNameEOF; - // this.chIndx = 0; - // this.rowCount = 1; - // this.columnCount = 0; - // this.phpEnd = false; - // getNextToken(); - this.initializeScanner(); - } +// public Parser(IFile fileToParse) { +// // if (keywordMap == null) { +// // keywordMap = new HashMap(); +// // for (int i = 0; i < PHP_KEYWORS.length; i++) { +// // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i])); +// // } +// // } +// // this.currentPHPString = 0; +// // PHPParserSuperclass.fileToParse = fileToParse; +// // this.phpList = null; +// this.includesList = null; +// // this.str = ""; +// this.token = TokenNameEOF; +// // this.chIndx = 0; +// // this.rowCount = 1; +// // this.columnCount = 0; +// // this.phpEnd = false; +// // getNextToken(); +// this.initializeScanner(); +// } 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.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 */); } /** @@ -142,18 +146,21 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * This method will throw the SyntaxError. It will add the good lines and * columns to the Error - * + * * @param error - * the error message + * the error message * @throws SyntaxError - * the error raised + * the error raised */ private void throwSyntaxError(String error) { int problemStartPosition = scanner.getCurrentTokenStartPosition(); int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1; - if (scanner.source.length <= problemEndPosition && problemEndPosition > 0) { + if (scanner.source.length <= problemEndPosition + && problemEndPosition > 0) { problemEndPosition = scanner.source.length - 1; - if (problemStartPosition > 0 && problemStartPosition >= problemEndPosition && problemEndPosition > 0) { + if (problemStartPosition > 0 + && problemStartPosition >= problemEndPosition + && problemEndPosition > 0) { problemStartPosition = problemEndPosition - 1; } } @@ -163,18 +170,20 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * This method will throw the SyntaxError. It will add the good lines and * columns to the Error - * + * * @param error - * the error message + * the error message * @throws SyntaxError - * the error raised + * the error raised */ // private void throwSyntaxError(String error, int startRow) { // throw new SyntaxError(startRow, 0, " ", error); // } - private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) { + private void throwSyntaxError(String error, int problemStartPosition, + int problemEndPosition) { if (referenceContext != null) { - problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + problemReporter.phpParsingError(new String[] { error }, + problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult); } throw new SyntaxError(1, 0, " ", error); @@ -186,9 +195,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI reportSyntaxError(error, problemStartPosition, problemEndPosition + 1); } - private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { + private void reportSyntaxError(String error, int problemStartPosition, + int problemEndPosition) { if (referenceContext != null) { - problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + problemReporter.phpParsingError(new String[] { error }, + problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult); } } @@ -210,8 +221,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI token = scanner.getNextToken(); if (Scanner.DEBUG) { int currentEndPosition = scanner.getCurrentTokenEndPosition(); - int currentStartPosition = scanner.getCurrentTokenStartPosition(); - System.out.print(currentStartPosition + "," + currentEndPosition + ": "); + int currentStartPosition = scanner + .getCurrentTokenStartPosition(); + System.out.print(currentStartPosition + "," + + currentEndPosition + ": "); System.out.println(scanner.toStringAction(token)); } } catch (InvalidInputException e) { @@ -246,7 +259,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI initialize(phpMode, null); } - protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) { + protected void initialize(boolean phpMode, + IdentifierIndexManager indexManager) { compilationUnit = null; referenceContext = null; this.includesList = new ArrayList(); @@ -301,7 +315,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } if (token != TokenNameEOF) { if (token == TokenNameERROR) { - throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")"); + throwSyntaxError("Scanner error (Found unknown token: " + + scanner.toStringAction(token) + ")"); } if (token == TokenNameRPAREN) { throwSyntaxError("Too many closing ')'; end-of-file not reached."); @@ -357,7 +372,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI this.fMethodVariables = variables; MethodDeclaration methodDecl = new MethodDeclaration(null); - methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + methodDecl.declarationSourceStart = scanner + .getCurrentTokenStartPosition(); methodDecl.modifiers = this.modifiers; methodDecl.type = MethodDeclaration.METHOD_DEFINITION; try { @@ -367,7 +383,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return; } finally { int sourceEnd = methodDecl.sourceEnd; - if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + if (sourceEnd <= 0 + || methodDecl.declarationSourceStart > sourceEnd) { sourceEnd = methodDecl.declarationSourceStart + 1; } methodDecl.sourceEnd = sourceEnd; @@ -386,7 +403,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // 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$ + // System.out.println("----------------------------------"); + // //$NON-NLS-1$ // } // } else { if (diet & VERBOSE_RECOVERY) { @@ -397,13 +415,18 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } // } if (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + compilationUnit.compilationResult.lineSeparatorPositions = scanner + .getLineEnds(); } if (scanner.taskTags != null) { for (int i = 0; i < scanner.foundTaskCount; i++) { - problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]), - scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]), - scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]); + problemReporter().task( + new String(scanner.foundTaskTags[i]), + new String(scanner.foundTaskMessages[i]), + scanner.foundTaskPriorities[i] == null ? null + : new String(scanner.foundTaskPriorities[i]), + scanner.foundTaskPositions[i][0], + scanner.foundTaskPositions[i][1]); } } compilationUnit.imports = new ImportReference[includesList.size()]; @@ -422,16 +445,38 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI try { statement = statement(); blockStatements.add(statement); + if (token == TokenNameEOF) { + return null; + } if (branchStatement && statement != null) { - // reportSyntaxError("Unreachable code", statement.sourceStart, + // reportSyntaxError("Unreachable code", + // statement.sourceStart, // statement.sourceEnd); - problemReporter.unreachableCode(new String(scanner.getCurrentIdentifierSource()), statement.sourceStart, - statement.sourceEnd, referenceContext, compilationUnit.compilationResult); + if (!(statement instanceof BreakStatement)) { + /* + * don't give an error for break statement following + * return statement Technically it's unreachable code, + * but in switch-case it's recommended to avoid + * accidental fall-through later when editing the code + */ + 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) - || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) - || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) { + 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 createBlock(blockStart, blockStatements); } branchStatement = checkUnreachableStatements(statement); @@ -445,18 +490,44 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } 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)) { + 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 createBlock(blockStart, blockStatements); } - 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) { + if (token == TokenNameif || token == TokenNameswitch + || token == TokenNamefor + || token == TokenNamewhile + || token == TokenNamedo + || token == TokenNameforeach + || token == TokenNamecontinue + || token == TokenNamebreak + || token == TokenNamereturn + || token == TokenNameexit + || token == TokenNameecho + || token == TokenNameECHO_INVISIBLE + || 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)); @@ -478,9 +549,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI * @return */ private boolean checkUnreachableStatements(Statement statement) { - if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) { + if (statement instanceof ReturnStatement + || statement instanceof ContinueStatement + || statement instanceof BreakStatement) { return true; - } else if (statement instanceof IfStatement && ((IfStatement) statement).checkUnreachable) { + } else if (statement instanceof IfStatement + && ((IfStatement) statement).checkUnreachable) { return true; } return false; @@ -541,7 +615,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("')' expected after 'if' condition."); } // create basic IfStatement - IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1); + IfStatement ifStatement = new IfStatement(expression, null, null, + sourceStart, -1); if (token == TokenNameCOLON) { getNextToken(); ifStatementColon(ifStatement); @@ -748,33 +823,27 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); } return statement; - } else if (token == TokenNameINLINE_HTML) { - if (scanner.phpExpressionTag) { - // start of block + } else if (token == TokenNameECHO_INVISIBLE) { + // 0-length token directly after PHP short tag <?= + getNextToken(); + expressionList(); + if (token == TokenNameSEMICOLON) { getNextToken(); - expr(); - if (token == TokenNameSEMICOLON) { - getNextToken(); - } + // if (token != TokenNameINLINE_HTML) { + // // TODO should this become a configurable warning? + // reportSyntaxError("Probably '?>' expected after PHP short tag + // expression (only the first expression will be echoed)."); + // } + } else { if (token != TokenNameINLINE_HTML) { - throwSyntaxError("Missing '?>' for open PHP expression block (' sourceEnd) { + if (sourceEnd <= 0 + || methodDecl.declarationSourceStart > sourceEnd) { sourceEnd = methodDecl.declarationSourceStart + 1; } methodDecl.declarationSourceEnd = sourceEnd; @@ -902,14 +974,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("';' expected after 'throw' exxpression."); } return statement; - } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) { + } else if (token == TokenNamefinal || token == TokenNameabstract + || token == TokenNameclass || token == TokenNameinterface) { try { - TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); - typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); - typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + 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); + typeDecl.superclass = new SingleTypeReference( + TypeConstants.OBJECT, 0); compilationUnit.types.add(typeDecl); pushOnAstStack(typeDecl); unticked_class_declaration_statement(typeDecl); @@ -941,10 +1018,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return statement; } else { if (token == TokenNameRBRACE) { - reportSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); + 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) + ")"); + throwSyntaxError("';' expected after expression (Found token: " + + scanner.toStringAction(token) + ")"); } getNextToken(); } @@ -1065,8 +1144,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | '$' '{' expr '}' if (token == TokenNameVariable) { if (fMethodVariables != null) { - VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR); - fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + VariableInfo info = new VariableInfo(scanner + .getCurrentTokenStartPosition(), + VariableInfo.LEVEL_GLOBAL_VAR); + fMethodVariables.put(new String(scanner + .getCurrentIdentifierSource()), info); } addVariableSet(set); getNextToken(); @@ -1095,8 +1177,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (true) { if (token == TokenNameVariable) { if (fMethodVariables != null) { - VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR); - fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + VariableInfo info = new VariableInfo(scanner + .getCurrentTokenStartPosition(), + VariableInfo.LEVEL_STATIC_VAR); + fMethodVariables.put(new String(scanner + .getCurrentIdentifierSource()), info); } addVariableSet(set); getNextToken(); @@ -1154,9 +1239,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { typeDecl.name = scanner.getCurrentIdentifierSource(); if (token > TokenNameKEYWORD) { - problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), - scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); - // throwSyntaxError("Don't use a keyword for interface declaration [" + problemReporter.phpKeywordWarning(new String[] { scanner + .toStringAction(token) }, scanner + .getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition(), referenceContext, + compilationUnit.compilationResult); + // throwSyntaxError("Don't use a keyword for interface + // declaration [" // + scanner.toStringAction(token) + "].", // typeDecl.sourceStart, typeDecl.sourceEnd); } @@ -1164,7 +1253,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI interface_extends_list(typeDecl); } else { typeDecl.name = new char[] { ' ' }; - throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd); + throwSyntaxError( + "Interface name expected after keyword 'interface'.", + typeDecl.sourceStart, typeDecl.sourceEnd); return; } } else { @@ -1180,9 +1271,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { typeDecl.name = scanner.getCurrentIdentifierSource(); if (token > TokenNameKEYWORD) { - problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), - scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); - // throwSyntaxError("Don't use a keyword for class declaration [" + + problemReporter.phpKeywordWarning(new String[] { scanner + .toStringAction(token) }, scanner + .getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition(), referenceContext, + compilationUnit.compilationResult); + // throwSyntaxError("Don't use a keyword for class + // declaration [" + // scanner.toStringAction(token) + "].", // typeDecl.sourceStart, typeDecl.sourceEnd); } @@ -1191,7 +1286,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // /* empty */ // | T_EXTENDS fully_qualified_class_name if (token == TokenNameextends) { - interface_extends_list(typeDecl); + class_extends_list(typeDecl); // getNextToken(); // if (token != TokenNameIdentifier) { // throwSyntaxError("Class name expected after keyword @@ -1203,7 +1298,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI implements_list(typeDecl); } else { typeDecl.name = new char[] { ' ' }; - throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd); + throwSyntaxError("Class name expected after keyword 'class'.", + typeDecl.sourceStart, typeDecl.sourceEnd); return; } } @@ -1219,7 +1315,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } if (token == TokenNameRBRACE) { - typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + typeDecl.declarationSourceEnd = scanner + .getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected at end of class body."); @@ -1273,7 +1370,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | T_EXTENDS interface_list if (token == TokenNameextends) { getNextToken(); - interface_list(); + interface_list(typeDecl); + } + } + + private void class_extends_list(TypeDeclaration typeDecl) { + // /* empty */ + // | T_EXTENDS interface_list + if (token == TokenNameextends) { + getNextToken(); + class_list(typeDecl); } } @@ -1282,11 +1388,38 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | T_IMPLEMENTS interface_list if (token == TokenNameimplements) { getNextToken(); - interface_list(); + interface_list(typeDecl); } } - private void interface_list() { + private void class_list(TypeDeclaration typeDecl) { + // class_list: + // fully_qualified_class_name + do { + if (token == TokenNameIdentifier) { + //char[] ident = scanner.getCurrentIdentifierSource(); + // TODO make this code working better: + // SingleTypeReference ref = + // ParserUtil.getTypeReference(scanner, + // includesList, ident); + // if (ref != null) { + // typeDecl.superclass = ref; + // } + getNextToken(); + } else { + throwSyntaxError("Classname expected after keyword 'extends'."); + } + if (token == TokenNameCOMMA) { + reportSyntaxError("No multiple inheritance allowed. Expected token 'implements' or '{'."); + getNextToken(); + continue; + } else { + break; + } + } while (true); + } + + private void interface_list(TypeDeclaration typeDecl) { // interface_list: // fully_qualified_class_name // | interface_list ',' fully_qualified_class_name @@ -1294,7 +1427,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameIdentifier) { getNextToken(); } else { - throwSyntaxError("Interface name expected after keyword 'implements'."); + throwSyntaxError("Interfacename expected after keyword 'implements'."); } if (token != TokenNameCOMMA) { return; @@ -1324,8 +1457,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI do { try { class_statement(list); - if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic - || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar + if (token == TokenNamepublic || token == TokenNameprotected + || token == TokenNameprivate + || token == TokenNamestatic + || token == TokenNameabstract + || token == TokenNamefinal + || token == TokenNamefunction || token == TokenNamevar || token == TokenNameconst) { continue; } @@ -1343,8 +1480,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // 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 + if (token == TokenNamepublic + || token == TokenNameprotected + || token == TokenNameprivate + || token == TokenNamestatic + || token == TokenNameabstract + || token == TokenNamefinal + || token == TokenNamefunction + || token == TokenNamevar || token == TokenNameconst) { break; } @@ -1372,8 +1515,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNamevar) { checkAndSetModifiers(AccPublic); - problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), - referenceContext, compilationUnit.compilationResult); + problemReporter.phpVarDeprecatedWarning(scanner + .getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition(), referenceContext, + compilationUnit.compilationResult); getNextToken(); class_variable_declaration(declarationSourceStart, list); } else if (token == TokenNameconst) { @@ -1389,8 +1534,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (!hasModifiers) { checkAndSetModifiers(AccPublic); } - MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult); - methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + MethodDeclaration methodDecl = new MethodDeclaration( + this.compilationUnit.compilationResult); + methodDecl.declarationSourceStart = scanner + .getCurrentTokenStartPosition(); methodDecl.modifiers = this.modifiers; methodDecl.type = MethodDeclaration.METHOD_DEFINITION; try { @@ -1398,7 +1545,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI functionDefinition(methodDecl); } finally { int sourceEnd = methodDecl.sourceEnd; - if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + if (sourceEnd <= 0 + || methodDecl.declarationSourceStart > sourceEnd) { sourceEnd = methodDecl.declarationSourceStart + 1; } methodDecl.declarationSourceEnd = sourceEnd; @@ -1413,7 +1561,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } - private void class_constant_declaration(int declarationSourceStart, ArrayList list) { + private void class_constant_declaration(int declarationSourceStart, + ArrayList list) { // class_constant_declaration ',' T_STRING '=' static_scalar // | T_CONST T_STRING '=' static_scalar if (token != TokenNameconst) { @@ -1425,11 +1574,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token != TokenNameIdentifier) { throwSyntaxError("Identifier expected in class const declaration."); } - FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner - .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition()); + FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner + .getCurrentIdentifierSource(), scanner + .getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition()); fieldDeclaration.modifiers = this.modifiers; fieldDeclaration.declarationSourceStart = declarationSourceStart; - fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + fieldDeclaration.declarationSourceEnd = scanner + .getCurrentTokenEndPosition(); fieldDeclaration.modifiersSourceStart = declarationSourceStart; // fieldDeclaration.type list.add(fieldDeclaration); @@ -1516,7 +1668,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return foundToken; } - private void class_variable_declaration(int declarationSourceStart, ArrayList list) { + private void class_variable_declaration(int declarationSourceStart, + ArrayList list) { // class_variable_declaration: // class_variable_declaration ',' T_VARIABLE // | class_variable_declaration ',' T_VARIABLE '=' static_scalar @@ -1526,18 +1679,24 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI do { if (token == TokenNameVariable) { classVariable = scanner.getCurrentIdentifierSource(); - // indexManager.addIdentifierInformation('v', classVariable, buf, -1, + // indexManager.addIdentifierInformation('v', classVariable, + // buf, -1, // -1); - FieldDeclaration fieldDeclaration = new FieldDeclaration(classVariable, scanner.getCurrentTokenStartPosition(), scanner - .getCurrentTokenEndPosition()); + FieldDeclaration fieldDeclaration = new FieldDeclaration( + classVariable, scanner.getCurrentTokenStartPosition(), + scanner.getCurrentTokenEndPosition()); fieldDeclaration.modifiers = this.modifiers; fieldDeclaration.declarationSourceStart = declarationSourceStart; - fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + fieldDeclaration.declarationSourceEnd = scanner + .getCurrentTokenEndPosition(); fieldDeclaration.modifiersSourceStart = declarationSourceStart; list.add(fieldDeclaration); if (fTypeVariables != null) { - VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_CLASS_UNIT); - fTypeVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + VariableInfo info = new VariableInfo(scanner + .getCurrentTokenStartPosition(), + VariableInfo.LEVEL_CLASS_UNIT); + fTypeVariables.put(new String(scanner + .getCurrentIdentifierSource()), info); } getNextToken(); if (token == TokenNameEQUAL) { @@ -1576,8 +1735,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl }; } else { AbstractMethodDeclaration[] newMethods; - System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 0, - typeDecl.methods.length); + System + .arraycopy( + typeDecl.methods, + 0, + newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], + 0, typeDecl.methods.length); newMethods[typeDecl.methods.length] = methodDecl; typeDecl.methods = newMethods; } @@ -1593,8 +1756,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI functionDeclarator(methodDecl); if (token == TokenNameSEMICOLON) { if (!isAbstract) { - methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; - throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector)); + methodDecl.sourceEnd = scanner + .getCurrentTokenStartPosition() - 1; + throwSyntaxError("Body declaration expected for method: " + + new String(methodDecl.selector)); } getNextToken(); return; @@ -1617,8 +1782,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (Scanner.isIdentifierOrKeyword(token)) { methodDecl.selector = scanner.getCurrentIdentifierSource(); if (token > TokenNameKEYWORD) { - problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), - scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); + problemReporter.phpKeywordWarning(new String[] { scanner + .toStringAction(token) }, scanner + .getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition(), referenceContext, + compilationUnit.compilationResult); } getNextToken(); if (token == TokenNameLPAREN) { @@ -1651,7 +1819,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI non_empty_parameter_list(methodDecl, true); } - private void non_empty_parameter_list(MethodDeclaration methodDecl, 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 @@ -1663,10 +1832,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' // static_scalar char[] typeIdentifier = null; - if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) { + if (token == TokenNameIdentifier || token == TokenNamearray + || token == TokenNameVariable || token == TokenNameAND) { HashSet set = peekVariableSet(); while (true) { - if (token == TokenNameIdentifier) { + if (token == TokenNameIdentifier || token == TokenNamearray) {// feature + // req. + // #1254275 typeIdentifier = scanner.getCurrentIdentifierSource(); getNextToken(); } @@ -1677,12 +1849,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (fMethodVariables != null) { VariableInfo info; if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) { - info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_FUNCTION_DEFINITION); + info = new VariableInfo(scanner + .getCurrentTokenStartPosition(), + VariableInfo.LEVEL_FUNCTION_DEFINITION); } else { - info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_METHOD_DEFINITION); + info = new VariableInfo(scanner + .getCurrentTokenStartPosition(), + VariableInfo.LEVEL_METHOD_DEFINITION); } info.typeIdentifier = typeIdentifier; - fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + fMethodVariables.put(new String(scanner + .getCurrentIdentifierSource()), info); } addVariableSet(set); getNextToken(); @@ -1705,10 +1882,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } - private void optional_class_type() { - // /* empty */ - // | T_STRING - } +// private void optional_class_type() { +// // /* empty */ +// // | T_STRING +// } // private void parameterDeclaration() { // //variable @@ -1746,6 +1923,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI expr(); // constant(); if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { getNextToken(); + if (token == TokenNameRBRACE) { + // empty case; assumes that the '}' token belongs to the + // wrapping + // switch statement - #1371992 + break; + } if (token == TokenNamecase || token == TokenNamedefault) { // empty case statement ? continue; @@ -1766,14 +1949,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // statementList(); // } else { - throwSyntaxError("':' character expected after 'case' constant (Found token: " + scanner.toStringAction(token) + ")"); + throwSyntaxError("':' character expected after 'case' constant (Found token: " + + scanner.toStringAction(token) + ")"); } } else { // TokenNamedefault getNextToken(); if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { getNextToken(); if (token == TokenNameRBRACE) { - // empty default case + // empty default case; ; assumes that the '}' token + // belongs to the + // wrapping switch statement - #1371992 break; } if (token != TokenNamecase) { @@ -1827,7 +2013,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'endif' expected."); } getNextToken(); - if (token != TokenNameSEMICOLON) { + if (token != TokenNameSEMICOLON && token != TokenNameINLINE_HTML) { reportSyntaxError("';' expected after if-statement."); iState.sourceEnd = scanner.getCurrentTokenStartPosition(); } else { @@ -1992,16 +2178,21 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI iState.checkUnreachable = false; } else { int off = b.statements.length - 1; - if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement) + if (!(b.statements[off] instanceof ReturnStatement) + && !(b.statements[off] instanceof ContinueStatement) && !(b.statements[off] instanceof BreakStatement)) { - if (!(b.statements[off] instanceof IfStatement) || !((IfStatement) b.statements[off]).checkUnreachable) { + if (!(b.statements[off] instanceof IfStatement) + || !((IfStatement) b.statements[off]).checkUnreachable) { iState.checkUnreachable = false; } } } } else { - if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) { - if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) { + if (!(s instanceof ReturnStatement) + && !(s instanceof ContinueStatement) + && !(s instanceof BreakStatement)) { + if (!(s instanceof IfStatement) + || !((IfStatement) s).checkUnreachable) { iState.checkUnreachable = false; } } @@ -2064,7 +2255,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'endswitch' expected."); } getNextToken(); - if (token != TokenNameSEMICOLON) { + if (token != TokenNameSEMICOLON && token != TokenNameINLINE_HTML) { throwSyntaxError("';' expected after switch-statement."); } getNextToken(); @@ -2092,7 +2283,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'endfor' expected."); } getNextToken(); - if (token != TokenNameSEMICOLON) { + if (token != TokenNameSEMICOLON && token != TokenNameINLINE_HTML) { throwSyntaxError("';' expected after for-statement."); } getNextToken(); @@ -2110,7 +2301,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'endwhile' expected."); } getNextToken(); - if (token != TokenNameSEMICOLON) { + if (token != TokenNameSEMICOLON && token != TokenNameINLINE_HTML) { throwSyntaxError("';' expected after while-statement."); } getNextToken(); @@ -2127,7 +2318,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI throwSyntaxError("'endforeach' expected."); } getNextToken(); - if (token != TokenNameSEMICOLON) { + if (token != TokenNameSEMICOLON && token != TokenNameINLINE_HTML) { throwSyntaxError("';' expected after foreach-statement."); } getNextToken(); @@ -2169,11 +2360,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (Scanner.TRACE) { System.out.println("TRACE: expr()"); } - return expr_without_variable(true); + return expr_without_variable(true, null); // } } - private Expression expr_without_variable(boolean only_variable) { + private Expression expr_without_variable(boolean only_variable, + UninitializedVariableHandler initHandler) { int exprSourceStart = scanner.getCurrentTokenStartPosition(); int exprSourceEnd = scanner.getCurrentTokenEndPosition(); Expression expression = new Expression(); @@ -2344,7 +2536,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } else { // encaps_list(); // if (token != TokenNameEncapsedString0) { - // throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + + // throwSyntaxError("\'`\' expected at end of string" + "(Found + // token: " + // scanner.toStringAction(token) + " )"); // } // } @@ -2367,7 +2560,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } else { // encaps_list(); // if (token != TokenNameEncapsedString1) { - // throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + // throwSyntaxError("\'\'\' expected at end of string" + "(Found + // token: " // + scanner.toStringAction(token) + " )"); // } else { // expression = new @@ -2395,7 +2589,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } else { // encaps_list(); // if (token != TokenNameEncapsedString2) { - // throwSyntaxError("'\"' expected at end of string" + "(Found token: " + + // throwSyntaxError("'\"' expected at end of string" + "(Found + // token: " + // scanner.toStringAction(token) + " )"); // } else { // expression = new @@ -2410,12 +2605,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // break; case TokenNameStringDoubleQuote: - expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner + expression = new StringLiteralDQ(scanner + .getCurrentStringLiteralSource(), scanner + .getCurrentTokenStartPosition(), scanner .getCurrentTokenEndPosition()); common_scalar(); break; case TokenNameStringSingleQuote: - expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner + expression = new StringLiteralSQ(scanner + .getCurrentStringLiteralSource(), scanner + .getCurrentTokenStartPosition(), scanner .getCurrentTokenEndPosition()); common_scalar(); break; @@ -2443,11 +2642,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } array_pair_list(); if (token != TokenNameRPAREN) { - throwSyntaxError("')' or ',' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); + throwSyntaxError("')' or ',' expected after keyword 'array'" + + "(Found token: " + + scanner.toStringAction(token) + ")"); } getNextToken(); } else { - throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); + throwSyntaxError("'(' expected after keyword 'array'" + + "(Found token: " + scanner.toStringAction(token) + + ")"); } break; case TokenNamelist: @@ -2502,37 +2705,46 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | rw_variable T_INC // | rw_variable T_DEC case TokenNameIdentifier: - char[] ident = scanner.getCurrentTokenSource(); - Expression lhsIdentifier = identifier(true, true); - if (lhsIdentifier != null) { - expression = lhsIdentifier; - } - if (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) { - String error = "Assignment operator '"+scanner.toStringAction(token)+"' not allowed after identifier '"+new String(ident)+"' (use 'define(...)' to define constants)."; - throwSyntaxError(error); - } - break; case TokenNameVariable: case TokenNameDOLLAR: + Expression lhs = null; boolean rememberedVar = false; - 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); + if (token == TokenNameIdentifier) { + lhs = identifier(true, true); + if (lhs != null) { + expression = lhs; + } + } else { + lhs = variable(true, true); + if (lhs != null) { + expression = lhs; + } + 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)) { + if (null == initHandler + || initHandler.reportError()) { + problemReporter.uninitializedLocalVariable( + new String(ref.token), ref.sourceStart, + ref.sourceEnd, referenceContext, + compilationUnit.compilationResult); + } + addVariableSet(ref.token); + } } } - switch (token) { case TokenNameEQUAL: if (lhs != null && lhs instanceof FieldReference) { @@ -2548,30 +2760,41 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI SingleTypeReference classRef = class_name_reference(); ctor_arguments(); if (classRef != null) { - if (lhs != null && lhs instanceof FieldReference) { + if (lhs != null + && lhs instanceof FieldReference) { // example: // $var = & new Object(); if (fMethodVariables != null) { - VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + VariableInfo lhsInfo = new VariableInfo( + ((FieldReference) lhs).sourceStart); lhsInfo.reference = classRef; lhsInfo.typeIdentifier = classRef.token; - fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + fMethodVariables.put(new String( + ((FieldReference) lhs).token), + lhsInfo); rememberedVar = true; } } } } else { Expression rhs = variable(false, false); - if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) { + 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()); + 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); + fMethodVariables.put(new String( + ((FieldReference) lhs).token), + lhsInfo); rememberedVar = true; } } @@ -2584,32 +2807,44 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // 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()); + 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); + fMethodVariables.put(new String( + ((FieldReference) lhs).token), + lhsInfo); rememberedVar = true; } } - } else if (rhs != null && rhs instanceof SingleTypeReference) { + } else if (rhs != null + && rhs instanceof SingleTypeReference) { // example: // $var = new Object(); if (fMethodVariables != null) { - VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + VariableInfo lhsInfo = new VariableInfo( + ((FieldReference) lhs).sourceStart); lhsInfo.reference = (SingleTypeReference) rhs; lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token; - fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + fMethodVariables.put(new String( + ((FieldReference) lhs).token), + lhsInfo); rememberedVar = true; } } } } - if (rememberedVar == false && lhs != null && lhs instanceof FieldReference) { + 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); + VariableInfo lhsInfo = new VariableInfo( + ((FieldReference) lhs).sourceStart); + fMethodVariables.put(new String( + ((FieldReference) lhs).token), lhsInfo); } } break; @@ -2636,7 +2871,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI break; default: if (!only_variable) { - throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "')."); + throwSyntaxError("Variable expression not allowed (found token '" + + scanner.toStringAction(token) + "')."); } if (lhs != null) { expression = lhs; @@ -2652,7 +2888,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // System.out.println(scanner.getCurrentTokenStartPosition()); // System.out.println(scanner.getCurrentTokenEndPosition()); - throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "')."); + throwSyntaxError("Error in expression (found token '" + + scanner.toStringAction(token) + "')."); } } return expression; @@ -2692,7 +2929,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI break; case TokenNameAND_AND: getNextToken(); - expression = new AND_AND_Expression(expression, expr(), token); + expression = new AND_AND_Expression(expression, expr(), + token); break; case TokenNameEQUAL_EQUAL: getNextToken(); @@ -2728,9 +2966,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); TypeReference classRef = class_name_reference(); if (classRef != null) { - expression = new InstanceOfExpression(expression, classRef, OperatorIds.INSTANCEOF); + expression = new InstanceOfExpression(expression, + classRef, OperatorIds.INSTANCEOF); expression.sourceStart = exprSourceStart; - expression.sourceEnd = scanner.getCurrentTokenEndPosition(); + expression.sourceEnd = scanner + .getCurrentTokenEndPosition(); } break; case TokenNameQUESTION: @@ -2742,7 +2982,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); Expression valueIfFalse = expr(); - expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse); + expression = new ConditionalExpression(expression, + valueIfTrue, valueIfFalse); break; default: return expression; @@ -2754,7 +2995,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI getNextToken(); return expression; } - if (token == TokenNameRBRACE || token == TokenNameRPAREN || token == TokenNameRBRACKET) { + if (token == TokenNameRBRACE || token == TokenNameRPAREN + || token == TokenNameRBRACKET) { getNextToken(); return expression; } @@ -2771,8 +3013,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI System.out.println("TRACE: class_name_reference()"); } if (token == TokenNameIdentifier) { - ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); + ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(), + scanner.getCurrentTokenStartPosition()); + int pos = scanner.currentPosition; getNextToken(); + if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) { + // Not terminated by T_STRING, reduce to dynamic_class_name_reference + scanner.currentPosition = pos; + token = TokenNameIdentifier; + ref = null; + dynamic_class_name_reference(); + } } else { ref = null; dynamic_class_name_reference(); @@ -2788,7 +3039,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (Scanner.TRACE) { System.out.println("TRACE: dynamic_class_name_reference()"); } - base_variable(); + base_variable(true); if (token == TokenNameMINUS_GREATER) { getNextToken(); object_property(); @@ -2802,7 +3053,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // dynamic_class_name_variable_property // | /* empty */ if (Scanner.TRACE) { - System.out.println("TRACE: dynamic_class_name_variable_properties()"); + System.out + .println("TRACE: dynamic_class_name_variable_properties()"); } while (token == TokenNameMINUS_GREATER) { dynamic_class_name_variable_property(); @@ -2861,6 +3113,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI variable(true, false); } else if (token == TokenNameDOLLAR) { variable(false, false); + } else if (token == TokenNameIdentifier) { + identifier(true, true); } else { if (token == TokenNamelist) { getNextToken(); @@ -2937,7 +3191,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // } while (true); // } - private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) { + private Expression variable_without_objects(boolean lefthandside, + boolean ignoreVar) { // variable_without_objects: // reference_variable // | simple_indirect_reference reference_variable @@ -2991,58 +3246,68 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (defineName != null) { // does this identifier contain only uppercase characters? if (defineName.length == 3) { - if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') { + if (defineName[0] == 'd' && defineName[1] == 'i' + && defineName[2] == 'e') { defineName = null; } } else if (defineName.length == 4) { - if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') { + if (defineName[0] == 't' && defineName[1] == 'r' + && defineName[2] == 'u' && defineName[3] == 'e') { defineName = null; - } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') { + } else if (defineName[0] == 'n' && defineName[1] == 'u' + && defineName[2] == 'l' && defineName[3] == 'l') { defineName = null; } } else if (defineName.length == 5) { - if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') { + if (defineName[0] == 'f' && defineName[1] == 'a' + && defineName[2] == 'l' && defineName[3] == 's' + && defineName[4] == 'e') { defineName = null; } } if (defineName != null) { for (int i = 0; i < defineName.length; i++) { if (Character.isLowerCase(defineName[i])) { - problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult); + problemReporter.phpUppercaseIdentifierWarning( + startPos, endPos, referenceContext, + compilationUnit.compilationResult); break; } } } } - // TODO is this ok ? - return ref; - // throwSyntaxError("'(' expected in function call."); - } - getNextToken(); - if (token == TokenNameRPAREN) { + } else { getNextToken(); - return ref; - } - non_empty_function_call_parameter_list(); - if (token != TokenNameRPAREN) { - String functionName; - if (ident == null) { - functionName = new String(" "); - } else { - functionName = new String(ident); + if (token == TokenNameRPAREN) { + getNextToken(); + return ref; + } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + String functionName; + if (ident == null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + throwSyntaxError("')' expected in function call (" + + functionName + ")."); } - throwSyntaxError("')' expected in function call (" + functionName + ")."); + getNextToken(); } - getNextToken(); return ref; } + private void non_empty_function_call_parameter_list() { + this.non_empty_function_call_parameter_list(null); + } + // private void function_call_parameter_list() { // function_call_parameter_list: // non_empty_function_call_parameter_list { $$ = $1; } // | /* empty */ // } - private void non_empty_function_call_parameter_list() { + private void non_empty_function_call_parameter_list(String functionName) { // non_empty_function_call_parameter_list: // expr_without_variable // | variable @@ -3051,9 +3316,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | non_empty_function_call_parameter_list ',' variable // | non_empty_function_call_parameter_list ',' '&' w_variable if (Scanner.TRACE) { - System.out.println("TRACE: non_empty_function_call_parameter_list()"); + System.out + .println("TRACE: non_empty_function_call_parameter_list()"); } + UninitializedVariableHandler initHandler = new UninitializedVariableHandler(); + initHandler.setFunctionName(functionName); while (true) { + initHandler.incrementArgumentCount(); if (token == TokenNameAND) { getNextToken(); w_variable(true); @@ -3063,7 +3332,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // || token == TokenNameDOLLAR) { // variable(); // } else { - expr_without_variable(true); + expr_without_variable(true, initHandler); // } } if (token != TokenNameCOMMA) { @@ -3096,7 +3365,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI variable_without_objects(false, false); } - private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) { + private Expression base_variable_with_function_calls(boolean lefthandside, + boolean ignoreVar) { // base_variable_with_function_calls: // base_variable // | function_call @@ -3106,7 +3376,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return function_call(lefthandside, ignoreVar); } - private Expression base_variable() { + private Expression base_variable(boolean lefthandside) { // base_variable: // reference_variable // | simple_indirect_reference reference_variable @@ -3121,7 +3391,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (token == TokenNameDOLLAR) { getNextToken(); } - reference_variable(false, false); + reference_variable(lefthandside, false); } return ref; } @@ -3131,7 +3401,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // // '$' // //| simple_indirect_reference '$' // } - private Expression reference_variable(boolean lefthandside, boolean ignoreVar) { + private Expression reference_variable(boolean lefthandside, + boolean ignoreVar) { // reference_variable: // reference_variable '[' dim_offset ']' // | reference_variable '{' expr '}' @@ -3151,11 +3422,9 @@ 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; + // To remove "ref = null;" here, is probably better than the + // patch + // commented in #1368081 - axelcl getNextToken(); if (token != TokenNameRBRACKET) { expr(); @@ -3185,8 +3454,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // reportSyntaxError("The local variable " + new // String(scanner.getCurrentIdentifierSource()) // + " may not have been initialized"); - problemReporter.uninitializedLocalVariable(new String(scanner.getCurrentIdentifierSource()), scanner - .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), referenceContext, + problemReporter.uninitializedLocalVariable(new String( + scanner.getCurrentIdentifierSource()), scanner + .getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); } } else { @@ -3194,7 +3465,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI addVariableSet(); } } - FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); + FieldReference ref = new FieldReference(scanner + .getCurrentIdentifierSource(), scanner + .getCurrentTokenStartPosition()); getNextToken(); return ref; } else { @@ -3309,7 +3582,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // 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, ignoreVar); + Expression ref = base_variable_with_function_calls(lefthandside, + ignoreVar); if (token == TokenNameMINUS_GREATER) { ref = null; getNextToken(); @@ -3349,7 +3623,131 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // base_variable_with_function_calls T_OBJECT_OPERATOR // object_property method_or_not variable_properties // | base_variable_with_function_calls - return base_variable_with_function_calls(lefthandside, ignoreVar); + + // Expression ref = function_call(lefthandside, ignoreVar); + + // function_call: + // T_STRING '(' function_call_parameter_list ')' + // | class_constant '(' function_call_parameter_list ')' + // | static_member '(' function_call_parameter_list ')' + // | variable_without_objects '(' function_call_parameter_list ')' + char[] defineName = null; + char[] ident = null; + int startPos = 0; + int endPos = 0; + Expression ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: function_call()"); + } + if (token == TokenNameIdentifier) { + ident = scanner.getCurrentIdentifierSource(); + defineName = ident; + startPos = scanner.getCurrentTokenStartPosition(); + endPos = scanner.getCurrentTokenEndPosition(); + getNextToken(); + + if (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) { + String error = "Assignment operator '" + + scanner.toStringAction(token) + + "' not allowed after identifier '" + + new String(ident) + + "' (use 'define(...)' to define constants)."; + reportSyntaxError(error); + } + + switch (token) { + case TokenNamePAAMAYIM_NEKUDOTAYIM: + // static member: + defineName = null; + getNextToken(); + if (token == TokenNameIdentifier) { + // class _constant + getNextToken(); + } else { + // static member: + variable_without_objects(true, false); + } + break; + } + } else { + ref = variable_without_objects(lefthandside, ignoreVar); + } + if (token != TokenNameLPAREN) { + if (defineName != null) { + // does this identifier contain only uppercase characters? + if (defineName.length == 3) { + if (defineName[0] == 'd' && defineName[1] == 'i' + && defineName[2] == 'e') { + defineName = null; + } + } else if (defineName.length == 4) { + if (defineName[0] == 't' && defineName[1] == 'r' + && defineName[2] == 'u' && defineName[3] == 'e') { + defineName = null; + } else if (defineName[0] == 'n' && defineName[1] == 'u' + && defineName[2] == 'l' && defineName[3] == 'l') { + defineName = null; + } + } else if (defineName.length == 5) { + if (defineName[0] == 'f' && defineName[1] == 'a' + && defineName[2] == 'l' && defineName[3] == 's' + && defineName[4] == 'e') { + defineName = null; + } + } + if (defineName != null) { + for (int i = 0; i < defineName.length; i++) { + if (Character.isLowerCase(defineName[i])) { + problemReporter.phpUppercaseIdentifierWarning( + startPos, endPos, referenceContext, + compilationUnit.compilationResult); + break; + } + } + } + } + // TODO is this ok ? + // return ref; + // throwSyntaxError("'(' expected in function call."); + } else { + getNextToken(); + + if (token == TokenNameRPAREN) { + getNextToken(); + ref = null; + } else { + String functionName; + if (ident == null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + non_empty_function_call_parameter_list(functionName); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in function call (" + + functionName + ")."); + } + getNextToken(); + } + } + if (token == TokenNameMINUS_GREATER) { + ref = null; + getNextToken(); + object_property(); + method_or_not(); + variable_properties(); + } + return ref; } private void method_or_not() { @@ -3698,7 +4096,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * Parse and check the include file name - * + * * @param includeToken */ private void checkFileName(int includeToken) { @@ -3715,7 +4113,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (token == TokenNameRPAREN) { getNextToken(); } else { - throwSyntaxError("')' expected for keyword '" + scanner.toStringAction(includeToken) + "'"); + throwSyntaxError("')' expected for keyword '" + + scanner.toStringAction(includeToken) + "'"); } } char[] currTokenSource = scanner.getCurrentTokenSource(start); @@ -3730,7 +4129,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI tokens = new char[1][]; tokens[0] = currTokenSource; - ImportReference impt = new ImportReference(tokens, currTokenSource, start, scanner.getCurrentTokenEndPosition(), false); + ImportReference impt = new ImportReference(tokens, currTokenSource, + start, scanner.getCurrentTokenEndPosition(), false); impt.declarationSourceEnd = impt.sourceEnd; impt.declarationEnd = impt.declarationSourceEnd; // endPosition is just before the ; @@ -3741,13 +4141,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI StringLiteral literal = (StringLiteral) expression; char[] includeName = literal.source(); if (includeName.length == 0) { - reportSyntaxError("Empty filename after keyword '" + scanner.toStringAction(includeToken) + "'", literal.sourceStart, - literal.sourceStart + 1); + reportSyntaxError("Empty filename after keyword '" + + scanner.toStringAction(includeToken) + "'", + literal.sourceStart, literal.sourceStart + 1); } String includeNameString = new String(includeName); if (literal instanceof StringLiteralDQ) { if (includeNameString.indexOf('$') >= 0) { - // assuming that the filename contains a variable => no filename check + // assuming that the filename contains a variable => no + // filename check return; } } @@ -3757,25 +4159,36 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } if (file != null) { // check the filename: - // System.out.println(new String(compilationUnit.getFileName())+" - "+ + // System.out.println(new + // String(compilationUnit.getFileName())+" - "+ // expression.toStringExpression()); IProject project = file.getProject(); if (project != null) { - IPath path = PHPFileUtil.determineFilePath(includeNameString, file, project); + IPath path = PHPFileUtil.determineFilePath( + includeNameString, file, project); if (path == null) { // SyntaxError: "File: << >> doesn't exist in project." - String[] args = { expression.toStringExpression(), project.getLocation().toString() }; - problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext, + String[] args = { expression.toStringExpression(), + project.getFullPath().toString() }; + problemReporter.phpIncludeNotExistWarning(args, + literal.sourceStart, literal.sourceEnd, + referenceContext, compilationUnit.compilationResult); } else { try { String filePath = path.toString(); - String ext = file.getRawLocation().getFileExtension(); - int fileExtensionLength = ext == null ? 0 : ext.length() + 1; + String ext = file.getRawLocation() + .getFileExtension(); + int fileExtensionLength = ext == null ? 0 : ext + .length() + 1; + + IFile f = PHPFileUtil.createFile(path, project); - impt.tokens = CharOperation.splitOn('/', filePath.toCharArray(), 0, filePath.length() - fileExtensionLength); - impt.setFile(PHPFileUtil.createFile(path, project)); + impt.tokens = CharOperation.splitOn('/', filePath + .toCharArray(), 0, filePath.length() + - fileExtensionLength); + impt.setFile(f); } catch (Exception e) { // the file is outside of the workspace } @@ -3846,17 +4259,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return false; } - private void scalar() { - // scalar: - // T_STRING - // | T_STRING_VARNAME - // | class_constant - // | common_scalar - // | '"' encaps_list '"' - // | '\'' encaps_list '\'' - // | T_START_HEREDOC encaps_list T_END_HEREDOC - throwSyntaxError("Not yet implemented (scalar)."); - } +// private void scalar() { +// // scalar: +// // T_STRING +// // | T_STRING_VARNAME +// // | class_constant +// // | common_scalar +// // | '"' encaps_list '"' +// // | '\'' encaps_list '\'' +// // | T_START_HEREDOC encaps_list T_END_HEREDOC +// throwSyntaxError("Not yet implemented (scalar)."); +// } private void static_scalar() { // static_scalar: /* compile-time evaluated scalars */ @@ -4039,8 +4452,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI ASTNode[] noAstNodes = new ASTNode[AstStackIncrement]; public CompilationUnitDeclaration compilationUnit; /* - * the result from parse() - */ + * the result from + * parse() + */ protected ReferenceContext referenceContext; @@ -4058,7 +4472,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI */ public ProblemReporter problemReporter() { if (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + compilationUnit.compilationResult.lineSeparatorPositions = scanner + .getLineEnds(); } problemReporter.referenceContext = referenceContext; return problemReporter; @@ -4076,9 +4491,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // int[] leftCount = { 0, 0, 0 }; // int[] rightCount = { 0, 0, 0 }; // int[] depths = { 0, 0, 0 }; - // int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] + // int[][] leftPositions = new int[][] { new int[10], new int[10], new + // int[10] + // }; + // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] // }; - // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] }; // int[][] rightPositions = new int[][] { new int[10], new int[10], new // int[10] }; // int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] @@ -4112,7 +4529,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter); // // } - // } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition)); + // } while (isWhiteSpace && (scanner.currentPosition < + // scanner.eofPosition)); // // -------consume token until } is found--------- // switch (scanner.currentCharacter) { // case '{': { @@ -4132,7 +4550,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // if (index == rightPositions[CurlyBracket].length) { // System.arraycopy(rightPositions[CurlyBracket], 0, // (rightPositions[CurlyBracket] = new int[index * 2]), 0, index); - // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = + // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] + // = // new int[index * 2]), 0, index); // } // rightPositions[CurlyBracket][index] = scanner.startPosition; @@ -4156,7 +4575,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // if (index == rightPositions[RoundBracket].length) { // System.arraycopy(rightPositions[RoundBracket], 0, // (rightPositions[RoundBracket] = new int[index * 2]), 0, index); - // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = + // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] + // = // new int[index * 2]), 0, index); // } // rightPositions[RoundBracket][index] = scanner.startPosition; @@ -4168,7 +4588,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // if (index == leftPositions[SquareBracket].length) { // System.arraycopy(leftPositions[SquareBracket], 0, // (leftPositions[SquareBracket] = new int[index * 2]), 0, index); - // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = + // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] + // = // new int[index * 2]), 0, index); // } // leftPositions[SquareBracket][index] = scanner.startPosition; @@ -4180,7 +4601,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // if (index == rightPositions[SquareBracket].length) { // System.arraycopy(rightPositions[SquareBracket], 0, // (rightPositions[SquareBracket] = new int[index * 2]), 0, index); - // System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] + // System.arraycopy(rightDepths[SquareBracket], 0, + // (rightDepths[SquareBracket] // = new int[index * 2]), 0, index); // } // rightPositions[SquareBracket][index] = scanner.startPosition; @@ -4267,11 +4689,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > // 15 || c1 < 0 - // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c2 < 0 - // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c3 < 0 - // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c4 < 0) { //error // // don't // // care of the @@ -4298,11 +4723,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > // 15 || c1 < 0 - // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c2 < 0 - // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c3 < 0 - // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c4 < 0) { //error // // don't // // care of the @@ -4363,11 +4791,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > // 15 || c1 < 0 - // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c2 < 0 - // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c3 < 0 - // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c4 < 0) { //error // // don't // // care of the @@ -4394,11 +4825,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // } // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > // 15 || c1 < 0 - // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c2 < 0 - // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c3 < 0 - // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 // || c4 < 0) { //error // // don't // // care of the @@ -4489,14 +4923,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // // too many opening brackets ? // for (int i = rightCount[kind]; i < leftCount[kind]; i++) { // anomaliesDetected = true; - // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - + // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i + // - // 1], referenceContext, // compilationUnit.compilationResult); // } // // too many closing brackets ? // for (int i = leftCount[kind]; i < rightCount[kind]; i++) { // anomaliesDetected = true; - // problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, + // problemReporter.unmatchedBracket(rightPositions[kind][i], + // referenceContext, // compilationUnit.compilationResult); // } // if (anomaliesDetected) @@ -4509,17 +4945,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // return anomaliesDetected; // } // } - protected void pushOnAstLengthStack(int pos) { - try { - astLengthStack[++astLengthPtr] = pos; - } catch (IndexOutOfBoundsException e) { - int oldStackLength = astLengthStack.length; - int[] oldPos = astLengthStack; - astLengthStack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); - astLengthStack[astLengthPtr] = pos; - } - } +// protected void pushOnAstLengthStack(int pos) { +// try { +// astLengthStack[++astLengthPtr] = pos; +// } catch (IndexOutOfBoundsException e) { +// int oldStackLength = astLengthStack.length; +// int[] oldPos = astLengthStack; +// astLengthStack = new int[oldStackLength + StackIncrement]; +// System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); +// astLengthStack[astLengthPtr] = pos; +// } +// } protected void pushOnAstStack(ASTNode node) { /* @@ -4555,22 +4991,29 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI 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; - char[][] tokens; - if (filePath.startsWith(projectPath)) { - tokens = CharOperation - .splitOn('/', filePath.toCharArray(), projectPath.length() + 1, filePath.length() - fileExtensionLength); - } else { + // incastrix + //String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()) + // .toString(); + //String filePath = file.getFullPath().toString(); + + String ext = file.getFileExtension(); + int fileExtensionLength = ext == null ? 0 : ext.length() + 1; + ImportReference impt; + 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, name.length() - fileExtensionLength).toCharArray(); - } + tokens[0] = name.substring(0, name.length() - fileExtensionLength) + .toCharArray(); + //} - this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true); + this.compilationUnit.currentPackage = impt = new ImportReference( + tokens, new char[0], 0, 0, true); impt.declarationSourceStart = 0; impt.declarationSourceEnd = 0; @@ -4579,11 +5022,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } - public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV", "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", - "$_SESSION", "$_SERVER" }; + public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV", + "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", "$_SESSION", + "$_SERVER" }; /** - * + * */ private void pushFunctionVariableSet() { HashSet set = new HashSet(); @@ -4604,7 +5048,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI private HashSet removeIfVariableSet() { if (!fStackUnassigned.isEmpty()) { - return (HashSet) fStackUnassigned.remove(fStackUnassigned.size() - 1); + return (HashSet) fStackUnassigned + .remove(fStackUnassigned.size() - 1); } return null; } @@ -4621,8 +5066,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } /** - * add the current identifier source to the set of assigned variables - * + * add the current identifier source to the set of assigned variables + * + * * @param set */ private void addVariableSet(HashSet set) { @@ -4632,8 +5078,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } /** - * add the current identifier source to the set of assigned variables - * + * add the current identifier source to the set of assigned variables + * + * */ private void addVariableSet() { HashSet set = peekVariableSet(); @@ -4643,8 +5090,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } /** - * add the current identifier source to the set of assigned variables - * + * add the current identifier source to the set of assigned variables + * + * */ private void addVariableSet(char[] token) { HashSet set = peekVariableSet(); @@ -4657,7 +5105,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI * check if the current identifier source is in the set of assigned * variables Returns true, if no set is defined for the current scanner * position - * + * */ private boolean containsVariableSet() { return containsVariableSet(scanner.getCurrentTokenSource());