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;
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
15 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
16 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
17 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
18 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
19 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
20 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
21 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
22 import net.sourceforge.phpdt.internal.compiler.util.Util;
23 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
24 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
25 import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression;
26 import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
27 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
28 import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression;
29 import net.sourceforge.phpeclipse.internal.compiler.ast.Block;
30 import net.sourceforge.phpeclipse.internal.compiler.ast.BreakStatement;
31 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
32 import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression;
33 import net.sourceforge.phpeclipse.internal.compiler.ast.ContinueStatement;
34 import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression;
35 import net.sourceforge.phpeclipse.internal.compiler.ast.Expression;
36 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
37 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldReference;
38 import net.sourceforge.phpeclipse.internal.compiler.ast.IfStatement;
39 import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
40 import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression;
41 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
42 import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression;
43 import net.sourceforge.phpeclipse.internal.compiler.ast.OperatorIds;
44 import net.sourceforge.phpeclipse.internal.compiler.ast.ReturnStatement;
45 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
46 import net.sourceforge.phpeclipse.internal.compiler.ast.Statement;
47 import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral;
48 import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralDQ;
49 import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralSQ;
50 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
51 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference;
52 import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
54 import org.eclipse.core.resources.IFile;
55 import org.eclipse.core.resources.IProject;
56 import org.eclipse.core.resources.IResource;
57 import org.eclipse.core.runtime.IPath;
59 public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
60 protected final static int StackIncrement = 255;
62 protected int stateStackTop;
64 // protected int[] stack = new int[StackIncrement];
66 public int firstToken; // handle for multiple parsing goals
68 public int lastAct; //handle for multiple parsing goals
70 // protected RecoveredElement currentElement;
72 public static boolean VERBOSE_RECOVERY = false;
74 protected boolean diet = false; //tells the scanner to jump over some
76 // parts of the code/expressions like
79 public Scanner scanner;
81 // private ArrayList phpList;
83 // private int currentPHPString;
85 // private boolean phpEnd;
87 // private static HashMap keywordMap = null;
95 // row counter for syntax errors:
97 // column counter for syntax errors:
101 // // current identifier
102 // String identifier;
105 // Double doubleNumber;
107 // private String stringValue;
109 /** Contains the current expression. */
110 // private StringBuffer expression;
111 //private boolean phpMode;
112 protected int modifiers;
114 protected int modifiersSourceStart;
116 protected Parser(ProblemReporter problemReporter) {
117 this.problemReporter = problemReporter;
118 this.options = problemReporter.options;
119 // this.currentPHPString = 0;
120 // PHPParserSuperclass.fileToParse = fileToParse;
121 // this.phpList = null;
122 // this.indexManager = null;
124 this.token = TokenNameEOF;
126 // this.rowCount = 1;
127 // this.columnCount = 0;
128 // this.phpEnd = false;
130 this.initializeScanner();
133 public void setFileToParse(IFile fileToParse) {
134 // this.currentPHPString = 0;
135 // PHPParserSuperclass.fileToParse = fileToParse;
136 // this.phpList = null;
137 // this.indexManager = null;
139 this.token = TokenNameEOF;
140 // this.phpEnd = false;
141 this.initializeScanner();
145 * ClassDeclaration Constructor.
149 * Description of Parameter
152 public Parser(IFile fileToParse) {
153 // if (keywordMap == null) {
154 // keywordMap = new HashMap();
155 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
156 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
159 // this.currentPHPString = 0;
160 // PHPParserSuperclass.fileToParse = fileToParse;
161 // this.phpList = null;
162 this.includesList = null;
164 this.token = TokenNameEOF;
166 // this.rowCount = 1;
167 // this.columnCount = 0;
168 // this.phpEnd = false;
170 this.initializeScanner();
173 public void initializeScanner() {
174 this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options
175 .getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false,
176 this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */, true/* isTaskCaseSensitive */);
180 * Create marker for the parse error
182 // private void setMarker(String message, int charStart, int charEnd, int
184 // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
187 * This method will throw the SyntaxError. It will add the good lines and columns to the Error
191 * @throws SyntaxError
194 private void throwSyntaxError(String error) {
195 int problemStartPosition = scanner.getCurrentTokenStartPosition();
196 int problemEndPosition = scanner.getCurrentTokenEndPosition();
197 throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
201 * This method will throw the SyntaxError. It will add the good lines and columns to the Error
205 * @throws SyntaxError
208 // private void throwSyntaxError(String error, int startRow) {
209 // throw new SyntaxError(startRow, 0, " ", error);
211 private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
212 if (referenceContext != null) {
213 problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext,
214 compilationUnit.compilationResult);
216 throw new SyntaxError(1, 0, " ", error);
219 private void reportSyntaxError(String error) {
220 int problemStartPosition = scanner.getCurrentTokenStartPosition();
221 int problemEndPosition = scanner.getCurrentTokenEndPosition();
222 reportSyntaxError(error, problemStartPosition, problemEndPosition + 1);
225 private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
226 if (referenceContext != null) {
227 problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext,
228 compilationUnit.compilationResult);
232 private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) {
233 if (referenceContext != null) {
234 problemReporter.phpParsingWarning(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext,
235 compilationUnit.compilationResult);
240 * gets the next token from input
242 private void getNextToken() {
244 token = scanner.getNextToken();
246 int currentEndPosition = scanner.getCurrentTokenEndPosition();
247 int currentStartPosition = scanner.getCurrentTokenStartPosition();
248 System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
249 System.out.println(scanner.toStringAction(token));
251 } catch (InvalidInputException e) {
252 token = TokenNameERROR;
253 String detailedMessage = e.getMessage();
255 if (detailedMessage == Scanner.UNTERMINATED_STRING) {
256 throwSyntaxError("Unterminated string.");
257 } else if (detailedMessage == Scanner.UNTERMINATED_COMMENT) {
258 throwSyntaxError("Unterminated commment.");
264 public void init(String s) {
266 this.token = TokenNameEOF;
267 this.includesList = new ArrayList();
269 // this.rowCount = 1;
270 // this.columnCount = 0;
271 // this.phpEnd = false;
272 // this.phpMode = false;
273 /* scanner initialization */
274 scanner.setSource(s.toCharArray());
275 scanner.setPHPMode(false);
279 protected void initialize(boolean phpMode) {
280 initialize(phpMode, null);
283 protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) {
284 compilationUnit = null;
285 referenceContext = null;
286 this.includesList = new ArrayList();
287 // this.indexManager = indexManager;
289 this.token = TokenNameEOF;
291 // this.rowCount = 1;
292 // this.columnCount = 0;
293 // this.phpEnd = false;
294 // this.phpMode = phpMode;
295 scanner.setPHPMode(phpMode);
300 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>'
302 public void parse(String s) {
307 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>'
309 public void parse(String s, HashMap variables) {
310 fMethodVariables = variables;
316 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>'
318 protected void parse() {
319 if (scanner.compilationUnit != null) {
320 IResource resource = scanner.compilationUnit.getResource();
321 if (resource != null && resource instanceof IFile) {
322 // set the package name
323 consumePackageDeclarationName((IFile) resource);
329 if (token != TokenNameEOF && token != TokenNameERROR) {
332 if (token != TokenNameEOF) {
333 if (token == TokenNameERROR) {
334 throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
336 if (token == TokenNameRPAREN) {
337 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
339 if (token == TokenNameRBRACE) {
340 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
342 if (token == TokenNameRBRACKET) {
343 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
345 if (token == TokenNameLPAREN) {
346 throwSyntaxError("Read character '('; end-of-file not reached.");
348 if (token == TokenNameLBRACE) {
349 throwSyntaxError("Read character '{'; end-of-file not reached.");
351 if (token == TokenNameLBRACKET) {
352 throwSyntaxError("Read character '['; end-of-file not reached.");
354 throwSyntaxError("End-of-file not reached.");
357 } catch (SyntaxError sytaxErr1) {
359 // // if an error occured,
360 // // try to find keywords 'abstract' 'final' 'class' or 'function'
361 // // to parse the rest of the string
362 // boolean tokenize = scanner.tokenizeStrings;
364 // scanner.tokenizeStrings = true;
367 // while (token != TokenNameEOF) {
368 // if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) {
373 // if (token == TokenNameEOF) {
376 // } catch (SyntaxError sytaxErr2) {
379 // scanner.tokenizeStrings = tokenize;
388 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>'
390 public void parseFunction(String s, HashMap variables) {
392 scanner.phpMode = true;
393 parseFunction(variables);
397 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> </body>'
399 protected void parseFunction(HashMap variables) {
401 boolean hasModifiers = member_modifiers();
402 if (token == TokenNamefunction) {
404 checkAndSetModifiers(AccPublic);
406 this.fMethodVariables = variables;
408 MethodDeclaration methodDecl = new MethodDeclaration(null);
409 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
410 methodDecl.modifiers = this.modifiers;
411 methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
414 functionDefinition(methodDecl);
415 } catch (SyntaxError sytaxErr1) {
418 int sourceEnd = scanner.getCurrentTokenStartPosition();
419 if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
420 sourceEnd = methodDecl.declarationSourceStart + 1;
422 methodDecl.declarationSourceEnd = sourceEnd;
427 protected CompilationUnitDeclaration endParse(int act) {
431 // if (currentElement != null) {
432 // currentElement.topElement().updateParseTree();
433 // if (VERBOSE_RECOVERY) {
434 // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
435 // System.out.println("--------------------------"); //$NON-NLS-1$
436 // System.out.println(compilationUnit);
437 // System.out.println("----------------------------------"); //$NON-NLS-1$
440 if (diet & VERBOSE_RECOVERY) {
441 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
442 System.out.println("--------------------------"); //$NON-NLS-1$
443 System.out.println(compilationUnit);
444 System.out.println("----------------------------------"); //$NON-NLS-1$
447 if (scanner.recordLineSeparator) {
448 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
450 if (scanner.taskTags != null) {
451 for (int i = 0; i < scanner.foundTaskCount; i++) {
452 problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]),
453 scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
454 scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]);
457 compilationUnit.imports = new ImportReference[includesList.size()];
458 for (int i = 0; i < includesList.size(); i++) {
459 compilationUnit.imports[i] = (ImportReference) includesList.get(i);
461 return compilationUnit;
464 private Block statementList() {
465 boolean branchStatement = false;
469 int blockStart = scanner.getCurrentTokenStartPosition();
470 ArrayList blockStatements = new ArrayList();
473 sourceStart = scanner.getCurrentTokenStartPosition();
474 statement = statement();
475 blockStatements.add(statement);
476 if (branchStatement) {
477 sourceEnd = scanner.getCurrentTokenEndPosition();
478 reportSyntaxError("Unreachable code", sourceStart, sourceEnd);
480 if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
481 || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
482 || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
483 || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
484 return createBlock(blockStart, blockStatements);
486 branchStatement = checkUnreachableStatements(statement);
487 // return createBlock(blockStart, blockStatements);
488 } catch (SyntaxError sytaxErr1) {
489 // if an error occured,
490 // try to find keywords
491 // to parse the rest of the string
492 boolean tokenize = scanner.tokenizeStrings;
494 scanner.tokenizeStrings = true;
497 while (token != TokenNameEOF) {
498 if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
499 || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
500 || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
501 || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
502 return createBlock(blockStart, blockStatements);
504 if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile
505 || token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak
506 || token == TokenNamereturn || token == TokenNameexit || token == TokenNameecho || token == TokenNameglobal
507 || token == TokenNamestatic || token == TokenNameunset || token == TokenNamefunction || token == TokenNamedeclare
508 || token == TokenNametry || token == TokenNamecatch || token == TokenNamethrow || token == TokenNamefinal
509 || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
512 // System.out.println(scanner.toStringAction(token));
514 // System.out.println(scanner.toStringAction(token));
516 if (token == TokenNameEOF) {
520 scanner.tokenizeStrings = tokenize;
530 private boolean checkUnreachableStatements(Statement statement) {
531 boolean branchStatement = false;
532 if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) {
533 branchStatement = true;
534 } else if (statement instanceof IfStatement && ((IfStatement)statement).checkUnreachable) {
535 branchStatement = true;
537 return branchStatement;
542 * @param blockStatements
545 private Block createBlock(int blockStart, ArrayList blockStatements) {
546 int blockEnd = scanner.getCurrentTokenEndPosition();
547 Block b = Block.EmptyWith(blockStart, blockEnd);
548 b.statements = new Statement[blockStatements.size()];
549 blockStatements.toArray(b.statements);
553 private void functionBody(MethodDeclaration methodDecl) {
554 // '{' [statement-list] '}'
555 if (token == TokenNameLBRACE) {
558 throwSyntaxError("'{' expected in compound-statement.");
560 if (token != TokenNameRBRACE) {
563 if (token == TokenNameRBRACE) {
564 // methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
567 throwSyntaxError("'}' expected in compound-statement.");
571 private Statement statement() {
572 Statement statement = null;
573 Expression expression;
574 int sourceStart = scanner.getCurrentTokenStartPosition();
576 if (token == TokenNameif) {
577 // T_IF '(' expr ')' statement elseif_list else_single
578 // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
580 if (token == TokenNameLPAREN) {
583 throwSyntaxError("'(' expected after 'if' keyword.");
586 if (token == TokenNameRPAREN) {
589 throwSyntaxError("')' expected after 'if' condition.");
591 // create basic IfStatement
592 IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1);
593 if (token == TokenNameCOLON) {
595 ifStatementColon(ifStatement);
597 ifStatement(ifStatement);
600 } else if (token == TokenNameswitch) {
602 if (token == TokenNameLPAREN) {
605 throwSyntaxError("'(' expected after 'switch' keyword.");
608 if (token == TokenNameRPAREN) {
611 throwSyntaxError("')' expected after 'switch' condition.");
615 } else if (token == TokenNamefor) {
617 if (token == TokenNameLPAREN) {
620 throwSyntaxError("'(' expected after 'for' keyword.");
622 if (token == TokenNameSEMICOLON) {
626 if (token == TokenNameSEMICOLON) {
629 throwSyntaxError("';' expected after 'for'.");
632 if (token == TokenNameSEMICOLON) {
636 if (token == TokenNameSEMICOLON) {
639 throwSyntaxError("';' expected after 'for'.");
642 if (token == TokenNameRPAREN) {
646 if (token == TokenNameRPAREN) {
649 throwSyntaxError("')' expected after 'for'.");
654 } else if (token == TokenNamewhile) {
656 if (token == TokenNameLPAREN) {
659 throwSyntaxError("'(' expected after 'while' keyword.");
662 if (token == TokenNameRPAREN) {
665 throwSyntaxError("')' expected after 'while' condition.");
669 } else if (token == TokenNamedo) {
671 if (token == TokenNameLBRACE) {
673 if (token != TokenNameRBRACE) {
676 if (token == TokenNameRBRACE) {
679 throwSyntaxError("'}' expected after 'do' keyword.");
684 if (token == TokenNamewhile) {
686 if (token == TokenNameLPAREN) {
689 throwSyntaxError("'(' expected after 'while' keyword.");
692 if (token == TokenNameRPAREN) {
695 throwSyntaxError("')' expected after 'while' condition.");
698 throwSyntaxError("'while' expected after 'do' keyword.");
700 if (token == TokenNameSEMICOLON) {
703 if (token != TokenNameINLINE_HTML) {
704 throwSyntaxError("';' expected after do-while statement.");
709 } else if (token == TokenNameforeach) {
711 if (token == TokenNameLPAREN) {
714 throwSyntaxError("'(' expected after 'foreach' keyword.");
717 if (token == TokenNameas) {
720 throwSyntaxError("'as' expected after 'foreach' exxpression.");
724 foreach_optional_arg();
725 if (token == TokenNameEQUAL_GREATER) {
729 if (token == TokenNameRPAREN) {
732 throwSyntaxError("')' expected after 'foreach' expression.");
736 } else if (token == TokenNamebreak) {
739 if (token != TokenNameSEMICOLON) {
742 if (token == TokenNameSEMICOLON) {
743 sourceEnd = scanner.getCurrentTokenEndPosition();
746 if (token != TokenNameINLINE_HTML) {
747 throwSyntaxError("';' expected after 'break'.");
749 sourceEnd = scanner.getCurrentTokenEndPosition();
752 return new BreakStatement(null, sourceStart, sourceEnd);
753 } else if (token == TokenNamecontinue) {
756 if (token != TokenNameSEMICOLON) {
759 if (token == TokenNameSEMICOLON) {
760 sourceEnd = scanner.getCurrentTokenEndPosition();
763 if (token != TokenNameINLINE_HTML) {
764 throwSyntaxError("';' expected after 'continue'.");
766 sourceEnd = scanner.getCurrentTokenEndPosition();
769 return new ContinueStatement(null, sourceStart, sourceEnd);
770 } else if (token == TokenNamereturn) {
773 if (token != TokenNameSEMICOLON) {
776 if (token == TokenNameSEMICOLON) {
777 sourceEnd = scanner.getCurrentTokenEndPosition();
780 if (token != TokenNameINLINE_HTML) {
781 throwSyntaxError("';' expected after 'return'.");
783 sourceEnd = scanner.getCurrentTokenEndPosition();
786 return new ReturnStatement(expression, sourceStart, sourceEnd);
787 } else if (token == TokenNameecho) {
790 if (token == TokenNameSEMICOLON) {
793 if (token != TokenNameINLINE_HTML) {
794 throwSyntaxError("';' expected after 'echo' statement.");
799 } else if (token == TokenNameINLINE_HTML) {
802 // } else if (token == TokenNameprint) {
805 // if (token == TokenNameSEMICOLON) {
808 // if (token != TokenNameStopPHP) {
809 // throwSyntaxError("';' expected after 'print' statement.");
814 } else if (token == TokenNameglobal) {
817 if (token == TokenNameSEMICOLON) {
820 if (token != TokenNameINLINE_HTML) {
821 throwSyntaxError("';' expected after 'global' statement.");
826 } else if (token == TokenNamestatic) {
829 if (token == TokenNameSEMICOLON) {
832 if (token != TokenNameINLINE_HTML) {
833 throwSyntaxError("';' expected after 'static' statement.");
838 } else if (token == TokenNameunset) {
840 if (token == TokenNameLPAREN) {
843 throwSyntaxError("'(' expected after 'unset' statement.");
846 if (token == TokenNameRPAREN) {
849 throwSyntaxError("')' expected after 'unset' statement.");
851 if (token == TokenNameSEMICOLON) {
854 if (token != TokenNameINLINE_HTML) {
855 throwSyntaxError("';' expected after 'unset' statement.");
860 } else if (token == TokenNamefunction) {
861 MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
862 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
863 methodDecl.modifiers = AccDefault;
864 methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
867 functionDefinition(methodDecl);
869 sourceEnd = scanner.getCurrentTokenStartPosition();
870 if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
871 sourceEnd = methodDecl.declarationSourceStart + 1;
873 methodDecl.declarationSourceEnd = sourceEnd;
876 } else if (token == TokenNamedeclare) {
877 //T_DECLARE '(' declare_list ')' declare_statement
879 if (token != TokenNameLPAREN) {
880 throwSyntaxError("'(' expected in 'declare' statement.");
884 if (token != TokenNameRPAREN) {
885 throwSyntaxError("')' expected in 'declare' statement.");
890 } else if (token == TokenNametry) {
892 if (token != TokenNameLBRACE) {
893 throwSyntaxError("'{' expected in 'try' statement.");
897 if (token != TokenNameRBRACE) {
898 throwSyntaxError("'}' expected in 'try' statement.");
902 } else if (token == TokenNamecatch) {
904 if (token != TokenNameLPAREN) {
905 throwSyntaxError("'(' expected in 'catch' statement.");
908 fully_qualified_class_name();
909 if (token != TokenNameVariable) {
910 throwSyntaxError("Variable expected in 'catch' statement.");
913 if (token != TokenNameRPAREN) {
914 throwSyntaxError("')' expected in 'catch' statement.");
917 if (token != TokenNameLBRACE) {
918 throwSyntaxError("'{' expected in 'catch' statement.");
921 if (token != TokenNameRBRACE) {
923 if (token != TokenNameRBRACE) {
924 throwSyntaxError("'}' expected in 'catch' statement.");
928 additional_catches();
930 } else if (token == TokenNamethrow) {
933 if (token == TokenNameSEMICOLON) {
936 throwSyntaxError("';' expected after 'throw' exxpression.");
939 } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
941 TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
942 typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
943 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
944 typeDecl.name = new char[] { ' ' };
945 // default super class
946 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
947 compilationUnit.types.add(typeDecl);
948 pushOnAstStack(typeDecl);
949 unticked_class_declaration_statement(typeDecl);
957 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
958 } else if (token == TokenNameLBRACE) {
960 if (token != TokenNameRBRACE) {
961 statement = statementList();
963 if (token == TokenNameRBRACE) {
967 throwSyntaxError("'}' expected.");
970 if (token != TokenNameSEMICOLON) {
973 if (token == TokenNameSEMICOLON) {
977 if (token == TokenNameRBRACE) {
978 reportSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
980 if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
981 throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
991 private void declare_statement() {
993 //| ':' inner_statement_list T_ENDDECLARE ';'
995 if (token == TokenNameCOLON) {
997 // TODO: implement inner_statement_list();
999 if (token != TokenNameenddeclare) {
1000 throwSyntaxError("'enddeclare' expected in 'declare' statement.");
1003 if (token != TokenNameSEMICOLON) {
1004 throwSyntaxError("';' expected after 'enddeclare' keyword.");
1012 private void declare_list() {
1013 // T_STRING '=' static_scalar
1014 //| declare_list ',' T_STRING '=' static_scalar
1016 if (token != TokenNameIdentifier) {
1017 throwSyntaxError("Identifier expected in 'declare' list.");
1020 if (token != TokenNameEQUAL) {
1021 throwSyntaxError("'=' expected in 'declare' list.");
1025 if (token != TokenNameCOMMA) {
1032 private void additional_catches() {
1033 while (token == TokenNamecatch) {
1035 if (token != TokenNameLPAREN) {
1036 throwSyntaxError("'(' expected in 'catch' statement.");
1039 fully_qualified_class_name();
1040 if (token != TokenNameVariable) {
1041 throwSyntaxError("Variable expected in 'catch' statement.");
1044 if (token != TokenNameRPAREN) {
1045 throwSyntaxError("')' expected in 'catch' statement.");
1048 if (token != TokenNameLBRACE) {
1049 throwSyntaxError("'{' expected in 'catch' statement.");
1052 if (token != TokenNameRBRACE) {
1055 if (token != TokenNameRBRACE) {
1056 throwSyntaxError("'}' expected in 'catch' statement.");
1062 private void foreach_variable() {
1065 if (token == TokenNameAND) {
1071 private void foreach_optional_arg() {
1073 //| T_DOUBLE_ARROW foreach_variable
1074 if (token == TokenNameEQUAL_GREATER) {
1080 private void global_var_list() {
1082 // global_var_list ',' global_var
1086 if (token != TokenNameCOMMA) {
1093 private void global_var() {
1097 //| '$' '{' expr '}'
1098 if (token == TokenNameVariable) {
1099 VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR);
1100 if (fMethodVariables != null) {
1101 fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
1104 } else if (token == TokenNameDOLLAR) {
1106 if (token == TokenNameLBRACE) {
1109 if (token != TokenNameRBRACE) {
1110 throwSyntaxError("'}' expected in global variable.");
1119 private void static_var_list() {
1121 // static_var_list ',' T_VARIABLE
1122 //| static_var_list ',' T_VARIABLE '=' static_scalar
1124 //| T_VARIABLE '=' static_scalar
1126 if (token == TokenNameVariable) {
1127 VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR);
1128 if (fMethodVariables != null) {
1129 fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
1132 if (token == TokenNameEQUAL) {
1136 if (token != TokenNameCOMMA) {
1146 private void unset_variables() {
1149 // | unset_variables ',' unset_variable
1154 if (token != TokenNameCOMMA) {
1161 private final void initializeModifiers() {
1163 this.modifiersSourceStart = -1;
1166 private final void checkAndSetModifiers(int flag) {
1167 this.modifiers |= flag;
1168 if (this.modifiersSourceStart < 0)
1169 this.modifiersSourceStart = this.scanner.startPosition;
1172 private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1173 initializeModifiers();
1174 if (token == TokenNameinterface) {
1175 // interface_entry T_STRING
1176 // interface_extends_list
1177 // '{' class_statement_list '}'
1178 checkAndSetModifiers(AccInterface);
1180 typeDecl.modifiers = this.modifiers;
1181 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1182 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1183 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1184 typeDecl.name = scanner.getCurrentIdentifierSource();
1185 if (token > TokenNameKEYWORD) {
1186 problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(),
1187 scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult);
1188 // throwSyntaxError("Don't use a keyword for interface declaration [" + scanner.toStringAction(token) + "].",
1189 // typeDecl.sourceStart, typeDecl.sourceEnd);
1192 interface_extends_list(typeDecl);
1194 typeDecl.name = new char[] { ' ' };
1195 throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd);
1199 // class_entry_type T_STRING extends_from
1201 // '{' class_statement_list'}'
1203 typeDecl.modifiers = this.modifiers;
1204 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1205 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1207 //identifier 'extends' identifier
1208 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1209 typeDecl.name = scanner.getCurrentIdentifierSource();
1210 if (token > TokenNameKEYWORD) {
1211 problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(),
1212 scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult);
1213 // throwSyntaxError("Don't use a keyword for class declaration [" + scanner.toStringAction(token) + "].",
1214 // typeDecl.sourceStart, typeDecl.sourceEnd);
1219 // | T_EXTENDS fully_qualified_class_name
1220 if (token == TokenNameextends) {
1221 interface_extends_list(typeDecl);
1223 // if (token != TokenNameIdentifier) {
1224 // throwSyntaxError("Class name expected after keyword
1226 // scanner.getCurrentTokenStartPosition(), scanner
1227 // .getCurrentTokenEndPosition());
1230 implements_list(typeDecl);
1232 typeDecl.name = new char[] { ' ' };
1233 throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd);
1237 // '{' class_statement_list '}'
1238 if (token == TokenNameLBRACE) {
1240 if (token != TokenNameRBRACE) {
1241 ArrayList list = new ArrayList();
1242 class_statement_list(list);
1243 typeDecl.fields = new FieldDeclaration[list.size()];
1244 for (int i = 0; i < list.size(); i++) {
1245 typeDecl.fields[i] = (FieldDeclaration) list.get(i);
1248 if (token == TokenNameRBRACE) {
1249 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1252 throwSyntaxError("'}' expected at end of class body.");
1255 throwSyntaxError("'{' expected at start of class body.");
1259 private void class_entry_type() {
1261 // | T_ABSTRACT T_CLASS
1262 // | T_FINAL T_CLASS
1263 if (token == TokenNameclass) {
1265 } else if (token == TokenNameabstract) {
1266 checkAndSetModifiers(AccAbstract);
1268 if (token != TokenNameclass) {
1269 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1272 } else if (token == TokenNamefinal) {
1273 checkAndSetModifiers(AccFinal);
1275 if (token != TokenNameclass) {
1276 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1280 throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1284 private void class_extends(TypeDeclaration typeDecl) {
1286 // | T_EXTENDS interface_list
1287 if (token == TokenNameextends) {
1290 if (token == TokenNameIdentifier) {
1293 throwSyntaxError("Class name expected after keyword 'extends'.");
1298 private void interface_extends_list(TypeDeclaration typeDecl) {
1300 // | T_EXTENDS interface_list
1301 if (token == TokenNameextends) {
1307 private void implements_list(TypeDeclaration typeDecl) {
1309 // | T_IMPLEMENTS interface_list
1310 if (token == TokenNameimplements) {
1316 private void interface_list() {
1318 // fully_qualified_class_name
1319 //| interface_list ',' fully_qualified_class_name
1321 if (token == TokenNameIdentifier) {
1324 throwSyntaxError("Interface name expected after keyword 'implements'.");
1326 if (token != TokenNameCOMMA) {
1333 // private void classBody(TypeDeclaration typeDecl) {
1334 // //'{' [class-element-list] '}'
1335 // if (token == TokenNameLBRACE) {
1337 // if (token != TokenNameRBRACE) {
1338 // class_statement_list();
1340 // if (token == TokenNameRBRACE) {
1341 // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1344 // throwSyntaxError("'}' expected at end of class body.");
1347 // throwSyntaxError("'{' expected at start of class body.");
1350 private void class_statement_list(ArrayList list) {
1353 class_statement(list);
1354 if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
1355 || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
1356 || token == TokenNameconst) {
1359 if (token == TokenNameRBRACE) {
1362 throwSyntaxError("'}' at end of class statement.");
1363 } catch (SyntaxError sytaxErr1) {
1364 boolean tokenize = scanner.tokenizeStrings;
1366 scanner.tokenizeStrings = true;
1369 // if an error occured,
1370 // try to find keywords
1371 // to parse the rest of the string
1372 while (token != TokenNameEOF) {
1373 if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
1374 || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
1375 || token == TokenNameconst) {
1378 // System.out.println(scanner.toStringAction(token));
1381 if (token == TokenNameEOF) {
1385 scanner.tokenizeStrings = tokenize;
1391 private void class_statement(ArrayList list) {
1393 // variable_modifiers class_variable_declaration ';'
1394 // | class_constant_declaration ';'
1395 // | method_modifiers T_FUNCTION is_reference T_STRING
1396 // '(' parameter_list ')' method_body
1397 initializeModifiers();
1398 int declarationSourceStart = scanner.getCurrentTokenStartPosition();
1400 if (token == TokenNamevar) {
1401 checkAndSetModifiers(AccPublic);
1402 problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
1403 referenceContext, compilationUnit.compilationResult);
1405 class_variable_declaration(declarationSourceStart, list);
1406 } else if (token == TokenNameconst) {
1407 checkAndSetModifiers(AccFinal | AccPublic);
1408 class_constant_declaration(declarationSourceStart, list);
1409 if (token != TokenNameSEMICOLON) {
1410 throwSyntaxError("';' expected after class const declaration.");
1414 boolean hasModifiers = member_modifiers();
1415 if (token == TokenNamefunction) {
1416 if (!hasModifiers) {
1417 checkAndSetModifiers(AccPublic);
1419 MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
1420 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
1421 methodDecl.modifiers = this.modifiers;
1422 methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
1425 functionDefinition(methodDecl);
1427 int sourceEnd = scanner.getCurrentTokenStartPosition();
1428 if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
1429 sourceEnd = methodDecl.declarationSourceStart + 1;
1431 methodDecl.declarationSourceEnd = sourceEnd;
1434 if (!hasModifiers) {
1435 throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1437 class_variable_declaration(declarationSourceStart, list);
1442 private void class_constant_declaration(int declarationSourceStart, ArrayList list) {
1443 // class_constant_declaration ',' T_STRING '=' static_scalar
1444 // | T_CONST T_STRING '=' static_scalar
1445 if (token != TokenNameconst) {
1446 throwSyntaxError("'const' keyword expected in class declaration.");
1451 if (token != TokenNameIdentifier) {
1452 throwSyntaxError("Identifier expected in class const declaration.");
1454 FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner
1455 .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
1456 fieldDeclaration.modifiers = this.modifiers;
1457 fieldDeclaration.declarationSourceStart = declarationSourceStart;
1458 fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1459 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1460 // fieldDeclaration.type
1461 list.add(fieldDeclaration);
1463 if (token != TokenNameEQUAL) {
1464 throwSyntaxError("'=' expected in class const declaration.");
1468 if (token != TokenNameCOMMA) {
1469 break; // while(true)-loop
1475 // private void variable_modifiers() {
1476 // // variable_modifiers:
1477 // // non_empty_member_modifiers
1479 // initializeModifiers();
1480 // if (token == TokenNamevar) {
1481 // checkAndSetModifiers(AccPublic);
1482 // reportSyntaxError(
1483 // "Keyword 'var' is deprecated. Please use 'public' 'private' or
1485 // modifier for field declarations.",
1486 // scanner.getCurrentTokenStartPosition(), scanner
1487 // .getCurrentTokenEndPosition());
1490 // if (!member_modifiers()) {
1491 // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1492 // field declarations.");
1496 // private void method_modifiers() {
1497 // //method_modifiers:
1499 // //| non_empty_member_modifiers
1500 // initializeModifiers();
1501 // if (!member_modifiers()) {
1502 // checkAndSetModifiers(AccPublic);
1505 private boolean member_modifiers() {
1512 boolean foundToken = false;
1514 if (token == TokenNamepublic) {
1515 checkAndSetModifiers(AccPublic);
1518 } else if (token == TokenNameprotected) {
1519 checkAndSetModifiers(AccProtected);
1522 } else if (token == TokenNameprivate) {
1523 checkAndSetModifiers(AccPrivate);
1526 } else if (token == TokenNamestatic) {
1527 checkAndSetModifiers(AccStatic);
1530 } else if (token == TokenNameabstract) {
1531 checkAndSetModifiers(AccAbstract);
1534 } else if (token == TokenNamefinal) {
1535 checkAndSetModifiers(AccFinal);
1545 private void class_variable_declaration(int declarationSourceStart, ArrayList list) {
1546 // class_variable_declaration:
1547 // class_variable_declaration ',' T_VARIABLE
1548 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1550 // | T_VARIABLE '=' static_scalar
1551 char[] classVariable;
1553 if (token == TokenNameVariable) {
1554 classVariable = scanner.getCurrentIdentifierSource();
1555 // indexManager.addIdentifierInformation('v', classVariable, buf, -1, -1);
1556 FieldDeclaration fieldDeclaration = new FieldDeclaration(classVariable, scanner.getCurrentTokenStartPosition(), scanner
1557 .getCurrentTokenEndPosition());
1558 fieldDeclaration.modifiers = this.modifiers;
1559 fieldDeclaration.declarationSourceStart = declarationSourceStart;
1560 fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1561 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1562 list.add(fieldDeclaration);
1563 if (fTypeVariables != null) {
1564 VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_CLASS_UNIT);
1565 fTypeVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
1568 if (token == TokenNameEQUAL) {
1573 // if (token == TokenNamethis) {
1574 // throwSyntaxError("'$this' not allowed after keyword 'public'
1575 // 'protected' 'private' 'var'.");
1577 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1579 if (token != TokenNameCOMMA) {
1584 if (token != TokenNameSEMICOLON) {
1585 throwSyntaxError("';' expected after field declaration.");
1590 private void functionDefinition(MethodDeclaration methodDecl) {
1591 boolean isAbstract = false;
1593 if (compilationUnit != null) {
1594 compilationUnit.types.add(methodDecl);
1597 ASTNode node = astStack[astPtr];
1598 if (node instanceof TypeDeclaration) {
1599 TypeDeclaration typeDecl = ((TypeDeclaration) node);
1600 if (typeDecl.methods == null) {
1601 typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl };
1603 AbstractMethodDeclaration[] newMethods;
1604 System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 0,
1605 typeDecl.methods.length);
1606 newMethods[typeDecl.methods.length] = methodDecl;
1607 typeDecl.methods = newMethods;
1609 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1611 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1616 functionDeclarator(methodDecl);
1617 if (token == TokenNameSEMICOLON) {
1619 throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
1624 functionBody(methodDecl);
1627 private void functionDeclarator(MethodDeclaration methodDecl) {
1628 //identifier '(' [parameter-list] ')'
1629 if (token == TokenNameAND) {
1632 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1633 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1634 if (Scanner.isIdentifierOrKeyword(token)) {
1635 methodDecl.selector = scanner.getCurrentIdentifierSource();
1636 if (token > TokenNameKEYWORD) {
1637 problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(),
1638 scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult);
1641 if (token == TokenNameLPAREN) {
1644 throwSyntaxError("'(' expected in function declaration.");
1646 if (token != TokenNameRPAREN) {
1647 parameter_list(methodDecl);
1649 if (token != TokenNameRPAREN) {
1650 throwSyntaxError("')' expected in function declaration.");
1652 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1656 methodDecl.selector = "<undefined>".toCharArray();
1657 throwSyntaxError("Function name expected after keyword 'function'.");
1662 private void parameter_list(MethodDeclaration methodDecl) {
1663 // non_empty_parameter_list
1665 non_empty_parameter_list(methodDecl, true);
1668 private void non_empty_parameter_list(MethodDeclaration methodDecl, boolean empty_allowed) {
1669 // optional_class_type T_VARIABLE
1670 // | optional_class_type '&' T_VARIABLE
1671 // | optional_class_type '&' T_VARIABLE '=' static_scalar
1672 // | optional_class_type T_VARIABLE '=' static_scalar
1673 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1674 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1675 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1677 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1679 char[] typeIdentifier = null;
1680 if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
1682 if (token == TokenNameIdentifier) {
1683 typeIdentifier = scanner.getCurrentIdentifierSource();
1686 if (token == TokenNameAND) {
1689 if (token == TokenNameVariable) {
1690 if (fMethodVariables != null) {
1692 if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) {
1693 info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_FUNCTION_DEFINITION);
1695 info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_METHOD_DEFINITION);
1697 info.typeIdentifier = typeIdentifier;
1698 fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
1701 if (token == TokenNameEQUAL) {
1706 throwSyntaxError("Variable expected in parameter list.");
1708 if (token != TokenNameCOMMA) {
1715 if (!empty_allowed) {
1716 throwSyntaxError("Identifier expected in parameter list.");
1720 private void optional_class_type() {
1725 // private void parameterDeclaration() {
1727 // //variable-reference
1728 // if (token == TokenNameAND) {
1730 // if (isVariable()) {
1733 // throwSyntaxError("Variable expected after reference operator '&'.");
1736 // //variable '=' constant
1737 // if (token == TokenNameVariable) {
1739 // if (token == TokenNameEQUAL) {
1745 // // if (token == TokenNamethis) {
1746 // // throwSyntaxError("Reserved word '$this' not allowed in parameter
1747 // // declaration.");
1751 private void labeledStatementList() {
1752 if (token != TokenNamecase && token != TokenNamedefault) {
1753 throwSyntaxError("'case' or 'default' expected.");
1756 if (token == TokenNamecase) {
1758 expr(); //constant();
1759 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1761 if (token == TokenNamecase || token == TokenNamedefault) {
1762 // empty case statement ?
1767 // else if (token == TokenNameSEMICOLON) {
1769 // "':' expected after 'case' keyword (Found token: " +
1770 // scanner.toStringAction(token) + ")",
1771 // scanner.getCurrentTokenStartPosition(),
1772 // scanner.getCurrentTokenEndPosition(),
1775 // if (token == TokenNamecase) { // empty case statement ?
1781 throwSyntaxError("':' character expected after 'case' constant (Found token: " + scanner.toStringAction(token) + ")");
1783 } else { // TokenNamedefault
1785 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1787 if (token == TokenNameRBRACE) {
1788 // empty default case
1791 if (token != TokenNamecase) {
1795 throwSyntaxError("':' character expected after 'default'.");
1798 } while (token == TokenNamecase || token == TokenNamedefault);
1801 private void ifStatementColon(IfStatement iState) {
1802 // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
1803 Block b = inner_statement_list();
1804 iState.thenStatement = b;
1805 checkUnreachable(iState, b);
1806 if (token == TokenNameelseif) {
1807 new_elseif_list(iState);
1809 new_else_single(iState);
1810 if (token != TokenNameendif) {
1811 throwSyntaxError("'endif' expected.");
1814 if (token != TokenNameSEMICOLON) {
1815 reportSyntaxError("';' expected after if-statement.");
1816 iState.sourceEnd = scanner.getCurrentTokenStartPosition();
1818 iState.sourceEnd = scanner.getCurrentTokenEndPosition();
1823 private void ifStatement(IfStatement iState) {
1824 // T_IF '(' expr ')' statement elseif_list else_single
1825 Statement s = statement();
1826 iState.thenStatement = s;
1827 checkUnreachable(iState, s);
1828 if (token == TokenNameelseif) {
1829 elseif_list(iState);
1831 else_single(iState);
1834 private void elseif_list(IfStatement iState) {
1836 //| elseif_list T_ELSEIF '(' expr ')' statement
1837 ArrayList conditionList = new ArrayList();
1838 ArrayList statementList = new ArrayList();
1841 while (token == TokenNameelseif) {
1843 if (token == TokenNameLPAREN) {
1846 throwSyntaxError("'(' expected after 'elseif' keyword.");
1849 conditionList.add(e);
1850 if (token == TokenNameRPAREN) {
1853 throwSyntaxError("')' expected after 'elseif' condition.");
1856 statementList.add(s);
1857 checkUnreachable(iState, s);
1859 iState.elseifConditions = new Expression[conditionList.size()];
1860 iState.elseifStatements = new Statement[statementList.size()];
1861 conditionList.toArray(iState.elseifConditions);
1862 statementList.toArray(iState.elseifStatements);
1865 private void new_elseif_list(IfStatement iState) {
1867 //| new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
1868 ArrayList conditionList = new ArrayList();
1869 ArrayList statementList = new ArrayList();
1872 while (token == TokenNameelseif) {
1874 if (token == TokenNameLPAREN) {
1877 throwSyntaxError("'(' expected after 'elseif' keyword.");
1880 conditionList.add(e);
1881 if (token == TokenNameRPAREN) {
1884 throwSyntaxError("')' expected after 'elseif' condition.");
1886 if (token == TokenNameCOLON) {
1889 throwSyntaxError("':' expected after 'elseif' keyword.");
1891 b = inner_statement_list();
1892 statementList.add(b);
1893 checkUnreachable(iState, b);
1895 iState.elseifConditions = new Expression[conditionList.size()];
1896 iState.elseifStatements = new Statement[statementList.size()];
1897 conditionList.toArray(iState.elseifConditions);
1898 statementList.toArray(iState.elseifStatements);
1901 private void else_single(IfStatement iState) {
1904 if (token == TokenNameelse) {
1906 Statement s = statement();
1907 iState.elseStatement = s;
1908 checkUnreachable(iState, s);
1910 iState.checkUnreachable = false;
1912 iState.sourceEnd = scanner.getCurrentTokenStartPosition();
1915 private void new_else_single(IfStatement iState) {
1917 //| T_ELSE ':' inner_statement_list
1918 if (token == TokenNameelse) {
1920 if (token == TokenNameCOLON) {
1923 throwSyntaxError("':' expected after 'else' keyword.");
1925 Block b = inner_statement_list();
1926 iState.elseStatement = b;
1927 checkUnreachable(iState, b);
1929 iState.checkUnreachable = false;
1933 private Block inner_statement_list() {
1934 // inner_statement_list inner_statement
1936 return statementList();
1943 private void checkUnreachable(IfStatement iState, Statement s) {
1944 if (s instanceof Block) {
1945 Block b = (Block) s;
1946 if (b.statements == null || b.statements.length == 0) {
1947 iState.checkUnreachable = false;
1949 int off = b.statements.length - 1;
1950 if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement)
1951 && !(b.statements[off] instanceof BreakStatement)) {
1952 iState.checkUnreachable = false;
1956 if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) {
1957 iState.checkUnreachable = false;
1962 // private void elseifStatementList() {
1964 // elseifStatement();
1966 // case TokenNameelse:
1968 // if (token == TokenNameCOLON) {
1970 // if (token != TokenNameendif) {
1975 // if (token == TokenNameif) { //'else if'
1978 // throwSyntaxError("':' expected after 'else'.");
1982 // case TokenNameelseif:
1991 // private void elseifStatement() {
1992 // if (token == TokenNameLPAREN) {
1995 // if (token != TokenNameRPAREN) {
1996 // throwSyntaxError("')' expected in else-if-statement.");
1999 // if (token != TokenNameCOLON) {
2000 // throwSyntaxError("':' expected in else-if-statement.");
2003 // if (token != TokenNameendif) {
2009 private void switchStatement() {
2010 if (token == TokenNameCOLON) {
2011 // ':' [labeled-statement-list] 'endswitch' ';'
2013 labeledStatementList();
2014 if (token != TokenNameendswitch) {
2015 throwSyntaxError("'endswitch' expected.");
2018 if (token != TokenNameSEMICOLON) {
2019 throwSyntaxError("';' expected after switch-statement.");
2023 // '{' [labeled-statement-list] '}'
2024 if (token != TokenNameLBRACE) {
2025 throwSyntaxError("'{' expected in switch statement.");
2028 if (token != TokenNameRBRACE) {
2029 labeledStatementList();
2031 if (token != TokenNameRBRACE) {
2032 throwSyntaxError("'}' expected in switch statement.");
2038 private void forStatement() {
2039 if (token == TokenNameCOLON) {
2042 if (token != TokenNameendfor) {
2043 throwSyntaxError("'endfor' expected.");
2046 if (token != TokenNameSEMICOLON) {
2047 throwSyntaxError("';' expected after for-statement.");
2055 private void whileStatement() {
2056 // ':' statement-list 'endwhile' ';'
2057 if (token == TokenNameCOLON) {
2060 if (token != TokenNameendwhile) {
2061 throwSyntaxError("'endwhile' expected.");
2064 if (token != TokenNameSEMICOLON) {
2065 throwSyntaxError("';' expected after while-statement.");
2073 private void foreachStatement() {
2074 if (token == TokenNameCOLON) {
2077 if (token != TokenNameendforeach) {
2078 throwSyntaxError("'endforeach' expected.");
2081 if (token != TokenNameSEMICOLON) {
2082 throwSyntaxError("';' expected after foreach-statement.");
2090 // private void exitStatus() {
2091 // if (token == TokenNameLPAREN) {
2094 // throwSyntaxError("'(' expected in 'exit-status'.");
2096 // if (token != TokenNameRPAREN) {
2099 // if (token == TokenNameRPAREN) {
2102 // throwSyntaxError("')' expected after 'exit-status'.");
2105 private void expressionList() {
2108 if (token == TokenNameCOMMA) {
2116 private Expression expr() {
2118 // | expr_without_variable
2119 // if (token!=TokenNameEOF) {
2120 if (Scanner.TRACE) {
2121 System.out.println("TRACE: expr()");
2123 return expr_without_variable(true);
2127 private Expression expr_without_variable(boolean only_variable) {
2128 int exprSourceStart = scanner.getCurrentTokenStartPosition();
2129 int exprSourceEnd = scanner.getCurrentTokenEndPosition();
2130 Expression expression = new Expression();
2131 expression.sourceStart = exprSourceStart;
2132 // default, may be overwritten
2133 expression.sourceEnd = exprSourceEnd;
2135 // internal_functions_in_yacc
2144 // | T_INC rw_variable
2145 // | T_DEC rw_variable
2146 // | T_INT_CAST expr
2147 // | T_DOUBLE_CAST expr
2148 // | T_STRING_CAST expr
2149 // | T_ARRAY_CAST expr
2150 // | T_OBJECT_CAST expr
2151 // | T_BOOL_CAST expr
2152 // | T_UNSET_CAST expr
2153 // | T_EXIT exit_expr
2155 // | T_ARRAY '(' array_pair_list ')'
2156 // | '`' encaps_list '`'
2157 // | T_LIST '(' assignment_list ')' '=' expr
2158 // | T_NEW class_name_reference ctor_arguments
2159 // | variable '=' expr
2160 // | variable '=' '&' variable
2161 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2162 // | variable T_PLUS_EQUAL expr
2163 // | variable T_MINUS_EQUAL expr
2164 // | variable T_MUL_EQUAL expr
2165 // | variable T_DIV_EQUAL expr
2166 // | variable T_CONCAT_EQUAL expr
2167 // | variable T_MOD_EQUAL expr
2168 // | variable T_AND_EQUAL expr
2169 // | variable T_OR_EQUAL expr
2170 // | variable T_XOR_EQUAL expr
2171 // | variable T_SL_EQUAL expr
2172 // | variable T_SR_EQUAL expr
2173 // | rw_variable T_INC
2174 // | rw_variable T_DEC
2175 // | expr T_BOOLEAN_OR expr
2176 // | expr T_BOOLEAN_AND expr
2177 // | expr T_LOGICAL_OR expr
2178 // | expr T_LOGICAL_AND expr
2179 // | expr T_LOGICAL_XOR expr
2191 // | expr T_IS_IDENTICAL expr
2192 // | expr T_IS_NOT_IDENTICAL expr
2193 // | expr T_IS_EQUAL expr
2194 // | expr T_IS_NOT_EQUAL expr
2196 // | expr T_IS_SMALLER_OR_EQUAL expr
2198 // | expr T_IS_GREATER_OR_EQUAL expr
2199 // | expr T_INSTANCEOF class_name_reference
2200 // | expr '?' expr ':' expr
2201 if (Scanner.TRACE) {
2202 System.out.println("TRACE: expr_without_variable() PART 1");
2205 case TokenNameisset:
2206 case TokenNameempty:
2208 case TokenNameinclude:
2209 case TokenNameinclude_once:
2210 case TokenNamerequire:
2211 case TokenNamerequire_once:
2212 internal_functions_in_yacc();
2215 case TokenNameLPAREN:
2218 if (token == TokenNameRPAREN) {
2221 throwSyntaxError("')' expected in expression.");
2231 // | T_INT_CAST expr
2232 // | T_DOUBLE_CAST expr
2233 // | T_STRING_CAST expr
2234 // | T_ARRAY_CAST expr
2235 // | T_OBJECT_CAST expr
2236 // | T_BOOL_CAST expr
2237 // | T_UNSET_CAST expr
2238 case TokenNameclone:
2239 case TokenNameprint:
2242 case TokenNameMINUS:
2244 case TokenNameTWIDDLE:
2245 case TokenNameintCAST:
2246 case TokenNamedoubleCAST:
2247 case TokenNamestringCAST:
2248 case TokenNamearrayCAST:
2249 case TokenNameobjectCAST:
2250 case TokenNameboolCAST:
2251 case TokenNameunsetCAST:
2261 //| T_STRING_VARNAME
2263 //| T_START_HEREDOC encaps_list T_END_HEREDOC
2264 // | '`' encaps_list '`'
2266 // | '`' encaps_list '`'
2267 case TokenNameEncapsedString0:
2268 scanner.encapsedStringStack.push(new Character('`'));
2271 if (token == TokenNameEncapsedString0) {
2274 if (token != TokenNameEncapsedString0) {
2275 throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2279 scanner.encapsedStringStack.pop();
2283 // | '\'' encaps_list '\''
2284 case TokenNameEncapsedString1:
2285 scanner.encapsedStringStack.push(new Character('\''));
2288 exprSourceStart = scanner.getCurrentTokenStartPosition();
2289 if (token == TokenNameEncapsedString1) {
2290 expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
2291 .getCurrentTokenEndPosition());
2294 if (token != TokenNameEncapsedString1) {
2295 throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2297 expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
2298 .getCurrentTokenEndPosition());
2302 scanner.encapsedStringStack.pop();
2306 //| '"' encaps_list '"'
2307 case TokenNameEncapsedString2:
2308 scanner.encapsedStringStack.push(new Character('"'));
2311 exprSourceStart = scanner.getCurrentTokenStartPosition();
2312 if (token == TokenNameEncapsedString2) {
2313 expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
2314 .getCurrentTokenEndPosition());
2317 if (token != TokenNameEncapsedString2) {
2318 throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2320 expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
2321 .getCurrentTokenEndPosition());
2325 scanner.encapsedStringStack.pop();
2329 case TokenNameStringDoubleQuote:
2330 expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
2331 .getCurrentTokenEndPosition());
2334 case TokenNameStringSingleQuote:
2335 expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
2336 .getCurrentTokenEndPosition());
2339 case TokenNameIntegerLiteral:
2340 case TokenNameDoubleLiteral:
2341 case TokenNameStringInterpolated:
2344 case TokenNameCLASS_C:
2345 case TokenNameMETHOD_C:
2346 case TokenNameFUNC_C:
2349 case TokenNameHEREDOC:
2352 case TokenNamearray:
2353 // T_ARRAY '(' array_pair_list ')'
2355 if (token == TokenNameLPAREN) {
2357 if (token == TokenNameRPAREN) {
2362 if (token != TokenNameRPAREN) {
2363 throwSyntaxError("')' or ',' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
2367 throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
2371 // | T_LIST '(' assignment_list ')' '=' expr
2373 if (token == TokenNameLPAREN) {
2376 if (token != TokenNameRPAREN) {
2377 throwSyntaxError("')' expected after 'list' keyword.");
2380 if (token != TokenNameEQUAL) {
2381 throwSyntaxError("'=' expected after 'list' keyword.");
2386 throwSyntaxError("'(' expected after 'list' keyword.");
2390 // | T_NEW class_name_reference ctor_arguments
2392 Expression typeRef = class_name_reference();
2394 if (typeRef != null) {
2395 expression = typeRef;
2398 // | T_INC rw_variable
2399 // | T_DEC rw_variable
2400 case TokenNamePLUS_PLUS:
2401 case TokenNameMINUS_MINUS:
2405 // | variable '=' expr
2406 // | variable '=' '&' variable
2407 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2408 // | variable T_PLUS_EQUAL expr
2409 // | variable T_MINUS_EQUAL expr
2410 // | variable T_MUL_EQUAL expr
2411 // | variable T_DIV_EQUAL expr
2412 // | variable T_CONCAT_EQUAL expr
2413 // | variable T_MOD_EQUAL expr
2414 // | variable T_AND_EQUAL expr
2415 // | variable T_OR_EQUAL expr
2416 // | variable T_XOR_EQUAL expr
2417 // | variable T_SL_EQUAL expr
2418 // | variable T_SR_EQUAL expr
2419 // | rw_variable T_INC
2420 // | rw_variable T_DEC
2421 case TokenNameIdentifier:
2422 case TokenNameVariable:
2423 case TokenNameDOLLAR:
2424 boolean rememberedVar = false;
2425 Expression lhs = variable();
2427 case TokenNameEQUAL:
2429 if (token == TokenNameAND) {
2431 if (token == TokenNamenew) {
2432 // | variable '=' '&' T_NEW class_name_reference
2435 SingleTypeReference classRef = class_name_reference();
2437 if (classRef != null) {
2438 if (lhs != null && lhs instanceof FieldReference) {
2440 // $var = & new Object();
2441 if (fMethodVariables != null) {
2442 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
2443 lhsInfo.reference = classRef;
2444 lhsInfo.typeIdentifier = classRef.token;
2445 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
2446 rememberedVar = true;
2451 Expression rhs = variable();
2452 if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) {
2455 if (fMethodVariables != null) {
2456 VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token);
2457 if (rhsInfo != null && rhsInfo.reference != null) {
2458 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
2459 lhsInfo.reference = rhsInfo.reference;
2460 lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
2461 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
2462 rememberedVar = true;
2468 Expression rhs = expr();
2469 if (lhs != null && lhs instanceof FieldReference) {
2470 if (rhs != null && rhs instanceof FieldReference) {
2473 if (fMethodVariables != null) {
2474 VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token);
2475 if (rhsInfo != null && rhsInfo.reference != null) {
2476 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
2477 lhsInfo.reference = rhsInfo.reference;
2478 lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
2479 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
2480 rememberedVar = true;
2483 } else if (rhs != null && rhs instanceof SingleTypeReference) {
2485 // $var = new Object();
2486 if (fMethodVariables != null) {
2487 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
2488 lhsInfo.reference = (SingleTypeReference) rhs;
2489 lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token;
2490 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
2491 rememberedVar = true;
2496 if (rememberedVar == false && lhs != null && lhs instanceof FieldReference) {
2497 if (fMethodVariables != null) {
2498 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
2499 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
2503 case TokenNamePLUS_EQUAL:
2504 case TokenNameMINUS_EQUAL:
2505 case TokenNameMULTIPLY_EQUAL:
2506 case TokenNameDIVIDE_EQUAL:
2507 case TokenNameDOT_EQUAL:
2508 case TokenNameREMAINDER_EQUAL:
2509 case TokenNameAND_EQUAL:
2510 case TokenNameOR_EQUAL:
2511 case TokenNameXOR_EQUAL:
2512 case TokenNameRIGHT_SHIFT_EQUAL:
2513 case TokenNameLEFT_SHIFT_EQUAL:
2517 case TokenNamePLUS_PLUS:
2518 case TokenNameMINUS_MINUS:
2522 if (!only_variable) {
2523 throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "').");
2531 if (token != TokenNameINLINE_HTML) {
2532 if (token > TokenNameKEYWORD) {
2536 throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "').");
2541 if (Scanner.TRACE) {
2542 System.out.println("TRACE: expr_without_variable() PART 2");
2544 // | expr T_BOOLEAN_OR expr
2545 // | expr T_BOOLEAN_AND expr
2546 // | expr T_LOGICAL_OR expr
2547 // | expr T_LOGICAL_AND expr
2548 // | expr T_LOGICAL_XOR expr
2560 // | expr T_IS_IDENTICAL expr
2561 // | expr T_IS_NOT_IDENTICAL expr
2562 // | expr T_IS_EQUAL expr
2563 // | expr T_IS_NOT_EQUAL expr
2565 // | expr T_IS_SMALLER_OR_EQUAL expr
2567 // | expr T_IS_GREATER_OR_EQUAL expr
2570 case TokenNameOR_OR:
2572 expression = new OR_OR_Expression(expression, expr(), token);
2574 case TokenNameAND_AND:
2576 expression = new AND_AND_Expression(expression, expr(), token);
2578 case TokenNameEQUAL_EQUAL:
2580 expression = new EqualExpression(expression, expr(), token);
2590 case TokenNameMINUS:
2591 case TokenNameMULTIPLY:
2592 case TokenNameDIVIDE:
2593 case TokenNameREMAINDER:
2594 case TokenNameLEFT_SHIFT:
2595 case TokenNameRIGHT_SHIFT:
2596 case TokenNameEQUAL_EQUAL_EQUAL:
2597 case TokenNameNOT_EQUAL_EQUAL:
2598 case TokenNameNOT_EQUAL:
2600 case TokenNameLESS_EQUAL:
2601 case TokenNameGREATER:
2602 case TokenNameGREATER_EQUAL:
2604 expression = new BinaryExpression(expression, expr(), token);
2606 // | expr T_INSTANCEOF class_name_reference
2607 // | expr '?' expr ':' expr
2608 case TokenNameinstanceof:
2610 TypeReference classRef = class_name_reference();
2611 expression = new InstanceOfExpression(expression, classRef, OperatorIds.INSTANCEOF);
2612 expression.sourceStart = exprSourceStart;
2613 expression.sourceEnd = scanner.getCurrentTokenEndPosition();
2615 case TokenNameQUESTION:
2617 Expression valueIfTrue = expr();
2618 if (token != TokenNameCOLON) {
2619 throwSyntaxError("':' expected in conditional expression.");
2622 Expression valueIfFalse = expr();
2624 expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse);
2630 } catch (SyntaxError e) {
2631 // try to find next token after expression with errors:
2632 if (token == TokenNameSEMICOLON) {
2636 if (token == TokenNameRBRACE || token == TokenNameRPAREN || token == TokenNameRBRACKET) {
2644 private SingleTypeReference class_name_reference() {
2645 // class_name_reference:
2647 //| dynamic_class_name_reference
2648 SingleTypeReference ref = null;
2649 if (Scanner.TRACE) {
2650 System.out.println("TRACE: class_name_reference()");
2652 if (token == TokenNameIdentifier) {
2653 ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition());
2657 dynamic_class_name_reference();
2662 private void dynamic_class_name_reference() {
2663 //dynamic_class_name_reference:
2664 // base_variable T_OBJECT_OPERATOR object_property
2665 // dynamic_class_name_variable_properties
2667 if (Scanner.TRACE) {
2668 System.out.println("TRACE: dynamic_class_name_reference()");
2671 if (token == TokenNameMINUS_GREATER) {
2674 dynamic_class_name_variable_properties();
2678 private void dynamic_class_name_variable_properties() {
2679 // dynamic_class_name_variable_properties:
2680 // dynamic_class_name_variable_properties
2681 // dynamic_class_name_variable_property
2683 if (Scanner.TRACE) {
2684 System.out.println("TRACE: dynamic_class_name_variable_properties()");
2686 while (token == TokenNameMINUS_GREATER) {
2687 dynamic_class_name_variable_property();
2691 private void dynamic_class_name_variable_property() {
2692 // dynamic_class_name_variable_property:
2693 // T_OBJECT_OPERATOR object_property
2694 if (Scanner.TRACE) {
2695 System.out.println("TRACE: dynamic_class_name_variable_property()");
2697 if (token == TokenNameMINUS_GREATER) {
2703 private void ctor_arguments() {
2706 //| '(' function_call_parameter_list ')'
2707 if (token == TokenNameLPAREN) {
2709 if (token == TokenNameRPAREN) {
2713 non_empty_function_call_parameter_list();
2714 if (token != TokenNameRPAREN) {
2715 throwSyntaxError("')' expected in ctor_arguments.");
2721 private void assignment_list() {
2723 // assignment_list ',' assignment_list_element
2724 //| assignment_list_element
2726 assignment_list_element();
2727 if (token != TokenNameCOMMA) {
2734 private void assignment_list_element() {
2735 //assignment_list_element:
2737 //| T_LIST '(' assignment_list ')'
2739 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2742 if (token == TokenNamelist) {
2744 if (token == TokenNameLPAREN) {
2747 if (token != TokenNameRPAREN) {
2748 throwSyntaxError("')' expected after 'list' keyword.");
2752 throwSyntaxError("'(' expected after 'list' keyword.");
2758 private void array_pair_list() {
2761 //| non_empty_array_pair_list possible_comma
2762 non_empty_array_pair_list();
2763 if (token == TokenNameCOMMA) {
2768 private void non_empty_array_pair_list() {
2769 //non_empty_array_pair_list:
2770 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2771 //| non_empty_array_pair_list ',' expr
2772 //| expr T_DOUBLE_ARROW expr
2774 //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2775 //| non_empty_array_pair_list ',' '&' w_variable
2776 //| expr T_DOUBLE_ARROW '&' w_variable
2779 if (token == TokenNameAND) {
2784 if (token == TokenNameAND) {
2787 } else if (token == TokenNameEQUAL_GREATER) {
2789 if (token == TokenNameAND) {
2797 if (token != TokenNameCOMMA) {
2801 if (token == TokenNameRPAREN) {
2807 // private void variableList() {
2810 // if (token == TokenNameCOMMA) {
2817 private Expression variable_without_objects() {
2818 // variable_without_objects:
2819 // reference_variable
2820 // | simple_indirect_reference reference_variable
2821 if (Scanner.TRACE) {
2822 System.out.println("TRACE: variable_without_objects()");
2824 while (token == TokenNameDOLLAR) {
2827 return reference_variable();
2830 private Expression function_call() {
2832 // T_STRING '(' function_call_parameter_list ')'
2833 //| class_constant '(' function_call_parameter_list ')'
2834 //| static_member '(' function_call_parameter_list ')'
2835 //| variable_without_objects '(' function_call_parameter_list ')'
2836 char[] defineName = null;
2837 char[] ident = null;
2840 Expression ref = null;
2841 if (Scanner.TRACE) {
2842 System.out.println("TRACE: function_call()");
2844 if (token == TokenNameIdentifier) {
2845 ident = scanner.getCurrentIdentifierSource();
2847 startPos = scanner.getCurrentTokenStartPosition();
2848 endPos = scanner.getCurrentTokenEndPosition();
2851 case TokenNamePAAMAYIM_NEKUDOTAYIM:
2855 if (token == TokenNameIdentifier) {
2860 variable_without_objects();
2865 ref = variable_without_objects();
2867 if (token != TokenNameLPAREN) {
2868 if (defineName != null) {
2869 // does this identifier contain only uppercase characters?
2870 if (defineName.length == 3) {
2871 if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') {
2874 } else if (defineName.length == 4) {
2875 if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') {
2877 } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') {
2880 } else if (defineName.length == 5) {
2881 if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') {
2885 if (defineName != null) {
2886 for (int i = 0; i < defineName.length; i++) {
2887 if (Character.isLowerCase(defineName[i])) {
2888 problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult);
2894 // TODO is this ok ?
2896 // throwSyntaxError("'(' expected in function call.");
2899 if (token == TokenNameRPAREN) {
2903 non_empty_function_call_parameter_list();
2904 if (token != TokenNameRPAREN) {
2905 String functionName;
2906 if (ident == null) {
2907 functionName = new String(" ");
2909 functionName = new String(ident);
2911 throwSyntaxError("')' expected in function call (" + functionName + ").");
2917 // private void function_call_parameter_list() {
2918 // function_call_parameter_list:
2919 // non_empty_function_call_parameter_list { $$ = $1; }
2922 private void non_empty_function_call_parameter_list() {
2923 //non_empty_function_call_parameter_list:
2924 // expr_without_variable
2927 // | non_empty_function_call_parameter_list ',' expr_without_variable
2928 // | non_empty_function_call_parameter_list ',' variable
2929 // | non_empty_function_call_parameter_list ',' '&' w_variable
2930 if (Scanner.TRACE) {
2931 System.out.println("TRACE: non_empty_function_call_parameter_list()");
2934 if (token == TokenNameAND) {
2938 // if (token == TokenNameIdentifier || token ==
2939 // TokenNameVariable
2940 // || token == TokenNameDOLLAR) {
2943 expr_without_variable(true);
2946 if (token != TokenNameCOMMA) {
2953 private void fully_qualified_class_name() {
2954 if (token == TokenNameIdentifier) {
2957 throwSyntaxError("Class name expected.");
2961 private void static_member() {
2963 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2964 // variable_without_objects
2965 if (Scanner.TRACE) {
2966 System.out.println("TRACE: static_member()");
2968 fully_qualified_class_name();
2969 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2970 throwSyntaxError("'::' expected after class name (static_member).");
2973 variable_without_objects();
2976 private Expression base_variable_with_function_calls() {
2977 // base_variable_with_function_calls:
2980 boolean functionCall = false;
2981 if (Scanner.TRACE) {
2982 System.out.println("TRACE: base_variable_with_function_calls()");
2984 // if (token == TokenNameIdentifier) {
2985 // functionCall = true;
2986 // } else if (token == TokenNameVariable) {
2987 // int tempToken = token;
2988 // int tempPosition = scanner.currentPosition;
2990 // if (token == TokenNameLPAREN) {
2991 // functionCall = true;
2993 // token = tempToken;
2994 // scanner.currentPosition = tempPosition;
2995 // scanner.phpMode = true;
2997 // if (functionCall) {
2998 return function_call();
3004 private Expression base_variable() {
3006 // reference_variable
3007 // | simple_indirect_reference reference_variable
3009 Expression ref = null;
3010 if (Scanner.TRACE) {
3011 System.out.println("TRACE: base_variable()");
3013 if (token == TokenNameIdentifier) {
3016 while (token == TokenNameDOLLAR) {
3019 reference_variable();
3024 // private void simple_indirect_reference() {
3025 // // simple_indirect_reference:
3027 // //| simple_indirect_reference '$'
3029 private Expression reference_variable() {
3030 // reference_variable:
3031 // reference_variable '[' dim_offset ']'
3032 // | reference_variable '{' expr '}'
3033 // | compound_variable
3034 Expression ref = null;
3035 if (Scanner.TRACE) {
3036 System.out.println("TRACE: reference_variable()");
3038 ref = compound_variable();
3040 if (token == TokenNameLBRACE) {
3044 if (token != TokenNameRBRACE) {
3045 throwSyntaxError("'}' expected in reference variable.");
3048 } else if (token == TokenNameLBRACKET) {
3051 if (token != TokenNameRBRACKET) {
3054 if (token != TokenNameRBRACKET) {
3055 throwSyntaxError("']' expected in reference variable.");
3066 private Expression compound_variable() {
3067 // compound_variable:
3069 // | '$' '{' expr '}'
3070 if (Scanner.TRACE) {
3071 System.out.println("TRACE: compound_variable()");
3073 if (token == TokenNameVariable) {
3074 FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition());
3078 // because of simple_indirect_reference
3079 while (token == TokenNameDOLLAR) {
3082 if (token != TokenNameLBRACE) {
3083 reportSyntaxError("'{' expected after compound variable token '$'.");
3088 if (token != TokenNameRBRACE) {
3089 throwSyntaxError("'}' expected after compound variable token '$'.");
3096 // private void dim_offset() {
3102 private void object_property() {
3105 //| variable_without_objects
3106 if (Scanner.TRACE) {
3107 System.out.println("TRACE: object_property()");
3109 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
3110 variable_without_objects();
3116 private void object_dim_list() {
3118 // object_dim_list '[' dim_offset ']'
3119 //| object_dim_list '{' expr '}'
3121 if (Scanner.TRACE) {
3122 System.out.println("TRACE: object_dim_list()");
3126 if (token == TokenNameLBRACE) {
3129 if (token != TokenNameRBRACE) {
3130 throwSyntaxError("'}' expected in object_dim_list.");
3133 } else if (token == TokenNameLBRACKET) {
3135 if (token == TokenNameRBRACKET) {
3140 if (token != TokenNameRBRACKET) {
3141 throwSyntaxError("']' expected in object_dim_list.");
3150 private void variable_name() {
3154 if (Scanner.TRACE) {
3155 System.out.println("TRACE: variable_name()");
3157 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
3158 if (token > TokenNameKEYWORD) {
3159 // TODO show a warning "Keyword used as variable" ?
3163 if (token != TokenNameLBRACE) {
3164 throwSyntaxError("'{' expected in variable name.");
3168 if (token != TokenNameRBRACE) {
3169 throwSyntaxError("'}' expected in variable name.");
3175 private void r_variable() {
3179 private void w_variable() {
3183 private void rw_variable() {
3187 private Expression variable() {
3189 // base_variable_with_function_calls T_OBJECT_OPERATOR
3190 // object_property method_or_not variable_properties
3191 // | base_variable_with_function_calls
3192 Expression ref = base_variable_with_function_calls();
3193 if (token == TokenNameMINUS_GREATER) {
3198 variable_properties();
3203 private void variable_properties() {
3204 // variable_properties:
3205 // variable_properties variable_property
3207 while (token == TokenNameMINUS_GREATER) {
3208 variable_property();
3212 private void variable_property() {
3213 // variable_property:
3214 // T_OBJECT_OPERATOR object_property method_or_not
3215 if (Scanner.TRACE) {
3216 System.out.println("TRACE: variable_property()");
3218 if (token == TokenNameMINUS_GREATER) {
3223 throwSyntaxError("'->' expected in variable_property.");
3227 private void method_or_not() {
3229 // '(' function_call_parameter_list ')'
3231 if (Scanner.TRACE) {
3232 System.out.println("TRACE: method_or_not()");
3234 if (token == TokenNameLPAREN) {
3236 if (token == TokenNameRPAREN) {
3240 non_empty_function_call_parameter_list();
3241 if (token != TokenNameRPAREN) {
3242 throwSyntaxError("')' expected in method_or_not.");
3248 private void exit_expr() {
3252 if (token != TokenNameLPAREN) {
3256 if (token == TokenNameRPAREN) {
3261 if (token != TokenNameRPAREN) {
3262 throwSyntaxError("')' expected after keyword 'exit'");
3267 private void encaps_list() {
3268 // encaps_list encaps_var
3269 // | encaps_list T_STRING
3270 // | encaps_list T_NUM_STRING
3271 // | encaps_list T_ENCAPSED_AND_WHITESPACE
3272 // | encaps_list T_CHARACTER
3273 // | encaps_list T_BAD_CHARACTER
3274 // | encaps_list '['
3275 // | encaps_list ']'
3276 // | encaps_list '{'
3277 // | encaps_list '}'
3278 // | encaps_list T_OBJECT_OPERATOR
3282 case TokenNameSTRING:
3285 case TokenNameLBRACE:
3286 // scanner.encapsedStringStack.pop();
3289 case TokenNameRBRACE:
3290 // scanner.encapsedStringStack.pop();
3293 case TokenNameLBRACKET:
3294 // scanner.encapsedStringStack.pop();
3297 case TokenNameRBRACKET:
3298 // scanner.encapsedStringStack.pop();
3301 case TokenNameMINUS_GREATER:
3302 // scanner.encapsedStringStack.pop();
3305 case TokenNameVariable:
3306 case TokenNameDOLLAR_LBRACE:
3307 case TokenNameLBRACE_DOLLAR:
3311 char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
3312 if (encapsedChar == '$') {
3313 scanner.encapsedStringStack.pop();
3314 encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
3315 switch (encapsedChar) {
3317 if (token == TokenNameEncapsedString0) {
3320 token = TokenNameSTRING;
3323 if (token == TokenNameEncapsedString1) {
3326 token = TokenNameSTRING;
3329 if (token == TokenNameEncapsedString2) {
3332 token = TokenNameSTRING;
3341 private void encaps_var() {
3343 // | T_VARIABLE '[' encaps_var_offset ']'
3344 // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
3345 // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
3346 // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
3347 // | T_CURLY_OPEN variable '}'
3349 case TokenNameVariable:
3351 if (token == TokenNameLBRACKET) {
3353 expr(); //encaps_var_offset();
3354 if (token != TokenNameRBRACKET) {
3355 throwSyntaxError("']' expected after variable.");
3357 // scanner.encapsedStringStack.pop();
3360 } else if (token == TokenNameMINUS_GREATER) {
3362 if (token != TokenNameIdentifier) {
3363 throwSyntaxError("Identifier expected after '->'.");
3365 // scanner.encapsedStringStack.pop();
3369 // // scanner.encapsedStringStack.pop();
3370 // int tempToken = TokenNameSTRING;
3371 // if (!scanner.encapsedStringStack.isEmpty()
3372 // && (token == TokenNameEncapsedString0
3373 // || token == TokenNameEncapsedString1
3374 // || token == TokenNameEncapsedString2 || token ==
3375 // TokenNameERROR)) {
3376 // char encapsedChar = ((Character)
3377 // scanner.encapsedStringStack.peek())
3380 // case TokenNameEncapsedString0 :
3381 // if (encapsedChar == '`') {
3382 // tempToken = TokenNameEncapsedString0;
3385 // case TokenNameEncapsedString1 :
3386 // if (encapsedChar == '\'') {
3387 // tempToken = TokenNameEncapsedString1;
3390 // case TokenNameEncapsedString2 :
3391 // if (encapsedChar == '"') {
3392 // tempToken = TokenNameEncapsedString2;
3395 // case TokenNameERROR :
3396 // if (scanner.source[scanner.currentPosition - 1] == '\\') {
3397 // scanner.currentPosition--;
3403 // token = tempToken;
3406 case TokenNameDOLLAR_LBRACE:
3408 if (token == TokenNameDOLLAR_LBRACE) {
3410 } else if (token == TokenNameIdentifier) {
3412 if (token == TokenNameLBRACKET) {
3414 // if (token == TokenNameRBRACKET) {
3418 if (token != TokenNameRBRACKET) {
3419 throwSyntaxError("']' expected after '${'.");
3427 if (token != TokenNameRBRACE) {
3428 throwSyntaxError("'}' expected.");
3432 case TokenNameLBRACE_DOLLAR:
3434 if (token == TokenNameLBRACE_DOLLAR) {
3436 } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
3438 if (token == TokenNameLBRACKET) {
3440 // if (token == TokenNameRBRACKET) {
3444 if (token != TokenNameRBRACKET) {
3445 throwSyntaxError("']' expected.");
3449 } else if (token == TokenNameMINUS_GREATER) {
3451 if (token != TokenNameIdentifier && token != TokenNameVariable) {
3452 throwSyntaxError("String or Variable token expected.");
3455 if (token == TokenNameLBRACKET) {
3457 // if (token == TokenNameRBRACKET) {
3461 if (token != TokenNameRBRACKET) {
3462 throwSyntaxError("']' expected after '${'.");
3468 // if (token != TokenNameRBRACE) {
3469 // throwSyntaxError("'}' expected after '{$'.");
3471 // // scanner.encapsedStringStack.pop();
3475 if (token != TokenNameRBRACE) {
3476 throwSyntaxError("'}' expected.");
3478 // scanner.encapsedStringStack.pop();
3485 private void encaps_var_offset() {
3490 case TokenNameSTRING:
3493 case TokenNameIntegerLiteral:
3496 case TokenNameVariable:
3499 case TokenNameIdentifier:
3503 throwSyntaxError("Variable or String token expected.");
3508 private void internal_functions_in_yacc() {
3511 case TokenNameisset:
3512 // T_ISSET '(' isset_variables ')'
3514 if (token != TokenNameLPAREN) {
3515 throwSyntaxError("'(' expected after keyword 'isset'");
3519 if (token != TokenNameRPAREN) {
3520 throwSyntaxError("')' expected after keyword 'isset'");
3524 case TokenNameempty:
3525 // T_EMPTY '(' variable ')'
3527 if (token != TokenNameLPAREN) {
3528 throwSyntaxError("'(' expected after keyword 'empty'");
3532 if (token != TokenNameRPAREN) {
3533 throwSyntaxError("')' expected after keyword 'empty'");
3537 case TokenNameinclude:
3539 checkFileName(token);
3541 case TokenNameinclude_once:
3542 // T_INCLUDE_ONCE expr
3543 checkFileName(token);
3546 // T_EVAL '(' expr ')'
3548 if (token != TokenNameLPAREN) {
3549 throwSyntaxError("'(' expected after keyword 'eval'");
3553 if (token != TokenNameRPAREN) {
3554 throwSyntaxError("')' expected after keyword 'eval'");
3558 case TokenNamerequire:
3560 checkFileName(token);
3562 case TokenNamerequire_once:
3563 // T_REQUIRE_ONCE expr
3564 checkFileName(token);
3569 private void checkFileName(int includeToken) {
3570 //<include-token> expr
3571 int start = scanner.getCurrentTokenStartPosition();
3572 boolean hasLPAREN = false;
3574 if (token == TokenNameLPAREN) {
3578 Expression expression = expr();
3580 if (token == TokenNameRPAREN) {
3583 throwSyntaxError("')' expected for keyword '" + scanner.toStringAction(includeToken) + "'");
3586 char[] currTokenSource = scanner.getCurrentTokenSource(start);
3588 if (scanner.compilationUnit != null) {
3589 IResource resource = scanner.compilationUnit.getResource();
3590 if (resource != null && resource instanceof IFile) {
3591 file = (IFile) resource;
3595 tokens = new char[1][];
3596 tokens[0] = currTokenSource;
3598 ImportReference impt = new ImportReference(tokens, currTokenSource, start, scanner.getCurrentTokenEndPosition(), false);
3599 impt.declarationSourceEnd = impt.sourceEnd;
3600 impt.declarationEnd = impt.declarationSourceEnd;
3601 //endPosition is just before the ;
3602 impt.declarationSourceStart = start;
3603 includesList.add(impt);
3605 if (expression instanceof StringLiteral) {
3606 StringLiteral literal = (StringLiteral) expression;
3607 char[] includeName = literal.source();
3608 if (includeName.length == 0) {
3609 reportSyntaxError("Empty filename after keyword '" + scanner.toStringAction(includeToken) + "'", literal.sourceStart,
3610 literal.sourceStart + 1);
3612 String includeNameString = new String(includeName);
3613 if (literal instanceof StringLiteralDQ) {
3614 if (includeNameString.indexOf('$') >= 0) {
3615 // assuming that the filename contains a variable => no filename check
3619 if (includeNameString.startsWith("http://")) {
3620 // assuming external include location
3624 // check the filename:
3625 // System.out.println(new String(compilationUnit.getFileName())+" - "+ expression.toStringExpression());
3626 IProject project = file.getProject();
3627 if (project != null) {
3628 IPath path = PHPFileUtil.determineFilePath(includeNameString, file, project);
3631 // reportSyntaxError("File: " + expression.toStringExpression() + " doesn't exist in project: "
3632 // + project.getLocation().toString(), literal.sourceStart, literal.sourceEnd);
3633 String[] args = { expression.toStringExpression(), project.getLocation().toString() };
3634 problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext,
3635 compilationUnit.compilationResult);
3638 // String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString();
3639 // String filePath = file.getRawLocation().toString();
3640 String filePath = path.toString();
3641 String ext = file.getRawLocation().getFileExtension();
3642 int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
3645 impt.tokens = CharOperation.splitOn('/', filePath.toCharArray(), 0, filePath.length() - fileExtensionLength);
3646 impt.setFile(PHPFileUtil.createFile(path, project));
3647 } catch (Exception e) {
3648 // the file is outside of the workspace
3656 private void isset_variables() {
3658 // | isset_variables ','
3659 if (token == TokenNameRPAREN) {
3660 throwSyntaxError("Variable expected after keyword 'isset'");
3664 if (token == TokenNameCOMMA) {
3672 private boolean common_scalar() {
3676 // | T_CONSTANT_ENCAPSED_STRING
3683 case TokenNameIntegerLiteral:
3686 case TokenNameDoubleLiteral:
3689 case TokenNameStringDoubleQuote:
3692 case TokenNameStringSingleQuote:
3695 case TokenNameStringInterpolated:
3704 case TokenNameCLASS_C:
3707 case TokenNameMETHOD_C:
3710 case TokenNameFUNC_C:
3717 private void scalar() {
3720 //| T_STRING_VARNAME
3723 //| '"' encaps_list '"'
3724 //| '\'' encaps_list '\''
3725 //| T_START_HEREDOC encaps_list T_END_HEREDOC
3726 throwSyntaxError("Not yet implemented (scalar).");
3729 private void static_scalar() {
3730 // static_scalar: /* compile-time evaluated scalars */
3733 // | '+' static_scalar
3734 // | '-' static_scalar
3735 // | T_ARRAY '(' static_array_pair_list ')'
3736 // | static_class_constant
3737 if (common_scalar()) {
3741 case TokenNameIdentifier:
3743 // static_class_constant:
3744 // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3745 if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3747 if (token == TokenNameIdentifier) {
3750 throwSyntaxError("Identifier expected after '::' operator.");
3754 case TokenNameEncapsedString0:
3756 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3757 while (scanner.currentCharacter != '`') {
3758 if (scanner.currentCharacter == '\\') {
3759 scanner.currentPosition++;
3761 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3764 } catch (IndexOutOfBoundsException e) {
3765 throwSyntaxError("'`' expected at end of static string.");
3768 case TokenNameEncapsedString1:
3770 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3771 while (scanner.currentCharacter != '\'') {
3772 if (scanner.currentCharacter == '\\') {
3773 scanner.currentPosition++;
3775 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3778 } catch (IndexOutOfBoundsException e) {
3779 throwSyntaxError("'\'' expected at end of static string.");
3782 case TokenNameEncapsedString2:
3784 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3785 while (scanner.currentCharacter != '"') {
3786 if (scanner.currentCharacter == '\\') {
3787 scanner.currentPosition++;
3789 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3792 } catch (IndexOutOfBoundsException e) {
3793 throwSyntaxError("'\"' expected at end of static string.");
3800 case TokenNameMINUS:
3804 case TokenNamearray:
3806 if (token != TokenNameLPAREN) {
3807 throwSyntaxError("'(' expected after keyword 'array'");
3810 if (token == TokenNameRPAREN) {
3814 non_empty_static_array_pair_list();
3815 if (token != TokenNameRPAREN) {
3816 throwSyntaxError("')' or ',' expected after keyword 'array'");
3820 // case TokenNamenull :
3823 // case TokenNamefalse :
3826 // case TokenNametrue :
3830 throwSyntaxError("Static scalar/constant expected.");
3834 private void non_empty_static_array_pair_list() {
3835 // non_empty_static_array_pair_list:
3836 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3838 //| non_empty_static_array_pair_list ',' static_scalar
3839 //| static_scalar T_DOUBLE_ARROW static_scalar
3843 if (token == TokenNameEQUAL_GREATER) {
3847 if (token != TokenNameCOMMA) {
3851 if (token == TokenNameRPAREN) {
3857 public void reportSyntaxError() { //int act, int currentKind, int
3859 /* remember current scanner position */
3860 int startPos = scanner.startPosition;
3861 int currentPos = scanner.currentPosition;
3862 // String[] expectings;
3863 // String tokenName = name[symbol_index[currentKind]];
3864 //fetch all "accurate" possible terminals that could recover the error
3865 // int start, end = start = asi(stack[stateStackTop]);
3866 // while (asr[end] != 0)
3868 // int length = end - start;
3869 // expectings = new String[length];
3870 // if (length != 0) {
3871 // char[] indexes = new char[length];
3872 // System.arraycopy(asr, start, indexes, 0, length);
3873 // for (int i = 0; i < length; i++) {
3874 // expectings[i] = name[symbol_index[indexes[i]]];
3877 //if the pb is an EOF, try to tell the user that they are some
3878 // if (tokenName.equals(UNEXPECTED_EOF)) {
3879 // if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3880 // char[] tokenSource;
3882 // tokenSource = this.scanner.getCurrentTokenSource();
3883 // } catch (Exception e) {
3884 // tokenSource = new char[] {};
3886 // problemReporter().parseError(
3887 // this.scanner.startPosition,
3888 // this.scanner.currentPosition - 1,
3893 // } else { //the next test is HEAVILY grammar DEPENDENT.
3894 // if ((length == 14)
3895 // && (expectings[0] == "=") //$NON-NLS-1$
3896 // && (expectings[1] == "*=") //$NON-NLS-1$
3897 // && (expressionPtr > -1)) {
3898 // switch(currentKind) {
3899 // case TokenNameSEMICOLON:
3900 // case TokenNamePLUS:
3901 // case TokenNameMINUS:
3902 // case TokenNameDIVIDE:
3903 // case TokenNameREMAINDER:
3904 // case TokenNameMULTIPLY:
3905 // case TokenNameLEFT_SHIFT:
3906 // case TokenNameRIGHT_SHIFT:
3907 //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3908 // case TokenNameLESS:
3909 // case TokenNameGREATER:
3910 // case TokenNameLESS_EQUAL:
3911 // case TokenNameGREATER_EQUAL:
3912 // case TokenNameEQUAL_EQUAL:
3913 // case TokenNameNOT_EQUAL:
3914 // case TokenNameXOR:
3915 // case TokenNameAND:
3916 // case TokenNameOR:
3917 // case TokenNameOR_OR:
3918 // case TokenNameAND_AND:
3919 // // the ; is not the expected token ==> it ends a statement when an
3920 // expression is not ended
3921 // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3923 // case TokenNameRBRACE :
3924 // problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3927 // char[] tokenSource;
3929 // tokenSource = this.scanner.getCurrentTokenSource();
3930 // } catch (Exception e) {
3931 // tokenSource = new char[] {};
3933 // problemReporter().parseError(
3934 // this.scanner.startPosition,
3935 // this.scanner.currentPosition - 1,
3939 // this.checkAndReportBracketAnomalies(problemReporter());
3944 tokenSource = this.scanner.getCurrentTokenSource();
3945 } catch (Exception e) {
3946 tokenSource = new char[] {};
3948 // problemReporter().parseError(
3949 // this.scanner.startPosition,
3950 // this.scanner.currentPosition - 1,
3954 this.checkAndReportBracketAnomalies(problemReporter());
3957 /* reset scanner where it was */
3958 scanner.startPosition = startPos;
3959 scanner.currentPosition = currentPos;
3962 public static final int RoundBracket = 0;
3964 public static final int SquareBracket = 1;
3966 public static final int CurlyBracket = 2;
3968 public static final int BracketKinds = 3;
3970 protected int[] nestedMethod; //the ptr is nestedType
3972 protected int nestedType, dimensions;
3974 //variable set stack
3975 final static int VariableStackIncrement = 10;
3977 HashMap fTypeVariables = null;
3979 HashMap fMethodVariables = null;
3982 final static int AstStackIncrement = 100;
3984 protected int astPtr;
3986 protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
3988 protected int astLengthPtr;
3990 protected int[] astLengthStack;
3992 ASTNode[] noAstNodes = new ASTNode[AstStackIncrement];
3994 public CompilationUnitDeclaration compilationUnit; /*
3995 * the result from parse()
3998 protected ReferenceContext referenceContext;
4000 protected ProblemReporter problemReporter;
4002 protected CompilerOptions options;
4004 private ArrayList includesList;
4006 // protected CompilationResult compilationResult;
4008 * Returns this parser's problem reporter initialized with its reference context. Also it is assumed that a problem is going to be
4009 * reported, so initializes the compilation result's line positions.
4011 public ProblemReporter problemReporter() {
4012 if (scanner.recordLineSeparator) {
4013 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
4015 problemReporter.referenceContext = referenceContext;
4016 return problemReporter;
4020 * Reconsider the entire source looking for inconsistencies in {} () []
4022 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
4023 scanner.wasAcr = false;
4024 boolean anomaliesDetected = false;
4026 char[] source = scanner.source;
4027 int[] leftCount = { 0, 0, 0 };
4028 int[] rightCount = { 0, 0, 0 };
4029 int[] depths = { 0, 0, 0 };
4030 int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] };
4031 int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] };
4032 int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] };
4033 int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] };
4034 scanner.currentPosition = scanner.initialPosition; //starting
4036 // (first-zero-based
4038 while (scanner.currentPosition < scanner.eofPosition) { //loop for
4043 // ---------Consume white space and handles
4044 // startPosition---------
4045 boolean isWhiteSpace;
4047 scanner.startPosition = scanner.currentPosition;
4048 // if (((scanner.currentCharacter =
4049 // source[scanner.currentPosition++]) == '\\') &&
4050 // (source[scanner.currentPosition] == 'u')) {
4051 // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
4053 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
4054 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
4055 // only record line positions we have not
4057 scanner.pushLineSeparator();
4060 isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
4062 } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
4063 // -------consume token until } is found---------
4064 switch (scanner.currentCharacter) {
4066 int index = leftCount[CurlyBracket]++;
4067 if (index == leftPositions[CurlyBracket].length) {
4068 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
4069 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
4071 leftPositions[CurlyBracket][index] = scanner.startPosition;
4072 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
4076 int index = rightCount[CurlyBracket]++;
4077 if (index == rightPositions[CurlyBracket].length) {
4078 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
4079 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
4081 rightPositions[CurlyBracket][index] = scanner.startPosition;
4082 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
4086 int index = leftCount[RoundBracket]++;
4087 if (index == leftPositions[RoundBracket].length) {
4088 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
4089 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
4091 leftPositions[RoundBracket][index] = scanner.startPosition;
4092 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
4096 int index = rightCount[RoundBracket]++;
4097 if (index == rightPositions[RoundBracket].length) {
4098 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
4099 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
4101 rightPositions[RoundBracket][index] = scanner.startPosition;
4102 rightDepths[RoundBracket][index] = --depths[RoundBracket];
4106 int index = leftCount[SquareBracket]++;
4107 if (index == leftPositions[SquareBracket].length) {
4108 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
4109 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
4111 leftPositions[SquareBracket][index] = scanner.startPosition;
4112 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
4116 int index = rightCount[SquareBracket]++;
4117 if (index == rightPositions[SquareBracket].length) {
4118 System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
4119 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
4121 rightPositions[SquareBracket][index] = scanner.startPosition;
4122 rightDepths[SquareBracket][index] = --depths[SquareBracket];
4126 if (scanner.getNextChar('\\')) {
4127 scanner.scanEscapeCharacter();
4128 } else { // consume next character
4129 scanner.unicodeAsBackSlash = false;
4130 // if (((scanner.currentCharacter =
4131 // source[scanner.currentPosition++]) ==
4133 // (source[scanner.currentPosition] ==
4135 // scanner.getNextUnicodeChar();
4137 if (scanner.withoutUnicodePtr != 0) {
4138 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
4142 scanner.getNextChar('\'');
4146 // consume next character
4147 scanner.unicodeAsBackSlash = false;
4148 // if (((scanner.currentCharacter =
4149 // source[scanner.currentPosition++]) == '\\') &&
4150 // (source[scanner.currentPosition] == 'u')) {
4151 // scanner.getNextUnicodeChar();
4153 if (scanner.withoutUnicodePtr != 0) {
4154 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
4157 while (scanner.currentCharacter != '"') {
4158 if (scanner.currentCharacter == '\r') {
4159 if (source[scanner.currentPosition] == '\n')
4160 scanner.currentPosition++;
4161 break; // the string cannot go further that
4164 if (scanner.currentCharacter == '\n') {
4165 break; // the string cannot go further that
4168 if (scanner.currentCharacter == '\\') {
4169 scanner.scanEscapeCharacter();
4171 // consume next character
4172 scanner.unicodeAsBackSlash = false;
4173 // if (((scanner.currentCharacter =
4174 // source[scanner.currentPosition++]) == '\\')
4175 // && (source[scanner.currentPosition] == 'u'))
4177 // scanner.getNextUnicodeChar();
4179 if (scanner.withoutUnicodePtr != 0) {
4180 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
4187 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
4190 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
4191 && (source[scanner.currentPosition] == 'u')) {
4192 //-------------unicode traitement
4194 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
4195 scanner.currentPosition++;
4196 while (source[scanner.currentPosition] == 'u') {
4197 scanner.currentPosition++;
4199 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
4200 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
4201 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
4202 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
4206 scanner.currentCharacter = 'A';
4207 } //something different from \n and \r
4209 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
4212 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
4214 scanner.startPosition = scanner.currentPosition;
4215 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
4216 && (source[scanner.currentPosition] == 'u')) {
4217 //-------------unicode traitement
4219 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
4220 scanner.currentPosition++;
4221 while (source[scanner.currentPosition] == 'u') {
4222 scanner.currentPosition++;
4224 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
4225 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
4226 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
4227 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
4231 scanner.currentCharacter = 'A';
4232 } //something different from \n
4235 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
4239 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
4240 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
4241 // only record line positions we
4242 // have not recorded yet
4243 scanner.pushLineSeparator();
4244 if (this.scanner.taskTags != null) {
4245 this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner
4246 .getCurrentTokenEndPosition());
4252 if (test > 0) { //traditional and annotation
4254 boolean star = false;
4255 // consume next character
4256 scanner.unicodeAsBackSlash = false;
4257 // if (((scanner.currentCharacter =
4258 // source[scanner.currentPosition++]) ==
4260 // (source[scanner.currentPosition] ==
4262 // scanner.getNextUnicodeChar();
4264 if (scanner.withoutUnicodePtr != 0) {
4265 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
4268 if (scanner.currentCharacter == '*') {
4272 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
4273 && (source[scanner.currentPosition] == 'u')) {
4274 //-------------unicode traitement
4276 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
4277 scanner.currentPosition++;
4278 while (source[scanner.currentPosition] == 'u') {
4279 scanner.currentPosition++;
4281 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
4282 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
4283 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
4284 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
4288 scanner.currentCharacter = 'A';
4289 } //something different from * and /
4291 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
4294 //loop until end of comment */
4295 while ((scanner.currentCharacter != '/') || (!star)) {
4296 star = scanner.currentCharacter == '*';
4298 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
4299 && (source[scanner.currentPosition] == 'u')) {
4300 //-------------unicode traitement
4302 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
4303 scanner.currentPosition++;
4304 while (source[scanner.currentPosition] == 'u') {
4305 scanner.currentPosition++;
4307 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
4308 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
4309 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
4310 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
4314 scanner.currentCharacter = 'A';
4315 } //something different from * and
4318 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
4322 if (this.scanner.taskTags != null) {
4323 this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
4330 if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
4331 scanner.scanIdentifierOrKeyword(false);
4334 if (Character.isDigit(scanner.currentCharacter)) {
4335 scanner.scanNumber(false);
4339 //-----------------end switch while
4340 // try--------------------
4341 } catch (IndexOutOfBoundsException e) {
4342 break; // read until EOF
4343 } catch (InvalidInputException e) {
4344 return false; // no clue
4347 if (scanner.recordLineSeparator) {
4348 // compilationUnit.compilationResult.lineSeparatorPositions =
4349 // scanner.getLineEnds();
4351 // check placement anomalies against other kinds of brackets
4352 for (int kind = 0; kind < BracketKinds; kind++) {
4353 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
4354 int start = leftPositions[kind][leftIndex]; // deepest
4356 // find matching closing bracket
4357 int depth = leftDepths[kind][leftIndex];
4359 for (int i = 0; i < rightCount[kind]; i++) {
4360 int pos = rightPositions[kind][i];
4361 // want matching bracket further in source with same
4363 if ((pos > start) && (depth == rightDepths[kind][i])) {
4368 if (end < 0) { // did not find a good closing match
4369 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
4372 // check if even number of opening/closing other brackets
4373 // in between this pair of brackets
4375 for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
4376 for (int i = 0; i < leftCount[otherKind]; i++) {
4377 int pos = leftPositions[otherKind][i];
4378 if ((pos > start) && (pos < end))
4381 for (int i = 0; i < rightCount[otherKind]; i++) {
4382 int pos = rightPositions[otherKind][i];
4383 if ((pos > start) && (pos < end))
4387 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket
4393 // too many opening brackets ?
4394 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
4395 anomaliesDetected = true;
4396 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext,
4397 compilationUnit.compilationResult);
4399 // too many closing brackets ?
4400 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
4401 anomaliesDetected = true;
4402 problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
4404 if (anomaliesDetected)
4407 return anomaliesDetected;
4408 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
4409 return anomaliesDetected;
4410 } catch (NullPointerException e) { // jdk1.2.2 jit bug
4411 return anomaliesDetected;
4415 protected void pushOnAstLengthStack(int pos) {
4417 astLengthStack[++astLengthPtr] = pos;
4418 } catch (IndexOutOfBoundsException e) {
4419 int oldStackLength = astLengthStack.length;
4420 int[] oldPos = astLengthStack;
4421 astLengthStack = new int[oldStackLength + StackIncrement];
4422 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
4423 astLengthStack[astLengthPtr] = pos;
4427 protected void pushOnAstStack(ASTNode node) {
4429 * add a new obj on top of the ast stack
4432 astStack[++astPtr] = node;
4433 } catch (IndexOutOfBoundsException e) {
4434 int oldStackLength = astStack.length;
4435 ASTNode[] oldStack = astStack;
4436 astStack = new ASTNode[oldStackLength + AstStackIncrement];
4437 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
4438 astPtr = oldStackLength;
4439 astStack[astPtr] = node;
4442 astLengthStack[++astLengthPtr] = 1;
4443 } catch (IndexOutOfBoundsException e) {
4444 int oldStackLength = astLengthStack.length;
4445 int[] oldPos = astLengthStack;
4446 astLengthStack = new int[oldStackLength + AstStackIncrement];
4447 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
4448 astLengthStack[astLengthPtr] = 1;
4452 protected void resetModifiers() {
4453 this.modifiers = AccDefault;
4454 this.modifiersSourceStart = -1; // <-- see comment into
4455 // modifiersFlag(int)
4456 this.scanner.commentPtr = -1;
4459 protected void consumePackageDeclarationName(IFile file) {
4460 // create a package name similar to java package names
4461 String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString();
4462 String filePath = file.getRawLocation().toString();
4463 String ext = file.getRawLocation().getFileExtension();
4464 int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
4465 ImportReference impt;
4468 if (filePath.startsWith(projectPath)) {
4469 tokens = CharOperation
4470 .splitOn('/', filePath.toCharArray(), projectPath.length() + 1, filePath.length() - fileExtensionLength);
4472 String name = file.getName();
4473 tokens = new char[1][];
4474 tokens[0] = name.substring(0, name.length() - fileExtensionLength).toCharArray();
4477 this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true);
4479 impt.declarationSourceStart = 0;
4480 impt.declarationSourceEnd = 0;
4481 impt.declarationEnd = 0;
4482 //endPosition is just before the ;