1 /***********************************************************************************************************************************
 
   2  * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material are made available under the
 
   3  * terms of the Common Public License v1.0 which accompanies this distribution, and is available at
 
   4  * http://www.eclipse.org/legal/cpl-v10.html
 
   6  * Contributors: www.phpeclipse.de
 
   7  **********************************************************************************************************************************/
 
   8 package net.sourceforge.phpdt.internal.compiler.parser;
 
  10 import java.util.ArrayList;
 
  11 import java.util.HashMap;
 
  12 import java.util.HashSet;
 
  14 import net.sourceforge.phpdt.core.compiler.CharOperation;
 
  15 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
  16 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 
  17 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols.TokenName;
 
  18 import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression;
 
  19 import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
 
  20 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
 
  21 import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression;
 
  22 import net.sourceforge.phpdt.internal.compiler.ast.Block;
 
  23 import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement;
 
  24 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
 
  25 import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression;
 
  26 import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement;
 
  27 import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression;
 
  28 import net.sourceforge.phpdt.internal.compiler.ast.Expression;
 
  29 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
 
  30 import net.sourceforge.phpdt.internal.compiler.ast.FieldReference;
 
  31 import net.sourceforge.phpdt.internal.compiler.ast.IfStatement;
 
  32 import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
 
  33 import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression;
 
  34 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
 
  35 import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression;
 
  36 import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
 
  37 import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
 
  38 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
 
  39 import net.sourceforge.phpdt.internal.compiler.ast.Statement;
 
  40 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
 
  41 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ;
 
  42 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ;
 
  43 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
 
  44 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
 
  45 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 
  46 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
 
  47 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
 
  48 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
 
  49 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 
  50 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
 
  51 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  52 import net.sourceforge.phpdt.internal.core.util.PHPFileUtil;
 
  53 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
 
  54 //import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
 
  56 import org.eclipse.core.resources.IFile;
 
  57 import org.eclipse.core.resources.IProject;
 
  58 import org.eclipse.core.resources.IResource;
 
  59 import org.eclipse.core.runtime.IPath;
 
  61 public class Parser implements ITerminalSymbols, CompilerModifiers,
 
  62                 ParserBasicInformation {
 
  63         protected final static int StackIncrement = 255;
 
  65         protected int stateStackTop;
 
  67         // protected int[] stack = new int[StackIncrement];
 
  69         public TokenName firstToken; // handle for multiple parsing goals
 
  71         public int lastAct; // handle for multiple parsing goals
 
  73         // protected RecoveredElement currentElement;
 
  75         public static boolean VERBOSE_RECOVERY = false;
 
  77         protected boolean diet = false; // tells the scanner to jump over some
 
  80          * the PHP token scanner
 
  82         public Scanner scanner;
 
  86         protected int modifiers;
 
  88         protected int modifiersSourceStart;
 
  90         protected Parser(ProblemReporter problemReporter) {
 
  91                 this.problemReporter = problemReporter;
 
  92                 this.options = problemReporter.options;
 
  93                 this.token = TokenName.EOF;
 
  94                 this.initializeScanner();
 
  97 //      public void setFileToParse(IFile fileToParse) {
 
  98 //              this.token = TokenName.EOF;
 
  99 //              this.initializeScanner();
 
 103          * ClassDeclaration Constructor.
 
 107          *            Description of Parameter
 
 110 //      public Parser(IFile fileToParse) {
 
 111 //              // if (keywordMap == null) {
 
 112 //              // keywordMap = new HashMap();
 
 113 //              // for (int i = 0; i < PHP_KEYWORS.length; i++) {
 
 114 //              // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
 
 117 //              // this.currentPHPString = 0;
 
 118 //              // PHPParserSuperclass.fileToParse = fileToParse;
 
 119 //              // this.phpList = null;
 
 120 //              this.includesList = null;
 
 122 //              this.token = TokenName.EOF;
 
 123 //              // this.chIndx = 0;
 
 124 //              // this.rowCount = 1;
 
 125 //              // this.columnCount = 0;
 
 126 //              // this.phpEnd = false;
 
 127 //              // getNextToken();
 
 128 //              this.initializeScanner();
 
 131         public void initializeScanner() {
 
 132                 this.scanner = new Scanner(
 
 134                                 false /* whitespace */,
 
 135                                 this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */,
 
 136                                 false, false, this.options.taskTags/* taskTags */,
 
 137                                 this.options.taskPriorites/* taskPriorities */, true/* isTaskCaseSensitive */);
 
 141          * Create marker for the parse error
 
 143         // private void setMarker(String message, int charStart, int charEnd, int
 
 145         // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
 
 148          * This method will throw the SyntaxError. It will add the good lines and
 
 149          * columns to the Error
 
 153          * @throws SyntaxError
 
 156         private void throwSyntaxError(String error) {
 
 157                 int problemStartPosition = scanner.getCurrentTokenStartPosition();
 
 158                 int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1;
 
 159                 if (scanner.source.length <= problemEndPosition
 
 160                                 && problemEndPosition > 0) {
 
 161                         problemEndPosition = scanner.source.length - 1;
 
 162                         if (problemStartPosition > 0
 
 163                                         && problemStartPosition >= problemEndPosition
 
 164                                         && problemEndPosition > 0) {
 
 165                                 problemStartPosition = problemEndPosition - 1;
 
 168                 throwSyntaxError(error, problemStartPosition, problemEndPosition);
 
 172          * This method will throw the SyntaxError. It will add the good lines and
 
 173          * columns to the Error
 
 177          * @throws SyntaxError
 
 180         // private void throwSyntaxError(String error, int startRow) {
 
 181         // throw new SyntaxError(startRow, 0, " ", error);
 
 183         private void throwSyntaxError(String error, int problemStartPosition,
 
 184                         int problemEndPosition) {
 
 185                 if (referenceContext != null) {
 
 186                         problemReporter.phpParsingError(new String[] { error },
 
 187                                         problemStartPosition, problemEndPosition, referenceContext,
 
 188                                         compilationUnit.compilationResult);
 
 190                 throw new SyntaxError(1, 0, " ", error);
 
 193         private void reportSyntaxError(String error) {
 
 194                 int problemStartPosition = scanner.getCurrentTokenStartPosition();
 
 195                 int problemEndPosition = scanner.getCurrentTokenEndPosition();
 
 196                 reportSyntaxError(error, problemStartPosition, problemEndPosition + 1);
 
 199         private void reportSyntaxError(String error, int problemStartPosition,
 
 200                         int problemEndPosition) {
 
 201                 if (referenceContext != null) {
 
 202                         problemReporter.phpParsingError(new String[] { error },
 
 203                                         problemStartPosition, problemEndPosition, referenceContext,
 
 204                                         compilationUnit.compilationResult);
 
 208         // private void reportSyntaxWarning(String error, int problemStartPosition,
 
 209         // int problemEndPosition) {
 
 210         // if (referenceContext != null) {
 
 211         // problemReporter.phpParsingWarning(new String[] { error },
 
 212         // problemStartPosition, problemEndPosition, referenceContext,
 
 213         // compilationUnit.compilationResult);
 
 218          * Read the next token from input
 
 220         private void getNextToken() {
 
 222                         token = scanner.getNextToken();
 
 224                                 int currentEndPosition   = scanner.getCurrentTokenEndPosition();
 
 225                                 int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
 227                                 System.out.print ("getNextToken: from " + currentStartPosition + " to " + currentEndPosition + ": ");
 
 228                                 System.out.println(scanner.toStringAction(token));
 
 230                 } catch (InvalidInputException e) {
 
 231                         token = TokenName.ERROR;
 
 232                         String detailedMessage = e.getMessage();
 
 234                         if (detailedMessage == Scanner.UNTERMINATED_STRING) {
 
 235                                 throwSyntaxError("Unterminated string.");
 
 236                         } else if (detailedMessage == Scanner.UNTERMINATED_COMMENT) {
 
 237                                 throwSyntaxError("Unterminated commment.");
 
 243         public void init(String s) {
 
 245                 this.token = TokenName.EOF;
 
 246                 this.includesList = new ArrayList();
 
 248                 // this.rowCount = 1;
 
 249                 // this.columnCount = 0;
 
 250                 // this.phpEnd = false;
 
 251                 // this.phpMode = false;
 
 252                 /* scanner initialization */
 
 253                 scanner.setSource(s.toCharArray());
 
 254                 scanner.setPHPMode(false);
 
 258         protected void initialize(boolean phpMode) {
 
 259                 initialize(phpMode, null);
 
 262         protected void initialize(boolean phpMode,
 
 263                         IdentifierIndexManager indexManager) {
 
 264                 compilationUnit = null;
 
 265                 referenceContext = null;
 
 266                 this.includesList = new ArrayList();
 
 267                 // this.indexManager = indexManager;
 
 269                 this.token = TokenName.EOF;
 
 271                 // this.rowCount = 1;
 
 272                 // this.columnCount = 0;
 
 273                 // this.phpEnd = false;
 
 274                 // this.phpMode = phpMode;
 
 275                 scanner.setPHPMode(phpMode);
 
 280          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 283         public void parse(String s) {
 
 288          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 291         public void parse(String s, HashMap variables) {
 
 292                 fMethodVariables = variables;
 
 293                 fStackUnassigned = new ArrayList();
 
 299          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 302          * The main entry point when parsing a file
 
 304         protected void parse() {
 
 305                 if (scanner.compilationUnit != null) {
 
 306                         IResource resource = scanner.compilationUnit.getResource();
 
 307                         if (resource != null && resource instanceof IFile) {
 
 308                                 // set the package name
 
 309                                 consumePackageDeclarationName((IFile) resource);
 
 317                                 if (token != TokenName.EOF &&                       // If we are not at the end of file
 
 318                                     token != TokenName.ERROR) {                     // and have no error
 
 319                                         statementList();                                // build the statement list for the entire file
 
 322                                 if (token != TokenName.EOF) {
 
 325                                                         throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
 
 329                                                         throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
 333                                                         throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
 337                                                         throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
 341                                                         throwSyntaxError("Read character '('; end-of-file not reached.");
 
 345                                                         throwSyntaxError("Read character '{';  end-of-file not reached.");
 
 349                                                         throwSyntaxError("Read character '[';  end-of-file not reached.");
 
 353                                                         throwSyntaxError("End-of-file not reached.");
 
 358                         } catch (SyntaxError syntaxError) {
 
 359                                 // syntaxError.printStackTrace();
 
 368          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 371         public void parseFunction(String s, HashMap variables) {
 
 373                 scanner.phpMode = true;
 
 374                 parseFunction(variables);
 
 378          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 381         protected void parseFunction(HashMap variables) {
 
 383                 boolean hasModifiers = member_modifiers();
 
 384                 if (token == TokenName.FUNCTION) {
 
 386                                 checkAndSetModifiers(AccPublic);
 
 388                         this.fMethodVariables = variables;
 
 390                         MethodDeclaration methodDecl = new MethodDeclaration(null);
 
 391                         methodDecl.declarationSourceStart = scanner
 
 392                                         .getCurrentTokenStartPosition();
 
 393                         methodDecl.modifiers = this.modifiers;
 
 394                         methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
 
 397                                 functionDefinition(methodDecl);
 
 398                         } catch (SyntaxError sytaxErr1) {
 
 401                                 int sourceEnd = methodDecl.sourceEnd;
 
 403                                                 || methodDecl.declarationSourceStart > sourceEnd) {
 
 404                                         sourceEnd = methodDecl.declarationSourceStart + 1;
 
 406                                 methodDecl.sourceEnd = sourceEnd;
 
 407                                 methodDecl.declarationSourceEnd = sourceEnd;
 
 412         protected CompilationUnitDeclaration endParse(int act) {
 
 416                 // if (currentElement != null) {
 
 417                 // currentElement.topElement().updateParseTree();
 
 418                 // if (VERBOSE_RECOVERY) {
 
 419                 // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
 
 420                 // System.out.println("--------------------------"); //$NON-NLS-1$
 
 421                 // System.out.println(compilationUnit);
 
 422                 // System.out.println("----------------------------------");
 
 426                 if (diet & VERBOSE_RECOVERY) {
 
 427                         System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
 
 428                         System.out.println("--------------------------"); //$NON-NLS-1$
 
 429                         System.out.println(compilationUnit);
 
 430                         System.out.println("----------------------------------"); //$NON-NLS-1$
 
 433                 if (scanner.recordLineSeparator) {
 
 434                         compilationUnit.compilationResult.lineSeparatorPositions = scanner
 
 437                 if (scanner.taskTags != null) {
 
 438                         for (int i = 0; i < scanner.foundTaskCount; i++) {
 
 439                                 problemReporter().task(
 
 440                                                 new String(scanner.foundTaskTags[i]),
 
 441                                                 new String(scanner.foundTaskMessages[i]),
 
 442                                                 scanner.foundTaskPriorities[i] == null ? null
 
 443                                                                 : new String(scanner.foundTaskPriorities[i]),
 
 444                                                 scanner.foundTaskPositions[i][0],
 
 445                                                 scanner.foundTaskPositions[i][1]);
 
 448                 compilationUnit.imports = new ImportReference[includesList.size()];
 
 449                 for (int i = 0; i < includesList.size(); i++) {
 
 450                         compilationUnit.imports[i] = (ImportReference) includesList.get(i);
 
 452                 return compilationUnit;
 
 457          * @return A block object which contains all statements from within the current block
 
 459         private Block statementList() {
 
 460                 boolean    branchStatement = false;
 
 461                 int        blockStart      = scanner.getCurrentTokenStartPosition();
 
 462                 ArrayList  blockStatements = new ArrayList();
 
 467                                 statement = statement();
 
 469                                 if (statement != null) {
 
 470                                     blockStatements.add(statement);
 
 473                                 if (token == TokenName.EOF) {
 
 477                                 if (branchStatement && statement != null) {
 
 478                                         // reportSyntaxError("Unreachable code", statement.sourceStart, statement.sourceEnd);
 
 479                                         if (!(statement instanceof BreakStatement)) {
 
 481                                                  * Don't give an error for break statement following return statement.
 
 482                                                  * Technically it's unreachable code, but in switch-case it's recommended to avoid
 
 483                                                  * accidental fall-through later when editing the code
 
 485                                                 problemReporter.unreachableCode (new String (scanner.getCurrentIdentifierSource ()),
 
 486                                                                                          statement.sourceStart,
 
 489                                                                                          compilationUnit.compilationResult);
 
 507                                                 return createBlock (blockStart, blockStatements);          // Create and return a block object (contains all the statements from the current read block)
 
 510                                 branchStatement = checkUnreachableStatements(statement);
 
 512                         catch (SyntaxError sytaxErr1) {
 
 513                                 // If an error occurred, try to find keywords
 
 514                                 // to parse the rest of the string
 
 515                                 boolean tokenize = scanner.tokenizeStrings;
 
 518                                         scanner.tokenizeStrings = true;
 
 522                                         boolean bBreakLoop = false;
 
 524                                         while (token != TokenName.EOF) {                               // As long as we are not at the end of file
 
 525                                                 switch (token) {                                           // If a block close?
 
 539                                                                 return createBlock (blockStart, blockStatements);  // Create and return a block object (contains all the statements from the current read block)
 
 576                                                 // System.out.println(scanner.toStringAction(token));
 
 578                                                 // System.out.println(scanner.toStringAction(token));
 
 581                                         if (token == TokenName.EOF) {
 
 585                                         scanner.tokenizeStrings = tokenize;
 
 595         private boolean checkUnreachableStatements(Statement statement) {
 
 596                 if (statement instanceof ReturnStatement   ||
 
 597                         statement instanceof ContinueStatement ||
 
 598                         statement instanceof BreakStatement) {
 
 600                 } else if (statement instanceof IfStatement
 
 601                                 && ((IfStatement) statement).checkUnreachable) {
 
 609          * @param blockStatements
 
 612         private Block createBlock (int blockStart, ArrayList blockStatements) {
 
 613                 int    blockEnd = scanner.getCurrentTokenEndPosition ();
 
 614                 Block  b        = Block.EmptyWith (blockStart, blockEnd);
 
 616                 b.statements = new Statement[blockStatements.size()];
 
 617                 blockStatements.toArray (b.statements);
 
 622         private void functionBody(MethodDeclaration methodDecl) {
 
 623                 // '{' [statement-list] '}'
 
 624                 if (token == TokenName.LBRACE) {
 
 627                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
 628                         throwSyntaxError("'{' expected in compound-statement.");
 
 631                 if (token != TokenName.RBRACE) {
 
 635                 if (token == TokenName.RBRACE) {
 
 636                         methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
 639                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
 640                         throwSyntaxError("'}' expected in compound-statement.");
 
 645          * Try to create an statement reading from the current token position
 
 647          * @return Returns a found statement or empty statement
 
 649         private Statement statement() {
 
 650                 Statement   statement = null;
 
 651                 Expression  expression;
 
 652                 int         sourceStart = scanner.getCurrentTokenStartPosition();
 
 657                                 // T_IF '(' expr ')' statement elseif_list else_single
 
 658                                 // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
 
 659                                 // new_else_single T_ENDIF ';'
 
 661                                 if (token == TokenName.LPAREN) {
 
 664                                         throwSyntaxError("'(' expected after 'if' keyword.");
 
 669                                 if (token == TokenName.RPAREN) {
 
 672                                         throwSyntaxError("')' expected after 'if' condition.");
 
 674                                 // create basic IfStatement
 
 675                                 IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1);
 
 677                                 if (token == TokenName.COLON) {
 
 679                                         ifStatementColon(ifStatement);
 
 681                                         ifStatement(ifStatement);
 
 687                                 if (token == TokenName.LPAREN) {
 
 690                                         throwSyntaxError("'(' expected after 'switch' keyword.");
 
 693                                 if (token == TokenName.RPAREN) {
 
 696                                         throwSyntaxError("')' expected after 'switch' condition.");
 
 703                                 if (token == TokenName.LPAREN) {
 
 706                                         throwSyntaxError("'(' expected after 'for' keyword.");
 
 708                                 if (token == TokenName.SEMICOLON) {
 
 712                                         if (token == TokenName.SEMICOLON) {
 
 715                                                 throwSyntaxError("';' expected after 'for'.");
 
 718                                 if (token == TokenName.SEMICOLON) {
 
 722                                         if (token == TokenName.SEMICOLON) {
 
 725                                                 throwSyntaxError("';' expected after 'for'.");
 
 728                                 if (token == TokenName.RPAREN) {
 
 732                                         if (token == TokenName.RPAREN) {
 
 735                                                 throwSyntaxError("')' expected after 'for'.");
 
 743                                 if (token == TokenName.LPAREN) {
 
 746                                         throwSyntaxError("'(' expected after 'while' keyword.");
 
 749                                 if (token == TokenName.RPAREN) {
 
 752                                         throwSyntaxError("')' expected after 'while' condition.");
 
 759                                 if (token == TokenName.LBRACE) {
 
 761                                         if (token != TokenName.RBRACE) {
 
 764                                         if (token == TokenName.RBRACE) {
 
 767                                                 throwSyntaxError("'}' expected after 'do' keyword.");
 
 772                                 if (token == TokenName.WHILE) {
 
 774                                         if (token == TokenName.LPAREN) {
 
 777                                                 throwSyntaxError("'(' expected after 'while' keyword.");
 
 780                                         if (token == TokenName.RPAREN) {
 
 783                                                 throwSyntaxError("')' expected after 'while' condition.");
 
 786                                         throwSyntaxError("'while' expected after 'do' keyword.");
 
 788                                 if (token == TokenName.SEMICOLON) {
 
 791                                         if (token != TokenName.INLINE_HTML) {
 
 792                                                 throwSyntaxError("';' expected after do-while statement.");
 
 800                                 if (token == TokenName.LPAREN) {
 
 803                                         throwSyntaxError("'(' expected after 'foreach' keyword.");
 
 806                                 if (token == TokenName.AS) {
 
 809                                         throwSyntaxError("'as' expected after 'foreach' exxpression.");
 
 813                                 foreach_optional_arg();
 
 814                                 if (token == TokenName.EQUAL_GREATER) {
 
 816                                         variable(false, false);
 
 818                                 if (token == TokenName.RPAREN) {
 
 821                                         throwSyntaxError("')' expected after 'foreach' expression.");
 
 829                                 if (token != TokenName.SEMICOLON) {
 
 832                                 if (token == TokenName.SEMICOLON) {
 
 833                                         sourceEnd = scanner.getCurrentTokenEndPosition();
 
 836                                         if (token != TokenName.INLINE_HTML) {
 
 837                                                 throwSyntaxError("';' expected after 'break'.");
 
 839                                         sourceEnd = scanner.getCurrentTokenEndPosition();
 
 842                                 return new BreakStatement(null, sourceStart, sourceEnd);
 
 847                                 if (token != TokenName.SEMICOLON) {
 
 850                                 if (token == TokenName.SEMICOLON) {
 
 851                                         sourceEnd = scanner.getCurrentTokenEndPosition();
 
 854                                         if (token != TokenName.INLINE_HTML) {
 
 855                                                 throwSyntaxError("';' expected after 'continue'.");
 
 857                                         sourceEnd = scanner.getCurrentTokenEndPosition();
 
 860                                 return new ContinueStatement(null, sourceStart, sourceEnd);
 
 866                                 if (token == TokenName.VARIABLE) {
 
 869                                         if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
 
 872                                                 if (token != TokenName.IDENTIFIER) {
 
 873                                                         throwSyntaxError("identifier expected after '::'.");
 
 881                                 if (token != TokenName.SEMICOLON) {
 
 885                                 if (token == TokenName.SEMICOLON) {
 
 886                                         sourceEnd = scanner.getCurrentTokenEndPosition();
 
 890                                         if (token != TokenName.INLINE_HTML) {
 
 891                                                 throwSyntaxError("';' expected after 'return'.");
 
 894                                         sourceEnd = scanner.getCurrentTokenEndPosition();
 
 897                                 return new ReturnStatement(expression, sourceStart, sourceEnd);
 
 900                                 getNextToken();                                 // Read the token after 'echo'
 
 901                                 expressionList();                               // Read everything after 'echo'
 
 902                                 if (token == TokenName.SEMICOLON) {
 
 905                                         if (token != TokenName.INLINE_HTML) {
 
 906                                                 throwSyntaxError("';' expected after 'echo' statement.");
 
 910                                 return statement;   // return null statement
 
 913                                 // 0-length token directly after PHP short tag <?=
 
 916                                 if (token == TokenName.SEMICOLON) {
 
 918                                         // if (token != TokenName.INLINE_HTML) {
 
 919                                         // // TODO should this become a configurable warning?
 
 920                                         // reportSyntaxError("Probably '?>' expected after PHP short tag
 
 921                                         // expression (only the first expression will be echoed).");
 
 924                                         if (token != TokenName.INLINE_HTML) {
 
 925                                                 throwSyntaxError("';' expected after PHP short tag '<?=' expression.");
 
 938                                 if (token == TokenName.SEMICOLON) {
 
 941                                         if (token != TokenName.INLINE_HTML) {
 
 942                                                 throwSyntaxError("';' expected after 'global' statement.");
 
 951                                 if (token == TokenName.SEMICOLON) {
 
 954                                         if (token != TokenName.INLINE_HTML) {
 
 955                                                 throwSyntaxError("';' expected after 'static' statement.");
 
 963                                 if (token == TokenName.LPAREN) {
 
 966                                         throwSyntaxError("'(' expected after 'unset' statement.");
 
 969                                 if (token == TokenName.RPAREN) {
 
 972                                         throwSyntaxError("')' expected after 'unset' statement.");
 
 974                                 if (token == TokenName.SEMICOLON) {
 
 977                                         if (token != TokenName.INLINE_HTML) {
 
 978                                                 throwSyntaxError("';' expected after 'unset' statement.");
 
 988                 if (token == TokenName.SEMICOLON) {             // After the namespace identifier there is a ';'
 
 991                 else if (token == TokenName.LBRACE) {           // or a '{'
 
 992                     getNextToken();                             // set to next token
 
 994                     if (token != TokenName.RBRACE) {            // if next token is not a '}'
 
 995                         statementList();                        // read the entire block
 
 998                     if (token == TokenName.RBRACE) {            // If the end is a '}'
 
 999                         getNextToken();                         // go for the next token
 
1001                     else {                                      // Not a '}' as expected
 
1002                         throwSyntaxError("'}' expected after 'do' keyword.");
 
1006                     if (token != TokenName.INLINE_HTML) {
 
1007                         throwSyntaxError("';' expected after 'namespace' statement.");
 
1014                 getNextToken ();                                // This should get the label
 
1016                 if (token == TokenName.IDENTIFIER) {
 
1020                     throwSyntaxError("expected a label after goto");
 
1023                 if (token == TokenName.SEMICOLON) {             // After the 'goto' label name there is a ';'
 
1027                     throwSyntaxError("expected a ';' after goto label");
 
1032                                 MethodDeclaration methodDecl = new MethodDeclaration (this.compilationUnit.compilationResult);
 
1033                                 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1034                                 methodDecl.modifiers = AccDefault;
 
1035                                 methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
 
1038                                         functionDefinition(methodDecl);
 
1040                                         sourceEnd = methodDecl.sourceEnd;
 
1041                                         if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
 
1042                                                 sourceEnd = methodDecl.declarationSourceStart + 1;
 
1044                                         methodDecl.declarationSourceEnd = sourceEnd;
 
1045                                         methodDecl.sourceEnd = sourceEnd;
 
1050                                 // T_DECLARE '(' declare_list ')' declare_statement
 
1052                                 if (token != TokenName.LPAREN) {
 
1053                                         throwSyntaxError("'(' expected in 'declare' statement.");
 
1057                                 if (token != TokenName.RPAREN) {
 
1058                                         throwSyntaxError("')' expected in 'declare' statement.");
 
1061                                 declare_statement();
 
1066                                 if (token != TokenName.LBRACE) {
 
1067                                         throwSyntaxError("'{' expected in 'try' statement.");
 
1071                                 if (token != TokenName.RBRACE) {
 
1072                                         throwSyntaxError("'}' expected in 'try' statement.");
 
1079                                 if (token != TokenName.LPAREN) {
 
1080                                         throwSyntaxError("'(' expected in 'catch' statement.");
 
1083                                 fully_qualified_class_name();
 
1084                                 if (token != TokenName.VARIABLE) {
 
1085                                         throwSyntaxError("Variable expected in 'catch' statement.");
 
1089                                 if (token != TokenName.RPAREN) {
 
1090                                         throwSyntaxError("')' expected in 'catch' statement.");
 
1093                                 if (token != TokenName.LBRACE) {
 
1094                                         throwSyntaxError("'{' expected in 'catch' statement.");
 
1097                                 if (token != TokenName.RBRACE) {
 
1099                                         if (token != TokenName.RBRACE) {
 
1100                                                 throwSyntaxError("'}' expected in 'catch' statement.");
 
1104                                 additional_catches();
 
1110                                 if (token == TokenName.SEMICOLON) {
 
1113                                         throwSyntaxError("';' expected after 'throw' exxpression.");
 
1122                                         TypeDeclaration typeDecl = new TypeDeclaration (this.compilationUnit.compilationResult);
 
1123                                         typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1124                                         typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1125                                         typeDecl.name = new char[] { ' ' };
 
1126                                         // default super class
 
1127                                         typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
 
1128                                         compilationUnit.types.add(typeDecl);
 
1129                                         pushOnAstStack(typeDecl);
 
1130                                         unticked_class_declaration_statement(typeDecl);
 
1140                                 if (token != TokenName.RBRACE) {
 
1141                                         statement = statementList();
 
1143                                 if (token == TokenName.RBRACE) {
 
1147                                         throwSyntaxError("'}' expected.");
 
1152                                 if (token != TokenName.SEMICOLON) {
 
1156                                 if (token == TokenName.SEMICOLON) {
 
1160                                 else if (token == TokenName.COLON) {            // Colon after Label identifier
 
1165                                         if (token == TokenName.RBRACE) {
 
1166                                                 reportSyntaxError ("';' expected after expression (Found token: "
 
1167                                                                 + scanner.toStringAction(token) + ")");
 
1170                                                 if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
 
1173                                                         if (token != TokenName.IDENTIFIER) {
 
1174                                                                 throwSyntaxError("identifier expected after '::'.");
 
1180                                                 else if (token != TokenName.INLINE_HTML && token != TokenName.EOF) {
 
1181                                                         throwSyntaxError ("';' expected after expression (Found token: "
 
1182                                                                         + scanner.toStringAction(token) + ")");
 
1193         private void declare_statement() {
 
1195                 // | ':' inner_statement_list T_ENDDECLARE ';'
 
1197                 if (token == TokenName.COLON) {
 
1199                         // TODO: implement inner_statement_list();
 
1201                         if (token != TokenName.ENDDECLARE) {
 
1202                                 throwSyntaxError("'enddeclare' expected in 'declare' statement.");
 
1205                         if (token != TokenName.SEMICOLON) {
 
1206                                 throwSyntaxError("';' expected after 'enddeclare' keyword.");
 
1214         private void declare_list() {
 
1215                 // T_STRING '=' static_scalar
 
1216                 // | declare_list ',' T_STRING '=' static_scalar
 
1218                         if (token != TokenName.IDENTIFIER) {
 
1219                                 throwSyntaxError("Identifier expected in 'declare' list.");
 
1222                         if (token != TokenName.EQUAL) {
 
1223                                 throwSyntaxError("'=' expected in 'declare' list.");
 
1227                         if (token != TokenName.COMMA) {
 
1234         private void additional_catches() {
 
1235                 while (token == TokenName.CATCH) {
 
1237                         if (token != TokenName.LPAREN) {
 
1238                                 throwSyntaxError("'(' expected in 'catch' statement.");
 
1241                         fully_qualified_class_name();
 
1242                         if (token != TokenName.VARIABLE) {
 
1243                                 throwSyntaxError("Variable expected in 'catch' statement.");
 
1247                         if (token != TokenName.RPAREN) {
 
1248                                 throwSyntaxError("')' expected in 'catch' statement.");
 
1251                         if (token != TokenName.LBRACE) {
 
1252                                 throwSyntaxError("'{' expected in 'catch' statement.");
 
1255                         if (token != TokenName.RBRACE) {
 
1258                         if (token != TokenName.RBRACE) {
 
1259                                 throwSyntaxError("'}' expected in 'catch' statement.");
 
1265         private void foreach_variable() {
 
1268                 if (token == TokenName.OP_AND) {
 
1274         private void foreach_optional_arg() {
 
1276                 // | T_DOUBLE_ARROW foreach_variable
 
1277                 if (token == TokenName.EQUAL_GREATER) {
 
1283         private void global_var_list() {
 
1285                 // global_var_list ',' global_var
 
1287                 HashSet set = peekVariableSet();
 
1290                         if (token != TokenName.COMMA) {
 
1297         private void global_var(HashSet set) {
 
1301                 // | '$' '{' expr '}'
 
1302                 if (token == TokenName.VARIABLE) {
 
1303                         if (fMethodVariables != null) {
 
1304                                 VariableInfo info = new VariableInfo(scanner
 
1305                                                 .getCurrentTokenStartPosition(),
 
1306                                                 VariableInfo.LEVEL_GLOBAL_VAR);
 
1307                                 fMethodVariables.put(new String(scanner
 
1308                                                 .getCurrentIdentifierSource()), info);
 
1310                         addVariableSet(set);
 
1312                 } else if (token == TokenName.DOLLAR) {
 
1314                         if (token == TokenName.LBRACE) {
 
1317                                 if (token != TokenName.RBRACE) {
 
1318                                         throwSyntaxError("'}' expected in global variable.");
 
1327         private void static_var_list() {
 
1329                 // static_var_list ',' T_VARIABLE
 
1330                 // | static_var_list ',' T_VARIABLE '=' static_scalar
 
1332                 // | T_VARIABLE '=' static_scalar,
 
1333                 HashSet set = peekVariableSet();
 
1335                         if (token == TokenName.VARIABLE) {
 
1336                                 if (fMethodVariables != null) {
 
1337                                         VariableInfo info = new VariableInfo(scanner
 
1338                                                         .getCurrentTokenStartPosition(),
 
1339                                                         VariableInfo.LEVEL_STATIC_VAR);
 
1340                                         fMethodVariables.put(new String(scanner
 
1341                                                         .getCurrentIdentifierSource()), info);
 
1343                                 addVariableSet(set);
 
1345                                 if (token == TokenName.EQUAL) {
 
1349                                 if (token != TokenName.COMMA) {
 
1359         private void unset_variables() {
 
1362                 // | unset_variables ',' unset_variable
 
1366                         variable(false, false);
 
1367                         if (token != TokenName.COMMA) {
 
1374         private final void initializeModifiers() {
 
1376                 this.modifiersSourceStart = -1;
 
1379         private final void checkAndSetModifiers(int flag) {
 
1380                 this.modifiers |= flag;
 
1381                 if (this.modifiersSourceStart < 0)
 
1382                         this.modifiersSourceStart = this.scanner.startPosition;
 
1385         private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
 
1386                 initializeModifiers();
 
1387                 if (token == TokenName.INTERFACE) {
 
1388                         // interface_entry T_STRING
 
1389                         // interface_extends_list
 
1390                         // '{' class_statement_list '}'
 
1391                         checkAndSetModifiers(AccInterface);
 
1393                         typeDecl.modifiers = this.modifiers;
 
1394                         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1395                         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1396                         if (token == TokenName.IDENTIFIER || token.compareTo (TokenName.KEYWORD) > 0) {
 
1397                                 typeDecl.name = scanner.getCurrentIdentifierSource();
 
1398                                 if (token.compareTo (TokenName.KEYWORD) > 0) {
 
1399                                         problemReporter.phpKeywordWarning(new String[] { scanner
 
1400                                                         .toStringAction(token) }, scanner
 
1401                                                         .getCurrentTokenStartPosition(), scanner
 
1402                                                         .getCurrentTokenEndPosition(), referenceContext,
 
1403                                                         compilationUnit.compilationResult);
 
1404                                         // throwSyntaxError("Don't use a keyword for interface
 
1406                                         // + scanner.toStringAction(token) + "].",
 
1407                                         // typeDecl.sourceStart, typeDecl.sourceEnd);
 
1410                                 interface_extends_list(typeDecl);
 
1412                                 typeDecl.name = new char[] { ' ' };
 
1414                                                 "Interface name expected after keyword 'interface'.",
 
1415                                                 typeDecl.sourceStart, typeDecl.sourceEnd);
 
1419                         // class_entry_type T_STRING extends_from
 
1421                         // '{' class_statement_list'}'
 
1423                         typeDecl.modifiers = this.modifiers;
 
1424                         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1425                         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1427                         // identifier 'extends' identifier
 
1428                         if (token == TokenName.IDENTIFIER || token.compareTo (TokenName.KEYWORD) > 0) {
 
1429                                 typeDecl.name = scanner.getCurrentIdentifierSource();
 
1430                                 if (token.compareTo (TokenName.KEYWORD) > 0) {
 
1431                                         problemReporter.phpKeywordWarning(new String[] { scanner
 
1432                                                         .toStringAction(token) }, scanner
 
1433                                                         .getCurrentTokenStartPosition(), scanner
 
1434                                                         .getCurrentTokenEndPosition(), referenceContext,
 
1435                                                         compilationUnit.compilationResult);
 
1436                                         // throwSyntaxError("Don't use a keyword for class
 
1438                                         // scanner.toStringAction(token) + "].",
 
1439                                         // typeDecl.sourceStart, typeDecl.sourceEnd);
 
1444                                 // | T_EXTENDS fully_qualified_class_name
 
1445                                 if (token == TokenName.EXTENDS) {
 
1446                                         class_extends_list(typeDecl);
 
1448                                         // if (token != TokenName.IDENTIFIER) {
 
1449                                         // throwSyntaxError("Class name expected after keyword
 
1451                                         // scanner.getCurrentTokenStartPosition(), scanner
 
1452                                         // .getCurrentTokenEndPosition());
 
1455                                 implements_list(typeDecl);
 
1457                                 typeDecl.name = new char[] { ' ' };
 
1458                                 throwSyntaxError("Class name expected after keyword 'class'.",
 
1459                                                 typeDecl.sourceStart, typeDecl.sourceEnd);
 
1463                 // '{' class_statement_list '}'
 
1464                 if (token == TokenName.LBRACE) {
 
1466                         if (token != TokenName.RBRACE) {
 
1467                                 ArrayList list = new ArrayList();
 
1468                                 class_statement_list(list);
 
1469                                 typeDecl.fields = new FieldDeclaration[list.size()];
 
1470                                 for (int i = 0; i < list.size(); i++) {
 
1471                                         typeDecl.fields[i] = (FieldDeclaration) list.get(i);
 
1474                         if (token == TokenName.RBRACE) {
 
1475                                 typeDecl.declarationSourceEnd = scanner
 
1476                                                 .getCurrentTokenEndPosition();
 
1479                                 throwSyntaxError("'}' expected at end of class body.");
 
1482                         throwSyntaxError("'{' expected at start of class body.");
 
1486         private void class_entry_type() {
 
1488                 // | T_ABSTRACT T_CLASS
 
1489                 // | T_FINAL T_CLASS
 
1490                 if (token == TokenName.CLASS) {
 
1492                 } else if (token == TokenName.ABSTRACT) {
 
1493                         checkAndSetModifiers(AccAbstract);
 
1495                         if (token != TokenName.CLASS) {
 
1496                                 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
 
1499                 } else if (token == TokenName.FINAL) {
 
1500                         checkAndSetModifiers(AccFinal);
 
1502                         if (token != TokenName.CLASS) {
 
1503                                 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
 
1507                         throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
 
1511         // private void class_extends(TypeDeclaration typeDecl) {
 
1513         // // | T_EXTENDS interface_list
 
1514         // if (token == TokenName.EXTENDS) {
 
1517         // if (token == TokenName.IDENTIFIER) {
 
1520         // throwSyntaxError("Class name expected after keyword 'extends'.");
 
1525         private void interface_extends_list(TypeDeclaration typeDecl) {
 
1527                 // | T_EXTENDS interface_list
 
1528                 if (token == TokenName.EXTENDS) {
 
1530                         interface_list(typeDecl);
 
1534         private void class_extends_list(TypeDeclaration typeDecl) {
 
1536                 // | T_EXTENDS interface_list
 
1537                 if (token == TokenName.EXTENDS) {
 
1539                         class_list(typeDecl);
 
1543         private void implements_list(TypeDeclaration typeDecl) {
 
1545                 // | T_IMPLEMENTS interface_list
 
1546                 if (token == TokenName.IMPLEMENTS) {
 
1548                         interface_list(typeDecl);
 
1552         private void class_list(TypeDeclaration typeDecl) {
 
1554                 // fully_qualified_class_name
 
1556                         if (token == TokenName.IDENTIFIER) {
 
1557                                 //char[] ident = scanner.getCurrentIdentifierSource();
 
1558                                 // TODO make this code working better:
 
1559                                 // SingleTypeReference ref =
 
1560                                 // ParserUtil.getTypeReference(scanner,
 
1561                                 // includesList, ident);
 
1562                                 // if (ref != null) {
 
1563                                 // typeDecl.superclass = ref;
 
1567                                 throwSyntaxError("Classname expected after keyword 'extends'.");
 
1569                         if (token == TokenName.COMMA) {
 
1570                                 reportSyntaxError("No multiple inheritance allowed. Expected token 'implements' or '{'.");
 
1579         private void interface_list(TypeDeclaration typeDecl) {
 
1581                 // fully_qualified_class_name
 
1582                 // | interface_list ',' fully_qualified_class_name
 
1584                         if (token == TokenName.IDENTIFIER) {
 
1587                                 throwSyntaxError("Interfacename expected after keyword 'implements'.");
 
1589                         if (token != TokenName.COMMA) {
 
1596         // private void classBody(TypeDeclaration typeDecl) {
 
1597         // //'{' [class-element-list] '}'
 
1598         // if (token == TokenName.LBRACE) {
 
1600         // if (token != TokenName.RBRACE) {
 
1601         // class_statement_list();
 
1603         // if (token == TokenName.RBRACE) {
 
1604         // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1607         // throwSyntaxError("'}' expected at end of class body.");
 
1610         // throwSyntaxError("'{' expected at start of class body.");
 
1613         private void class_statement_list(ArrayList list) {
 
1616                                 class_statement(list);
 
1617                                 if (token == TokenName.PUBLIC       ||
 
1618                                     token == TokenName.PROTECTED        ||
 
1619                                         token == TokenName.PRIVATE      ||
 
1620                                         token == TokenName.STATIC       ||
 
1621                                         token == TokenName.ABSTRACT     ||
 
1622                                         token == TokenName.FINAL        ||
 
1623                                         token == TokenName.FUNCTION     ||
 
1624                                         token == TokenName.VAR          ||
 
1625                                         token == TokenName.CONST) {
 
1629                                 if (token == TokenName.RBRACE) {
 
1633                                 throwSyntaxError("'}' at end of class statement.");
 
1635                         catch (SyntaxError sytaxErr1) {
 
1636                                 boolean tokenize = scanner.tokenizeStrings;
 
1639                                         scanner.tokenizeStrings = true;
 
1642                                         // if an error occured,
 
1643                                         // try to find keywords
 
1644                                         // to parse the rest of the string
 
1645                                         while (token != TokenName.EOF) {
 
1646                                                 if (token == TokenName.PUBLIC       ||
 
1647                                                         token == TokenName.PROTECTED    ||
 
1648                                                         token == TokenName.PRIVATE      ||
 
1649                                                         token == TokenName.STATIC       ||
 
1650                                                         token == TokenName.ABSTRACT     ||
 
1651                                                         token == TokenName.FINAL        ||
 
1652                                                         token == TokenName.FUNCTION     ||
 
1653                                                         token == TokenName.VAR          ||
 
1654                                                         token == TokenName.CONST) {
 
1657                                                 // System.out.println(scanner.toStringAction(token));
 
1660                                         if (token == TokenName.EOF) {
 
1664                                         scanner.tokenizeStrings = tokenize;
 
1673         private void class_statement(ArrayList list) {
 
1675                 // variable_modifiers class_variable_declaration ';'
 
1676                 // | class_constant_declaration ';'
 
1677                 // | method_modifiers T_FUNCTION is_reference T_STRING
 
1678                 // '(' parameter_list ')' method_body
 
1679                 initializeModifiers();
 
1680                 int declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1682                 if (token == TokenName.VAR) {
 
1683                         checkAndSetModifiers(AccPublic);
 
1684                         problemReporter.phpVarDeprecatedWarning(scanner
 
1685                                         .getCurrentTokenStartPosition(), scanner
 
1686                                         .getCurrentTokenEndPosition(), referenceContext,
 
1687                                         compilationUnit.compilationResult);
 
1689                         class_variable_declaration(declarationSourceStart, list);
 
1690                 } else if (token == TokenName.CONST) {
 
1691                         checkAndSetModifiers(AccFinal | AccPublic);
 
1692                         class_constant_declaration(declarationSourceStart, list);
 
1693                         if (token != TokenName.SEMICOLON) {
 
1694                                 throwSyntaxError("';' expected after class const declaration.");
 
1698                         boolean hasModifiers = member_modifiers();
 
1699                         if (token == TokenName.FUNCTION) {
 
1700                                 if (!hasModifiers) {
 
1701                                         checkAndSetModifiers(AccPublic);
 
1703                                 MethodDeclaration methodDecl = new MethodDeclaration(
 
1704                                                 this.compilationUnit.compilationResult);
 
1705                                 methodDecl.declarationSourceStart = scanner
 
1706                                                 .getCurrentTokenStartPosition();
 
1707                                 methodDecl.modifiers = this.modifiers;
 
1708                                 methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
 
1711                                         functionDefinition(methodDecl);
 
1713                                         int sourceEnd = methodDecl.sourceEnd;
 
1715                                                         || methodDecl.declarationSourceStart > sourceEnd) {
 
1716                                                 sourceEnd = methodDecl.declarationSourceStart + 1;
 
1718                                         methodDecl.declarationSourceEnd = sourceEnd;
 
1719                                         methodDecl.sourceEnd = sourceEnd;
 
1722                                 if (!hasModifiers) {
 
1723                                         throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
 
1725                                 class_variable_declaration(declarationSourceStart, list);
 
1730         private void class_constant_declaration(int declarationSourceStart,
 
1732                 // class_constant_declaration ',' T_STRING '=' static_scalar
 
1733                 // | T_CONST T_STRING '=' static_scalar
 
1734                 if (token != TokenName.CONST) {
 
1735                         throwSyntaxError("'const' keyword expected in class declaration.");
 
1740                         if (token != TokenName.IDENTIFIER) {
 
1741                                 throwSyntaxError("Identifier expected in class const declaration.");
 
1743                         FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner
 
1744                                         .getCurrentIdentifierSource(), scanner
 
1745                                         .getCurrentTokenStartPosition(), scanner
 
1746                                         .getCurrentTokenEndPosition());
 
1747                         fieldDeclaration.modifiers = this.modifiers;
 
1748                         fieldDeclaration.declarationSourceStart = declarationSourceStart;
 
1749                         fieldDeclaration.declarationSourceEnd = scanner
 
1750                                         .getCurrentTokenEndPosition();
 
1751                         fieldDeclaration.modifiersSourceStart = declarationSourceStart;
 
1752                         // fieldDeclaration.type
 
1753                         list.add(fieldDeclaration);
 
1755                         if (token != TokenName.EQUAL) {
 
1756                                 throwSyntaxError("'=' expected in class const declaration.");
 
1760                         if (token != TokenName.COMMA) {
 
1761                                 break; // while(true)-loop
 
1767         // private void variable_modifiers() {
 
1768         // // variable_modifiers:
 
1769         // // non_empty_member_modifiers
 
1771         // initializeModifiers();
 
1772         // if (token == TokenName.var) {
 
1773         // checkAndSetModifiers(AccPublic);
 
1774         // reportSyntaxError(
 
1775         // "Keyword 'var' is deprecated. Please use 'public' 'private' or
 
1777         // modifier for field declarations.",
 
1778         // scanner.getCurrentTokenStartPosition(), scanner
 
1779         // .getCurrentTokenEndPosition());
 
1782         // if (!member_modifiers()) {
 
1783         // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
 
1784         // field declarations.");
 
1788         // private void method_modifiers() {
 
1789         // //method_modifiers:
 
1791         // //| non_empty_member_modifiers
 
1792         // initializeModifiers();
 
1793         // if (!member_modifiers()) {
 
1794         // checkAndSetModifiers(AccPublic);
 
1797         private boolean member_modifiers() {
 
1804                 boolean foundToken = false;
 
1806                         if (token == TokenName.PUBLIC) {
 
1807                                 checkAndSetModifiers(AccPublic);
 
1810                         } else if (token == TokenName.PROTECTED) {
 
1811                                 checkAndSetModifiers(AccProtected);
 
1814                         } else if (token == TokenName.PRIVATE) {
 
1815                                 checkAndSetModifiers(AccPrivate);
 
1818                         } else if (token == TokenName.STATIC) {
 
1819                                 checkAndSetModifiers(AccStatic);
 
1822                         } else if (token == TokenName.ABSTRACT) {
 
1823                                 checkAndSetModifiers(AccAbstract);
 
1826                         } else if (token == TokenName.FINAL) {
 
1827                                 checkAndSetModifiers(AccFinal);
 
1837         private void class_variable_declaration(int declarationSourceStart,
 
1839                 // class_variable_declaration:
 
1840                 // class_variable_declaration ',' T_VARIABLE
 
1841                 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
 
1843                 // | T_VARIABLE '=' static_scalar
 
1844                 char[] classVariable;
 
1846                         if (token == TokenName.VARIABLE) {
 
1847                                 classVariable = scanner.getCurrentIdentifierSource();
 
1848                                 // indexManager.addIdentifierInformation('v', classVariable,
 
1851                                 FieldDeclaration fieldDeclaration = new FieldDeclaration(
 
1852                                                 classVariable, scanner.getCurrentTokenStartPosition(),
 
1853                                                 scanner.getCurrentTokenEndPosition());
 
1854                                 fieldDeclaration.modifiers = this.modifiers;
 
1855                                 fieldDeclaration.declarationSourceStart = declarationSourceStart;
 
1856                                 fieldDeclaration.declarationSourceEnd = scanner
 
1857                                                 .getCurrentTokenEndPosition();
 
1858                                 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
 
1859                                 list.add(fieldDeclaration);
 
1860                                 if (fTypeVariables != null) {
 
1861                                         VariableInfo info = new VariableInfo(scanner
 
1862                                                         .getCurrentTokenStartPosition(),
 
1863                                                         VariableInfo.LEVEL_CLASS_UNIT);
 
1864                                         fTypeVariables.put(new String(scanner
 
1865                                                         .getCurrentIdentifierSource()), info);
 
1868                                 if (token == TokenName.EQUAL) {
 
1873                                 // if (token == TokenName.THIS) {
 
1874                                 // throwSyntaxError("'$this' not allowed after keyword 'public'
 
1875                                 // 'protected' 'private' 'var'.");
 
1877                                 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
 
1879                         if (token != TokenName.COMMA) {
 
1884                 if (token != TokenName.SEMICOLON) {
 
1885                         throwSyntaxError("';' expected after field declaration.");
 
1890         private void functionDefinition(MethodDeclaration methodDecl) {
 
1891                 boolean isAbstract = false;
 
1893                         if (compilationUnit != null) {
 
1894                                 compilationUnit.types.add(methodDecl);
 
1897                         ASTNode node = astStack[astPtr];
 
1898                         if (node instanceof TypeDeclaration) {
 
1899                                 TypeDeclaration typeDecl = ((TypeDeclaration) node);
 
1900                                 if (typeDecl.methods == null) {
 
1901                                         typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl };
 
1903                                         AbstractMethodDeclaration[] newMethods;
 
1908                                                                         newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
 
1909                                                                         0, typeDecl.methods.length);
 
1910                                         newMethods[typeDecl.methods.length] = methodDecl;
 
1911                                         typeDecl.methods = newMethods;
 
1913                                 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
 
1915                                 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
 
1921                         pushFunctionVariableSet();
 
1922                         functionDeclarator(methodDecl);
 
1923                         if (token == TokenName.SEMICOLON) {
 
1925                                         methodDecl.sourceEnd = scanner
 
1926                                                         .getCurrentTokenStartPosition() - 1;
 
1927                                         throwSyntaxError("Body declaration expected for method: "
 
1928                                                         + new String(methodDecl.selector));
 
1933                         functionBody(methodDecl);
 
1935                         if (!fStackUnassigned.isEmpty()) {
 
1936                                 fStackUnassigned.remove(fStackUnassigned.size() - 1);
 
1941         private void functionDeclarator(MethodDeclaration methodDecl) {
 
1942                 // identifier '(' [parameter-list] ')'
 
1943                 if (token == TokenName.OP_AND) {
 
1947                 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1948                 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1950                 if (Scanner.isIdentifierOrKeyword (token) ||
 
1951                     token == TokenName.LPAREN) {
 
1953                     if (token == TokenName.LPAREN) {
 
1954                         methodDecl.selector = scanner.getCurrentIdentifierSource();
 
1956                 if (token.compareTo (TokenName.KEYWORD) > 0) {
 
1957                     problemReporter.phpKeywordWarning (new String[] {scanner.toStringAction(token) },
 
1958                                                        scanner.getCurrentTokenStartPosition(),
 
1959                                                        scanner.getCurrentTokenEndPosition(),
 
1961                                                        compilationUnit.compilationResult);
 
1965                         methodDecl.selector = scanner.getCurrentIdentifierSource();
 
1967                         if (token.compareTo (TokenName.KEYWORD) > 0) {
 
1968                             problemReporter.phpKeywordWarning (new String[] {scanner.toStringAction(token) },
 
1969                                                                                scanner.getCurrentTokenStartPosition(),
 
1970                                                                                scanner.getCurrentTokenEndPosition(),
 
1972                                                                                compilationUnit.compilationResult);
 
1978                         if (token == TokenName.LPAREN) {
 
1982                                 methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
1983                                 throwSyntaxError("'(' expected in function declaration.");
 
1986                         if (token != TokenName.RPAREN) {
 
1987                                 parameter_list(methodDecl);
 
1990                         if (token != TokenName.RPAREN) {
 
1991                                 methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
1992                                 throwSyntaxError("')' expected in function declaration.");
 
1995                                 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
 
2000                         methodDecl.selector = "<undefined>".toCharArray();
 
2001                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
2002                         throwSyntaxError("Function name expected after keyword 'function'.");
 
2007         private void parameter_list(MethodDeclaration methodDecl) {
 
2008                 // non_empty_parameter_list
 
2010                 non_empty_parameter_list(methodDecl, true);
 
2013         private void non_empty_parameter_list(MethodDeclaration methodDecl,
 
2014                         boolean empty_allowed) {
 
2015                 // optional_class_type T_VARIABLE
 
2016                 // | optional_class_type '&' T_VARIABLE
 
2017                 // | optional_class_type '&' T_VARIABLE '=' static_scalar
 
2018                 // | optional_class_type T_VARIABLE '=' static_scalar
 
2019                 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
 
2020                 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
 
2021                 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
 
2023                 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
 
2025                 char[] typeIdentifier = null;
 
2026                 if (token == TokenName.IDENTIFIER ||
 
2027                     token == TokenName.ARRAY      ||
 
2028                     token == TokenName.VARIABLE   ||
 
2029                     token == TokenName.OP_AND) {
 
2030                         HashSet set = peekVariableSet();
 
2033                                 if (token == TokenName.IDENTIFIER || token == TokenName.ARRAY) {// feature req. #1254275
 
2034                                         typeIdentifier = scanner.getCurrentIdentifierSource();
 
2037                                 if (token == TokenName.OP_AND) {
 
2040                                 if (token == TokenName.VARIABLE) {
 
2041                                         if (fMethodVariables != null) {
 
2043                                                 if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) {
 
2044                                                         info = new VariableInfo(scanner
 
2045                                                                         .getCurrentTokenStartPosition(),
 
2046                                                                         VariableInfo.LEVEL_FUNCTION_DEFINITION);
 
2048                                                         info = new VariableInfo(scanner
 
2049                                                                         .getCurrentTokenStartPosition(),
 
2050                                                                         VariableInfo.LEVEL_METHOD_DEFINITION);
 
2052                                                 info.typeIdentifier = typeIdentifier;
 
2053                                                 fMethodVariables.put(new String(scanner
 
2054                                                                 .getCurrentIdentifierSource()), info);
 
2056                                         addVariableSet(set);
 
2058                                         if (token == TokenName.EQUAL) {
 
2063                                         throwSyntaxError("Variable expected in parameter list.");
 
2065                                 if (token != TokenName.COMMA) {
 
2072                 if (!empty_allowed) {
 
2073                         throwSyntaxError("Identifier expected in parameter list.");
 
2077 //      private void optional_class_type() {
 
2082         // private void parameterDeclaration() {
 
2084         // //variable-reference
 
2085         // if (token == TokenName.AND) {
 
2087         // if (isVariable()) {
 
2090         // throwSyntaxError("Variable expected after reference operator '&'.");
 
2093         // //variable '=' constant
 
2094         // if (token == TokenName.VARIABLE) {
 
2096         // if (token == TokenName.EQUAL) {
 
2102         // // if (token == TokenName.THIS) {
 
2103         // // throwSyntaxError("Reserved word '$this' not allowed in parameter
 
2104         // // declaration.");
 
2108         private void labeledStatementList() {
 
2109                 if (token != TokenName.CASE && token != TokenName.DEFAULT) {
 
2110                         throwSyntaxError("'case' or 'default' expected.");
 
2113                         if (token == TokenName.CASE) {
 
2115                                 expr_without_variable (true, null, true); // constant();
 
2116                                 if (token == TokenName.COLON || token == TokenName.SEMICOLON) {
 
2118                                         if (token == TokenName.RBRACE) {
 
2119                                                 // empty case; assumes that the '}' token belongs to the wrapping
 
2120                                                 // switch statement - #1371992
 
2123                                         if (token == TokenName.CASE || token == TokenName.DEFAULT) {
 
2124                                                 // empty case statement ?
 
2129                                 // else if (token == TokenName.SEMICOLON) {
 
2131                                 // "':' expected after 'case' keyword (Found token: " +
 
2132                                 // scanner.toStringAction(token) + ")",
 
2133                                 // scanner.getCurrentTokenStartPosition(),
 
2134                                 // scanner.getCurrentTokenEndPosition(),
 
2137                                 // if (token == TokenName.CASE) { // empty case statement ?
 
2143                                         throwSyntaxError("':' character expected after 'case' constant (Found token: "
 
2144                                                         + scanner.toStringAction(token) + ")");
 
2146                         } else { // TokenName.DEFAULT
 
2148                                 if (token == TokenName.COLON || token == TokenName.SEMICOLON) {
 
2150                                         if (token == TokenName.RBRACE) {
 
2151                                                 // empty default case; ; assumes that the '}' token belongs to the
 
2152                                                 // wrapping switch statement - #1371992
 
2155                                         if (token != TokenName.CASE) {
 
2159                                         throwSyntaxError("':' character expected after 'default'.");
 
2162                 } while (token == TokenName.CASE || token == TokenName.DEFAULT);
 
2165         private void ifStatementColon(IfStatement iState) {
 
2166                 // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
 
2167                 // new_else_single T_ENDIF ';'
 
2168                 HashSet assignedVariableSet = null;
 
2170                         Block b = inner_statement_list();
 
2171                         iState.thenStatement = b;
 
2172                         checkUnreachable(iState, b);
 
2174                         assignedVariableSet = removeIfVariableSet();
 
2176                 if (token == TokenName.ELSEIF) {
 
2178                                 pushIfVariableSet();
 
2179                                 new_elseif_list(iState);
 
2181                                 HashSet set = removeIfVariableSet();
 
2182                                 if (assignedVariableSet != null && set != null) {
 
2183                                         assignedVariableSet.addAll(set);
 
2188                         pushIfVariableSet();
 
2189                         new_else_single(iState);
 
2191                         HashSet set = removeIfVariableSet();
 
2192                         if (assignedVariableSet != null) {
 
2193                                 HashSet topSet = peekVariableSet();
 
2194                                 if (topSet != null) {
 
2198                                         topSet.addAll(assignedVariableSet);
 
2202                 if (token != TokenName.ENDIF) {
 
2203                         throwSyntaxError("'endif' expected.");
 
2206                 if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
 
2207                         reportSyntaxError("';' expected after if-statement.");
 
2208                         iState.sourceEnd = scanner.getCurrentTokenStartPosition();
 
2210                         iState.sourceEnd = scanner.getCurrentTokenEndPosition();
 
2215         private void ifStatement(IfStatement iState) {
 
2216                 // T_IF '(' expr ')' statement elseif_list else_single
 
2217                 HashSet assignedVariableSet = null;
 
2219                         pushIfVariableSet();
 
2220                         Statement s = statement();
 
2221                         iState.thenStatement = s;
 
2222                         checkUnreachable(iState, s);
 
2224                         assignedVariableSet = removeIfVariableSet();
 
2227                 if (token == TokenName.ELSEIF) {
 
2229                                 pushIfVariableSet();
 
2230                                 elseif_list(iState);
 
2232                                 HashSet set = removeIfVariableSet();
 
2233                                 if (assignedVariableSet != null && set != null) {
 
2234                                         assignedVariableSet.addAll(set);
 
2239                         pushIfVariableSet();
 
2240                         else_single(iState);
 
2242                         HashSet set = removeIfVariableSet();
 
2243                         if (assignedVariableSet != null) {
 
2244                                 HashSet topSet = peekVariableSet();
 
2245                                 if (topSet != null) {
 
2249                                         topSet.addAll(assignedVariableSet);
 
2255         private void elseif_list(IfStatement iState) {
 
2257                 // | elseif_list T_ELSEIF '(' expr ')' statement
 
2258                 ArrayList conditionList = new ArrayList();
 
2259                 ArrayList statementList = new ArrayList();
 
2262                 while (token == TokenName.ELSEIF) {
 
2264                         if (token == TokenName.LPAREN) {
 
2267                                 throwSyntaxError("'(' expected after 'elseif' keyword.");
 
2270                         conditionList.add(e);
 
2271                         if (token == TokenName.RPAREN) {
 
2274                                 throwSyntaxError("')' expected after 'elseif' condition.");
 
2277                         statementList.add(s);
 
2278                         checkUnreachable(iState, s);
 
2280                 iState.elseifConditions = new Expression[conditionList.size()];
 
2281                 iState.elseifStatements = new Statement[statementList.size()];
 
2282                 conditionList.toArray(iState.elseifConditions);
 
2283                 statementList.toArray(iState.elseifStatements);
 
2286         private void new_elseif_list(IfStatement iState) {
 
2288                 // | new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
 
2289                 ArrayList conditionList = new ArrayList();
 
2290                 ArrayList statementList = new ArrayList();
 
2293                 while (token == TokenName.ELSEIF) {
 
2295                         if (token == TokenName.LPAREN) {
 
2298                                 throwSyntaxError("'(' expected after 'elseif' keyword.");
 
2301                         conditionList.add(e);
 
2302                         if (token == TokenName.RPAREN) {
 
2305                                 throwSyntaxError("')' expected after 'elseif' condition.");
 
2307                         if (token == TokenName.COLON) {
 
2310                                 throwSyntaxError("':' expected after 'elseif' keyword.");
 
2312                         b = inner_statement_list();
 
2313                         statementList.add(b);
 
2314                         checkUnreachable(iState, b);
 
2316                 iState.elseifConditions = new Expression[conditionList.size()];
 
2317                 iState.elseifStatements = new Statement[statementList.size()];
 
2318                 conditionList.toArray(iState.elseifConditions);
 
2319                 statementList.toArray(iState.elseifStatements);
 
2322         private void else_single(IfStatement iState) {
 
2325                 if (token == TokenName.ELSE) {
 
2327                         Statement s = statement();
 
2328                         iState.elseStatement = s;
 
2329                         checkUnreachable(iState, s);
 
2331                         iState.checkUnreachable = false;
 
2333                 iState.sourceEnd = scanner.getCurrentTokenStartPosition();
 
2336         private void new_else_single(IfStatement iState) {
 
2338                 // | T_ELSE ':' inner_statement_list
 
2339                 if (token == TokenName.ELSE) {
 
2341                         if (token == TokenName.COLON) {
 
2344                                 throwSyntaxError("':' expected after 'else' keyword.");
 
2346                         Block b = inner_statement_list();
 
2347                         iState.elseStatement = b;
 
2348                         checkUnreachable(iState, b);
 
2350                         iState.checkUnreachable = false;
 
2354         private Block inner_statement_list() {
 
2355                 // inner_statement_list inner_statement
 
2357                 return statementList();
 
2364         private void checkUnreachable(IfStatement iState, Statement s) {
 
2365                 if (s instanceof Block) {
 
2366                         Block b = (Block) s;
 
2367                         if (b.statements == null || b.statements.length == 0) {
 
2368                                 iState.checkUnreachable = false;
 
2370                                 int off = b.statements.length - 1;
 
2371                                 if (!(b.statements[off] instanceof ReturnStatement)
 
2372                                                 && !(b.statements[off] instanceof ContinueStatement)
 
2373                                                 && !(b.statements[off] instanceof BreakStatement)) {
 
2374                                         if (!(b.statements[off] instanceof IfStatement)
 
2375                                                         || !((IfStatement) b.statements[off]).checkUnreachable) {
 
2376                                                 iState.checkUnreachable = false;
 
2381                         if (!(s instanceof ReturnStatement)
 
2382                                         && !(s instanceof ContinueStatement)
 
2383                                         && !(s instanceof BreakStatement)) {
 
2384                                 if (!(s instanceof IfStatement)
 
2385                                                 || !((IfStatement) s).checkUnreachable) {
 
2386                                         iState.checkUnreachable = false;
 
2392         // private void elseifStatementList() {
 
2394         // elseifStatement();
 
2396         // case TokenName.else:
 
2398         // if (token == TokenName.COLON) {
 
2400         // if (token != TokenName.endif) {
 
2405         // if (token == TokenName.if) { //'else if'
 
2408         // throwSyntaxError("':' expected after 'else'.");
 
2412         // case TokenName.elseif:
 
2421         // private void elseifStatement() {
 
2422         // if (token == TokenName.LPAREN) {
 
2425         // if (token != TokenName.RPAREN) {
 
2426         // throwSyntaxError("')' expected in else-if-statement.");
 
2429         // if (token != TokenName.COLON) {
 
2430         // throwSyntaxError("':' expected in else-if-statement.");
 
2433         // if (token != TokenName.endif) {
 
2439         private void switchStatement() {
 
2440                 if (token == TokenName.COLON) {
 
2441                         // ':' [labeled-statement-list] 'endswitch' ';'
 
2443                         labeledStatementList();
 
2444                         if (token != TokenName.ENDSWITCH) {
 
2445                                 throwSyntaxError("'endswitch' expected.");
 
2448                         if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
 
2449                                 throwSyntaxError("';' expected after switch-statement.");
 
2453                         // '{' [labeled-statement-list] '}'
 
2454                         if (token != TokenName.LBRACE) {
 
2455                                 throwSyntaxError("'{' expected in switch statement.");
 
2458                         if (token != TokenName.RBRACE) {
 
2459                                 labeledStatementList();
 
2461                         if (token != TokenName.RBRACE) {
 
2462                                 throwSyntaxError("'}' expected in switch statement.");
 
2468         private void forStatement() {
 
2469                 if (token == TokenName.COLON) {
 
2472                         if (token != TokenName.ENDFOR) {
 
2473                                 throwSyntaxError("'endfor' expected.");
 
2476                         if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
 
2477                                 throwSyntaxError("';' expected after for-statement.");
 
2485         private void whileStatement() {
 
2486                 // ':' statement-list 'endwhile' ';'
 
2487                 if (token == TokenName.COLON) {
 
2490                         if (token != TokenName.ENDWHILE) {
 
2491                                 throwSyntaxError("'endwhile' expected.");
 
2494                         if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
 
2495                                 throwSyntaxError("';' expected after while-statement.");
 
2503         private void foreachStatement() {
 
2504                 if (token == TokenName.COLON) {
 
2507                         if (token != TokenName.ENDFOREACH) {
 
2508                                 throwSyntaxError("'endforeach' expected.");
 
2511                         if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
 
2512                                 throwSyntaxError("';' expected after foreach-statement.");
 
2520         // private void exitStatus() {
 
2521         // if (token == TokenName.LPAREN) {
 
2524         // throwSyntaxError("'(' expected in 'exit-status'.");
 
2526         // if (token != TokenName.RPAREN) {
 
2529         // if (token == TokenName.RPAREN) {
 
2532         // throwSyntaxError("')' expected after 'exit-status'.");
 
2538     private void namespacePath () {
 
2540            expr_without_variable (true, null, false);
 
2542            if (token == TokenName.BACKSLASH) {
 
2553         private void expressionList() {
 
2555                         expr_without_variable (true, null, false);
 
2557                         if (token == TokenName.COMMA) {         // If it's a list of (comma separated) expressions
 
2558                                 getNextToken();                     // read all in, untill no more found
 
2565         private Expression expr() {
 
2566                 return expr_without_variable(true, null, false);
 
2571          * @param only_variable
 
2572          * @param initHandler
 
2574         private Expression expr_without_variable (boolean only_variable,
 
2575                                                   UninitializedVariableHandler initHandler,
 
2576                                                   boolean bColonAllowed) {
 
2577                 int exprSourceStart    = scanner.getCurrentTokenStartPosition();
 
2578                 int exprSourceEnd      = scanner.getCurrentTokenEndPosition();
 
2579                 Expression expression  = new Expression();
 
2581                 expression.sourceStart = exprSourceStart;
 
2582                 expression.sourceEnd   = exprSourceEnd;                     // default, may be overwritten
 
2585                         // internal_functions_in_yacc
 
2594                         // | T_INC rw_variable
 
2595                         // | T_DEC rw_variable
 
2596                         // | T_INT_CAST expr
 
2597                         // | T_DOUBLE_CAST expr
 
2598                         // | T_STRING_CAST expr
 
2599                         // | T_ARRAY_CAST expr
 
2600                         // | T_OBJECT_CAST expr
 
2601                         // | T_BOOL_CAST expr
 
2602                         // | T_UNSET_CAST expr
 
2603                         // | T_EXIT exit_expr
 
2605                         // | T_ARRAY '(' array_pair_list ')'
 
2606                         // | '`' encaps_list '`'
 
2607                         // | T_LIST '(' assignment_list ')' '=' expr
 
2608                         // | T_NEW class_name_reference ctor_arguments
 
2609                         // | variable '=' expr
 
2610                         // | variable '=' '&' variable
 
2611                         // | variable '=' '&' T_NEW class_name_reference ctor_arguments
 
2612                         // | variable T_PLUS_EQUAL expr
 
2613                         // | variable T_MINUS_EQUAL expr
 
2614                         // | variable T_MUL_EQUAL expr
 
2615                         // | variable T_DIV_EQUAL expr
 
2616                         // | variable T_CONCAT_EQUAL expr
 
2617                         // | variable T_MOD_EQUAL expr
 
2618                         // | variable T_AND_EQUAL expr
 
2619                         // | variable T_OR_EQUAL expr
 
2620                         // | variable T_XOR_EQUAL expr
 
2621                         // | variable T_SL_EQUAL expr
 
2622                         // | variable T_SR_EQUAL expr
 
2623                         // | rw_variable T_INC
 
2624                         // | rw_variable T_DEC
 
2625                         // | expr T_BOOLEAN_OR expr
 
2626                         // | expr T_BOOLEAN_AND expr
 
2627                         // | expr T_LOGICAL_OR expr
 
2628                         // | expr T_LOGICAL_AND expr
 
2629                         // | expr T_LOGICAL_XOR expr
 
2641                         // | expr T_IS_IDENTICAL expr
 
2642                         // | expr T_IS_NOT_IDENTICAL expr
 
2643                         // | expr T_IS_EQUAL expr
 
2644                         // | expr T_IS_NOT_EQUAL expr
 
2646                         // | expr T_IS_SMALLER_OR_EQUAL expr
 
2648                         // | expr T_IS_GREATER_OR_EQUAL expr
 
2649                         // | expr T_INSTANCEOF class_name_reference
 
2650                         // | expr '?' expr ':' expr
 
2651                         if (Scanner.TRACE) {
 
2652                                 System.out.println("TRACE: expr_without_variable() PART 1");
 
2657                                         // T_ISSET '(' isset_variables ')'
 
2659                                         if (token != TokenName.LPAREN) {
 
2660                                                 throwSyntaxError("'(' expected after keyword 'isset'");
 
2664                                         if (token != TokenName.RPAREN) {
 
2665                                                 throwSyntaxError("')' expected after keyword 'isset'");
 
2671                                         if (token != TokenName.LPAREN) {
 
2672                                                 throwSyntaxError("'(' expected after keyword 'empty'");
 
2675                                         variable(true, false);
 
2676                                         if (token != TokenName.RPAREN) {
 
2677                                                 throwSyntaxError("')' expected after keyword 'empty'");
 
2686                                         internal_functions_in_yacc();
 
2693                                         if (token == TokenName.RPAREN) {
 
2696                                                 throwSyntaxError("')' expected in expression.");
 
2706                                 // | T_INT_CAST expr
 
2707                                 // | T_DOUBLE_CAST expr
 
2708                                 // | T_STRING_CAST expr
 
2709                                 // | T_ARRAY_CAST expr
 
2710                                 // | T_OBJECT_CAST expr
 
2711                                 // | T_BOOL_CAST expr
 
2712                                 // | T_UNSET_CAST expr
 
2728                     expr_without_variable (only_variable, initHandler, bColonAllowed);
 
2736                                 // | T_STRING_VARNAME
 
2738                                 // | T_START_HEREDOC encaps_list T_END_HEREDOC
 
2739                                 // | '`' encaps_list '`'
 
2741                                 // | '`' encaps_list '`'
 
2742                                 // case TokenName.EncapsedString0:
 
2743                                 // scanner.encapsedStringStack.push(new Character('`'));
 
2746                                 // if (token == TokenName.EncapsedString0) {
 
2749                                 // if (token != TokenName.EncapsedString0) {
 
2750                                 // throwSyntaxError("\'`\' expected at end of string" + "(Found
 
2752                                 // scanner.toStringAction(token) + " )");
 
2756                                 // scanner.encapsedStringStack.pop();
 
2760                                 // // | '\'' encaps_list '\''
 
2761                                 // case TokenName.EncapsedString1:
 
2762                                 // scanner.encapsedStringStack.push(new Character('\''));
 
2765                                 // exprSourceStart = scanner.getCurrentTokenStartPosition();
 
2766                                 // if (token == TokenName.EncapsedString1) {
 
2768                                 // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2769                                 // exprSourceStart, scanner
 
2770                                 // .getCurrentTokenEndPosition());
 
2773                                 // if (token != TokenName.EncapsedString1) {
 
2774                                 // throwSyntaxError("\'\'\' expected at end of string" + "(Found
 
2776                                 // + scanner.toStringAction(token) + " )");
 
2779                                 // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2780                                 // exprSourceStart, scanner
 
2781                                 // .getCurrentTokenEndPosition());
 
2785                                 // scanner.encapsedStringStack.pop();
 
2789                                 // //| '"' encaps_list '"'
 
2790                                 // case TokenName.EncapsedString2:
 
2791                                 // scanner.encapsedStringStack.push(new Character('"'));
 
2794                                 // exprSourceStart = scanner.getCurrentTokenStartPosition();
 
2795                                 // if (token == TokenName.EncapsedString2) {
 
2797                                 // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2798                                 // exprSourceStart, scanner
 
2799                                 // .getCurrentTokenEndPosition());
 
2802                                 // if (token != TokenName.EncapsedString2) {
 
2803                                 // throwSyntaxError("'\"' expected at end of string" + "(Found
 
2805                                 // scanner.toStringAction(token) + " )");
 
2808                                 // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2809                                 // exprSourceStart, scanner
 
2810                                 // .getCurrentTokenEndPosition());
 
2814                                 // scanner.encapsedStringStack.pop();
 
2818                                 case STRINGDOUBLEQUOTE:
 
2819                                         expression = new StringLiteralDQ (scanner.getCurrentStringLiteralSource(),
 
2820                                                                           scanner.getCurrentTokenStartPosition(),
 
2821                                                                                                           scanner.getCurrentTokenEndPosition());
 
2824                                 case STRINGSINGLEQUOTE:
 
2825                                         expression = new StringLiteralSQ (scanner.getCurrentStringLiteralSource(),
 
2826                                                                           scanner.getCurrentTokenStartPosition(),
 
2827                                                                                                           scanner.getCurrentTokenEndPosition());
 
2830                                 case INTEGERLITERAL:
 
2832                                 case STRINGINTERPOLATED:
 
2844                                         // T_ARRAY '(' array_pair_list ')'
 
2846                                         if (token == TokenName.LPAREN) {
 
2848                                                 if (token == TokenName.RPAREN) {
 
2853                                                 if (token != TokenName.RPAREN) {
 
2854                                                         throwSyntaxError("')' or ',' expected after keyword 'array'"
 
2856                                                                         + scanner.toStringAction(token) + ")");
 
2860                                                 throwSyntaxError("'(' expected after keyword 'array'"
 
2861                                                                 + "(Found token: " + scanner.toStringAction(token)
 
2866                                         // | T_LIST '(' assignment_list ')' '=' expr
 
2868                                         if (token == TokenName.LPAREN) {
 
2871                                                 if (token != TokenName.RPAREN) {
 
2872                                                         throwSyntaxError("')' expected after 'list' keyword.");
 
2875                                                 if (token != TokenName.EQUAL) {
 
2876                                                         throwSyntaxError("'=' expected after 'list' keyword.");
 
2881                                                 throwSyntaxError("'(' expected after 'list' keyword.");
 
2885                                         // | T_NEW class_name_reference ctor_arguments
 
2887                                         Expression typeRef = class_name_reference();
 
2889                                         if (typeRef != null) {
 
2890                                                 expression = typeRef;
 
2893                                 // | T_INC rw_variable
 
2894                                 // | T_DEC rw_variable
 
2900                                 // | variable '=' expr
 
2901                                 // | variable '=' '&' variable
 
2902                                 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
 
2903                                 // | variable T_PLUS_EQUAL expr
 
2904                                 // | variable T_MINUS_EQUAL expr
 
2905                                 // | variable T_MUL_EQUAL expr
 
2906                                 // | variable T_DIV_EQUAL expr
 
2907                                 // | variable T_CONCAT_EQUAL expr
 
2908                                 // | variable T_MOD_EQUAL expr
 
2909                                 // | variable T_AND_EQUAL expr
 
2910                                 // | variable T_OR_EQUAL expr
 
2911                                 // | variable T_XOR_EQUAL expr
 
2912                                 // | variable T_SL_EQUAL expr
 
2913                                 // | variable T_SR_EQUAL expr
 
2914                                 // | rw_variable T_INC
 
2915                                 // | rw_variable T_DEC
 
2919                                         Expression lhs = null;
 
2920                                         boolean rememberedVar = false;
 
2922                                         if (token == TokenName.IDENTIFIER) {
 
2923                                                 lhs = identifier(true, true, bColonAllowed);
 
2930                                                 lhs = variable (true, true);
 
2937                                                     lhs instanceof FieldReference        &&
 
2938                                                         token != TokenName.EQUAL             &&
 
2939                                                         token != TokenName.PLUS_EQUAL        &&
 
2940                                                         token != TokenName.MINUS_EQUAL       &&
 
2941                                                         token != TokenName.MULTIPLY_EQUAL    &&
 
2942                                                         token != TokenName.DIVIDE_EQUAL      &&
 
2943                                                         token != TokenName.DOT_EQUAL         &&
 
2944                                                         token != TokenName.REMAINDER_EQUAL   &&
 
2945                                                         token != TokenName.AND_EQUAL         &&
 
2946                                                         token != TokenName.OR_EQUAL          &&
 
2947                                                         token != TokenName.XOR_EQUAL         &&
 
2948                                                         token != TokenName.RIGHT_SHIFT_EQUAL &&
 
2949                                                         token != TokenName.LEFT_SHIFT_EQUAL) {
 
2951                                                         FieldReference ref = (FieldReference) lhs;
 
2953                                                         if (!containsVariableSet(ref.token)) {
 
2954                                                                 if (null == initHandler || initHandler.reportError()) {
 
2955                                                                         problemReporter.uninitializedLocalVariable(
 
2956                                                                                         new String(ref.token), ref.sourceStart,
 
2957                                                                                         ref.sourceEnd, referenceContext,
 
2958                                                                                         compilationUnit.compilationResult);
 
2960                                                                 addVariableSet(ref.token);
 
2967                                                         if (lhs != null && lhs instanceof FieldReference) {
 
2968                                                                 addVariableSet(((FieldReference) lhs).token);
 
2971                                                         if (token == TokenName.OP_AND) {
 
2973                                                                 if (token == TokenName.NEW) {
 
2974                                                                         // | variable '=' '&' T_NEW class_name_reference
 
2977                                                                         SingleTypeReference classRef = class_name_reference();
 
2979                                                                         if (classRef != null) {
 
2981                                                                                                 && lhs instanceof FieldReference) {
 
2983                                                                                         // $var = & new Object();
 
2984                                                                                         if (fMethodVariables != null) {
 
2985                                                                                                 VariableInfo lhsInfo = new VariableInfo(
 
2986                                                                                                                 ((FieldReference) lhs).sourceStart);
 
2987                                                                                                 lhsInfo.reference = classRef;
 
2988                                                                                                 lhsInfo.typeIdentifier = classRef.token;
 
2989                                                                                                 fMethodVariables.put(new String(
 
2990                                                                                                                 ((FieldReference) lhs).token),
 
2992                                                                                                 rememberedVar = true;
 
2997                                                                         Expression rhs = variable(false, false);
 
2998                                                                         if (rhs != null && rhs instanceof FieldReference
 
3000                                                                                         && lhs instanceof FieldReference) {
 
3003                                                                                 if (fMethodVariables != null) {
 
3004                                                                                         VariableInfo rhsInfo = (VariableInfo) fMethodVariables
 
3005                                                                                                         .get(((FieldReference) rhs).token);
 
3007                                                                                                         && rhsInfo.reference != null) {
 
3008                                                                                                 VariableInfo lhsInfo = new VariableInfo(
 
3009                                                                                                                 ((FieldReference) lhs).sourceStart);
 
3010                                                                                                 lhsInfo.reference = rhsInfo.reference;
 
3011                                                                                                 lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
 
3012                                                                                                 fMethodVariables.put(new String(
 
3013                                                                                                                 ((FieldReference) lhs).token),
 
3015                                                                                                 rememberedVar = true;
 
3021                                                                 Expression rhs = expr_without_variable (only_variable, initHandler, bColonAllowed);
 
3023                                                                 if (lhs != null && lhs instanceof FieldReference) {
 
3024                                                                         if (rhs != null && rhs instanceof FieldReference) {
 
3027                                                                                 if (fMethodVariables != null) {
 
3028                                                                                         VariableInfo rhsInfo = (VariableInfo) fMethodVariables
 
3029                                                                                                         .get(((FieldReference) rhs).token);
 
3031                                                                                                         && rhsInfo.reference != null) {
 
3032                                                                                                 VariableInfo lhsInfo = new VariableInfo(
 
3033                                                                                                                 ((FieldReference) lhs).sourceStart);
 
3034                                                                                                 lhsInfo.reference = rhsInfo.reference;
 
3035                                                                                                 lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
 
3036                                                                                                 fMethodVariables.put(new String(
 
3037                                                                                                                 ((FieldReference) lhs).token),
 
3039                                                                                                 rememberedVar = true;
 
3042                                                                         } else if (rhs != null
 
3043                                                                                         && rhs instanceof SingleTypeReference) {
 
3045                                                                                 // $var = new Object();
 
3046                                                                                 if (fMethodVariables != null) {
 
3047                                                                                         VariableInfo lhsInfo = new VariableInfo(
 
3048                                                                                                         ((FieldReference) lhs).sourceStart);
 
3049                                                                                         lhsInfo.reference = (SingleTypeReference) rhs;
 
3050                                                                                         lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token;
 
3051                                                                                         fMethodVariables.put(new String(
 
3052                                                                                                         ((FieldReference) lhs).token),
 
3054                                                                                         rememberedVar = true;
 
3059                                                         if (rememberedVar == false && lhs != null
 
3060                                                                         && lhs instanceof FieldReference) {
 
3061                                                                 if (fMethodVariables != null) {
 
3062                                                                         VariableInfo lhsInfo = new VariableInfo(
 
3063                                                                                         ((FieldReference) lhs).sourceStart);
 
3064                                                                         fMethodVariables.put(new String(
 
3065                                                                                         ((FieldReference) lhs).token), lhsInfo);
 
3071                                                 case MULTIPLY_EQUAL:
 
3074                                                 case REMAINDER_EQUAL:
 
3078                                                 case RIGHT_SHIFT_EQUAL:
 
3079                                                 case LEFT_SHIFT_EQUAL:
 
3080                                                         if (lhs != null && lhs instanceof FieldReference) {
 
3081                                                                 addVariableSet(((FieldReference) lhs).token);
 
3084                                                         expr_without_variable (only_variable, initHandler, bColonAllowed);
 
3091                                                         if (!only_variable) {
 
3092                                                                 throwSyntaxError("Variable expression not allowed (found token '"
 
3093                                                                                 + scanner.toStringAction(token) + "').");
 
3098                                         } // case DOLLAR, VARIABLE, IDENTIFIER: switch token
 
3102                                         MethodDeclaration methodDecl = new MethodDeclaration (this.compilationUnit.compilationResult);
 
3103                                         methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
3104                                         methodDecl.modifiers = AccDefault;
 
3105                                         methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
 
3108                                                 functionDefinition(methodDecl);
 
3110                                                 int sourceEnd = methodDecl.sourceEnd;
 
3111                                                 if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
 
3112                                                         sourceEnd = methodDecl.declarationSourceStart + 1;
 
3114                                                 methodDecl.declarationSourceEnd = sourceEnd;
 
3115                                                 methodDecl.sourceEnd = sourceEnd;
 
3120                                         if (token != TokenName.INLINE_HTML) {
 
3121                                                 if (token.compareTo (TokenName.KEYWORD) > 0) {
 
3125                                                         // System.out.println(scanner.getCurrentTokenStartPosition());
 
3126                                                         // System.out.println(scanner.getCurrentTokenEndPosition());
 
3128                                                         throwSyntaxError("Error in expression (found token '"
 
3129                                                                         + scanner.toStringAction(token) + "').");
 
3135                         if (Scanner.TRACE) {
 
3136                                 System.out.println("TRACE: expr_without_variable() PART 2");
 
3139                         // | expr T_BOOLEAN_OR expr
 
3140                         // | expr T_BOOLEAN_AND expr
 
3141                         // | expr T_LOGICAL_OR expr
 
3142                         // | expr T_LOGICAL_AND expr
 
3143                         // | expr T_LOGICAL_XOR expr
 
3155                         // | expr T_IS_IDENTICAL expr
 
3156                         // | expr T_IS_NOT_IDENTICAL expr
 
3157                         // | expr T_IS_EQUAL expr
 
3158                         // | expr T_IS_NOT_EQUAL expr
 
3160                         // | expr T_IS_SMALLER_OR_EQUAL expr
 
3162                         // | expr T_IS_GREATER_OR_EQUAL expr
 
3167                                                 expression = new OR_OR_Expression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.OR_OR);
 
3171                                                 expression = new AND_AND_Expression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.AND_AND);
 
3175                                                 expression = new EqualExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.EQUAL_EQUAL);
 
3179                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.AND);
 
3183                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.OR);
 
3187                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.XOR);
 
3191                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.AND);
 
3195                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.OR);
 
3199                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.XOR);
 
3203                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.TWIDDLE);
 
3207                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.PLUS);
 
3211                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.MINUS);
 
3215                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.MULTIPLY);
 
3219                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.DIVIDE);
 
3223                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.REMAINDER);
 
3227                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.LEFT_SHIFT);
 
3231                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.RIGHT_SHIFT);
 
3233                                         case EQUAL_EQUAL_EQUAL:
 
3235                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.EQUAL_EQUAL);
 
3237                                         case NOT_EQUAL_EQUAL:
 
3239                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.NOT_EQUAL);
 
3243                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.NOT_EQUAL);
 
3247                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.LESS);
 
3251                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.LESS_EQUAL);
 
3255                             expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.GREATER);
 
3259                                                 expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.GREATER_EQUAL);
 
3261                                         // | expr T_INSTANCEOF class_name_reference
 
3262                                         // | expr '?' expr ':' expr
 
3265                                                 TypeReference classRef = class_name_reference();
 
3267                                                 if (classRef != null) {
 
3268                                                         expression = new InstanceOfExpression (expression, classRef, OperatorIds.INSTANCEOF);
 
3269                                                         expression.sourceStart = exprSourceStart;
 
3270                                                         expression.sourceEnd = scanner.getCurrentTokenEndPosition();
 
3275                                                 Expression valueIfTrue = expr_without_variable (true, null, true);
 
3276                                                 if (token != TokenName.COLON) {
 
3277                                                         throwSyntaxError("':' expected in conditional expression.");
 
3280                                                 Expression valueIfFalse = expr();
 
3282                                                 expression = new ConditionalExpression(expression,
 
3283                                                                 valueIfTrue, valueIfFalse);
 
3289                 } catch (SyntaxError e) {
 
3290                         // try to find next token after expression with errors:
 
3291                         if (token == TokenName.SEMICOLON) {
 
3296                         if (token == TokenName.RBRACE ||
 
3297                             token == TokenName.RPAREN ||
 
3298                                 token == TokenName.RBRACKET) {
 
3309         private SingleTypeReference class_name_reference() {
 
3310                 // class_name_reference:
 
3312                 // | dynamic_class_name_reference
 
3313                 SingleTypeReference ref = null;
 
3314                 if (Scanner.TRACE) {
 
3315                         System.out.println("TRACE: class_name_reference()");
 
3317                 if (token == TokenName.IDENTIFIER) {
 
3318                         ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(),
 
3319                                         scanner.getCurrentTokenStartPosition());
 
3320                         int pos = scanner.currentPosition;
 
3322                         if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
 
3323                                 // Not terminated by T_STRING, reduce to dynamic_class_name_reference
 
3324                                 scanner.currentPosition = pos;
 
3325                                 token = TokenName.IDENTIFIER;
 
3327                                 dynamic_class_name_reference();
 
3331                         dynamic_class_name_reference();
 
3336         private void dynamic_class_name_reference() {
 
3337                 // dynamic_class_name_reference:
 
3338                 // base_variable T_OBJECT_OPERATOR object_property
 
3339                 // dynamic_class_name_variable_properties
 
3341                 if (Scanner.TRACE) {
 
3342                         System.out.println("TRACE: dynamic_class_name_reference()");
 
3344                 base_variable(true);
 
3345                 if (token == TokenName.MINUS_GREATER) {
 
3348                         dynamic_class_name_variable_properties();
 
3352         private void dynamic_class_name_variable_properties() {
 
3353                 // dynamic_class_name_variable_properties:
 
3354                 // dynamic_class_name_variable_properties
 
3355                 // dynamic_class_name_variable_property
 
3357                 if (Scanner.TRACE) {
 
3359                                         .println("TRACE: dynamic_class_name_variable_properties()");
 
3361                 while (token == TokenName.MINUS_GREATER) {
 
3362                         dynamic_class_name_variable_property();
 
3366         private void dynamic_class_name_variable_property() {
 
3367                 // dynamic_class_name_variable_property:
 
3368                 // T_OBJECT_OPERATOR object_property
 
3369                 if (Scanner.TRACE) {
 
3370                         System.out.println("TRACE: dynamic_class_name_variable_property()");
 
3372                 if (token == TokenName.MINUS_GREATER) {
 
3378         private void ctor_arguments() {
 
3381                 // | '(' function_call_parameter_list ')'
 
3382                 if (token == TokenName.LPAREN) {
 
3384                         if (token == TokenName.RPAREN) {
 
3388                         non_empty_function_call_parameter_list();
 
3389                         if (token != TokenName.RPAREN) {
 
3390                                 throwSyntaxError("')' expected in ctor_arguments.");
 
3396         private void assignment_list() {
 
3398                 // assignment_list ',' assignment_list_element
 
3399                 // | assignment_list_element
 
3401                         assignment_list_element();
 
3402                         if (token != TokenName.COMMA) {
 
3409         private void assignment_list_element() {
 
3410                 // assignment_list_element:
 
3412                 // | T_LIST '(' assignment_list ')'
 
3414                 if (token == TokenName.VARIABLE) {
 
3415                         variable(true, false);
 
3416                 } else if (token == TokenName.DOLLAR) {
 
3417                         variable(false, false);
 
3418                 } else if (token == TokenName.IDENTIFIER) {
 
3419                         identifier(true, true, false);
 
3421                         if (token == TokenName.LIST) {
 
3423                                 if (token == TokenName.LPAREN) {
 
3426                                         if (token != TokenName.RPAREN) {
 
3427                                                 throwSyntaxError("')' expected after 'list' keyword.");
 
3431                                         throwSyntaxError("'(' expected after 'list' keyword.");
 
3437         private void array_pair_list() {
 
3440                 // | non_empty_array_pair_list possible_comma
 
3441                 non_empty_array_pair_list();
 
3442                 if (token == TokenName.COMMA) {
 
3447         private void non_empty_array_pair_list() {
 
3448                 // non_empty_array_pair_list:
 
3449                 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
 
3450                 // | non_empty_array_pair_list ',' expr
 
3451                 // | expr T_DOUBLE_ARROW expr
 
3453                 // | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
 
3454                 // | non_empty_array_pair_list ',' '&' w_variable
 
3455                 // | expr T_DOUBLE_ARROW '&' w_variable
 
3458                         if (token == TokenName.OP_AND) {
 
3460                                 variable(true, false);
 
3463                                 if (token == TokenName.OP_AND) {
 
3465                                         variable(true, false);
 
3466                                 } else if (token == TokenName.EQUAL_GREATER) {
 
3468                                         if (token == TokenName.OP_AND) {
 
3470                                                 variable(true, false);
 
3476                         if (token != TokenName.COMMA) {
 
3480                         if (token == TokenName.RPAREN) {
 
3486         // private void variableList() {
 
3489         // if (token == TokenName.COMMA) {
 
3496         private Expression variable_without_objects(boolean lefthandside,
 
3497                         boolean ignoreVar) {
 
3498                 // variable_without_objects:
 
3499                 // reference_variable
 
3500                 // | simple_indirect_reference reference_variable
 
3501                 if (Scanner.TRACE) {
 
3502                         System.out.println("TRACE: variable_without_objects()");
 
3504                 while (token == TokenName.DOLLAR) {
 
3507                 return reference_variable(lefthandside, ignoreVar);
 
3510         private Expression function_call(boolean lefthandside, boolean ignoreVar) {
 
3512                 // T_STRING '(' function_call_parameter_list ')'
 
3513                 // | class_constant '(' function_call_parameter_list ')'
 
3514                 // | static_member '(' function_call_parameter_list ')'
 
3515                 // | variable_without_objects '(' function_call_parameter_list ')'
 
3516                 char[] defineName = null;
 
3517                 char[] ident = null;
 
3520                 Expression ref = null;
 
3521                 if (Scanner.TRACE) {
 
3522                         System.out.println("TRACE: function_call()");
 
3524                 if (token == TokenName.IDENTIFIER) {
 
3525                         ident = scanner.getCurrentIdentifierSource();
 
3527                         startPos = scanner.getCurrentTokenStartPosition();
 
3528                         endPos = scanner.getCurrentTokenEndPosition();
 
3531                         case PAAMAYIM_NEKUDOTAYIM:
 
3535                                 if (token == TokenName.IDENTIFIER) {
 
3540                                         variable_without_objects(true, false);
 
3545                         ref = variable_without_objects(lefthandside, ignoreVar);
 
3547                 if (token != TokenName.LPAREN) {
 
3548                         if (defineName != null) {
 
3549                                 // does this identifier contain only uppercase characters?
 
3550                                 if (defineName.length == 3) {
 
3551                                         if (defineName[0] == 'd' &&
 
3552                                             defineName[1] == 'i' &&
 
3553                                                 defineName[2] == 'e') {
 
3556                                 } else if (defineName.length == 4) {
 
3557                                         if (defineName[0] == 't' &&
 
3558                                             defineName[1] == 'r' &&
 
3559                                                 defineName[2] == 'u' &&
 
3560                                                 defineName[3] == 'e') {
 
3562                                         } else if (defineName[0] == 'n' &&
 
3563                                                    defineName[1] == 'u' &&
 
3564                                                            defineName[2] == 'l' &&
 
3565                                                            defineName[3] == 'l') {
 
3568                                 } else if (defineName.length == 5) {
 
3569                                         if (defineName[0] == 'f' &&
 
3570                                             defineName[1] == 'a' &&
 
3571                                                 defineName[2] == 'l' &&
 
3572                                                 defineName[3] == 's' &&
 
3573                                                 defineName[4] == 'e') {
 
3577                                 if (defineName != null) {
 
3578                                         for (int i = 0; i < defineName.length; i++) {
 
3579                                                 if (Character.isLowerCase(defineName[i])) {
 
3580                                                         problemReporter.phpUppercaseIdentifierWarning(
 
3581                                                                         startPos, endPos, referenceContext,
 
3582                                                                         compilationUnit.compilationResult);
 
3590                         if (token == TokenName.RPAREN) {
 
3595                         non_empty_function_call_parameter_list();
 
3597                         if (token != TokenName.RPAREN) {
 
3598                                 String functionName;
 
3600                                 if (ident == null) {
 
3601                                         functionName = new String(" ");
 
3603                                         functionName = new String(ident);
 
3606                                 throwSyntaxError("')' expected in function call (" + functionName + ").");
 
3613         private void non_empty_function_call_parameter_list() {
 
3614                 this.non_empty_function_call_parameter_list(null);
 
3617         // private void function_call_parameter_list() {
 
3618         // function_call_parameter_list:
 
3619         // non_empty_function_call_parameter_list { $$ = $1; }
 
3622         private void non_empty_function_call_parameter_list(String functionName) {
 
3623                 // non_empty_function_call_parameter_list:
 
3624                 // expr_without_variable
 
3627                 // | non_empty_function_call_parameter_list ',' expr_without_variable
 
3628                 // | non_empty_function_call_parameter_list ',' variable
 
3629                 // | non_empty_function_call_parameter_list ',' '&' w_variable
 
3630                 if (Scanner.TRACE) {
 
3632                                         .println("TRACE: non_empty_function_call_parameter_list()");
 
3634                 UninitializedVariableHandler initHandler = new UninitializedVariableHandler();
 
3635                 initHandler.setFunctionName(functionName);
 
3637                         initHandler.incrementArgumentCount();
 
3638                         if (token == TokenName.OP_AND) {
 
3642                                 // if (token == TokenName.Identifier || token ==
 
3643                                 // TokenName.Variable
 
3644                                 // || token == TokenName.DOLLAR) {
 
3647                                 expr_without_variable(true, initHandler, false);
 
3650                         if (token != TokenName.COMMA) {
 
3657         private void fully_qualified_class_name() {
 
3658                 if (token == TokenName.IDENTIFIER) {
 
3661                         throwSyntaxError("Class name expected.");
 
3665         private void static_member() {
 
3667                 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
 
3668                 // variable_without_objects
 
3669                 if (Scanner.TRACE) {
 
3670                         System.out.println("TRACE: static_member()");
 
3672                 fully_qualified_class_name();
 
3673                 if (token != TokenName.PAAMAYIM_NEKUDOTAYIM) {
 
3674                         throwSyntaxError("'::' expected after class name (static_member).");
 
3677                 variable_without_objects(false, false);
 
3680         private Expression base_variable_with_function_calls(boolean lefthandside,
 
3681                         boolean ignoreVar) {
 
3682                 // base_variable_with_function_calls:
 
3685                 if (Scanner.TRACE) {
 
3686                         System.out.println("TRACE: base_variable_with_function_calls()");
 
3688                 return function_call(lefthandside, ignoreVar);
 
3691         private Expression base_variable(boolean lefthandside) {
 
3693                 // reference_variable
 
3694                 // | simple_indirect_reference reference_variable
 
3696                 Expression ref = null;
 
3697                 if (Scanner.TRACE) {
 
3698                         System.out.println("TRACE: base_variable()");
 
3700                 if (token == TokenName.IDENTIFIER) {
 
3703                         while (token == TokenName.DOLLAR) {
 
3706                         reference_variable(lefthandside, false);
 
3711         // private void simple_indirect_reference() {
 
3712         // // simple_indirect_reference:
 
3714         // //| simple_indirect_reference '$'
 
3716         private Expression reference_variable(boolean lefthandside,
 
3717                         boolean ignoreVar) {
 
3718                 // reference_variable:
 
3719                 // reference_variable '[' dim_offset ']'
 
3720                 // | reference_variable '{' expr '}'
 
3721                 // | compound_variable
 
3722                 Expression ref = null;
 
3723                 if (Scanner.TRACE) {
 
3724                         System.out.println("TRACE: reference_variable()");
 
3726                 ref = compound_variable(lefthandside, ignoreVar);
 
3728                         if (token == TokenName.LBRACE) {
 
3732                                 if (token != TokenName.RBRACE) {
 
3733                                         throwSyntaxError("'}' expected in reference variable.");
 
3736                         } else if (token == TokenName.LBRACKET) {
 
3737                                 // To remove "ref = null;" here, is probably better than the
 
3739                                 // commented in #1368081 - axelcl
 
3741                                 if (token != TokenName.RBRACKET) {
 
3744                                         if (token != TokenName.RBRACKET) {
 
3745                                                 throwSyntaxError("']' expected in reference variable.");
 
3756         private Expression compound_variable(boolean lefthandside, boolean ignoreVar) {
 
3757                 // compound_variable:
 
3759                 // | '$' '{' expr '}'
 
3760                 if (Scanner.TRACE) {
 
3761                         System.out.println("TRACE: compound_variable()");
 
3763                 if (token == TokenName.VARIABLE) {
 
3764                         if (!lefthandside) {
 
3765                                 if (!containsVariableSet()) {
 
3766                                         // reportSyntaxError("The local variable " + new
 
3767                                         // String(scanner.getCurrentIdentifierSource())
 
3768                                         // + " may not have been initialized");
 
3769                                         problemReporter.uninitializedLocalVariable(new String(
 
3770                                                         scanner.getCurrentIdentifierSource()), scanner
 
3771                                                         .getCurrentTokenStartPosition(), scanner
 
3772                                                         .getCurrentTokenEndPosition(), referenceContext,
 
3773                                                         compilationUnit.compilationResult);
 
3780                         FieldReference ref = new FieldReference(scanner
 
3781                                         .getCurrentIdentifierSource(), scanner
 
3782                                         .getCurrentTokenStartPosition());
 
3786                         // because of simple_indirect_reference
 
3787                         while (token == TokenName.DOLLAR) {
 
3790                         if (token != TokenName.LBRACE) {
 
3791                                 reportSyntaxError("'{' expected after compound variable token '$'.");
 
3796                         if (token != TokenName.RBRACE) {
 
3797                                 throwSyntaxError("'}' expected after compound variable token '$'.");
 
3802         } // private void dim_offset() { // // dim_offset: // // /* empty */
 
3807         private void object_property() {
 
3810                 // | variable_without_objects
 
3811                 if (Scanner.TRACE) {
 
3812                         System.out.println("TRACE: object_property()");
 
3814                 if (token == TokenName.VARIABLE || token == TokenName.DOLLAR) {
 
3815                         variable_without_objects(false, false);
 
3821         private void object_dim_list() {
 
3823                 // object_dim_list '[' dim_offset ']'
 
3824                 // | object_dim_list '{' expr '}'
 
3826                 if (Scanner.TRACE) {
 
3827                         System.out.println("TRACE: object_dim_list()");
 
3831                         if (token == TokenName.LBRACE) {
 
3834                                 if (token != TokenName.RBRACE) {
 
3835                                         throwSyntaxError("'}' expected in object_dim_list.");
 
3838                         } else if (token == TokenName.LBRACKET) {
 
3840                                 if (token == TokenName.RBRACKET) {
 
3845                                 if (token != TokenName.RBRACKET) {
 
3846                                         throwSyntaxError("']' expected in object_dim_list.");
 
3855         private void variable_name() {
 
3859                 if (Scanner.TRACE) {
 
3860                         System.out.println("TRACE: variable_name()");
 
3862                 if (token == TokenName.IDENTIFIER || token.compareTo (TokenName.KEYWORD) > 0) {
 
3863                         if (token.compareTo (TokenName.KEYWORD) > 0) {
 
3864                                 // TODO show a warning "Keyword used as variable" ?
 
3868                         if (token != TokenName.LBRACE) {
 
3869                                 throwSyntaxError("'{' expected in variable name.");
 
3873                         if (token != TokenName.RBRACE) {
 
3874                                 throwSyntaxError("'}' expected in variable name.");
 
3880         private void r_variable() {
 
3881                 variable(false, false);
 
3884         private void w_variable(boolean lefthandside) {
 
3885                 variable(lefthandside, false);
 
3888         private void rw_variable() {
 
3889                 variable(false, false);
 
3892         private Expression variable(boolean lefthandside, boolean ignoreVar) {
 
3894                 // base_variable_with_function_calls T_OBJECT_OPERATOR
 
3895                 // object_property method_or_not variable_properties
 
3896                 // | base_variable_with_function_calls
 
3897                 Expression ref = base_variable_with_function_calls(lefthandside,
 
3899                 if (token == TokenName.MINUS_GREATER) {
 
3904                         variable_properties();
 
3906                 else if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
 
3911                         variable_properties();
 
3917         private void variable_properties() {
 
3918                 // variable_properties:
 
3919                 // variable_properties variable_property
 
3921                 while (token == TokenName.MINUS_GREATER) {
 
3922                         variable_property();
 
3926         private void variable_property() {
 
3927                 // variable_property:
 
3928                 // T_OBJECT_OPERATOR object_property method_or_not
 
3929                 if (Scanner.TRACE) {
 
3930                         System.out.println("TRACE: variable_property()");
 
3932                 if (token == TokenName.MINUS_GREATER) {
 
3937                         throwSyntaxError("'->' expected in variable_property.");
 
3944          * base_variable_with_function_calls T_OBJECT_OPERATOR
 
3945          * object_property method_or_not variable_properties
 
3946          * | base_variable_with_function_calls
 
3948          * Expression ref = function_call(lefthandside, ignoreVar);
 
3951          * T_STRING '(' function_call_parameter_list ')'
 
3952          * | class_constant '(' function_call_parameter_list ')'
 
3953          * | static_member '(' function_call_parameter_list ')'
 
3954          * | variable_without_objects '(' function_call_parameter_list ')'
 
3956          * @param lefthandside
 
3961         private Expression identifier (boolean lefthandside, boolean ignoreVar, boolean bColonAllowed) {
 
3962                 char[] defineName = null;
 
3963                 char[] ident      = null;
 
3966                 Expression ref    = null;
 
3968                 if (Scanner.TRACE) {
 
3969                         System.out.println("TRACE: function_call()");
 
3972                 if (token == TokenName.IDENTIFIER) {
 
3973                         ident      = scanner.getCurrentIdentifierSource();
 
3975                         startPos   = scanner.getCurrentTokenStartPosition();
 
3976                         endPos     = scanner.getCurrentTokenEndPosition();
 
3978                         getNextToken();              // Get the token after the identifier
 
3984                                 case MULTIPLY_EQUAL:
 
3987                                 case REMAINDER_EQUAL:
 
3991                                 case RIGHT_SHIFT_EQUAL:
 
3992                                 case LEFT_SHIFT_EQUAL:
 
3993                                         String error = "Assignment operator '"
 
3994                                                         + scanner.toStringAction(token)
 
3995                                                         + "' not allowed after identifier '"
 
3997                                                         + "' (use 'define(...)' to define constants).";
 
3998                                         reportSyntaxError(error);
 
4002                         if (token == TokenName.COLON) {                    // If it's a ':', the identifier is a label
 
4007                             if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) { // '::'
 
4010                                 getNextToken ();                           // Read the identifier
 
4012                                 if (token == TokenName.IDENTIFIER) {       // class _constant
 
4015                                 else {                                     // static member:
 
4016                                     variable_without_objects (true, false);
 
4020                             else if (token == TokenName.BACKSLASH) {       // '\' namespace path separator
 
4023                         if (token == TokenName.IDENTIFIER) {       // If it's an identifier
 
4024                             getNextToken ();                       // go for the next token
 
4026                         else {                                     // It's not an identifiere, something wrong
 
4027                                                 throwSyntaxError ("an identifier expected after '\\' ");
 
4035                 else {                                                 // Token is not an identifier
 
4036                         ref = variable_without_objects(lefthandside, ignoreVar);
 
4039                 if (token == TokenName.LPAREN) {                       // If token is '('
 
4042             if (token == TokenName.RPAREN) {                   // If token is ')'
 
4047                 String functionName;
 
4049                 if (ident == null) {
 
4050                     functionName = new String(" ");
 
4052                     functionName = new String(ident);
 
4055                 non_empty_function_call_parameter_list(functionName); // Get the parameter list for the given function name
 
4057                 if (token != TokenName.RPAREN) {                      // If token is not a ')', throw error
 
4058                     throwSyntaxError ("')' expected in function call (" + functionName + ").");
 
4061                 getNextToken();                                 // Get the token after ')'
 
4064                 else {                                                  // It's not an '('
 
4065                         if (defineName != null) {                                       // does this identifier contain only uppercase characters?
 
4066                                 if (defineName.length == 3) {                   // If it's a 'die'
 
4067                                         if (defineName[0] == 'd' &&
 
4068                                             defineName[1] == 'i' &&
 
4069                                             defineName[2] == 'e') {
 
4073                                 else if (defineName.length == 4) {              // If it's a 'true'
 
4074                                         if (defineName[0] == 't' &&
 
4075                                             defineName[1] == 'r' &&
 
4076                                             defineName[2] == 'u' &&
 
4077                                             defineName[3] == 'e') {
 
4080                                         else if (defineName[0] == 'n' &&            // If it's a 'null'
 
4081                                                  defineName[1] == 'u' &&
 
4082                                                  defineName[2] == 'l' &&
 
4083                                                  defineName[3] == 'l') {
 
4087                                 else if (defineName.length == 5) {              // If it's a 'false'
 
4088                                         if (defineName[0] == 'f' &&
 
4089                                             defineName[1] == 'a' &&
 
4090                                             defineName[2] == 'l' &&
 
4091                                             defineName[3] == 's' &&
 
4092                                             defineName[4] == 'e') {
 
4097                                 if (defineName != null) {
 
4098                                     for (int i = 0; i < defineName.length; i++) {
 
4099                                         if (Character.isLowerCase (defineName[i])) {
 
4100                                             problemReporter.phpUppercaseIdentifierWarning (startPos, endPos, referenceContext,
 
4101                                                                                            compilationUnit.compilationResult);
 
4107                         // TODO is this ok ?
 
4109                         // throwSyntaxError("'(' expected in function call.");
 
4112                 if (token == TokenName.MINUS_GREATER) {
 
4117                         variable_properties();
 
4120                 // A colon is only allowed here if it is an expression read after a '?'
 
4122                 if ((token == TokenName.COLON) &&
 
4124                     throwSyntaxError ("No ':' allowed");
 
4130         private void method_or_not() {
 
4132                 // '(' function_call_parameter_list ')'
 
4134                 if (Scanner.TRACE) {
 
4135                         System.out.println("TRACE: method_or_not()");
 
4137                 if (token == TokenName.LPAREN) {
 
4139                         if (token == TokenName.RPAREN) {
 
4143                         non_empty_function_call_parameter_list();
 
4144                         if (token != TokenName.RPAREN) {
 
4145                                 throwSyntaxError("')' expected in method_or_not.");
 
4151         private void exit_expr() {
 
4155                 if (token != TokenName.LPAREN) {
 
4159                 if (token == TokenName.RPAREN) {
 
4164                 if (token != TokenName.RPAREN) {
 
4165                         throwSyntaxError("')' expected after keyword 'exit'");
 
4170         // private void encaps_list() {
 
4171         // // encaps_list encaps_var
 
4172         // // | encaps_list T_STRING
 
4173         // // | encaps_list T_NUM_STRING
 
4174         // // | encaps_list T_ENCAPSED_AND_WHITESPACE
 
4175         // // | encaps_list T_CHARACTER
 
4176         // // | encaps_list T_BAD_CHARACTER
 
4177         // // | encaps_list '['
 
4178         // // | encaps_list ']'
 
4179         // // | encaps_list '{'
 
4180         // // | encaps_list '}'
 
4181         // // | encaps_list T_OBJECT_OPERATOR
 
4185         // case TokenName.STRING:
 
4188         // case TokenName.LBRACE:
 
4189         // // scanner.encapsedStringStack.pop();
 
4192         // case TokenName.RBRACE:
 
4193         // // scanner.encapsedStringStack.pop();
 
4196         // case TokenName.LBRACKET:
 
4197         // // scanner.encapsedStringStack.pop();
 
4200         // case TokenName.RBRACKET:
 
4201         // // scanner.encapsedStringStack.pop();
 
4204         // case TokenName.MINUS_GREATER:
 
4205         // // scanner.encapsedStringStack.pop();
 
4208         // case TokenName.Variable:
 
4209         // case TokenName.DOLLAR_LBRACE:
 
4210         // case TokenName.LBRACE_DOLLAR:
 
4214         // char encapsedChar = ((Character)
 
4215         // scanner.encapsedStringStack.peek()).charValue();
 
4216         // if (encapsedChar == '$') {
 
4217         // scanner.encapsedStringStack.pop();
 
4218         // encapsedChar = ((Character)
 
4219         // scanner.encapsedStringStack.peek()).charValue();
 
4220         // switch (encapsedChar) {
 
4222         // if (token == TokenName.EncapsedString0) {
 
4225         // token = TokenName.STRING;
 
4228         // if (token == TokenName.EncapsedString1) {
 
4231         // token = TokenName.STRING;
 
4234         // if (token == TokenName.EncapsedString2) {
 
4237         // token = TokenName.STRING;
 
4246         // private void encaps_var() {
 
4248         // // | T_VARIABLE '[' encaps_var_offset ']'
 
4249         // // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
 
4250         // // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
 
4251         // // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
 
4252         // // | T_CURLY_OPEN variable '}'
 
4254         // case TokenName.Variable:
 
4256         // if (token == TokenName.LBRACKET) {
 
4258         // expr(); //encaps_var_offset();
 
4259         // if (token != TokenName.RBRACKET) {
 
4260         // throwSyntaxError("']' expected after variable.");
 
4262         // // scanner.encapsedStringStack.pop();
 
4265         // } else if (token == TokenName.MINUS_GREATER) {
 
4267         // if (token != TokenName.Identifier) {
 
4268         // throwSyntaxError("Identifier expected after '->'.");
 
4270         // // scanner.encapsedStringStack.pop();
 
4274         // // // scanner.encapsedStringStack.pop();
 
4275         // // int tempToken = TokenName.STRING;
 
4276         // // if (!scanner.encapsedStringStack.isEmpty()
 
4277         // // && (token == TokenName.EncapsedString0
 
4278         // // || token == TokenName.EncapsedString1
 
4279         // // || token == TokenName.EncapsedString2 || token ==
 
4280         // // TokenName.ERROR)) {
 
4281         // // char encapsedChar = ((Character)
 
4282         // // scanner.encapsedStringStack.peek())
 
4284         // // switch (token) {
 
4285         // // case TokenName.EncapsedString0 :
 
4286         // // if (encapsedChar == '`') {
 
4287         // // tempToken = TokenName.EncapsedString0;
 
4290         // // case TokenName.EncapsedString1 :
 
4291         // // if (encapsedChar == '\'') {
 
4292         // // tempToken = TokenName.EncapsedString1;
 
4295         // // case TokenName.EncapsedString2 :
 
4296         // // if (encapsedChar == '"') {
 
4297         // // tempToken = TokenName.EncapsedString2;
 
4300         // // case TokenName.ERROR :
 
4301         // // if (scanner.source[scanner.currentPosition - 1] == '\\') {
 
4302         // // scanner.currentPosition--;
 
4303         // // getNextToken();
 
4308         // // token = tempToken;
 
4311         // case TokenName.DOLLAR_LBRACE:
 
4313         // if (token == TokenName.DOLLAR_LBRACE) {
 
4315         // } else if (token == TokenName.Identifier) {
 
4317         // if (token == TokenName.LBRACKET) {
 
4319         // // if (token == TokenName.RBRACKET) {
 
4320         // // getNextToken();
 
4323         // if (token != TokenName.RBRACKET) {
 
4324         // throwSyntaxError("']' expected after '${'.");
 
4332         // if (token != TokenName.RBRACE) {
 
4333         // throwSyntaxError("'}' expected.");
 
4337         // case TokenName.LBRACE_DOLLAR:
 
4339         // if (token == TokenName.LBRACE_DOLLAR) {
 
4341         // } else if (token == TokenName.Identifier || token > TokenName.KEYWORD) {
 
4343         // if (token == TokenName.LBRACKET) {
 
4345         // // if (token == TokenName.RBRACKET) {
 
4346         // // getNextToken();
 
4349         // if (token != TokenName.RBRACKET) {
 
4350         // throwSyntaxError("']' expected.");
 
4354         // } else if (token == TokenName.MINUS_GREATER) {
 
4356         // if (token != TokenName.Identifier && token != TokenName.Variable) {
 
4357         // throwSyntaxError("String or Variable token expected.");
 
4360         // if (token == TokenName.LBRACKET) {
 
4362         // // if (token == TokenName.RBRACKET) {
 
4363         // // getNextToken();
 
4366         // if (token != TokenName.RBRACKET) {
 
4367         // throwSyntaxError("']' expected after '${'.");
 
4373         // // if (token != TokenName.RBRACE) {
 
4374         // // throwSyntaxError("'}' expected after '{$'.");
 
4376         // // // scanner.encapsedStringStack.pop();
 
4377         // // getNextToken();
 
4380         // if (token != TokenName.RBRACE) {
 
4381         // throwSyntaxError("'}' expected.");
 
4383         // // scanner.encapsedStringStack.pop();
 
4390         // private void encaps_var_offset() {
 
4392         // // | T_NUM_STRING
 
4395         // case TokenName.STRING:
 
4398         // case TokenName.IntegerLiteral:
 
4401         // case TokenName.Variable:
 
4404         // case TokenName.Identifier:
 
4408         // throwSyntaxError("Variable or String token expected.");
 
4416         private void internal_functions_in_yacc() {
 
4419                 // case TokenName.isset:
 
4420                 // // T_ISSET '(' isset_variables ')'
 
4422                 // if (token != TokenName.LPAREN) {
 
4423                 // throwSyntaxError("'(' expected after keyword 'isset'");
 
4426                 // isset_variables();
 
4427                 // if (token != TokenName.RPAREN) {
 
4428                 // throwSyntaxError("')' expected after keyword 'isset'");
 
4432                 // case TokenName.empty:
 
4433                 // // T_EMPTY '(' variable ')'
 
4435                 // if (token != TokenName.LPAREN) {
 
4436                 // throwSyntaxError("'(' expected after keyword 'empty'");
 
4440                 // if (token != TokenName.RPAREN) {
 
4441                 // throwSyntaxError("')' expected after keyword 'empty'");
 
4447                         checkFileName(token);
 
4450                         // T_INCLUDE_ONCE expr
 
4451                         checkFileName(token);
 
4454                         // T_EVAL '(' expr ')'
 
4456                         if (token != TokenName.LPAREN) {
 
4457                                 throwSyntaxError("'(' expected after keyword 'eval'");
 
4461                         if (token != TokenName.RPAREN) {
 
4462                                 throwSyntaxError("')' expected after keyword 'eval'");
 
4468                         checkFileName(token);
 
4471                         // T_REQUIRE_ONCE expr
 
4472                         checkFileName(token);
 
4478          * Parse and check the include file name
 
4480          * @param includeToken
 
4482         private void checkFileName(TokenName includeToken) {
 
4483                 // <include-token> expr
 
4484                 int start = scanner.getCurrentTokenStartPosition();
 
4485                 boolean hasLPAREN = false;
 
4487                 if (token == TokenName.LPAREN) {
 
4491                 Expression expression = expr();
 
4493                         if (token == TokenName.RPAREN) {
 
4496                                 throwSyntaxError("')' expected for keyword '"
 
4497                                                 + scanner.toStringAction(includeToken) + "'");
 
4500                 char[] currTokenSource = scanner.getCurrentTokenSource(start);
 
4502                 if (scanner.compilationUnit != null) {
 
4503                         IResource resource = scanner.compilationUnit.getResource();
 
4504                         if (resource != null && resource instanceof IFile) {
 
4505                                 file = (IFile) resource;
 
4509                 tokens = new char[1][];
 
4510                 tokens[0] = currTokenSource;
 
4512                 ImportReference impt = new ImportReference(tokens, currTokenSource,
 
4513                                 start, scanner.getCurrentTokenEndPosition(), false);
 
4514                 impt.declarationSourceEnd = impt.sourceEnd;
 
4515                 impt.declarationEnd = impt.declarationSourceEnd;
 
4516                 // endPosition is just before the ;
 
4517                 impt.declarationSourceStart = start;
 
4518                 includesList.add(impt);
 
4520                 if (expression instanceof StringLiteral) {
 
4521                         StringLiteral literal = (StringLiteral) expression;
 
4522                         char[] includeName = literal.source();
 
4523                         if (includeName.length == 0) {
 
4524                                 reportSyntaxError("Empty filename after keyword '"
 
4525                                                 + scanner.toStringAction(includeToken) + "'",
 
4526                                                 literal.sourceStart, literal.sourceStart + 1);
 
4528                         String includeNameString = new String(includeName);
 
4529                         if (literal instanceof StringLiteralDQ) {
 
4530                                 if (includeNameString.indexOf('$') >= 0) {
 
4531                                         // assuming that the filename contains a variable => no
 
4536                         if (includeNameString.startsWith("http://")) {
 
4537                                 // assuming external include location
 
4541                                 // check the filename:
 
4542                                 // System.out.println(new
 
4543                                 // String(compilationUnit.getFileName())+" - "+
 
4544                                 // expression.toStringExpression());
 
4545                                 IProject project = file.getProject();
 
4546                                 if (project != null) {
 
4547                                         IPath path = PHPFileUtil.determineFilePath(
 
4548                                                         includeNameString, file, project);
 
4551                                                 // SyntaxError: "File: << >> doesn't exist in project."
 
4552                                                 String[] args = { expression.toStringExpression(),
 
4553                                                                 project.getFullPath().toString() };
 
4554                                                 problemReporter.phpIncludeNotExistWarning(args,
 
4555                                                                 literal.sourceStart, literal.sourceEnd,
 
4557                                                                 compilationUnit.compilationResult);
 
4560                                                         String filePath = path.toString();
 
4561                                                         String ext = file.getRawLocation()
 
4562                                                                         .getFileExtension();
 
4563                                                         int fileExtensionLength = ext == null ? 0 : ext
 
4566                                                         IFile f = PHPFileUtil.createFile(path, project);
 
4568                                                         impt.tokens = CharOperation.splitOn('/', filePath
 
4569                                                                         .toCharArray(), 0, filePath.length()
 
4570                                                                         - fileExtensionLength);
 
4572                                                 } catch (Exception e) {
 
4573                                                         // the file is outside of the workspace
 
4581         private void isset_variables() {
 
4583                 // | isset_variables ','
 
4584                 if (token == TokenName.RPAREN) {
 
4585                         throwSyntaxError("Variable expected after keyword 'isset'");
 
4588                         variable(true, false);
 
4589                         if (token == TokenName.COMMA) {
 
4597         private boolean common_scalar() {
 
4601                 // | T_CONSTANT_ENCAPSED_STRING
 
4608                 case INTEGERLITERAL:
 
4614                 case STRINGDOUBLEQUOTE:
 
4617                 case STRINGSINGLEQUOTE:
 
4620                 case STRINGINTERPOLATED:
 
4642 //      private void scalar() {
 
4645 //              // | T_STRING_VARNAME
 
4646 //              // | class_constant
 
4647 //              // | common_scalar
 
4648 //              // | '"' encaps_list '"'
 
4649 //              // | '\'' encaps_list '\''
 
4650 //              // | T_START_HEREDOC encaps_list T_END_HEREDOC
 
4651 //              throwSyntaxError("Not yet implemented (scalar).");
 
4654         private void static_scalar() {
 
4655                 // static_scalar: /* compile-time evaluated scalars */
 
4658                 // | '+' static_scalar
 
4659                 // | '-' static_scalar
 
4660                 // | T_ARRAY '(' static_array_pair_list ')'
 
4661                 // | static_class_constant
 
4662                 if (common_scalar()) {
 
4668                         // static_class_constant:
 
4669                         // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
 
4670                         if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
 
4672                                 if (token == TokenName.IDENTIFIER) {
 
4675                                         throwSyntaxError("Identifier expected after '::' operator.");
 
4679                 case ENCAPSEDSTRING0:
 
4681                                 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4682                                 while (scanner.currentCharacter != '`') {
 
4683                                         if (scanner.currentCharacter == '\\') {
 
4684                                                 scanner.currentPosition++;
 
4686                                         scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4689                         } catch (IndexOutOfBoundsException e) {
 
4690                                 throwSyntaxError("'`' expected at end of static string.");
 
4693                 // case TokenName.EncapsedString1:
 
4695                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4696                 // while (scanner.currentCharacter != '\'') {
 
4697                 // if (scanner.currentCharacter == '\\') {
 
4698                 // scanner.currentPosition++;
 
4700                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4703                 // } catch (IndexOutOfBoundsException e) {
 
4704                 // throwSyntaxError("'\'' expected at end of static string.");
 
4707                 // case TokenName.EncapsedString2:
 
4709                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4710                 // while (scanner.currentCharacter != '"') {
 
4711                 // if (scanner.currentCharacter == '\\') {
 
4712                 // scanner.currentPosition++;
 
4714                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4717                 // } catch (IndexOutOfBoundsException e) {
 
4718                 // throwSyntaxError("'\"' expected at end of static string.");
 
4721                 case STRINGSINGLEQUOTE:
 
4724                 case STRINGDOUBLEQUOTE:
 
4737                         if (token != TokenName.LPAREN) {
 
4738                                 throwSyntaxError("'(' expected after keyword 'array'");
 
4741                         if (token == TokenName.RPAREN) {
 
4745                         non_empty_static_array_pair_list();
 
4746                         if (token != TokenName.RPAREN) {
 
4747                                 throwSyntaxError("')' or ',' expected after keyword 'array'");
 
4751                 // case TokenName.null :
 
4754                 // case TokenName.false :
 
4757                 // case TokenName.true :
 
4761                         throwSyntaxError("Static scalar/constant expected.");
 
4765         private void non_empty_static_array_pair_list() {
 
4766                 // non_empty_static_array_pair_list:
 
4767                 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
 
4769                 // | non_empty_static_array_pair_list ',' static_scalar
 
4770                 // | static_scalar T_DOUBLE_ARROW static_scalar
 
4774                         if (token == TokenName.EQUAL_GREATER) {
 
4778                         if (token != TokenName.COMMA) {
 
4782                         if (token == TokenName.RPAREN) {
 
4788         // public void reportSyntaxError() { //int act, int currentKind, int
 
4789         // // stateStackTop) {
 
4790         // /* remember current scanner position */
 
4791         // int startPos = scanner.startPosition;
 
4792         // int currentPos = scanner.currentPosition;
 
4794         // this.checkAndReportBracketAnomalies(problemReporter());
 
4795         // /* reset scanner where it was */
 
4796         // scanner.startPosition = startPos;
 
4797         // scanner.currentPosition = currentPos;
 
4800         public static final int RoundBracket = 0;
 
4802         public static final int SquareBracket = 1;
 
4804         public static final int CurlyBracket = 2;
 
4806         public static final int BracketKinds = 3;
 
4808         protected int[] nestedMethod; // the ptr is nestedType
 
4810         protected int nestedType, dimensions;
 
4812         // variable set stack
 
4813         final static int VariableStackIncrement = 10;
 
4815         HashMap fTypeVariables = null;
 
4817         HashMap fMethodVariables = null;
 
4819         ArrayList fStackUnassigned = new ArrayList();
 
4822         final static int AstStackIncrement = 100;
 
4824         protected int astPtr;
 
4826         protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
 
4828         protected int astLengthPtr;
 
4830         protected int[] astLengthStack;
 
4832         ASTNode[] noAstNodes = new ASTNode[AstStackIncrement];
 
4834         public CompilationUnitDeclaration compilationUnit; /*
 
4839         protected ReferenceContext referenceContext;
 
4841         protected ProblemReporter problemReporter;
 
4843         protected CompilerOptions options;
 
4845         private ArrayList includesList;
 
4847         // protected CompilationResult compilationResult;
 
4849          * Returns this parser's problem reporter initialized with its reference
 
4850          * context. Also it is assumed that a problem is going to be reported, so
 
4851          * initializes the compilation result's line positions.
 
4853         public ProblemReporter problemReporter() {
 
4854                 if (scanner.recordLineSeparator) {
 
4855                         compilationUnit.compilationResult.lineSeparatorPositions = scanner
 
4858                 problemReporter.referenceContext = referenceContext;
 
4859                 return problemReporter;
 
4863          * Reconsider the entire source looking for inconsistencies in {} () []
 
4865         // public boolean checkAndReportBracketAnomalies(ProblemReporter
 
4866         // problemReporter) {
 
4867         // scanner.wasAcr = false;
 
4868         // boolean anomaliesDetected = false;
 
4870         // char[] source = scanner.source;
 
4871         // int[] leftCount = { 0, 0, 0 };
 
4872         // int[] rightCount = { 0, 0, 0 };
 
4873         // int[] depths = { 0, 0, 0 };
 
4874         // int[][] leftPositions = new int[][] { new int[10], new int[10], new
 
4877         // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10]
 
4879         // int[][] rightPositions = new int[][] { new int[10], new int[10], new
 
4881         // int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10]
 
4883         // scanner.currentPosition = scanner.initialPosition; //starting
 
4885         // // (first-zero-based
 
4887         // while (scanner.currentPosition < scanner.eofPosition) { //loop for
 
4892         // // ---------Consume white space and handles
 
4893         // // startPosition---------
 
4894         // boolean isWhiteSpace;
 
4896         // scanner.startPosition = scanner.currentPosition;
 
4897         // // if (((scanner.currentCharacter =
 
4898         // // source[scanner.currentPosition++]) == '\\') &&
 
4899         // // (source[scanner.currentPosition] == 'u')) {
 
4900         // // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
 
4902         // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
 
4903         // (scanner.currentCharacter == '\n'))) {
 
4904         // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
 
4905         // // only record line positions we have not
 
4907         // scanner.pushLineSeparator();
 
4910         // isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
 
4912         // } while (isWhiteSpace && (scanner.currentPosition <
 
4913         // scanner.eofPosition));
 
4914         // // -------consume token until } is found---------
 
4915         // switch (scanner.currentCharacter) {
 
4917         // int index = leftCount[CurlyBracket]++;
 
4918         // if (index == leftPositions[CurlyBracket].length) {
 
4919         // System.arraycopy(leftPositions[CurlyBracket], 0,
 
4920         // (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
 
4921         // System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] =
 
4922         // new int[index * 2]), 0, index);
 
4924         // leftPositions[CurlyBracket][index] = scanner.startPosition;
 
4925         // leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
 
4929         // int index = rightCount[CurlyBracket]++;
 
4930         // if (index == rightPositions[CurlyBracket].length) {
 
4931         // System.arraycopy(rightPositions[CurlyBracket], 0,
 
4932         // (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
 
4933         // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket]
 
4935         // new int[index * 2]), 0, index);
 
4937         // rightPositions[CurlyBracket][index] = scanner.startPosition;
 
4938         // rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
 
4942         // int index = leftCount[RoundBracket]++;
 
4943         // if (index == leftPositions[RoundBracket].length) {
 
4944         // System.arraycopy(leftPositions[RoundBracket], 0,
 
4945         // (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
 
4946         // System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] =
 
4947         // new int[index * 2]), 0, index);
 
4949         // leftPositions[RoundBracket][index] = scanner.startPosition;
 
4950         // leftDepths[RoundBracket][index] = depths[RoundBracket]++;
 
4954         // int index = rightCount[RoundBracket]++;
 
4955         // if (index == rightPositions[RoundBracket].length) {
 
4956         // System.arraycopy(rightPositions[RoundBracket], 0,
 
4957         // (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
 
4958         // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket]
 
4960         // new int[index * 2]), 0, index);
 
4962         // rightPositions[RoundBracket][index] = scanner.startPosition;
 
4963         // rightDepths[RoundBracket][index] = --depths[RoundBracket];
 
4967         // int index = leftCount[SquareBracket]++;
 
4968         // if (index == leftPositions[SquareBracket].length) {
 
4969         // System.arraycopy(leftPositions[SquareBracket], 0,
 
4970         // (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
 
4971         // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket]
 
4973         // new int[index * 2]), 0, index);
 
4975         // leftPositions[SquareBracket][index] = scanner.startPosition;
 
4976         // leftDepths[SquareBracket][index] = depths[SquareBracket]++;
 
4980         // int index = rightCount[SquareBracket]++;
 
4981         // if (index == rightPositions[SquareBracket].length) {
 
4982         // System.arraycopy(rightPositions[SquareBracket], 0,
 
4983         // (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
 
4984         // System.arraycopy(rightDepths[SquareBracket], 0,
 
4985         // (rightDepths[SquareBracket]
 
4986         // = new int[index * 2]), 0, index);
 
4988         // rightPositions[SquareBracket][index] = scanner.startPosition;
 
4989         // rightDepths[SquareBracket][index] = --depths[SquareBracket];
 
4993         // if (scanner.getNextChar('\\')) {
 
4994         // scanner.scanEscapeCharacter();
 
4995         // } else { // consume next character
 
4996         // scanner.unicodeAsBackSlash = false;
 
4997         // // if (((scanner.currentCharacter =
 
4998         // // source[scanner.currentPosition++]) ==
 
5000         // // (source[scanner.currentPosition] ==
 
5002         // // scanner.getNextUnicodeChar();
 
5004         // if (scanner.withoutUnicodePtr != 0) {
 
5005         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
5006         // scanner.currentCharacter;
 
5010         // scanner.getNextChar('\'');
 
5014         // // consume next character
 
5015         // scanner.unicodeAsBackSlash = false;
 
5016         // // if (((scanner.currentCharacter =
 
5017         // // source[scanner.currentPosition++]) == '\\') &&
 
5018         // // (source[scanner.currentPosition] == 'u')) {
 
5019         // // scanner.getNextUnicodeChar();
 
5021         // if (scanner.withoutUnicodePtr != 0) {
 
5022         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
5023         // scanner.currentCharacter;
 
5026         // while (scanner.currentCharacter != '"') {
 
5027         // if (scanner.currentCharacter == '\r') {
 
5028         // if (source[scanner.currentPosition] == '\n')
 
5029         // scanner.currentPosition++;
 
5030         // break; // the string cannot go further that
 
5033         // if (scanner.currentCharacter == '\n') {
 
5034         // break; // the string cannot go further that
 
5037         // if (scanner.currentCharacter == '\\') {
 
5038         // scanner.scanEscapeCharacter();
 
5040         // // consume next character
 
5041         // scanner.unicodeAsBackSlash = false;
 
5042         // // if (((scanner.currentCharacter =
 
5043         // // source[scanner.currentPosition++]) == '\\')
 
5044         // // && (source[scanner.currentPosition] == 'u'))
 
5046         // // scanner.getNextUnicodeChar();
 
5048         // if (scanner.withoutUnicodePtr != 0) {
 
5049         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
5050         // scanner.currentCharacter;
 
5057         // if ((test = scanner.getNextChar('/', '*')) == 0) { //line
 
5059         // //get the next char
 
5060         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
5062         // && (source[scanner.currentPosition] == 'u')) {
 
5063         // //-------------unicode traitement
 
5065         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
5066         // scanner.currentPosition++;
 
5067         // while (source[scanner.currentPosition] == 'u') {
 
5068         // scanner.currentPosition++;
 
5070         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5072         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5075         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5078         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5080         // || c4 < 0) { //error
 
5084         // scanner.currentCharacter = 'A';
 
5085         // } //something different from \n and \r
 
5087         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
5090         // while (scanner.currentCharacter != '\r' && scanner.currentCharacter !=
 
5092         // //get the next char
 
5093         // scanner.startPosition = scanner.currentPosition;
 
5094         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
5096         // && (source[scanner.currentPosition] == 'u')) {
 
5097         // //-------------unicode traitement
 
5099         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
5100         // scanner.currentPosition++;
 
5101         // while (source[scanner.currentPosition] == 'u') {
 
5102         // scanner.currentPosition++;
 
5104         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5106         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5109         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5112         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5114         // || c4 < 0) { //error
 
5118         // scanner.currentCharacter = 'A';
 
5119         // } //something different from \n
 
5122         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
5126         // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
 
5127         // (scanner.currentCharacter == '\n'))) {
 
5128         // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
 
5129         // // only record line positions we
 
5130         // // have not recorded yet
 
5131         // scanner.pushLineSeparator();
 
5132         // if (this.scanner.taskTags != null) {
 
5133         // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
 
5135         // .getCurrentTokenEndPosition());
 
5141         // if (test > 0) { //traditional and annotation
 
5143         // boolean star = false;
 
5144         // // consume next character
 
5145         // scanner.unicodeAsBackSlash = false;
 
5146         // // if (((scanner.currentCharacter =
 
5147         // // source[scanner.currentPosition++]) ==
 
5149         // // (source[scanner.currentPosition] ==
 
5151         // // scanner.getNextUnicodeChar();
 
5153         // if (scanner.withoutUnicodePtr != 0) {
 
5154         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
5155         // scanner.currentCharacter;
 
5158         // if (scanner.currentCharacter == '*') {
 
5161         // //get the next char
 
5162         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
5164         // && (source[scanner.currentPosition] == 'u')) {
 
5165         // //-------------unicode traitement
 
5167         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
5168         // scanner.currentPosition++;
 
5169         // while (source[scanner.currentPosition] == 'u') {
 
5170         // scanner.currentPosition++;
 
5172         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5174         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5177         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5180         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5182         // || c4 < 0) { //error
 
5186         // scanner.currentCharacter = 'A';
 
5187         // } //something different from * and /
 
5189         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
5192         // //loop until end of comment */
 
5193         // while ((scanner.currentCharacter != '/') || (!star)) {
 
5194         // star = scanner.currentCharacter == '*';
 
5196         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
5198         // && (source[scanner.currentPosition] == 'u')) {
 
5199         // //-------------unicode traitement
 
5201         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
5202         // scanner.currentPosition++;
 
5203         // while (source[scanner.currentPosition] == 'u') {
 
5204         // scanner.currentPosition++;
 
5206         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5208         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5211         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5214         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
5216         // || c4 < 0) { //error
 
5220         // scanner.currentCharacter = 'A';
 
5221         // } //something different from * and
 
5224         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
5228         // if (this.scanner.taskTags != null) {
 
5229         // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
 
5230         // this.scanner.getCurrentTokenEndPosition());
 
5237         // if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
 
5238         // scanner.scanIdentifierOrKeyword(false);
 
5241         // if (Character.isDigit(scanner.currentCharacter)) {
 
5242         // scanner.scanNumber(false);
 
5246         // //-----------------end switch while
 
5247         // // try--------------------
 
5248         // } catch (IndexOutOfBoundsException e) {
 
5249         // break; // read until EOF
 
5250         // } catch (InvalidInputException e) {
 
5251         // return false; // no clue
 
5254         // if (scanner.recordLineSeparator) {
 
5255         // compilationUnit.compilationResult.lineSeparatorPositions =
 
5256         // scanner.getLineEnds();
 
5258         // // check placement anomalies against other kinds of brackets
 
5259         // for (int kind = 0; kind < BracketKinds; kind++) {
 
5260         // for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
 
5261         // int start = leftPositions[kind][leftIndex]; // deepest
 
5263         // // find matching closing bracket
 
5264         // int depth = leftDepths[kind][leftIndex];
 
5266         // for (int i = 0; i < rightCount[kind]; i++) {
 
5267         // int pos = rightPositions[kind][i];
 
5268         // // want matching bracket further in source with same
 
5270         // if ((pos > start) && (depth == rightDepths[kind][i])) {
 
5275         // if (end < 0) { // did not find a good closing match
 
5276         // problemReporter.unmatchedBracket(start, referenceContext,
 
5277         // compilationUnit.compilationResult);
 
5280         // // check if even number of opening/closing other brackets
 
5281         // // in between this pair of brackets
 
5283         // for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds);
 
5285         // for (int i = 0; i < leftCount[otherKind]; i++) {
 
5286         // int pos = leftPositions[otherKind][i];
 
5287         // if ((pos > start) && (pos < end))
 
5290         // for (int i = 0; i < rightCount[otherKind]; i++) {
 
5291         // int pos = rightPositions[otherKind][i];
 
5292         // if ((pos > start) && (pos < end))
 
5295         // if (balance != 0) {
 
5296         // problemReporter.unmatchedBracket(start, referenceContext,
 
5297         // compilationUnit.compilationResult); //bracket
 
5303         // // too many opening brackets ?
 
5304         // for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
 
5305         // anomaliesDetected = true;
 
5306         // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i
 
5308         // 1], referenceContext,
 
5309         // compilationUnit.compilationResult);
 
5311         // // too many closing brackets ?
 
5312         // for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
 
5313         // anomaliesDetected = true;
 
5314         // problemReporter.unmatchedBracket(rightPositions[kind][i],
 
5315         // referenceContext,
 
5316         // compilationUnit.compilationResult);
 
5318         // if (anomaliesDetected)
 
5321         // return anomaliesDetected;
 
5322         // } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
 
5323         // return anomaliesDetected;
 
5324         // } catch (NullPointerException e) { // jdk1.2.2 jit bug
 
5325         // return anomaliesDetected;
 
5328 //      protected void pushOnAstLengthStack(int pos) {
 
5330 //                      astLengthStack[++astLengthPtr] = pos;
 
5331 //              } catch (IndexOutOfBoundsException e) {
 
5332 //                      int oldStackLength = astLengthStack.length;
 
5333 //                      int[] oldPos = astLengthStack;
 
5334 //                      astLengthStack = new int[oldStackLength + StackIncrement];
 
5335 //                      System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
 
5336 //                      astLengthStack[astLengthPtr] = pos;
 
5340         protected void pushOnAstStack(ASTNode node) {
 
5342                  * add a new obj on top of the ast stack
 
5345                         astStack[++astPtr] = node;
 
5346                 } catch (IndexOutOfBoundsException e) {
 
5347                         int oldStackLength = astStack.length;
 
5348                         ASTNode[] oldStack = astStack;
 
5349                         astStack = new ASTNode[oldStackLength + AstStackIncrement];
 
5350                         System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
 
5351                         astPtr = oldStackLength;
 
5352                         astStack[astPtr] = node;
 
5355                         astLengthStack[++astLengthPtr] = 1;
 
5356                 } catch (IndexOutOfBoundsException e) {
 
5357                         int oldStackLength = astLengthStack.length;
 
5358                         int[] oldPos = astLengthStack;
 
5359                         astLengthStack = new int[oldStackLength + AstStackIncrement];
 
5360                         System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
 
5361                         astLengthStack[astLengthPtr] = 1;
 
5365         protected void resetModifiers() {
 
5366                 this.modifiers = AccDefault;
 
5367                 this.modifiersSourceStart = -1; // <-- see comment into
 
5368                 // modifiersFlag(int)
 
5369                 this.scanner.commentPtr = -1;
 
5372         protected void consumePackageDeclarationName(IFile file) {
 
5373                 // create a package name similar to java package names
 
5375                 //String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject())
 
5377                  //String filePath = file.getFullPath().toString();
 
5379                 String ext = file.getFileExtension();
 
5380                 int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
 
5381                 ImportReference impt;
 
5384                 /*if (filePath.startsWith(projectPath)) {
 
5385                         tokens = CharOperation.splitOn('/', filePath.toCharArray(),
 
5386                                         projectPath.length() + 1, filePath.length()
 
5387                                                         - fileExtensionLength);
 
5389                         String name = file.getName();
 
5390                         tokens = new char[1][];
 
5391                         tokens[0] = name.substring(0, name.length() - fileExtensionLength)
 
5395                 this.compilationUnit.currentPackage = impt = new ImportReference(
 
5396                                 tokens, new char[0], 0, 0, true);
 
5398                 impt.declarationSourceStart = 0;
 
5399                 impt.declarationSourceEnd = 0;
 
5400                 impt.declarationEnd = 0;
 
5401                 // endPosition is just before the ;
 
5405         public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV",
 
5406                         "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", "$_SESSION",
 
5412         private void pushFunctionVariableSet() {
 
5413                 HashSet set = new HashSet();
 
5414                 if (fStackUnassigned.isEmpty()) {
 
5415                         for (int i = 0; i < GLOBALS.length; i++) {
 
5416                                 set.add(GLOBALS[i]);
 
5419                 fStackUnassigned.add(set);
 
5422         private void pushIfVariableSet() {
 
5423                 if (!fStackUnassigned.isEmpty()) {
 
5424                         HashSet set = new HashSet();
 
5425                         fStackUnassigned.add(set);
 
5429         private HashSet removeIfVariableSet() {
 
5430                 if (!fStackUnassigned.isEmpty()) {
 
5431                         return (HashSet) fStackUnassigned
 
5432                                         .remove(fStackUnassigned.size() - 1);
 
5438          * Returns the <i>set of assigned variables </i> returns null if no Set is
 
5439          * defined at the current scanner position
 
5441         private HashSet peekVariableSet() {
 
5442                 if (!fStackUnassigned.isEmpty()) {
 
5443                         return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1);
 
5449          * add the current identifier source to the <i>set of assigned variables
 
5454         private void addVariableSet(HashSet set) {
 
5456                         set.add(new String(scanner.getCurrentTokenSource()));
 
5461          * add the current identifier source to the <i>set of assigned variables
 
5465         private void addVariableSet() {
 
5466                 HashSet set = peekVariableSet();
 
5468                         set.add(new String(scanner.getCurrentTokenSource()));
 
5473          * add the current identifier source to the <i>set of assigned variables
 
5477         private void addVariableSet(char[] token) {
 
5478                 HashSet set = peekVariableSet();
 
5480                         set.add(new String(token));
 
5485          * check if the current identifier source is in the <i>set of assigned
 
5486          * variables </i> Returns true, if no set is defined for the current scanner
 
5490         private boolean containsVariableSet() {
 
5491                 return containsVariableSet(scanner.getCurrentTokenSource());
 
5494         private boolean containsVariableSet(char[] token) {
 
5496                 if (!fStackUnassigned.isEmpty()) {
 
5498                         String str = new String(token);
 
5499                         for (int i = 0; i < fStackUnassigned.size(); i++) {
 
5500                                 set = (HashSet) fStackUnassigned.get(i);
 
5501                                 if (set.contains(str)) {