-/*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
+/***********************************************************************************************************************************
+ * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material are made available under the
+ * terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: www.phpeclipse.de
+ **********************************************************************************************************************************/
package net.sourceforge.phpdt.internal.compiler.parser;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
import net.sourceforge.phpdt.core.compiler.InvalidInputException;
-import net.sourceforge.phpdt.internal.compiler.CompilationResult;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols.TokenName;
import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression;
+import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.AbstractVariableDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.AnonymousLocalTypeDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.Argument;
-import net.sourceforge.phpdt.internal.compiler.ast.ArrayAllocationExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer;
-import net.sourceforge.phpdt.internal.compiler.ast.ArrayQualifiedTypeReference;
-import net.sourceforge.phpdt.internal.compiler.ast.ArrayReference;
-import net.sourceforge.phpdt.internal.compiler.ast.ArrayTypeReference;
-import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.Assignment;
-import net.sourceforge.phpdt.internal.compiler.ast.AstNode;
import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression;
import net.sourceforge.phpdt.internal.compiler.ast.Block;
-import net.sourceforge.phpdt.internal.compiler.ast.Break;
-import net.sourceforge.phpdt.internal.compiler.ast.Case;
-import net.sourceforge.phpdt.internal.compiler.ast.CastExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.CharLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.ClassLiteralAccess;
+import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement;
import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.CompoundAssignment;
import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.Continue;
-import net.sourceforge.phpdt.internal.compiler.ast.DefaultCase;
-import net.sourceforge.phpdt.internal.compiler.ast.DoStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.DoubleLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement;
+import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement;
import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall;
import net.sourceforge.phpdt.internal.compiler.ast.Expression;
-import net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral;
import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
import net.sourceforge.phpdt.internal.compiler.ast.FieldReference;
-import net.sourceforge.phpdt.internal.compiler.ast.FloatLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.ForStatement;
import net.sourceforge.phpdt.internal.compiler.ast.IfStatement;
import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
-import net.sourceforge.phpdt.internal.compiler.ast.Initializer;
import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.IntLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.IntLiteralMinValue;
-import net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.LocalTypeDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.LongLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.LongLiteralMinValue;
-import net.sourceforge.phpdt.internal.compiler.ast.MemberTypeDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.MessageSend;
import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.NameReference;
-import net.sourceforge.phpdt.internal.compiler.ast.NullLiteral;
import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression;
-import net.sourceforge.phpdt.internal.compiler.ast.OperatorExpression;
import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
-import net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference;
-import net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference;
-import net.sourceforge.phpdt.internal.compiler.ast.QualifiedThisReference;
-import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference;
-import net.sourceforge.phpdt.internal.compiler.ast.Reference;
import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference;
import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
import net.sourceforge.phpdt.internal.compiler.ast.Statement;
import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.SuperReference;
-import net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.SynchronizedStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.ThisReference;
-import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral;
-import net.sourceforge.phpdt.internal.compiler.ast.TryStatement;
+import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ;
+import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ;
import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
-import net.sourceforge.phpdt.internal.compiler.ast.UnaryExpression;
-import net.sourceforge.phpdt.internal.compiler.ast.WhileStatement;
-import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
-import net.sourceforge.phpdt.internal.compiler.lookup.BindingIds;
import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
-import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds;
-import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
import net.sourceforge.phpdt.internal.compiler.util.Util;
-
-public class Parser implements BindingIds, ParserBasicInformation, ITerminalSymbols, CompilerModifiers, OperatorIds, TypeIds {
- protected ProblemReporter problemReporter;
- public int firstToken; // handle for multiple parsing goals
- public int lastAct; //handle for multiple parsing goals
- protected ReferenceContext referenceContext;
- public int currentToken;
- private int synchronizedBlockSourceStart;
-
- //error recovery management
- protected int lastCheckPoint;
- protected RecoveredElement currentElement;
- public static boolean VERBOSE_RECOVERY = false;
- protected boolean restartRecovery;
- protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
- protected boolean hasReportedError;
- protected int recoveredStaticInitializerStart;
- protected int lastIgnoredToken, nextIgnoredToken;
- protected int lastErrorEndPosition;
-
- // 1.4 feature
- protected boolean assertMode = false;
-
- //internal data for the automat
- protected final static int StackIncrement = 255;
- protected int stateStackTop;
- protected int[] stack = new int[StackIncrement];
- //scanner token
- public Scanner scanner;
- //ast stack
- final static int AstStackIncrement = 100;
- protected int astPtr;
- protected AstNode[] astStack = new AstNode[AstStackIncrement];
- protected int astLengthPtr;
- protected int[] astLengthStack;
- public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
- AstNode[] noAstNodes = new AstNode[AstStackIncrement];
- //expression stack
- final static int ExpressionStackIncrement = 100;
- protected int expressionPtr;
- protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
- protected int expressionLengthPtr;
- protected int[] expressionLengthStack;
- Expression[] noExpressions = new Expression[ExpressionStackIncrement];
- //identifiers stacks
- protected int identifierPtr;
- protected char[][] identifierStack;
- protected int identifierLengthPtr;
- protected int[] identifierLengthStack;
- protected long[] identifierPositionStack;
- //positions , dimensions , .... (what ever is int) ..... stack
- protected int intPtr;
- protected int[] intStack;
- protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
- protected int endStatementPosition;
- protected int lParenPos, rParenPos; //accurate only when used !
- //modifiers dimensions nestedType etc.......
- protected boolean optimizeStringLiterals = true;
- protected int modifiers;
- protected int modifiersSourceStart;
- protected int nestedType, dimensions;
- protected int[] nestedMethod; //the ptr is nestedType
- protected int[] realBlockStack;
- protected int realBlockPtr;
- protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
- protected int dietInt = 0;
- // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
- protected int[] variablesCounter;
- //===DATA===DATA===DATA===DATA===DATA===DATA===//
- public final static byte rhs[] =
- {
- 0,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 2,
- 2,
- 1,
- 1,
- 1,
- 1,
- 3,
- 4,
- 0,
- 1,
- 2,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 5,
- 1,
- 2,
- 1,
- 2,
- 2,
- 2,
- 1,
- 1,
- 2,
- 2,
- 2,
- 4,
- 1,
- 1,
- 1,
- 1,
- 2,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 2,
- 3,
- 3,
- 2,
- 2,
- 1,
- 3,
- 1,
- 3,
- 1,
- 2,
- 1,
- 1,
- 1,
- 3,
- 0,
- 3,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 4,
- 1,
- 3,
- 3,
- 7,
- 0,
- 0,
- 0,
- 0,
- 0,
- 2,
- 1,
- 1,
- 1,
- 2,
- 2,
- 4,
- 4,
- 5,
- 4,
- 4,
- 2,
- 1,
- 2,
- 3,
- 3,
- 1,
- 3,
- 3,
- 1,
- 3,
- 1,
- 4,
- 0,
- 2,
- 1,
- 2,
- 2,
- 4,
- 1,
- 1,
- 2,
- 5,
- 5,
- 7,
- 7,
- 7,
- 7,
- 2,
- 2,
- 3,
- 2,
- 2,
- 3,
- 1,
- 2,
- 1,
- 2,
- 1,
- 1,
- 2,
- 2,
- 1,
- 1,
- 1,
- 1,
- 1,
- 3,
- 3,
- 4,
- 1,
- 3,
- 4,
- 0,
- 1,
- 2,
- 1,
- 1,
- 1,
- 1,
- 2,
- 3,
- 4,
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 3,
- 3,
- 2,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 5,
- 7,
- 7,
- 6,
- 2,
- 3,
- 3,
- 4,
- 1,
- 2,
- 2,
- 1,
- 2,
- 3,
- 2,
- 5,
- 5,
- 7,
- 9,
- 9,
- 1,
- 1,
- 1,
- 1,
- 3,
- 3,
- 5,
- 2,
- 3,
- 2,
- 3,
- 3,
- 3,
- 5,
- 1,
- 3,
- 4,
- 1,
- 2,
- 5,
- 2,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 3,
- 1,
- 1,
- 3,
- 3,
- 3,
- 3,
- 3,
- 1,
- 1,
- 5,
- 6,
- 8,
- 7,
- 2,
- 0,
- 2,
- 0,
- 1,
- 3,
- 4,
- 4,
- 1,
- 2,
- 3,
- 2,
- 1,
- 1,
- 2,
- 2,
- 3,
- 3,
- 4,
- 6,
- 6,
- 4,
- 4,
- 1,
- 1,
- 1,
- 1,
- 2,
- 2,
- 0,
- 1,
- 1,
- 3,
- 3,
- 1,
- 3,
- 3,
- 1,
- 3,
- 3,
- 1,
- 5,
- 5,
- 4,
- 1,
- 3,
- 3,
- 3,
- 1,
- 3,
- 3,
- 1,
- 3,
- 3,
- 3,
- 1,
- 3,
- 3,
- 3,
- 3,
- 3,
- 1,
- 3,
- 3,
- 1,
- 3,
- 1,
- 3,
- 1,
- 3,
- 1,
- 3,
- 1,
- 3,
- 1,
- 5,
- 1,
- 1,
- 3,
- 3,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 2,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 2,
- 0,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1,
- 0,
- 1 };
-
- public static char asb[] = null;
- public static char asr[] = null;
- public static char symbol_index[] = null;
- private static final String UNEXPECTED_EOF = "Unexpected End Of File"; //$NON-NLS-1$
-
- public final static String name[] = { null, "++",
- //$NON-NLS-1$
- "--", //$NON-NLS-1$
- "==", //$NON-NLS-1$
- "<=", //$NON-NLS-1$
- ">=", //$NON-NLS-1$
- "!=", //$NON-NLS-1$
- "<<", //$NON-NLS-1$
- ">>", //$NON-NLS-1$
- ">>>", //$NON-NLS-1$
- "+=", //$NON-NLS-1$
- "-=", //$NON-NLS-1$
- "*=", //$NON-NLS-1$
- "/=", //$NON-NLS-1$
- "&=", //$NON-NLS-1$
- "|=", //$NON-NLS-1$
- "^=", //$NON-NLS-1$
- "%=", //$NON-NLS-1$
- "<<=", //$NON-NLS-1$
- ">>=", //$NON-NLS-1$
- ">>>=", //$NON-NLS-1$
- "||", //$NON-NLS-1$
- "&&", //$NON-NLS-1$
- "+", //$NON-NLS-1$
- "-", //$NON-NLS-1$
- "!", //$NON-NLS-1$
- "%", //$NON-NLS-1$
- "^", //$NON-NLS-1$
- "&", //$NON-NLS-1$
- "*", //$NON-NLS-1$
- "|", //$NON-NLS-1$
- "~", //$NON-NLS-1$
- "/", //$NON-NLS-1$
- ">", //$NON-NLS-1$
- "<", //$NON-NLS-1$
- "(", //$NON-NLS-1$
- ")", //$NON-NLS-1$
- "{", //$NON-NLS-1$
- "}", //$NON-NLS-1$
- "[", //$NON-NLS-1$
- "]", //$NON-NLS-1$
- ";", //$NON-NLS-1$
- "?", //$NON-NLS-1$
- ":", //$NON-NLS-1$
- ",", //$NON-NLS-1$
- ".", //$NON-NLS-1$
- "=", //$NON-NLS-1$
- "", //$NON-NLS-1$
- "$empty", //$NON-NLS-1$
- "Identifier", //$NON-NLS-1$
- "abstract", //$NON-NLS-1$
- "assert", //$NON-NLS-1$
- "boolean", //$NON-NLS-1$
- "break", //$NON-NLS-1$
- "byte", //$NON-NLS-1$
- "case", //$NON-NLS-1$
- "catch", //$NON-NLS-1$
- "char", //$NON-NLS-1$
- "class", //$NON-NLS-1$
- "continue", //$NON-NLS-1$
- "default", //$NON-NLS-1$
- "do", //$NON-NLS-1$
- "double", //$NON-NLS-1$
- "else", //$NON-NLS-1$
- "extends", //$NON-NLS-1$
- "false", //$NON-NLS-1$
- "final", //$NON-NLS-1$
- "finally", //$NON-NLS-1$
- "float", //$NON-NLS-1$
- "for", //$NON-NLS-1$
- "if", //$NON-NLS-1$
- "implements", //$NON-NLS-1$
- "import", //$NON-NLS-1$
- "instanceof", //$NON-NLS-1$
- "int", //$NON-NLS-1$
- "interface", //$NON-NLS-1$
- "long", //$NON-NLS-1$
- "native", //$NON-NLS-1$
- "new", //$NON-NLS-1$
- "null", //$NON-NLS-1$
- "package", //$NON-NLS-1$
- "private", //$NON-NLS-1$
- "protected", //$NON-NLS-1$
- "public", //$NON-NLS-1$
- "return", //$NON-NLS-1$
- "short", //$NON-NLS-1$
- "static", //$NON-NLS-1$
- "strictfp", //$NON-NLS-1$
- "super", //$NON-NLS-1$
- "switch", //$NON-NLS-1$
- "synchronized", //$NON-NLS-1$
- "this", //$NON-NLS-1$
- "throw", //$NON-NLS-1$
- "throws", //$NON-NLS-1$
- "transient", //$NON-NLS-1$
- "true", //$NON-NLS-1$
- "try", //$NON-NLS-1$
- "void", //$NON-NLS-1$
- "volatile", //$NON-NLS-1$
- "while", //$NON-NLS-1$
- "IntegerLiteral", //$NON-NLS-1$
- "LongLiteral", //$NON-NLS-1$
- "FloatingPointLiteral", //$NON-NLS-1$
- "DoubleLiteral", //$NON-NLS-1$
- "CharacterLiteral", //$NON-NLS-1$
- "StringLiteral", //$NON-NLS-1$
- UNEXPECTED_EOF, "Invalid Character",
- //$NON-NLS-1$
- "Goal", //$NON-NLS-1$
- "MethodBody", //$NON-NLS-1$
- "ConstructorBody", //$NON-NLS-1$
- "StaticInitializer", //$NON-NLS-1$
- "Initializer", //$NON-NLS-1$
- "Headers", //$NON-NLS-1$
- "BlockStatements", //$NON-NLS-1$
- "MethodPushModifiersHeader", //$NON-NLS-1$
- "CatchHeader", //$NON-NLS-1$
- "FieldDeclaration", //$NON-NLS-1$
- "ImportDeclaration", //$NON-NLS-1$
- "PackageDeclaration", //$NON-NLS-1$
- "TypeDeclaration", //$NON-NLS-1$
- "GenericMethodDeclaration", //$NON-NLS-1$
- "ClassBodyDeclaration", //$NON-NLS-1$
- "Expression", //$NON-NLS-1$
- "Type", //$NON-NLS-1$
- "PrimitiveType", //$NON-NLS-1$
- "ReferenceType", //$NON-NLS-1$
- "ClassOrInterfaceType", //$NON-NLS-1$
- "ArrayType", //$NON-NLS-1$
- "Name", //$NON-NLS-1$
- "Dims", //$NON-NLS-1$
- "ClassType", //$NON-NLS-1$
- "SimpleName", //$NON-NLS-1$
- "Header", //$NON-NLS-1$
- "ClassHeader", //$NON-NLS-1$
- "InterfaceHeader", //$NON-NLS-1$
- "MethodHeader", //$NON-NLS-1$
- "ConstructorHeader", //$NON-NLS-1$
- "FormalParameter", //$NON-NLS-1$
- "ImportDeclarations", //$NON-NLS-1$
- "TypeDeclarations", //$NON-NLS-1$
- "PackageDeclarationName", //$NON-NLS-1$
- "SingleTypeImportDeclarationName", //$NON-NLS-1$
- "TypeImportOnDemandDeclarationName", //$NON-NLS-1$
- "Modifiers", //$NON-NLS-1$
- "Modifier", //$NON-NLS-1$
- "ClassBody", //$NON-NLS-1$
- "ClassHeaderName", //$NON-NLS-1$
- "InterfaceTypeList", //$NON-NLS-1$
- "InterfaceType", //$NON-NLS-1$
- "ClassBodyDeclarations", //$NON-NLS-1$
- "Block", //$NON-NLS-1$
- "VariableDeclarators", //$NON-NLS-1$
- "VariableDeclarator", //$NON-NLS-1$
- "VariableDeclaratorId", //$NON-NLS-1$
- "VariableInitializer", //$NON-NLS-1$
- "ArrayInitializer", //$NON-NLS-1$
- "MethodHeaderName", //$NON-NLS-1$
- "MethodHeaderParameters", //$NON-NLS-1$
- "MethodPushModifiersHeaderName", //$NON-NLS-1$
- "ClassTypeList", //$NON-NLS-1$
- "ConstructorHeaderName", //$NON-NLS-1$
- "FormalParameterList", //$NON-NLS-1$
- "ClassTypeElt", //$NON-NLS-1$
- "StaticOnly", //$NON-NLS-1$
- "ExplicitConstructorInvocation", //$NON-NLS-1$
- "Primary", //$NON-NLS-1$
- "InterfaceBody", //$NON-NLS-1$
- "InterfaceHeaderName", //$NON-NLS-1$
- "InterfaceMemberDeclarations", //$NON-NLS-1$
- "InterfaceMemberDeclaration", //$NON-NLS-1$
- "VariableInitializers", //$NON-NLS-1$
- "BlockStatement", //$NON-NLS-1$
- "Statement", //$NON-NLS-1$
- "LocalVariableDeclaration", //$NON-NLS-1$
- "StatementWithoutTrailingSubstatement", //$NON-NLS-1$
- "StatementNoShortIf", //$NON-NLS-1$
- "StatementExpression", //$NON-NLS-1$
- "PostIncrementExpression", //$NON-NLS-1$
- "PostDecrementExpression", //$NON-NLS-1$
- "MethodInvocation", //$NON-NLS-1$
- "ClassInstanceCreationExpression", //$NON-NLS-1$
- "SwitchBlock", //$NON-NLS-1$
- "SwitchBlockStatements", //$NON-NLS-1$
- "SwitchLabels", //$NON-NLS-1$
- "SwitchBlockStatement", //$NON-NLS-1$
- "SwitchLabel", //$NON-NLS-1$
- "ConstantExpression", //$NON-NLS-1$
- "StatementExpressionList", //$NON-NLS-1$
- "OnlySynchronized", //$NON-NLS-1$
- "Catches", //$NON-NLS-1$
- "Finally", //$NON-NLS-1$
- "CatchClause", //$NON-NLS-1$
- "PushLPAREN", //$NON-NLS-1$
- "PushRPAREN", //$NON-NLS-1$
- "PrimaryNoNewArray", //$NON-NLS-1$
- "FieldAccess", //$NON-NLS-1$
- "ArrayAccess", //$NON-NLS-1$
- "ClassInstanceCreationExpressionName", //$NON-NLS-1$
- "ArgumentList", //$NON-NLS-1$
- "DimWithOrWithOutExprs", //$NON-NLS-1$
- "DimWithOrWithOutExpr", //$NON-NLS-1$
- "DimsLoop", //$NON-NLS-1$
- "OneDimLoop", //$NON-NLS-1$
- "PostfixExpression", //$NON-NLS-1$
- "UnaryExpression", //$NON-NLS-1$
- "UnaryExpressionNotPlusMinus", //$NON-NLS-1$
- "MultiplicativeExpression", //$NON-NLS-1$
- "AdditiveExpression", //$NON-NLS-1$
- "ShiftExpression", //$NON-NLS-1$
- "RelationalExpression", //$NON-NLS-1$
- "EqualityExpression", //$NON-NLS-1$
- "AndExpression", //$NON-NLS-1$
- "ExclusiveOrExpression", //$NON-NLS-1$
- "InclusiveOrExpression", //$NON-NLS-1$
- "ConditionalAndExpression", //$NON-NLS-1$
- "ConditionalOrExpression", //$NON-NLS-1$
- "ConditionalExpression", //$NON-NLS-1$
- "AssignmentExpression", //$NON-NLS-1$
- "LeftHandSide", //$NON-NLS-1$
- "AssignmentOperator" //$NON-NLS-1$
- };
-
- public static short check_table[] = null;
- public static char lhs[] = null;
- public static char action[] = lhs;
- private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
-
- static {
- try {
- initTables();
- } catch (java.io.IOException ex) {
- throw new ExceptionInInitializerError(ex.getMessage());
- }
- }
-
- public static final int RoundBracket = 0;
- public static final int SquareBracket = 1;
- public static final int CurlyBracket = 2;
- public static final int BracketKinds = 3;
-
- public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean assertMode) {
-
- this.problemReporter = problemReporter;
- this.optimizeStringLiterals = optimizeStringLiterals;
- this.assertMode = assertMode;
- this.initializeScanner();
- astLengthStack = new int[50];
- expressionLengthStack = new int[30];
- intStack = new int[50];
- identifierStack = new char[30][];
- identifierLengthStack = new int[30];
- nestedMethod = new int[30];
- realBlockStack = new int[30];
- identifierPositionStack = new long[30];
- variablesCounter = new int[30];
- }
- /**
- *
- * INTERNAL USE-ONLY
- */
- protected void adjustInterfaceModifiers() {
- intStack[intPtr - 1] |= AccInterface;
- }
- public final void arrayInitializer(int length) {
- //length is the size of the array Initializer
- //expressionPtr points on the last elt of the arrayInitializer
- //i.e. it has not been decremented yet.
-
- ArrayInitializer ai = new ArrayInitializer();
- if (length != 0) {
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
- }
- pushOnExpressionStack(ai);
- //positionning
- ai.sourceEnd = endStatementPosition;
- int searchPosition = length == 0 ? endPosition : ai.expressions[0].sourceStart;
- try {
- //does not work with comments(that contain '{') nor '{' describes as a unicode....
- while (scanner.source[--searchPosition] != '{') {
- }
- } catch (IndexOutOfBoundsException ex) {
- //should never occur (except for strange cases like whose describe above)
- searchPosition = (length == 0 ? endPosition : ai.expressions[0].sourceStart) - 1;
- }
- ai.sourceStart = searchPosition;
- }
- protected static int asi(int state) {
-
- return asb[original_state(state)];
- }
- protected void blockReal() {
- // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
- // increment the amount of declared variables for this block
- realBlockStack[realBlockPtr]++;
- }
- private final static void buildFileFor(String filename, String tag, String[] tokens, boolean isShort)
- throws java.io.IOException {
-
- //transform the String tokens into chars before dumping then into file
-
- int i = 0;
- //read upto the tag
- while (!tokens[i++].equals(tag)) {
- }
- //read upto the }
- char[] chars = new char[tokens.length]; //can't be bigger
- int ic = 0;
- String token;
- while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
- int c = Integer.parseInt(token);
- if (isShort)
- c += 32768;
- chars[ic++] = (char) c;
- }
-
- //resize
- System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
-
- buildFileForTable(filename, chars);
- }
- private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
-
- byte[] bytes = new byte[chars.length * 2];
- for (int i = 0; i < chars.length; i++) {
- bytes[2 * i] = (byte) (chars[i] >>> 8);
- bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
- }
-
- java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
- stream.write(bytes);
- stream.close();
- System.out.println(filename + " creation complete"); //$NON-NLS-1$
- }
- public final static void buildFilesFromLPG(String dataFilename) throws java.io.IOException {
-
- //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
-
- //build from the lpg javadcl.java files that represents the parser tables
- //lhs check_table asb asr symbol_index
-
- //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
-
- char[] contents = new char[] {
- };
- try {
- contents = Util.getFileCharContent(new File(dataFilename), null);
- } catch (IOException ex) {
- System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
- return;
- }
- java.util.StringTokenizer st = new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$
- String[] tokens = new String[st.countTokens()];
- int i = 0;
- while (st.hasMoreTokens()) {
- tokens[i++] = st.nextToken();
- }
- final String prefix = FILEPREFIX;
- i = 0;
- buildFileFor(prefix + (++i) + ".rsc", "lhs", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
- buildFileFor(prefix + (++i) + ".rsc", "check_table", tokens, true); //$NON-NLS-2$ //$NON-NLS-1$
- buildFileFor(prefix + (++i) + ".rsc", "asb", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
- buildFileFor(prefix + (++i) + ".rsc", "asr", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
- buildFileFor(prefix + (++i) + ".rsc", "symbol_index", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
- System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
- }
- /*
- * Build initial recovery state.
- * Recovery state is inferred from the current state of the parser (reduced node stack).
- */
- public RecoveredElement buildInitialRecoveryState() {
-
- /* initialize recovery by retrieving available reduced nodes
- * also rebuild bracket balance
- */
- lastCheckPoint = 0;
-
- RecoveredElement element = null;
- if (referenceContext instanceof CompilationUnitDeclaration) {
- element = new RecoveredUnit(compilationUnit, 0, this);
-
- /* ignore current stack state, since restarting from the beginnning
- since could not trust simple brace count */
- if (true) { // experimenting restart recovery from scratch
- compilationUnit.currentPackage = null;
- compilationUnit.imports = null;
- compilationUnit.types = null;
- currentToken = 0;
- listLength = 0;
- return element;
- }
- if (compilationUnit.currentPackage != null) {
- lastCheckPoint = compilationUnit.currentPackage.declarationSourceEnd + 1;
- }
- if (compilationUnit.imports != null) {
- lastCheckPoint = compilationUnit.imports[compilationUnit.imports.length - 1].declarationSourceEnd + 1;
- }
- } else {
- if (referenceContext instanceof AbstractMethodDeclaration) {
- element = new RecoveredMethod((AbstractMethodDeclaration) referenceContext, null, 0, this);
- lastCheckPoint = ((AbstractMethodDeclaration) referenceContext).bodyStart;
- } else {
- /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
- if (referenceContext instanceof TypeDeclaration) {
- TypeDeclaration type = (TypeDeclaration) referenceContext;
- for (int i = 0; i < type.fields.length; i++) {
- FieldDeclaration field = type.fields[i];
- if (!field.isField()
- && field.declarationSourceStart <= scanner.initialPosition
- && scanner.initialPosition <= field.declarationSourceEnd
- && scanner.eofPosition <= field.declarationSourceEnd + 1) {
- element = new RecoveredInitializer((Initializer) field, null, 1, this);
- lastCheckPoint = field.declarationSourceStart;
- break;
- }
- }
- }
- }
- }
-
- if (element == null)
- return element;
-
- for (int i = 0; i <= astPtr; i++) {
- AstNode node = astStack[i];
- if (node instanceof AbstractMethodDeclaration) {
- AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
- if (method.declarationSourceEnd == 0) {
- element = element.add(method, 0);
- lastCheckPoint = method.bodyStart;
- } else {
- element = element.add(method, 0);
- lastCheckPoint = method.declarationSourceEnd + 1;
- }
- continue;
- }
- if (node instanceof Initializer) {
- Initializer initializer = (Initializer) node;
- if (initializer.declarationSourceEnd == 0) {
- element = element.add(initializer, 1);
- lastCheckPoint = initializer.bodyStart;
- } else {
- element = element.add(initializer, 0);
- lastCheckPoint = initializer.declarationSourceEnd + 1;
- }
- continue;
- }
- if (node instanceof FieldDeclaration) {
- FieldDeclaration field = (FieldDeclaration) node;
- if (field.declarationSourceEnd == 0) {
- element = element.add(field, 0);
- if (field.initialization == null) {
- lastCheckPoint = field.sourceEnd + 1;
- } else {
- lastCheckPoint = field.initialization.sourceEnd + 1;
- }
- } else {
- element = element.add(field, 0);
- lastCheckPoint = field.declarationSourceEnd + 1;
- }
- continue;
- }
- if (node instanceof TypeDeclaration) {
- TypeDeclaration type = (TypeDeclaration) node;
- if (type.declarationSourceEnd == 0) {
- element = element.add(type, 0);
- lastCheckPoint = type.bodyStart;
- } else {
- element = element.add(type, 0);
- lastCheckPoint = type.declarationSourceEnd + 1;
- }
- continue;
- }
- if (node instanceof ImportReference) {
- ImportReference importRef = (ImportReference) node;
- element = element.add(importRef, 0);
- lastCheckPoint = importRef.declarationSourceEnd + 1;
- }
- }
- return element;
- }
- protected static short check(int i) {
- return check_table[i - (NUM_RULES + 1)];
- }
- /*
- * Reconsider the entire source looking for inconsistencies in {} () []
- */
- public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
-
- scanner.wasAcr = false;
- boolean anomaliesDetected = false;
- try {
- char[] source = scanner.source;
- int[] leftCount = { 0, 0, 0 };
- int[] rightCount = { 0, 0, 0 };
- int[] depths = { 0, 0, 0 };
- int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] };
- int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] };
- int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] };
- int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] };
- scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char)
- while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments
- try {
- // ---------Consume white space and handles startPosition---------
- boolean isWhiteSpace;
- do {
- scanner.startPosition = scanner.currentPosition;
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
- } else {
- if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
- if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
- // only record line positions we have not recorded yet
- scanner.pushLineSeparator();
+import net.sourceforge.phpdt.internal.core.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+//import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+
+public class Parser implements ITerminalSymbols, CompilerModifiers,
+ ParserBasicInformation {
+ protected final static int StackIncrement = 255;
+
+ protected int stateStackTop;
+
+ // protected int[] stack = new int[StackIncrement];
+
+ public TokenName firstToken; // handle for multiple parsing goals
+
+ public int lastAct; // handle for multiple parsing goals
+
+ // protected RecoveredElement currentElement;
+
+ public static boolean VERBOSE_RECOVERY = false;
+
+ protected boolean diet = false; // tells the scanner to jump over some
+
+ /**
+ * the PHP token scanner
+ */
+ public Scanner scanner;
+
+ TokenName token;
+
+ protected int modifiers;
+
+ protected int modifiersSourceStart;
+
+ protected Parser(ProblemReporter problemReporter) {
+ this.problemReporter = problemReporter;
+ this.options = problemReporter.options;
+ this.token = TokenName.EOF;
+ this.initializeScanner();
+ }
+
+// public void setFileToParse(IFile fileToParse) {
+// this.token = TokenName.EOF;
+// this.initializeScanner();
+// }
+
+ /**
+ * ClassDeclaration Constructor.
+ *
+ * @param s
+ * @param sess
+ * Description of Parameter
+ * @see
+ */
+// public Parser(IFile fileToParse) {
+// // if (keywordMap == null) {
+// // keywordMap = new HashMap();
+// // for (int i = 0; i < PHP_KEYWORS.length; i++) {
+// // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
+// // }
+// // }
+// // this.currentPHPString = 0;
+// // PHPParserSuperclass.fileToParse = fileToParse;
+// // this.phpList = null;
+// this.includesList = null;
+// // this.str = "";
+// this.token = TokenName.EOF;
+// // this.chIndx = 0;
+// // this.rowCount = 1;
+// // this.columnCount = 0;
+// // this.phpEnd = false;
+// // getNextToken();
+// this.initializeScanner();
+// }
+
+ public void initializeScanner() {
+ this.scanner = new Scanner(
+ false /* comment */,
+ false /* whitespace */,
+ this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */,
+ false, false, this.options.taskTags/* taskTags */,
+ this.options.taskPriorites/* taskPriorities */, true/* isTaskCaseSensitive */);
+ }
+
+ /**
+ * Create marker for the parse error
+ */
+ // private void setMarker(String message, int charStart, int charEnd, int
+ // errorLevel) {
+ // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
+ // }
+ /**
+ * This method will throw the SyntaxError. It will add the good lines and
+ * columns to the Error
+ *
+ * @param error
+ * the error message
+ * @throws SyntaxError
+ * the error raised
+ */
+ private void throwSyntaxError(String error) {
+ int problemStartPosition = scanner.getCurrentTokenStartPosition();
+ int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1;
+ if (scanner.source.length <= problemEndPosition
+ && problemEndPosition > 0) {
+ problemEndPosition = scanner.source.length - 1;
+ if (problemStartPosition > 0
+ && problemStartPosition >= problemEndPosition
+ && problemEndPosition > 0) {
+ problemStartPosition = problemEndPosition - 1;
+ }
+ }
+ throwSyntaxError(error, problemStartPosition, problemEndPosition);
+ }
+
+ /**
+ * This method will throw the SyntaxError. It will add the good lines and
+ * columns to the Error
+ *
+ * @param error
+ * the error message
+ * @throws SyntaxError
+ * the error raised
+ */
+ // private void throwSyntaxError(String error, int startRow) {
+ // throw new SyntaxError(startRow, 0, " ", error);
+ // }
+ private void throwSyntaxError(String error, int problemStartPosition,
+ int problemEndPosition) {
+ if (referenceContext != null) {
+ problemReporter.phpParsingError(new String[] { error },
+ problemStartPosition, problemEndPosition, referenceContext,
+ compilationUnit.compilationResult);
+ }
+ throw new SyntaxError(1, 0, " ", error);
+ }
+
+ private void reportSyntaxError(String error) {
+ int problemStartPosition = scanner.getCurrentTokenStartPosition();
+ int problemEndPosition = scanner.getCurrentTokenEndPosition();
+ reportSyntaxError(error, problemStartPosition, problemEndPosition + 1);
+ }
+
+ private void reportSyntaxError(String error, int problemStartPosition,
+ int problemEndPosition) {
+ if (referenceContext != null) {
+ problemReporter.phpParsingError(new String[] { error },
+ problemStartPosition, problemEndPosition, referenceContext,
+ compilationUnit.compilationResult);
+ }
+ }
+
+ // private void reportSyntaxWarning(String error, int problemStartPosition,
+ // int problemEndPosition) {
+ // if (referenceContext != null) {
+ // problemReporter.phpParsingWarning(new String[] { error },
+ // problemStartPosition, problemEndPosition, referenceContext,
+ // compilationUnit.compilationResult);
+ // }
+ // }
+
+ /**
+ * Read the next token from input
+ */
+ private void getNextToken() {
+ try {
+ token = scanner.getNextToken();
+ if (Scanner.DEBUG) {
+ int currentEndPosition = scanner.getCurrentTokenEndPosition();
+ int currentStartPosition = scanner.getCurrentTokenStartPosition();
+
+ System.out.print ("getNextToken: from " + currentStartPosition + " to " + currentEndPosition + ": ");
+ System.out.println(scanner.toStringAction(token));
+ }
+ } catch (InvalidInputException e) {
+ token = TokenName.ERROR;
+ String detailedMessage = e.getMessage();
+
+ if (detailedMessage == Scanner.UNTERMINATED_STRING) {
+ throwSyntaxError("Unterminated string.");
+ } else if (detailedMessage == Scanner.UNTERMINATED_COMMENT) {
+ throwSyntaxError("Unterminated commment.");
+ }
+ }
+ return;
+ }
+
+ public void init(String s) {
+ // this.str = s;
+ this.token = TokenName.EOF;
+ this.includesList = new ArrayList();
+ // this.chIndx = 0;
+ // this.rowCount = 1;
+ // this.columnCount = 0;
+ // this.phpEnd = false;
+ // this.phpMode = false;
+ /* scanner initialization */
+ scanner.setSource(s.toCharArray());
+ scanner.setPHPMode(false);
+ astPtr = 0;
+ }
+
+ protected void initialize(boolean phpMode) {
+ initialize(phpMode, null);
+ }
+
+ protected void initialize(boolean phpMode,
+ IdentifierIndexManager indexManager) {
+ compilationUnit = null;
+ referenceContext = null;
+ this.includesList = new ArrayList();
+ // this.indexManager = indexManager;
+ // this.str = "";
+ this.token = TokenName.EOF;
+ // this.chIndx = 0;
+ // this.rowCount = 1;
+ // this.columnCount = 0;
+ // this.phpEnd = false;
+ // this.phpMode = phpMode;
+ scanner.setPHPMode(phpMode);
+ astPtr = 0;
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ public void parse(String s) {
+ parse(s, null);
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ public void parse(String s, HashMap variables) {
+ fMethodVariables = variables;
+ fStackUnassigned = new ArrayList();
+ init(s);
+ parse();
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ *
+ * The main entry point when parsing a file
+ */
+ protected void parse() {
+ if (scanner.compilationUnit != null) {
+ IResource resource = scanner.compilationUnit.getResource();
+ if (resource != null && resource instanceof IFile) {
+ // set the package name
+ consumePackageDeclarationName((IFile) resource);
+ }
+ }
+
+ getNextToken();
+
+ do {
+ try {
+ if (token != TokenName.EOF && // If we are not at the end of file
+ token != TokenName.ERROR) { // and have no error
+ statementList(); // build the statement list for the entire file
+ }
+
+ if (token != TokenName.EOF) {
+ switch (token) {
+ case ERROR:
+ throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
+ break;
+
+ case RPAREN:
+ throwSyntaxError("Too many closing ')'; end-of-file not reached.");
+ break;
+
+ case RBRACE:
+ throwSyntaxError("Too many closing '}'; end-of-file not reached.");
+ break;
+
+ case RBRACKET:
+ throwSyntaxError("Too many closing ']'; end-of-file not reached.");
+ break;
+
+ case LPAREN:
+ throwSyntaxError("Read character '('; end-of-file not reached.");
+ break;
+
+ case LBRACE:
+ throwSyntaxError("Read character '{'; end-of-file not reached.");
+ break;
+
+ case LBRACKET:
+ throwSyntaxError("Read character '['; end-of-file not reached.");
+ break;
+
+ default:
+ throwSyntaxError("End-of-file not reached.");
+ break;
+ }
+ }
+ break;
+ } catch (SyntaxError syntaxError) {
+ // syntaxError.printStackTrace();
+ break;
+ }
+ } while (true);
+
+ endParse(0);
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ public void parseFunction(String s, HashMap variables) {
+ init(s);
+ scanner.phpMode = true;
+ parseFunction(variables);
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ protected void parseFunction(HashMap variables) {
+ getNextToken();
+ boolean hasModifiers = member_modifiers();
+ if (token == TokenName.FUNCTION) {
+ if (!hasModifiers) {
+ checkAndSetModifiers(AccPublic);
+ }
+ this.fMethodVariables = variables;
+
+ MethodDeclaration methodDecl = new MethodDeclaration(null);
+ methodDecl.declarationSourceStart = scanner
+ .getCurrentTokenStartPosition();
+ methodDecl.modifiers = this.modifiers;
+ methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } catch (SyntaxError sytaxErr1) {
+ return;
+ } finally {
+ int sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0
+ || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.sourceEnd = sourceEnd;
+ methodDecl.declarationSourceEnd = sourceEnd;
+ }
+ }
+ }
+
+ protected CompilationUnitDeclaration endParse(int act) {
+
+ this.lastAct = act;
+
+ // if (currentElement != null) {
+ // currentElement.topElement().updateParseTree();
+ // if (VERBOSE_RECOVERY) {
+ // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
+ // System.out.println("--------------------------"); //$NON-NLS-1$
+ // System.out.println(compilationUnit);
+ // System.out.println("----------------------------------");
+ // //$NON-NLS-1$
+ // }
+ // } else {
+ if (diet & VERBOSE_RECOVERY) {
+ System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
+ System.out.println("--------------------------"); //$NON-NLS-1$
+ System.out.println(compilationUnit);
+ System.out.println("----------------------------------"); //$NON-NLS-1$
+ }
+ // }
+ if (scanner.recordLineSeparator) {
+ compilationUnit.compilationResult.lineSeparatorPositions = scanner
+ .getLineEnds();
+ }
+ if (scanner.taskTags != null) {
+ for (int i = 0; i < scanner.foundTaskCount; i++) {
+ problemReporter().task(
+ new String(scanner.foundTaskTags[i]),
+ new String(scanner.foundTaskMessages[i]),
+ scanner.foundTaskPriorities[i] == null ? null
+ : new String(scanner.foundTaskPriorities[i]),
+ scanner.foundTaskPositions[i][0],
+ scanner.foundTaskPositions[i][1]);
+ }
+ }
+ compilationUnit.imports = new ImportReference[includesList.size()];
+ for (int i = 0; i < includesList.size(); i++) {
+ compilationUnit.imports[i] = (ImportReference) includesList.get(i);
+ }
+ return compilationUnit;
+ }
+
+ /**
+ *
+ * @return A block object which contains all statements from within the current block
+ */
+ private Block statementList() {
+ boolean branchStatement = false;
+ int blockStart = scanner.getCurrentTokenStartPosition();
+ ArrayList blockStatements = new ArrayList();
+ Statement statement;
+
+ do {
+ try {
+ statement = statement();
+
+ if (statement != null) {
+ blockStatements.add(statement);
+ }
+
+ if (token == TokenName.EOF) {
+ return null;
+ }
+
+ if (branchStatement && statement != null) {
+ // reportSyntaxError("Unreachable code", statement.sourceStart, statement.sourceEnd);
+ if (!(statement instanceof BreakStatement)) {
+ /*
+ * Don't give an error for break statement following return statement.
+ * Technically it's unreachable code, but in switch-case it's recommended to avoid
+ * accidental fall-through later when editing the code
+ */
+ problemReporter.unreachableCode (new String (scanner.getCurrentIdentifierSource ()),
+ statement.sourceStart,
+ statement.sourceEnd,
+ referenceContext,
+ compilationUnit.compilationResult);
+ }
+ }
+
+ switch (token) {
+ case RBRACE:
+ case CASE:
+ case DEFAULT:
+ case ELSE:
+ case ELSEIF:
+ case ENDIF:
+ case ENDFOR:
+ case ENDFOREACH:
+ case ENDWHILE:
+ case ENDSWITCH:
+ case ENDDECLARE:
+ case EOF:
+ case ERROR:
+ return createBlock (blockStart, blockStatements); // Create and return a block object (contains all the statements from the current read block)
+ }
+
+ branchStatement = checkUnreachableStatements(statement);
+ }
+ catch (SyntaxError sytaxErr1) {
+ // If an error occurred, try to find keywords
+ // to parse the rest of the string
+ boolean tokenize = scanner.tokenizeStrings;
+
+ if (!tokenize) {
+ scanner.tokenizeStrings = true;
+ }
+
+ try {
+ boolean bBreakLoop = false;
+
+ while (token != TokenName.EOF) { // As long as we are not at the end of file
+ switch (token) { // If a block close?
+ case RBRACE:
+ case CASE:
+ case DEFAULT:
+ case ELSE:
+ case ELSEIF:
+ case ENDIF:
+ case ENDFOR:
+ case ENDFOREACH:
+ case ENDWHILE:
+ case ENDSWITCH:
+ case ENDDECLARE:
+ case EOF:
+ case ERROR:
+ return createBlock (blockStart, blockStatements); // Create and return a block object (contains all the statements from the current read block)
+ }
+
+ switch (token) {
+ case IF:
+ case SWITCH:
+ case FOR:
+ case WHILE:
+ case DO:
+ case FOREACH:
+ case CONTINUE:
+ case BREAK:
+ case RETURN:
+ case EXIT:
+ case ECHO:
+ case NAMESPACE:
+ case ECHO_INVISIBLE:
+ case GLOBAL:
+ case STATIC:
+ case UNSET:
+ case FUNCTION:
+ case DECLARE:
+ case TRY:
+ case CATCH:
+ case THROW:
+ case FINAL:
+ case ABSTRACT:
+ case CLASS:
+ case INTERFACE:
+ bBreakLoop = true;
+ break;
+ }
+
+ if (bBreakLoop) {
+ break;
+ }
+
+ // System.out.println(scanner.toStringAction(token));
+ getNextToken();
+ // System.out.println(scanner.toStringAction(token));
+ }
+
+ if (token == TokenName.EOF) {
+ throw sytaxErr1;
+ }
+ } finally {
+ scanner.tokenizeStrings = tokenize;
+ }
+ } // catch
+ } while (true);
+ }
+
+ /**
+ * @param statement
+ * @return
+ */
+ private boolean checkUnreachableStatements(Statement statement) {
+ if (statement instanceof ReturnStatement ||
+ statement instanceof ContinueStatement ||
+ statement instanceof BreakStatement) {
+ return true;
+ } else if (statement instanceof IfStatement
+ && ((IfStatement) statement).checkUnreachable) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param blockStart
+ * @param blockStatements
+ * @return
+ */
+ private Block createBlock (int blockStart, ArrayList blockStatements) {
+ int blockEnd = scanner.getCurrentTokenEndPosition ();
+ Block b = Block.EmptyWith (blockStart, blockEnd);
+
+ b.statements = new Statement[blockStatements.size()];
+ blockStatements.toArray (b.statements);
+
+ return b;
+ }
+
+ private void functionBody(MethodDeclaration methodDecl) {
+ // '{' [statement-list] '}'
+ if (token == TokenName.LBRACE) {
+ getNextToken();
+ } else {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("'{' expected in compound-statement.");
+ }
+
+ if (token != TokenName.RBRACE) {
+ statementList();
+ }
+
+ if (token == TokenName.RBRACE) {
+ methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("'}' expected in compound-statement.");
+ }
+ }
+
+ /**
+ * Try to create an statement reading from the current token position
+ *
+ * @return Returns a found statement or empty statement
+ */
+ private Statement statement() {
+ Statement statement = null;
+ Expression expression;
+ int sourceStart = scanner.getCurrentTokenStartPosition();
+ int sourceEnd;
+
+ switch (token) {
+ case IF:
+ // T_IF '(' expr ')' statement elseif_list else_single
+ // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
+ // new_else_single T_ENDIF ';'
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'if' keyword.");
+ }
+
+ expression = expr();
+
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'if' condition.");
+ }
+ // create basic IfStatement
+ IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1);
+
+ if (token == TokenName.COLON) {
+ getNextToken();
+ ifStatementColon(ifStatement);
+ } else {
+ ifStatement(ifStatement);
+ }
+ return ifStatement;
+
+ case SWITCH:
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'switch' keyword.");
+ }
+ expr();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'switch' condition.");
+ }
+ switchStatement();
+ return statement;
+
+ case FOR:
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'for' keyword.");
+ }
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ expressionList();
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after 'for'.");
+ }
+ }
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ expressionList();
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after 'for'.");
+ }
+ }
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ expressionList();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'for'.");
+ }
+ }
+ forStatement();
+ return statement;
+
+ case WHILE:
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'while' keyword.");
+ }
+ expr();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'while' condition.");
+ }
+ whileStatement();
+ return statement;
+
+ case DO:
+ getNextToken();
+ if (token == TokenName.LBRACE) {
+ getNextToken();
+ if (token != TokenName.RBRACE) {
+ statementList();
+ }
+ if (token == TokenName.RBRACE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected after 'do' keyword.");
+ }
+ } else {
+ statement();
+ }
+ if (token == TokenName.WHILE) {
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'while' keyword.");
+ }
+ expr();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'while' condition.");
+ }
+ } else {
+ throwSyntaxError("'while' expected after 'do' keyword.");
+ }
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after do-while statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+
+ case FOREACH:
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'foreach' keyword.");
+ }
+ expr();
+ if (token == TokenName.AS) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'as' expected after 'foreach' exxpression.");
+ }
+ // variable();
+ foreach_variable();
+ foreach_optional_arg();
+ if (token == TokenName.EQUAL_GREATER) {
+ getNextToken();
+ variable(false, false);
+ }
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'foreach' expression.");
+ }
+ foreachStatement();
+ return statement;
+
+ case BREAK:
+ expression = null;
+ getNextToken();
+ if (token != TokenName.SEMICOLON) {
+ expression = expr();
+ }
+ if (token == TokenName.SEMICOLON) {
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'break'.");
+ }
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ return new BreakStatement(null, sourceStart, sourceEnd);
+
+ case CONTINUE:
+ expression = null;
+ getNextToken();
+ if (token != TokenName.SEMICOLON) {
+ expression = expr();
+ }
+ if (token == TokenName.SEMICOLON) {
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'continue'.");
+ }
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ return new ContinueStatement(null, sourceStart, sourceEnd);
+
+ case RETURN:
+ expression = null;
+ getNextToken();
+/*
+ if (token == TokenName.VARIABLE) {
+ getNextToken ();
+
+ if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+ getNextToken ();
+
+ if (token != TokenName.IDENTIFIER) {
+ throwSyntaxError("identifier expected after '::'.");
+ }
+ else {
+ getNextToken ();
+ }
+ }
+ }
+*/
+ if (token != TokenName.SEMICOLON) {
+ expression = expr();
+ }
+
+ if (token == TokenName.SEMICOLON) {
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'return'.");
+ }
+
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ return new ReturnStatement(expression, sourceStart, sourceEnd);
+
+ case ECHO:
+ getNextToken(); // Read the token after 'echo'
+ expressionList(); // Read everything after 'echo'
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'echo' statement.");
+ }
+ getNextToken();
+ }
+ return statement; // return null statement
+
+ case ECHO_INVISIBLE:
+ // 0-length token directly after PHP short tag <?=
+ getNextToken();
+ expressionList();
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ // if (token != TokenName.INLINE_HTML) {
+ // // TODO should this become a configurable warning?
+ // reportSyntaxError("Probably '?>' expected after PHP short tag
+ // expression (only the first expression will be echoed).");
+ // }
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after PHP short tag '<?=' expression.");
+ }
+ getNextToken();
+ }
+ return statement;
+
+ case INLINE_HTML:
+ getNextToken();
+ return statement;
+
+ case GLOBAL:
+ getNextToken();
+ global_var_list();
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'global' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+
+ case STATIC:
+ getNextToken();
+ static_var_list();
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ }
+ else if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+ getNextToken ();
+
+ if (token != TokenName.IDENTIFIER) {
+ throwSyntaxError("identifier expected after '::'.");
+ }
+ }
+ else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'static' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+
+ case UNSET:
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'unset' statement.");
+ }
+ unset_variables();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'unset' statement.");
+ }
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'unset' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+
+ case NAMESPACE:
+ getNextToken ();
+ namespacePath ();
+
+ if (token == TokenName.SEMICOLON) { // After the namespace identifier there is a ';'
+ getNextToken();
}
- }
- isWhiteSpace = Character.isWhitespace(scanner.currentCharacter);
- }
- } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
+ else if (token == TokenName.LBRACE) { // or a '{'
+ getNextToken(); // set to next token
- // -------consume token until } is found---------
+ if (token != TokenName.RBRACE) { // if next token is not a '}'
+ statementList(); // read the entire block
+ }
- switch (scanner.currentCharacter) {
- case '{' :
- {
- int index = leftCount[CurlyBracket]++;
- if (index == leftPositions[CurlyBracket].length) {
- System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
- System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
- }
- leftPositions[CurlyBracket][index] = scanner.startPosition;
- leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
- }
- break;
- case '}' :
- {
- int index = rightCount[CurlyBracket]++;
- if (index == rightPositions[CurlyBracket].length) {
- System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
- System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
- }
- rightPositions[CurlyBracket][index] = scanner.startPosition;
- rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
- }
- break;
- case '(' :
- {
- int index = leftCount[RoundBracket]++;
- if (index == leftPositions[RoundBracket].length) {
- System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
- System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
- }
- leftPositions[RoundBracket][index] = scanner.startPosition;
- leftDepths[RoundBracket][index] = depths[RoundBracket]++;
- }
- break;
- case ')' :
- {
- int index = rightCount[RoundBracket]++;
- if (index == rightPositions[RoundBracket].length) {
- System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
- System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
- }
- rightPositions[RoundBracket][index] = scanner.startPosition;
- rightDepths[RoundBracket][index] = --depths[RoundBracket];
- }
- break;
- case '[' :
- {
- int index = leftCount[SquareBracket]++;
- if (index == leftPositions[SquareBracket].length) {
- System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
- System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
- }
- leftPositions[SquareBracket][index] = scanner.startPosition;
- leftDepths[SquareBracket][index] = depths[SquareBracket]++;
- }
- break;
- case ']' :
- {
- int index = rightCount[SquareBracket]++;
- if (index == rightPositions[SquareBracket].length) {
- System.arraycopy(
- rightPositions[SquareBracket],
- 0,
- (rightPositions[SquareBracket] = new int[index * 2]),
- 0,
- index);
- System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
- }
- rightPositions[SquareBracket][index] = scanner.startPosition;
- rightDepths[SquareBracket][index] = --depths[SquareBracket];
- }
- break;
- case '\'' :
- {
- if (scanner.getNextChar('\\')) {
- scanner.scanEscapeCharacter();
- } else { // consume next character
- scanner.unicodeAsBackSlash = false;
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- scanner.getNextUnicodeChar();
- } else {
- if (scanner.withoutUnicodePtr != 0) {
- scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
+ if (token == TokenName.RBRACE) { // If the end is a '}'
+ getNextToken(); // go for the next token
+ }
+ else { // Not a '}' as expected
+ throwSyntaxError("'}' expected after 'do' keyword.");
}
- }
- }
- scanner.getNextChar('\'');
- break;
- }
- case '"' : // consume next character
- scanner.unicodeAsBackSlash = false;
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- scanner.getNextUnicodeChar();
- } else {
- if (scanner.withoutUnicodePtr != 0) {
- scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
}
- }
- while (scanner.currentCharacter != '"') {
- if (scanner.currentCharacter == '\r') {
- if (source[scanner.currentPosition] == '\n')
- scanner.currentPosition++;
- break; // the string cannot go further that the line
+ else {
+ if (token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after 'namespace' statement.");
+ }
+ getNextToken();
}
- if (scanner.currentCharacter == '\n') {
- break; // the string cannot go further that the line
+ return statement;
+
+ case GOTO:
+ getNextToken (); // This should get the label
+
+ if (token == TokenName.IDENTIFIER) {
+ getNextToken ();
}
- if (scanner.currentCharacter == '\\') {
- scanner.scanEscapeCharacter();
+ else {
+ throwSyntaxError("expected a label after goto");
}
- // consume next character
- scanner.unicodeAsBackSlash = false;
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- scanner.getNextUnicodeChar();
- } else {
- if (scanner.withoutUnicodePtr != 0) {
- scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
- }
+
+ if (token == TokenName.SEMICOLON) { // After the 'goto' label name there is a ';'
+ getNextToken ();
}
- }
- break;
- case '/' :
- {
- int test;
- if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment
- //get the next char
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- //-------------unicode traitement ------------
- int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
- scanner.currentPosition++;
- while (source[scanner.currentPosition] == 'u') {
- scanner.currentPosition++;
- }
- if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c1 < 0
- || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c2 < 0
- || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c3 < 0
- || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c4 < 0) { //error don't care of the value
- scanner.currentCharacter = 'A';
- } //something different from \n and \r
- else {
- scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
- }
- }
- while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
- //get the next char
- scanner.startPosition = scanner.currentPosition;
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- //-------------unicode traitement ------------
- int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
- scanner.currentPosition++;
- while (source[scanner.currentPosition] == 'u') {
- scanner.currentPosition++;
- }
- if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c1 < 0
- || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c2 < 0
- || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c3 < 0
- || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c4 < 0) { //error don't care of the value
- scanner.currentCharacter = 'A';
- } //something different from \n and \r
- else {
- scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
- }
- }
- }
- if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
- if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
- // only record line positions we have not recorded yet
- scanner.pushLineSeparator();
- }
- }
- break;
+ else {
+ throwSyntaxError("expected a ';' after goto label");
}
- if (test > 0) { //traditional and annotation comment
- boolean star = false;
- // consume next character
- scanner.unicodeAsBackSlash = false;
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- scanner.getNextUnicodeChar();
- } else {
- if (scanner.withoutUnicodePtr != 0) {
- scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
- }
- }
- if (scanner.currentCharacter == '*') {
- star = true;
- }
- //get the next char
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- //-------------unicode traitement ------------
- int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
- scanner.currentPosition++;
- while (source[scanner.currentPosition] == 'u') {
- scanner.currentPosition++;
- }
- if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c1 < 0
- || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c2 < 0
- || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c3 < 0
- || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c4 < 0) { //error don't care of the value
- scanner.currentCharacter = 'A';
- } //something different from * and /
- else {
- scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
- }
- }
- //loop until end of comment */
- while ((scanner.currentCharacter != '/') || (!star)) {
- star = scanner.currentCharacter == '*';
- //get next char
- if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
- && (source[scanner.currentPosition] == 'u')) {
- //-------------unicode traitement ------------
- int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
- scanner.currentPosition++;
- while (source[scanner.currentPosition] == 'u') {
- scanner.currentPosition++;
- }
- if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c1 < 0
- || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c2 < 0
- || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c3 < 0
- || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
- || c4 < 0) { //error don't care of the value
- scanner.currentCharacter = 'A';
- } //something different from * and /
- else {
- scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
- }
- }
- }
- break;
+ return statement;
+
+ case FUNCTION:
+ MethodDeclaration methodDecl = new MethodDeclaration (this.compilationUnit.compilationResult);
+ methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
+ methodDecl.modifiers = AccDefault;
+ methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } finally {
+ sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.declarationSourceEnd = sourceEnd;
+ methodDecl.sourceEnd = sourceEnd;
+ }
+ return statement;
+
+ case DECLARE:
+ // T_DECLARE '(' declare_list ')' declare_statement
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected in 'declare' statement.");
+ }
+ getNextToken();
+ declare_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected in 'declare' statement.");
+ }
+ getNextToken();
+ declare_statement();
+ return statement;
+
+ case TRY:
+ getNextToken();
+ if (token != TokenName.LBRACE) {
+ throwSyntaxError("'{' expected in 'try' statement.");
+ }
+
+ getNextToken();
+
+ if (token != TokenName.RBRACE) { // Process the statement only if there is (possibly) a statement
+ statementList ();
+
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in 'try' statement.");
+ }
+ }
+
+ getNextToken();
+ return statement;
+
+ case CATCH:
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected in 'catch' statement.");
+ }
+ getNextToken();
+ fully_qualified_class_name();
+ if (token != TokenName.VARIABLE) {
+ throwSyntaxError("Variable expected in 'catch' statement.");
+ }
+ addVariableSet();
+ getNextToken();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenName.LBRACE) {
+ throwSyntaxError("'{' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenName.RBRACE) {
+ statementList();
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in 'catch' statement.");
+ }
+ }
+ getNextToken();
+ additional_catches();
+ return statement;
+
+ case THROW:
+ getNextToken();
+ expr();
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after 'throw' exxpression.");
+ }
+ return statement;
+
+ case FINAL:
+ case ABSTRACT:
+ case CLASS:
+ case INTERFACE:
+ try {
+ TypeDeclaration typeDecl = new TypeDeclaration (this.compilationUnit.compilationResult);
+ typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
+ typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
+ typeDecl.name = new char[] { ' ' };
+ // default super class
+ typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
+ compilationUnit.types.add(typeDecl);
+ pushOnAstStack(typeDecl);
+ unticked_class_declaration_statement(typeDecl);
+ } finally {
+ // reduce stack:
+ astPtr--;
+ astLengthPtr--;
+ }
+ return statement;
+
+ case LBRACE:
+ getNextToken();
+ if (token != TokenName.RBRACE) {
+ statement = statementList();
+ }
+ if (token == TokenName.RBRACE) {
+ getNextToken();
+ return statement;
+ } else {
+ throwSyntaxError("'}' expected.");
+ }
+ break;
+
+ default:
+ if (token != TokenName.SEMICOLON) {
+ expr();
+ }
+
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ return statement;
+ }
+ else if (token == TokenName.COLON) { // Colon after Label identifier
+ getNextToken();
+ return statement;
+ }
+ else {
+ if (token == TokenName.RBRACE) {
+ reportSyntaxError ("';' expected after expression (Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ else {
+ if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+ getNextToken ();
+
+ if (token != TokenName.IDENTIFIER) {
+ throwSyntaxError("identifier expected after '::'.");
+ }
+ else {
+ getNextToken ();
+ }
+ }
+ else if (token != TokenName.INLINE_HTML && token != TokenName.EOF) {
+ throwSyntaxError ("';' expected after expression (Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ getNextToken();
+ }
+ }
+ break;
+ }
+ // may be null
+ return statement;
+ }
+
+ private void declare_statement() {
+ // statement
+ // | ':' inner_statement_list T_ENDDECLARE ';'
+ // ;
+ if (token == TokenName.COLON) {
+ getNextToken();
+ // TODO: implement inner_statement_list();
+ statementList();
+ if (token != TokenName.ENDDECLARE) {
+ throwSyntaxError("'enddeclare' expected in 'declare' statement.");
+ }
+ getNextToken();
+ if (token != TokenName.SEMICOLON) {
+ throwSyntaxError("';' expected after 'enddeclare' keyword.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ private void declare_list() {
+ // T_STRING '=' static_scalar
+ // | declare_list ',' T_STRING '=' static_scalar
+ while (true) {
+ if (token != TokenName.IDENTIFIER) {
+ throwSyntaxError("Identifier expected in 'declare' list.");
+ }
+ getNextToken();
+ if (token != TokenName.EQUAL) {
+ throwSyntaxError("'=' expected in 'declare' list.");
+ }
+ getNextToken();
+ static_scalar();
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void additional_catches() {
+ while (token == TokenName.CATCH) {
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected in 'catch' statement.");
+ }
+ getNextToken();
+ fully_qualified_class_name();
+ if (token != TokenName.VARIABLE) {
+ throwSyntaxError("Variable expected in 'catch' statement.");
+ }
+ addVariableSet();
+ getNextToken();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenName.LBRACE) {
+ throwSyntaxError("'{' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenName.RBRACE) {
+ statementList();
+ }
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in 'catch' statement.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void foreach_variable() {
+ // w_variable
+ // | '&' w_variable
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ }
+ w_variable(true);
+ }
+
+ private void foreach_optional_arg() {
+ // /* empty */
+ // | T_DOUBLE_ARROW foreach_variable
+ if (token == TokenName.EQUAL_GREATER) {
+ getNextToken();
+ foreach_variable();
+ }
+ }
+
+ private void global_var_list() {
+ // global_var_list:
+ // global_var_list ',' global_var
+ // | global_var
+ HashSet set = peekVariableSet();
+ while (true) {
+ global_var(set);
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void global_var(HashSet set) {
+ // global_var:
+ // T_VARIABLE
+ // | '$' r_variable
+ // | '$' '{' expr '}'
+ if (token == TokenName.VARIABLE) {
+ if (fMethodVariables != null) {
+ VariableInfo info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_GLOBAL_VAR);
+ fMethodVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ addVariableSet(set);
+ getNextToken();
+ } else if (token == TokenName.DOLLAR) {
+ getNextToken();
+ if (token == TokenName.LBRACE) {
+ getNextToken();
+ expr();
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in global variable.");
+ }
+ getNextToken();
+ } else {
+ r_variable();
+ }
+ }
+ }
+
+ private void static_var_list() {
+ // static_var_list:
+ // static_var_list ',' T_VARIABLE
+ // | static_var_list ',' T_VARIABLE '=' static_scalar
+ // | T_VARIABLE
+ // | T_VARIABLE '=' static_scalar,
+ HashSet set = peekVariableSet();
+ while (true) {
+ if (token == TokenName.VARIABLE) {
+ if (fMethodVariables != null) {
+ VariableInfo info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_STATIC_VAR);
+ fMethodVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ addVariableSet(set);
+ getNextToken();
+ if (token == TokenName.EQUAL) {
+ getNextToken();
+ static_scalar();
+ }
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ }
+
+ private void unset_variables() {
+ // unset_variables:
+ // unset_variable
+ // | unset_variables ',' unset_variable
+ // unset_variable:
+ // variable
+ while (true) {
+ variable(false, false);
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private final void initializeModifiers() {
+ this.modifiers = 0;
+ this.modifiersSourceStart = -1;
+ }
+
+ private final void checkAndSetModifiers(int flag) {
+ this.modifiers |= flag;
+ if (this.modifiersSourceStart < 0)
+ this.modifiersSourceStart = this.scanner.startPosition;
+ }
+
+ private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
+ initializeModifiers();
+ if (token == TokenName.INTERFACE) {
+ // interface_entry T_STRING
+ // interface_extends_list
+ // '{' class_statement_list '}'
+ checkAndSetModifiers(AccInterface);
+ getNextToken();
+ typeDecl.modifiers = this.modifiers;
+ typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+ typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ if (token == TokenName.IDENTIFIER || token.compareTo (TokenName.KEYWORD) > 0) {
+ typeDecl.name = scanner.getCurrentIdentifierSource();
+ if (token.compareTo (TokenName.KEYWORD) > 0) {
+ problemReporter.phpKeywordWarning(new String[] { scanner
+ .toStringAction(token) }, scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ // throwSyntaxError("Don't use a keyword for interface
+ // declaration ["
+ // + scanner.toStringAction(token) + "].",
+ // typeDecl.sourceStart, typeDecl.sourceEnd);
+ }
+ getNextToken();
+ interface_extends_list(typeDecl);
+ } else {
+ typeDecl.name = new char[] { ' ' };
+ throwSyntaxError(
+ "Interface name expected after keyword 'interface'.",
+ typeDecl.sourceStart, typeDecl.sourceEnd);
+ return;
+ }
+ } else {
+ // class_entry_type T_STRING extends_from
+ // implements_list
+ // '{' class_statement_list'}'
+ class_entry_type();
+ typeDecl.modifiers = this.modifiers;
+ typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+ typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ // identifier
+ // identifier 'extends' identifier
+ if (token == TokenName.IDENTIFIER || token.compareTo (TokenName.KEYWORD) > 0) {
+ typeDecl.name = scanner.getCurrentIdentifierSource();
+ if (token.compareTo (TokenName.KEYWORD) > 0) {
+ problemReporter.phpKeywordWarning(new String[] { scanner
+ .toStringAction(token) }, scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ // throwSyntaxError("Don't use a keyword for class
+ // declaration [" +
+ // scanner.toStringAction(token) + "].",
+ // typeDecl.sourceStart, typeDecl.sourceEnd);
+ }
+ getNextToken();
+ // extends_from:
+ // /* empty */
+ // | T_EXTENDS fully_qualified_class_name
+ if (token == TokenName.EXTENDS) {
+ class_extends_list(typeDecl);
+ // getNextToken();
+ // if (token != TokenName.IDENTIFIER) {
+ // throwSyntaxError("Class name expected after keyword
+ // 'extends'.",
+ // scanner.getCurrentTokenStartPosition(), scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ }
+ implements_list(typeDecl);
+ } else {
+ typeDecl.name = new char[] { ' ' };
+ throwSyntaxError("Class name expected after keyword 'class'.",
+ typeDecl.sourceStart, typeDecl.sourceEnd);
+ return;
+ }
+ }
+ // '{' class_statement_list '}'
+ if (token == TokenName.LBRACE) {
+ getNextToken();
+ if (token != TokenName.RBRACE) {
+ ArrayList list = new ArrayList();
+ class_statement_list(list);
+ typeDecl.fields = new FieldDeclaration[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ typeDecl.fields[i] = (FieldDeclaration) list.get(i);
+ }
+ }
+ if (token == TokenName.RBRACE) {
+ typeDecl.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected at end of class body.");
+ }
+ } else {
+ throwSyntaxError("'{' expected at start of class body.");
+ }
+ }
+
+ private void class_entry_type() {
+ // T_CLASS
+ // | T_ABSTRACT T_CLASS
+ // | T_FINAL T_CLASS
+ if (token == TokenName.CLASS) {
+ getNextToken();
+ } else if (token == TokenName.ABSTRACT) {
+ checkAndSetModifiers(AccAbstract);
+ getNextToken();
+ if (token != TokenName.CLASS) {
+ throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
+ }
+ getNextToken();
+ } else if (token == TokenName.FINAL) {
+ checkAndSetModifiers(AccFinal);
+ getNextToken();
+ if (token != TokenName.CLASS) {
+ throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
+ }
+ getNextToken();
+ } else {
+ throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
+ }
+ }
+
+ // private void class_extends(TypeDeclaration typeDecl) {
+ // // /* empty */
+ // // | T_EXTENDS interface_list
+ // if (token == TokenName.EXTENDS) {
+ // getNextToken();
+ //
+ // if (token == TokenName.IDENTIFIER) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("Class name expected after keyword 'extends'.");
+ // }
+ // }
+ // }
+
+ private void interface_extends_list(TypeDeclaration typeDecl) {
+ // /* empty */
+ // | T_EXTENDS interface_list
+ if (token == TokenName.EXTENDS) {
+ getNextToken();
+ interface_list(typeDecl);
+ }
+ }
+
+ private void class_extends_list(TypeDeclaration typeDecl) {
+ // /* empty */
+ // | T_EXTENDS interface_list
+ if (token == TokenName.EXTENDS) {
+ getNextToken();
+ class_list(typeDecl);
+ }
+ }
+
+ private void implements_list(TypeDeclaration typeDecl) {
+ // /* empty */
+ // | T_IMPLEMENTS interface_list
+ if (token == TokenName.IMPLEMENTS) {
+ getNextToken();
+ interface_list(typeDecl);
+ }
+ }
+
+ private void class_list(TypeDeclaration typeDecl) {
+ // class_list:
+ // fully_qualified_class_name
+ do {
+ if (token == TokenName.IDENTIFIER) {
+ //char[] ident = scanner.getCurrentIdentifierSource();
+ // TODO make this code working better:
+ // SingleTypeReference ref =
+ // ParserUtil.getTypeReference(scanner,
+ // includesList, ident);
+ // if (ref != null) {
+ // typeDecl.superclass = ref;
+ // }
+ getNextToken();
+ } else {
+ throwSyntaxError("Classname expected after keyword 'extends'.");
+ }
+ if (token == TokenName.COMMA) {
+ reportSyntaxError("No multiple inheritance allowed. Expected token 'implements' or '{'.");
+ getNextToken();
+ continue;
+ } else {
+ break;
+ }
+ } while (true);
+ }
+
+ private void interface_list(TypeDeclaration typeDecl) {
+ // interface_list:
+ // fully_qualified_class_name
+ // | interface_list ',' fully_qualified_class_name
+ do {
+ if (token == TokenName.IDENTIFIER) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Interfacename expected after keyword 'implements'.");
+ }
+ if (token != TokenName.COMMA) {
+ return;
+ }
+ getNextToken();
+ } while (true);
+ }
+
+ // private void classBody(TypeDeclaration typeDecl) {
+ // //'{' [class-element-list] '}'
+ // if (token == TokenName.LBRACE) {
+ // getNextToken();
+ // if (token != TokenName.RBRACE) {
+ // class_statement_list();
+ // }
+ // if (token == TokenName.RBRACE) {
+ // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("'}' expected at end of class body.");
+ // }
+ // } else {
+ // throwSyntaxError("'{' expected at start of class body.");
+ // }
+ // }
+ private void class_statement_list(ArrayList list) {
+ do {
+ try {
+ class_statement(list);
+ if (token == TokenName.PUBLIC ||
+ token == TokenName.PROTECTED ||
+ token == TokenName.PRIVATE ||
+ token == TokenName.STATIC ||
+ token == TokenName.ABSTRACT ||
+ token == TokenName.FINAL ||
+ token == TokenName.FUNCTION ||
+ token == TokenName.VAR ||
+ token == TokenName.CONST) {
+ continue;
+ }
+
+ if (token == TokenName.RBRACE) {
+ break;
+ }
+
+ throwSyntaxError("'}' at end of class statement.");
+ }
+ catch (SyntaxError sytaxErr1) {
+ boolean tokenize = scanner.tokenizeStrings;
+
+ if (!tokenize) {
+ scanner.tokenizeStrings = true;
+ }
+ try {
+ // if an error occured,
+ // try to find keywords
+ // to parse the rest of the string
+ while (token != TokenName.EOF) {
+ if (token == TokenName.PUBLIC ||
+ token == TokenName.PROTECTED ||
+ token == TokenName.PRIVATE ||
+ token == TokenName.STATIC ||
+ token == TokenName.ABSTRACT ||
+ token == TokenName.FINAL ||
+ token == TokenName.FUNCTION ||
+ token == TokenName.VAR ||
+ token == TokenName.CONST) {
+ break;
+ }
+ // System.out.println(scanner.toStringAction(token));
+ getNextToken();
+ }
+ if (token == TokenName.EOF) {
+ throw sytaxErr1;
+ }
+ } finally {
+ scanner.tokenizeStrings = tokenize;
+ }
+ }
+ } while (true);
+ }
+
+ /**
+ *
+ */
+ private void class_statement(ArrayList list) {
+ // class_statement:
+ // variable_modifiers class_variable_declaration ';'
+ // | class_constant_declaration ';'
+ // | method_modifiers T_FUNCTION is_reference T_STRING
+ // '(' parameter_list ')' method_body
+ initializeModifiers();
+ int declarationSourceStart = scanner.getCurrentTokenStartPosition();
+
+ if (token == TokenName.VAR) {
+ checkAndSetModifiers(AccPublic);
+ problemReporter.phpVarDeprecatedWarning(scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ getNextToken();
+ class_variable_declaration(declarationSourceStart, list);
+ } else if (token == TokenName.CONST) {
+ checkAndSetModifiers(AccFinal | AccPublic);
+ class_constant_declaration(declarationSourceStart, list);
+ if (token != TokenName.SEMICOLON) {
+ throwSyntaxError("';' expected after class const declaration.");
+ }
+ getNextToken();
+ } else {
+ boolean hasModifiers = member_modifiers();
+ if (token == TokenName.FUNCTION) {
+ if (!hasModifiers) {
+ checkAndSetModifiers(AccPublic);
+ }
+ MethodDeclaration methodDecl = new MethodDeclaration(
+ this.compilationUnit.compilationResult);
+ methodDecl.declarationSourceStart = scanner
+ .getCurrentTokenStartPosition();
+ methodDecl.modifiers = this.modifiers;
+ methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } finally {
+ int sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0
+ || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.declarationSourceEnd = sourceEnd;
+ methodDecl.sourceEnd = sourceEnd;
+ }
+ } else {
+ if (!hasModifiers) {
+ throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
+ }
+ class_variable_declaration(declarationSourceStart, list);
+ }
+ }
+ }
+
+ private void class_constant_declaration(int declarationSourceStart,
+ ArrayList list) {
+ // class_constant_declaration ',' T_STRING '=' static_scalar
+ // | T_CONST T_STRING '=' static_scalar
+ if (token != TokenName.CONST) {
+ throwSyntaxError("'const' keyword expected in class declaration.");
+ } else {
+ getNextToken();
+ }
+ while (true) {
+ if (token != TokenName.IDENTIFIER) {
+ throwSyntaxError("Identifier expected in class const declaration.");
+ }
+ FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner
+ .getCurrentIdentifierSource(), scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition());
+ fieldDeclaration.modifiers = this.modifiers;
+ fieldDeclaration.declarationSourceStart = declarationSourceStart;
+ fieldDeclaration.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ fieldDeclaration.modifiersSourceStart = declarationSourceStart;
+ // fieldDeclaration.type
+ list.add(fieldDeclaration);
+ getNextToken();
+ if (token != TokenName.EQUAL) {
+ throwSyntaxError("'=' expected in class const declaration.");
+ }
+ getNextToken();
+ static_scalar();
+ if (token != TokenName.COMMA) {
+ break; // while(true)-loop
+ }
+ getNextToken();
+ }
+ }
+
+ // private void variable_modifiers() {
+ // // variable_modifiers:
+ // // non_empty_member_modifiers
+ // //| T_VAR
+ // initializeModifiers();
+ // if (token == TokenName.var) {
+ // checkAndSetModifiers(AccPublic);
+ // reportSyntaxError(
+ // "Keyword 'var' is deprecated. Please use 'public' 'private' or
+ // 'protected'
+ // modifier for field declarations.",
+ // scanner.getCurrentTokenStartPosition(), scanner
+ // .getCurrentTokenEndPosition());
+ // getNextToken();
+ // } else {
+ // if (!member_modifiers()) {
+ // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
+ // field declarations.");
+ // }
+ // }
+ // }
+ // private void method_modifiers() {
+ // //method_modifiers:
+ // // /* empty */
+ // //| non_empty_member_modifiers
+ // initializeModifiers();
+ // if (!member_modifiers()) {
+ // checkAndSetModifiers(AccPublic);
+ // }
+ // }
+ private boolean member_modifiers() {
+ // T_PUBLIC
+ // | T_PROTECTED
+ // | T_PRIVATE
+ // | T_STATIC
+ // | T_ABSTRACT
+ // | T_FINAL
+ boolean foundToken = false;
+ while (true) {
+ if (token == TokenName.PUBLIC) {
+ checkAndSetModifiers(AccPublic);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenName.PROTECTED) {
+ checkAndSetModifiers(AccProtected);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenName.PRIVATE) {
+ checkAndSetModifiers(AccPrivate);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenName.STATIC) {
+ checkAndSetModifiers(AccStatic);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenName.ABSTRACT) {
+ checkAndSetModifiers(AccAbstract);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenName.FINAL) {
+ checkAndSetModifiers(AccFinal);
+ getNextToken();
+ foundToken = true;
+ } else {
+ break;
+ }
+ }
+ return foundToken;
+ }
+
+ private void class_variable_declaration(int declarationSourceStart,
+ ArrayList list) {
+ // class_variable_declaration:
+ // class_variable_declaration ',' T_VARIABLE
+ // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
+ // | T_VARIABLE
+ // | T_VARIABLE '=' static_scalar
+ char[] classVariable;
+ do {
+ if (token == TokenName.VARIABLE) {
+ classVariable = scanner.getCurrentIdentifierSource();
+ // indexManager.addIdentifierInformation('v', classVariable,
+ // buf, -1,
+ // -1);
+ FieldDeclaration fieldDeclaration = new FieldDeclaration(
+ classVariable, scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition());
+ fieldDeclaration.modifiers = this.modifiers;
+ fieldDeclaration.declarationSourceStart = declarationSourceStart;
+ fieldDeclaration.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ fieldDeclaration.modifiersSourceStart = declarationSourceStart;
+ list.add(fieldDeclaration);
+ if (fTypeVariables != null) {
+ VariableInfo info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_CLASS_UNIT);
+ fTypeVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ getNextToken();
+ if (token == TokenName.EQUAL) {
+ getNextToken();
+ static_scalar();
+ }
+ } else {
+ // if (token == TokenName.THIS) {
+ // throwSyntaxError("'$this' not allowed after keyword 'public'
+ // 'protected' 'private' 'var'.");
+ // }
+ throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
+ }
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ } while (true);
+ if (token != TokenName.SEMICOLON) {
+ throwSyntaxError("';' expected after field declaration.");
+ }
+ getNextToken();
+ }
+
+ private void functionDefinition(MethodDeclaration methodDecl) {
+ boolean isAbstract = false;
+ if (astPtr == 0) {
+ if (compilationUnit != null) {
+ compilationUnit.types.add(methodDecl);
+ }
+ } else {
+ ASTNode node = astStack[astPtr];
+ if (node instanceof TypeDeclaration) {
+ TypeDeclaration typeDecl = ((TypeDeclaration) node);
+ if (typeDecl.methods == null) {
+ typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl };
+ } else {
+ AbstractMethodDeclaration[] newMethods;
+ System
+ .arraycopy(
+ typeDecl.methods,
+ 0,
+ newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
+ 0, typeDecl.methods.length);
+ newMethods[typeDecl.methods.length] = methodDecl;
+ typeDecl.methods = newMethods;
+ }
+ if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
+ isAbstract = true;
+ } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
+ isAbstract = true;
+ }
+ }
+ }
+ try {
+ pushFunctionVariableSet();
+ functionDeclarator(methodDecl);
+ if (token == TokenName.SEMICOLON) {
+ if (!isAbstract) {
+ methodDecl.sourceEnd = scanner
+ .getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("Body declaration expected for method: "
+ + new String(methodDecl.selector));
+ }
+ getNextToken();
+ return;
+ }
+ functionBody(methodDecl);
+ } finally {
+ if (!fStackUnassigned.isEmpty()) {
+ fStackUnassigned.remove(fStackUnassigned.size() - 1);
+ }
+ }
+ }
+
+ private void functionDeclarator(MethodDeclaration methodDecl) {
+ // identifier '(' [parameter-list] ')'
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ }
+
+ methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+ methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+
+ if (Scanner.isIdentifierOrKeyword (token) ||
+ token == TokenName.LPAREN) {
+
+ if (token == TokenName.LPAREN) {
+ methodDecl.selector = scanner.getCurrentIdentifierSource();
+
+ if (token.compareTo (TokenName.KEYWORD) > 0) {
+ problemReporter.phpKeywordWarning (new String[] {scanner.toStringAction(token) },
+ scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition(),
+ referenceContext,
+ compilationUnit.compilationResult);
}
- break;
- }
- default :
- if (Character.isJavaIdentifierStart(scanner.currentCharacter)) {
- scanner.scanIdentifierOrKeyword();
- break;
- }
- if (Character.isDigit(scanner.currentCharacter)) {
- scanner.scanNumber(false);
- break;
- }
- }
- //-----------------end switch while try--------------------
- } catch (IndexOutOfBoundsException e) {
- break; // read until EOF
- } catch (InvalidInputException e) {
- return false; // no clue
- }
- }
- if (scanner.recordLineSeparator) {
- compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
- }
-
- // check placement anomalies against other kinds of brackets
- for (int kind = 0; kind < BracketKinds; kind++) {
- for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
- int start = leftPositions[kind][leftIndex]; // deepest first
- // find matching closing bracket
- int depth = leftDepths[kind][leftIndex];
- int end = -1;
- for (int i = 0; i < rightCount[kind]; i++) {
- int pos = rightPositions[kind][i];
- // want matching bracket further in source with same depth
- if ((pos > start) && (depth == rightDepths[kind][i])) {
- end = pos;
- break;
- }
- }
- if (end < 0) { // did not find a good closing match
- problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
- return true;
- }
- // check if even number of opening/closing other brackets in between this pair of brackets
- int balance = 0;
- for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) {
- for (int i = 0; i < leftCount[otherKind]; i++) {
- int pos = leftPositions[otherKind][i];
- if ((pos > start) && (pos < end))
- balance++;
- }
- for (int i = 0; i < rightCount[otherKind]; i++) {
- int pos = rightPositions[otherKind][i];
- if ((pos > start) && (pos < end))
- balance--;
- }
- if (balance != 0) {
- problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly
- return true;
- }
- }
- }
- // too many opening brackets ?
- for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
- anomaliesDetected = true;
- problemReporter.unmatchedBracket(
- leftPositions[kind][leftCount[kind] - i - 1],
- referenceContext,
- compilationUnit.compilationResult);
- }
- // too many closing brackets ?
- for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
- anomaliesDetected = true;
- problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
- }
- if (anomaliesDetected)
- return true;
- }
-
- return anomaliesDetected;
- } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
- return anomaliesDetected;
- } catch (NullPointerException e) { // jdk1.2.2 jit bug
- return anomaliesDetected;
- }
- }
- public final void checkAndSetModifiers(int flag) {
- /*modify the current modifiers buffer.
- When the startPosition of the modifiers is 0
- it means that the modifier being parsed is the first
- of a list of several modifiers. The startPosition
- is zeroed when a copy of modifiers-buffer is push
- onto the astStack. */
-
- if ((modifiers & flag) != 0) { // duplicate modifier
- modifiers |= AccAlternateModifierProblem;
- }
- modifiers |= flag;
-
- if (modifiersSourceStart < 0)
- modifiersSourceStart = scanner.startPosition;
- }
- public void checkAnnotation() {
-
- boolean deprecated = false;
- boolean checkDeprecated = false;
- int lastAnnotationIndex = -1;
-
- //since jdk1.2 look only in the last java doc comment...
- found : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--) {
- //look for @deprecated into the first javadoc comment preceeding the declaration
- int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
- // javadoc only (non javadoc comment have negative end positions.)
- if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
- continue;
- }
- if (scanner.commentStops[lastAnnotationIndex] < 0) {
- break found;
- }
- checkDeprecated = true;
- int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
- char[] comment = scanner.source;
-
- for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) {
- if ((comment[i] == '@')
- && (comment[i + 1] == 'd')
- && (comment[i + 2] == 'e')
- && (comment[i + 3] == 'p')
- && (comment[i + 4] == 'r')
- && (comment[i + 5] == 'e')
- && (comment[i + 6] == 'c')
- && (comment[i + 7] == 'a')
- && (comment[i + 8] == 't')
- && (comment[i + 9] == 'e')
- && (comment[i + 10] == 'd')) {
- // ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
- int nextPos = i + 11;
- deprecated =
- (comment[nextPos] == ' ')
- || (comment[nextPos] == '\t')
- || (comment[nextPos] == '\n')
- || (comment[nextPos] == '\r')
- || (comment[nextPos] == '*');
- break found;
- }
- }
- break found;
- }
- if (deprecated) {
- checkAndSetModifiers(AccDeprecated);
- }
- // modify the modifier source start to point at the first comment
- if (lastAnnotationIndex >= 0 && checkDeprecated) {
- modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex];
- }
- }
- protected void classInstanceCreation(boolean alwaysQualified) {
- // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
-
- // ClassBodyopt produces a null item on the astStak if it produces NO class body
- // An empty class body produces a 0 on the length stack.....
-
- AllocationExpression alloc;
- int length;
- if (((length = astLengthStack[astLengthPtr--]) == 1) && (astStack[astPtr] == null)) {
- //NO ClassBody
- astPtr--;
- if (alwaysQualified) {
- alloc = new QualifiedAllocationExpression();
- } else {
- alloc = new AllocationExpression();
- }
- alloc.sourceEnd = endPosition; //the position has been stored explicitly
-
- if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, alloc.arguments = new Expression[length], 0, length);
- }
- alloc.type = getTypeReference(0);
- //the default constructor with the correct number of argument
- //will be created and added by the TC (see createsInternalConstructorWithBinding)
- alloc.sourceStart = intStack[intPtr--];
- pushOnExpressionStack(alloc);
- } else {
- dispatchDeclarationInto(length);
- AnonymousLocalTypeDeclaration anonymousTypeDeclaration = (AnonymousLocalTypeDeclaration) astStack[astPtr];
- anonymousTypeDeclaration.declarationSourceEnd = endStatementPosition;
- anonymousTypeDeclaration.bodyEnd = endStatementPosition;
- if (anonymousTypeDeclaration.allocation != null) {
- anonymousTypeDeclaration.allocation.sourceEnd = endStatementPosition;
- }
- astPtr--;
- astLengthPtr--;
-
- // mark fields and initializer with local type mark if needed
- markFieldsWithLocalType(anonymousTypeDeclaration);
- }
- }
- protected final void concatExpressionLists() {
- expressionLengthStack[--expressionLengthPtr]++;
- }
- private final void concatNodeLists() {
- /*
- * This is a case where you have two sublists into the astStack that you want
- * to merge in one list. There is no action required on the astStack. The only
- * thing you need to do is merge the two lengths specified on the astStackLength.
- * The top two length are for example:
- * ... p n
- * and you want to result in a list like:
- * ... n+p
- * This means that the p could be equals to 0 in case there is no astNode pushed
- * on the astStack.
- * Look at the InterfaceMemberDeclarations for an example.
+ }
+ else {
+ methodDecl.selector = scanner.getCurrentIdentifierSource();
+
+ if (token.compareTo (TokenName.KEYWORD) > 0) {
+ problemReporter.phpKeywordWarning (new String[] {scanner.toStringAction(token) },
+ scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition(),
+ referenceContext,
+ compilationUnit.compilationResult);
+ }
+
+ getNextToken();
+ }
+
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ }
+ else {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("'(' expected in function declaration.");
+ }
+
+ if (token != TokenName.RPAREN) {
+ parameter_list(methodDecl);
+ }
+
+ if (token != TokenName.RPAREN) {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("')' expected in function declaration.");
+ }
+ else {
+ methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
+ getNextToken();
+ }
+ }
+ else {
+ methodDecl.selector = "<undefined>".toCharArray();
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("Function name expected after keyword 'function'.");
+ }
+ }
+
+ //
+ private void parameter_list(MethodDeclaration methodDecl) {
+ // non_empty_parameter_list
+ // | /* empty */
+ non_empty_parameter_list(methodDecl, true);
+ }
+
+ private void non_empty_parameter_list(MethodDeclaration methodDecl,
+ boolean empty_allowed) {
+ // optional_class_type T_VARIABLE
+ // | optional_class_type '&' T_VARIABLE
+ // | optional_class_type '&' T_VARIABLE '=' static_scalar
+ // | optional_class_type T_VARIABLE '=' static_scalar
+ // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
+ // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
+ // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
+ // static_scalar
+ // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
+ // static_scalar
+ char[] typeIdentifier = null;
+ if (token == TokenName.IDENTIFIER ||
+ token == TokenName.ARRAY ||
+ token == TokenName.VARIABLE ||
+ token == TokenName.OP_AND) {
+ HashSet set = peekVariableSet();
+
+ while (true) {
+ if (token == TokenName.IDENTIFIER || token == TokenName.ARRAY) {// feature req. #1254275
+ typeIdentifier = scanner.getCurrentIdentifierSource();
+ getNextToken();
+ }
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ }
+ if (token == TokenName.VARIABLE) {
+ if (fMethodVariables != null) {
+ VariableInfo info;
+ if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) {
+ info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_FUNCTION_DEFINITION);
+ } else {
+ info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_METHOD_DEFINITION);
+ }
+ info.typeIdentifier = typeIdentifier;
+ fMethodVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ addVariableSet(set);
+ getNextToken();
+ if (token == TokenName.EQUAL) {
+ getNextToken();
+ static_scalar();
+ }
+ } else {
+ throwSyntaxError("Variable expected in parameter list.");
+ }
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ return;
+ }
+ if (!empty_allowed) {
+ throwSyntaxError("Identifier expected in parameter list.");
+ }
+ }
+
+// private void optional_class_type() {
+// // /* empty */
+// // | T_STRING
+// }
+
+ // private void parameterDeclaration() {
+ // //variable
+ // //variable-reference
+ // if (token == TokenName.AND) {
+ // getNextToken();
+ // if (isVariable()) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("Variable expected after reference operator '&'.");
+ // }
+ // }
+ // //variable '=' constant
+ // if (token == TokenName.VARIABLE) {
+ // getNextToken();
+ // if (token == TokenName.EQUAL) {
+ // getNextToken();
+ // static_scalar();
+ // }
+ // return;
+ // }
+ // // if (token == TokenName.THIS) {
+ // // throwSyntaxError("Reserved word '$this' not allowed in parameter
+ // // declaration.");
+ // // }
+ // }
+
+ private void labeledStatementList() {
+ if (token != TokenName.CASE && token != TokenName.DEFAULT) {
+ throwSyntaxError("'case' or 'default' expected.");
+ }
+ do {
+ if (token == TokenName.CASE) {
+ getNextToken();
+ expr_without_variable (true, null, true); // constant();
+ if (token == TokenName.COLON || token == TokenName.SEMICOLON) {
+ getNextToken();
+ if (token == TokenName.RBRACE) {
+ // empty case; assumes that the '}' token belongs to the wrapping
+ // switch statement - #1371992
+ break;
+ }
+ if (token == TokenName.CASE || token == TokenName.DEFAULT) {
+ // empty case statement ?
+ continue;
+ }
+ statementList();
+ }
+ // else if (token == TokenName.SEMICOLON) {
+ // setMarker(
+ // "':' expected after 'case' keyword (Found token: " +
+ // scanner.toStringAction(token) + ")",
+ // scanner.getCurrentTokenStartPosition(),
+ // scanner.getCurrentTokenEndPosition(),
+ // INFO);
+ // getNextToken();
+ // if (token == TokenName.CASE) { // empty case statement ?
+ // continue;
+ // }
+ // statementList();
+ // }
+ else {
+ throwSyntaxError("':' character expected after 'case' constant (Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ } else { // TokenName.DEFAULT
+ getNextToken();
+ if (token == TokenName.COLON || token == TokenName.SEMICOLON) {
+ getNextToken();
+ if (token == TokenName.RBRACE) {
+ // empty default case; ; assumes that the '}' token belongs to the
+ // wrapping switch statement - #1371992
+ break;
+ }
+ if (token != TokenName.CASE) {
+ statementList();
+ }
+ } else {
+ throwSyntaxError("':' character expected after 'default'.");
+ }
+ }
+ } while (token == TokenName.CASE || token == TokenName.DEFAULT);
+ }
+
+ private void ifStatementColon(IfStatement iState) {
+ // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
+ // new_else_single T_ENDIF ';'
+ HashSet assignedVariableSet = null;
+ try {
+ Block b = inner_statement_list();
+ iState.thenStatement = b;
+ checkUnreachable(iState, b);
+ } finally {
+ assignedVariableSet = removeIfVariableSet();
+ }
+ if (token == TokenName.ELSEIF) {
+ try {
+ pushIfVariableSet();
+ new_elseif_list(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null && set != null) {
+ assignedVariableSet.addAll(set);
+ }
+ }
+ }
+ try {
+ pushIfVariableSet();
+ new_else_single(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null) {
+ HashSet topSet = peekVariableSet();
+ if (topSet != null) {
+ if (set != null) {
+ topSet.addAll(set);
+ }
+ topSet.addAll(assignedVariableSet);
+ }
+ }
+ }
+ if (token != TokenName.ENDIF) {
+ throwSyntaxError("'endif' expected.");
+ }
+ getNextToken();
+ if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
+ reportSyntaxError("';' expected after if-statement.");
+ iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+ } else {
+ iState.sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ }
+
+ private void ifStatement(IfStatement iState) {
+ // T_IF '(' expr ')' statement elseif_list else_single
+ HashSet assignedVariableSet = null;
+ try {
+ pushIfVariableSet();
+ Statement s = statement();
+ iState.thenStatement = s;
+ checkUnreachable(iState, s);
+ } finally {
+ assignedVariableSet = removeIfVariableSet();
+ }
+
+ if (token == TokenName.ELSEIF) {
+ try {
+ pushIfVariableSet();
+ elseif_list(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null && set != null) {
+ assignedVariableSet.addAll(set);
+ }
+ }
+ }
+ try {
+ pushIfVariableSet();
+ else_single(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null) {
+ HashSet topSet = peekVariableSet();
+ if (topSet != null) {
+ if (set != null) {
+ topSet.addAll(set);
+ }
+ topSet.addAll(assignedVariableSet);
+ }
+ }
+ }
+ }
+
+ private void elseif_list(IfStatement iState) {
+ // /* empty */
+ // | elseif_list T_ELSEIF '(' expr ')' statement
+ ArrayList conditionList = new ArrayList();
+ ArrayList statementList = new ArrayList();
+ Expression e;
+ Statement s;
+ while (token == TokenName.ELSEIF) {
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'elseif' keyword.");
+ }
+ e = expr();
+ conditionList.add(e);
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'elseif' condition.");
+ }
+ s = statement();
+ statementList.add(s);
+ checkUnreachable(iState, s);
+ }
+ iState.elseifConditions = new Expression[conditionList.size()];
+ iState.elseifStatements = new Statement[statementList.size()];
+ conditionList.toArray(iState.elseifConditions);
+ statementList.toArray(iState.elseifStatements);
+ }
+
+ private void new_elseif_list(IfStatement iState) {
+ // /* empty */
+ // | new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
+ ArrayList conditionList = new ArrayList();
+ ArrayList statementList = new ArrayList();
+ Expression e;
+ Block b;
+ while (token == TokenName.ELSEIF) {
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'elseif' keyword.");
+ }
+ e = expr();
+ conditionList.add(e);
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'elseif' condition.");
+ }
+ if (token == TokenName.COLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("':' expected after 'elseif' keyword.");
+ }
+ b = inner_statement_list();
+ statementList.add(b);
+ checkUnreachable(iState, b);
+ }
+ iState.elseifConditions = new Expression[conditionList.size()];
+ iState.elseifStatements = new Statement[statementList.size()];
+ conditionList.toArray(iState.elseifConditions);
+ statementList.toArray(iState.elseifStatements);
+ }
+
+ private void else_single(IfStatement iState) {
+ // /* empty */
+ // T_ELSE statement
+ if (token == TokenName.ELSE) {
+ getNextToken();
+ Statement s = statement();
+ iState.elseStatement = s;
+ checkUnreachable(iState, s);
+ } else {
+ iState.checkUnreachable = false;
+ }
+ iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+ }
+
+ private void new_else_single(IfStatement iState) {
+ // /* empty */
+ // | T_ELSE ':' inner_statement_list
+ if (token == TokenName.ELSE) {
+ getNextToken();
+ if (token == TokenName.COLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("':' expected after 'else' keyword.");
+ }
+ Block b = inner_statement_list();
+ iState.elseStatement = b;
+ checkUnreachable(iState, b);
+ } else {
+ iState.checkUnreachable = false;
+ }
+ }
+
+ private Block inner_statement_list() {
+ // inner_statement_list inner_statement
+ // /* empty */
+ return statementList();
+ }
+
+ /**
+ * @param iState
+ * @param b
+ */
+ private void checkUnreachable(IfStatement iState, Statement s) {
+ if (s instanceof Block) {
+ Block b = (Block) s;
+ if (b.statements == null || b.statements.length == 0) {
+ iState.checkUnreachable = false;
+ } else {
+ int off = b.statements.length - 1;
+ if (!(b.statements[off] instanceof ReturnStatement)
+ && !(b.statements[off] instanceof ContinueStatement)
+ && !(b.statements[off] instanceof BreakStatement)) {
+ if (!(b.statements[off] instanceof IfStatement)
+ || !((IfStatement) b.statements[off]).checkUnreachable) {
+ iState.checkUnreachable = false;
+ }
+ }
+ }
+ } else {
+ if (!(s instanceof ReturnStatement)
+ && !(s instanceof ContinueStatement)
+ && !(s instanceof BreakStatement)) {
+ if (!(s instanceof IfStatement)
+ || !((IfStatement) s).checkUnreachable) {
+ iState.checkUnreachable = false;
+ }
+ }
+ }
+ }
+
+ // private void elseifStatementList() {
+ // do {
+ // elseifStatement();
+ // switch (token) {
+ // case TokenName.else:
+ // getNextToken();
+ // if (token == TokenName.COLON) {
+ // getNextToken();
+ // if (token != TokenName.endif) {
+ // statementList();
+ // }
+ // return;
+ // } else {
+ // if (token == TokenName.if) { //'else if'
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("':' expected after 'else'.");
+ // }
+ // }
+ // break;
+ // case TokenName.elseif:
+ // getNextToken();
+ // break;
+ // default:
+ // return;
+ // }
+ // } while (true);
+ // }
+
+ // private void elseifStatement() {
+ // if (token == TokenName.LPAREN) {
+ // getNextToken();
+ // expr();
+ // if (token != TokenName.RPAREN) {
+ // throwSyntaxError("')' expected in else-if-statement.");
+ // }
+ // getNextToken();
+ // if (token != TokenName.COLON) {
+ // throwSyntaxError("':' expected in else-if-statement.");
+ // }
+ // getNextToken();
+ // if (token != TokenName.endif) {
+ // statementList();
+ // }
+ // }
+ // }
+
+ private void switchStatement() {
+ if (token == TokenName.COLON) {
+ // ':' [labeled-statement-list] 'endswitch' ';'
+ getNextToken();
+ labeledStatementList();
+ if (token != TokenName.ENDSWITCH) {
+ throwSyntaxError("'endswitch' expected.");
+ }
+ getNextToken();
+ if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after switch-statement.");
+ }
+ getNextToken();
+ } else {
+ // '{' [labeled-statement-list] '}'
+ if (token != TokenName.LBRACE) {
+ throwSyntaxError("'{' expected in switch statement.");
+ }
+ getNextToken();
+ if (token != TokenName.RBRACE) {
+ labeledStatementList();
+ }
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in switch statement.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void forStatement() {
+ if (token == TokenName.COLON) {
+ getNextToken();
+ statementList();
+ if (token != TokenName.ENDFOR) {
+ throwSyntaxError("'endfor' expected.");
+ }
+ getNextToken();
+ if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after for-statement.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ private void whileStatement() {
+ // ':' statement-list 'endwhile' ';'
+ if (token == TokenName.COLON) {
+ getNextToken();
+ statementList();
+ if (token != TokenName.ENDWHILE) {
+ throwSyntaxError("'endwhile' expected.");
+ }
+ getNextToken();
+ if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after while-statement.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ private void foreachStatement() {
+ if (token == TokenName.COLON) {
+ getNextToken();
+ statementList();
+ if (token != TokenName.ENDFOREACH) {
+ throwSyntaxError("'endforeach' expected.");
+ }
+ getNextToken();
+ if (token != TokenName.SEMICOLON && token != TokenName.INLINE_HTML) {
+ throwSyntaxError("';' expected after foreach-statement.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ // private void exitStatus() {
+ // if (token == TokenName.LPAREN) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("'(' expected in 'exit-status'.");
+ // }
+ // if (token != TokenName.RPAREN) {
+ // expression();
+ // }
+ // if (token == TokenName.RPAREN) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("')' expected after 'exit-status'.");
+ // }
+ // }
+ /**
+ *
*/
-
- astLengthStack[astLengthPtr - 1] += astLengthStack[astLengthPtr--];
- }
- protected void consumeAllocationHeader() {
- // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
-
- // ClassBodyopt produces a null item on the astStak if it produces NO class body
- // An empty class body produces a 0 on the length stack.....
-
- if (currentElement == null) {
- return; // should never occur, this consumeRule is only used in recovery mode
- }
- if (currentToken == TokenNameLBRACE) {
- // beginning of an anonymous type
- AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
- anonymousType.sourceStart = intStack[intPtr--];
- anonymousType.sourceEnd = rParenPos; // closing parenthesis
- lastCheckPoint = anonymousType.bodyStart = scanner.currentPosition;
- currentElement = currentElement.add(anonymousType, 0);
- lastIgnoredToken = -1;
- currentToken = 0; // opening brace already taken into account
- return;
- }
- lastCheckPoint = scanner.startPosition; // force to restart at this exact position
- restartRecovery = true; // request to restart from here on
- }
- protected void consumeArgumentList() {
- // ArgumentList ::= ArgumentList ',' Expression
- concatExpressionLists();
- }
- protected void consumeArrayAccess(boolean unspecifiedReference) {
- // ArrayAccess ::= Name '[' Expression ']' ==> true
- // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
-
- //optimize push/pop
- Expression exp;
- if (unspecifiedReference) {
- exp = expressionStack[expressionPtr] = new ArrayReference(getUnspecifiedReferenceOptimized(), expressionStack[expressionPtr]);
- } else {
- expressionPtr--;
- expressionLengthPtr--;
- exp = expressionStack[expressionPtr] = new ArrayReference(expressionStack[expressionPtr], expressionStack[expressionPtr + 1]);
- }
- exp.sourceEnd = endPosition;
- }
- protected void consumeArrayCreationExpression() {
- // ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
- // ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
-
- int length;
- ArrayAllocationExpression aae = new ArrayAllocationExpression();
- if (expressionLengthStack[expressionLengthPtr] != 0) {
- expressionLengthPtr--;
- aae.initializer = (ArrayInitializer) expressionStack[expressionPtr--];
- } else {
- expressionLengthPtr--;
- }
-
- aae.type = getTypeReference(0);
- length = (expressionLengthStack[expressionLengthPtr--]);
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, aae.dimensions = new Expression[length], 0, length);
- aae.sourceStart = intStack[intPtr--];
- if (aae.initializer == null) {
- aae.sourceEnd = endPosition;
- } else {
- aae.sourceEnd = aae.initializer.sourceEnd;
- }
- pushOnExpressionStack(aae);
- }
- protected void consumeArrayInitializer() {
- // ArrayInitializer ::= '{' VariableInitializers '}'
- // ArrayInitializer ::= '{' VariableInitializers , '}'
-
- arrayInitializer(expressionLengthStack[expressionLengthPtr--]);
- }
-
- protected void consumeAssertStatement() {
- // AssertStatement ::= 'assert' Expression ':' Expression ';'
- expressionLengthPtr -= 2;
- pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], expressionStack[expressionPtr--], intStack[intPtr--]));
- }
-
- protected void consumeAssignment() {
- // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
- //optimize the push/pop
-
- int op = intStack[intPtr--]; //<--the encoded operator
-
- expressionPtr--;
- expressionLengthPtr--;
- expressionStack[expressionPtr] =
- (op != EQUAL)
- ? new CompoundAssignment(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op, scanner.startPosition - 1)
- : new Assignment(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], scanner.startPosition - 1);
- }
- protected void consumeAssignmentOperator(int pos) {
- // AssignmentOperator ::= '='
- // AssignmentOperator ::= '*='
- // AssignmentOperator ::= '/='
- // AssignmentOperator ::= '%='
- // AssignmentOperator ::= '+='
- // AssignmentOperator ::= '-='
- // AssignmentOperator ::= '<<='
- // AssignmentOperator ::= '>>='
- // AssignmentOperator ::= '>>>='
- // AssignmentOperator ::= '&='
- // AssignmentOperator ::= '^='
- // AssignmentOperator ::= '|='
-
- try {
- intStack[++intPtr] = pos;
- } catch (IndexOutOfBoundsException e) {
- //intPtr is correct
- int oldStackLength = intStack.length;
- int oldStack[] = intStack;
- intStack = new int[oldStackLength + StackIncrement];
- System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
- intStack[intPtr] = pos;
- }
- }
- protected void consumeBinaryExpression(int op) {
- // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
- // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
- // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
- // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
- // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
- // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
- // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
- // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
- // RelationalExpression ::= RelationalExpression '<' ShiftExpression
- // RelationalExpression ::= RelationalExpression '>' ShiftExpression
- // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
- // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
- // AndExpression ::= AndExpression '&' EqualityExpression
- // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
- // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
- // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
- // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
-
- //optimize the push/pop
-
- expressionPtr--;
- expressionLengthPtr--;
- if (op == OR_OR) {
- expressionStack[expressionPtr] = new OR_OR_Expression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
- } else {
- if (op == AND_AND) {
- expressionStack[expressionPtr] =
- new AND_AND_Expression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
- } else {
- // look for "string1" + "string2"
- if ((op == PLUS) && optimizeStringLiterals) {
- Expression expr1, expr2;
- expr1 = expressionStack[expressionPtr];
- expr2 = expressionStack[expressionPtr + 1];
- if (expr1 instanceof StringLiteral) {
- if (expr2 instanceof CharLiteral) { // string+char
- expressionStack[expressionPtr] = ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
- } else if (expr2 instanceof StringLiteral) { //string+string
- expressionStack[expressionPtr] = ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
- } else {
- expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+ private void namespacePath () {
+ do {
+ expr_without_variable (true, null, false);
+
+ if (token == TokenName.BACKSLASH) {
+ getNextToken();
+ } else {
+ break;
+ }
+ } while (true);
+ }
+
+ /**
+ *
+ */
+ private void expressionList() {
+ do {
+ expr_without_variable (true, null, false);
+
+ if (token == TokenName.COMMA) { // If it's a list of (comma separated) expressions
+ getNextToken(); // read all in, untill no more found
+ } else {
+ break;
+ }
+ } while (true);
+ }
+
+ private Expression expr() {
+ return expr_without_variable(true, null, false);
+ }
+
+ /**
+ *
+ * @param only_variable
+ * @param initHandler
+ */
+ private Expression expr_without_variable (boolean only_variable,
+ UninitializedVariableHandler initHandler,
+ boolean bColonAllowed) {
+ int exprSourceStart = scanner.getCurrentTokenStartPosition();
+ int exprSourceEnd = scanner.getCurrentTokenEndPosition();
+ Expression expression = new Expression();
+
+ expression.sourceStart = exprSourceStart;
+ expression.sourceEnd = exprSourceEnd; // default, may be overwritten
+
+ try {
+ // internal_functions_in_yacc
+ // | T_CLONE expr
+ // | T_PRINT expr
+ // | '(' expr ')'
+ // | '@' expr
+ // | '+' expr
+ // | '-' expr
+ // | '!' expr
+ // | '~' expr
+ // | T_INC rw_variable
+ // | T_DEC rw_variable
+ // | T_INT_CAST expr
+ // | T_DOUBLE_CAST expr
+ // | T_STRING_CAST expr
+ // | T_ARRAY_CAST expr
+ // | T_OBJECT_CAST expr
+ // | T_BOOL_CAST expr
+ // | T_UNSET_CAST expr
+ // | T_EXIT exit_expr
+ // | scalar
+ // | T_ARRAY '(' array_pair_list ')'
+ // | '`' encaps_list '`'
+ // | T_LIST '(' assignment_list ')' '=' expr
+ // | T_NEW class_name_reference ctor_arguments
+ // | variable '=' expr
+ // | variable '=' '&' variable
+ // | variable '=' '&' T_NEW class_name_reference ctor_arguments
+ // | variable T_PLUS_EQUAL expr
+ // | variable T_MINUS_EQUAL expr
+ // | variable T_MUL_EQUAL expr
+ // | variable T_DIV_EQUAL expr
+ // | variable T_CONCAT_EQUAL expr
+ // | variable T_MOD_EQUAL expr
+ // | variable T_AND_EQUAL expr
+ // | variable T_OR_EQUAL expr
+ // | variable T_XOR_EQUAL expr
+ // | variable T_SL_EQUAL expr
+ // | variable T_SR_EQUAL expr
+ // | rw_variable T_INC
+ // | rw_variable T_DEC
+ // | expr T_BOOLEAN_OR expr
+ // | expr T_BOOLEAN_AND expr
+ // | expr T_LOGICAL_OR expr
+ // | expr T_LOGICAL_AND expr
+ // | expr T_LOGICAL_XOR expr
+ // | expr '|' expr
+ // | expr '&' expr
+ // | expr '^' expr
+ // | expr '.' expr
+ // | expr '+' expr
+ // | expr '-' expr
+ // | expr '*' expr
+ // | expr '/' expr
+ // | expr '%' expr
+ // | expr T_SL expr
+ // | expr T_SR expr
+ // | expr T_IS_IDENTICAL expr
+ // | expr T_IS_NOT_IDENTICAL expr
+ // | expr T_IS_EQUAL expr
+ // | expr T_IS_NOT_EQUAL expr
+ // | expr '<' expr
+ // | expr T_IS_SMALLER_OR_EQUAL expr
+ // | expr '>' expr
+ // | expr T_IS_GREATER_OR_EQUAL expr
+ // | expr T_INSTANCEOF class_name_reference
+ // | expr '?' expr ':' expr
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: expr_without_variable() PART 1");
+ }
+
+ switch (token) {
+ case ISSET:
+ // T_ISSET '(' isset_variables ')'
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected after keyword 'isset'");
+ }
+ getNextToken();
+ isset_variables();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected after keyword 'isset'");
+ }
+ getNextToken();
+ break;
+ case EMPTY:
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected after keyword 'empty'");
+ }
+ getNextToken();
+ variable(true, false);
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected after keyword 'empty'");
+ }
+ getNextToken();
+ break;
+ case EVAL:
+ case INCLUDE:
+ case INCLUDE_ONCE:
+ case REQUIRE:
+ case REQUIRE_ONCE:
+ internal_functions_in_yacc();
+ break;
+
+ // | '(' expr ')'
+ case LPAREN:
+ getNextToken();
+ expr();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected in expression.");
+ }
+ break;
+ // | T_CLONE expr
+ // | T_PRINT expr
+ // | '@' expr
+ // | '+' expr
+ // | '-' expr
+ // | '!' expr
+ // | '~' expr
+ // | T_INT_CAST expr
+ // | T_DOUBLE_CAST expr
+ // | T_STRING_CAST expr
+ // | T_ARRAY_CAST expr
+ // | T_OBJECT_CAST expr
+ // | T_BOOL_CAST expr
+ // | T_UNSET_CAST expr
+ case OP_AT:
+ case CLONE:
+ case PRINT:
+ case PLUS:
+ case MINUS:
+ case NOT:
+ case TWIDDLE:
+ case INTCAST:
+ case DOUBLECAST:
+ case STRINGCAST:
+ case ARRAYCAST:
+ case OBJECTCAST:
+ case BOOLCAST:
+ case UNSETCAST:
+ getNextToken();
+ expr_without_variable (only_variable, initHandler, bColonAllowed);
+ break;
+ case EXIT:
+ getNextToken();
+ exit_expr();
+ break;
+ // scalar:
+ // T_STRING
+ // | T_STRING_VARNAME
+ // | class_constant
+ // | T_START_HEREDOC encaps_list T_END_HEREDOC
+ // | '`' encaps_list '`'
+ // | common_scalar
+ // | '`' encaps_list '`'
+ // case TokenName.EncapsedString0:
+ // scanner.encapsedStringStack.push(new Character('`'));
+ // getNextToken();
+ // try {
+ // if (token == TokenName.EncapsedString0) {
+ // } else {
+ // encaps_list();
+ // if (token != TokenName.EncapsedString0) {
+ // throwSyntaxError("\'`\' expected at end of string" + "(Found
+ // token: " +
+ // scanner.toStringAction(token) + " )");
+ // }
+ // }
+ // } finally {
+ // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ // // | '\'' encaps_list '\''
+ // case TokenName.EncapsedString1:
+ // scanner.encapsedStringStack.push(new Character('\''));
+ // getNextToken();
+ // try {
+ // exprSourceStart = scanner.getCurrentTokenStartPosition();
+ // if (token == TokenName.EncapsedString1) {
+ // expression = new
+ // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // } else {
+ // encaps_list();
+ // if (token != TokenName.EncapsedString1) {
+ // throwSyntaxError("\'\'\' expected at end of string" + "(Found
+ // token: "
+ // + scanner.toStringAction(token) + " )");
+ // } else {
+ // expression = new
+ // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ // }
+ // } finally {
+ // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ // //| '"' encaps_list '"'
+ // case TokenName.EncapsedString2:
+ // scanner.encapsedStringStack.push(new Character('"'));
+ // getNextToken();
+ // try {
+ // exprSourceStart = scanner.getCurrentTokenStartPosition();
+ // if (token == TokenName.EncapsedString2) {
+ // expression = new
+ // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // } else {
+ // encaps_list();
+ // if (token != TokenName.EncapsedString2) {
+ // throwSyntaxError("'\"' expected at end of string" + "(Found
+ // token: " +
+ // scanner.toStringAction(token) + " )");
+ // } else {
+ // expression = new
+ // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ // }
+ // } finally {
+ // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ case STRINGDOUBLEQUOTE:
+ expression = new StringLiteralDQ (scanner.getCurrentStringLiteralSource(),
+ scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition());
+ common_scalar();
+ break;
+ case STRINGSINGLEQUOTE:
+ expression = new StringLiteralSQ (scanner.getCurrentStringLiteralSource(),
+ scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition());
+ common_scalar();
+ break;
+ case INTEGERLITERAL:
+ case DOUBLELITERAL:
+ case STRINGINTERPOLATED:
+ case FILE:
+ case LINE:
+ case CLASS_C:
+ case METHOD_C:
+ case FUNC_C:
+ common_scalar();
+ break;
+ case HEREDOC:
+ getNextToken();
+ break;
+ case ARRAY:
+ // T_ARRAY '(' array_pair_list ')'
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ break;
+ }
+ array_pair_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' or ',' expected after keyword 'array'"
+ + "(Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after keyword 'array'"
+ + "(Found token: " + scanner.toStringAction(token)
+ + ")");
+ }
+ break;
+ case LIST:
+ // | T_LIST '(' assignment_list ')' '=' expr
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ assignment_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected after 'list' keyword.");
+ }
+ getNextToken();
+ if (token != TokenName.EQUAL) {
+ throwSyntaxError("'=' expected after 'list' keyword.");
+ }
+ getNextToken();
+ expr();
+ } else {
+ throwSyntaxError("'(' expected after 'list' keyword.");
+ }
+ break;
+ case NEW:
+ // | T_NEW class_name_reference ctor_arguments
+ getNextToken();
+ Expression typeRef = class_name_reference();
+ ctor_arguments();
+ if (typeRef != null) {
+ expression = typeRef;
+ }
+ break;
+ // | T_INC rw_variable
+ // | T_DEC rw_variable
+ case PLUS_PLUS:
+ case MINUS_MINUS:
+ getNextToken();
+ rw_variable();
+ break;
+ // | variable '=' expr
+ // | variable '=' '&' variable
+ // | variable '=' '&' T_NEW class_name_reference ctor_arguments
+ // | variable T_PLUS_EQUAL expr
+ // | variable T_MINUS_EQUAL expr
+ // | variable T_MUL_EQUAL expr
+ // | variable T_DIV_EQUAL expr
+ // | variable T_CONCAT_EQUAL expr
+ // | variable T_MOD_EQUAL expr
+ // | variable T_AND_EQUAL expr
+ // | variable T_OR_EQUAL expr
+ // | variable T_XOR_EQUAL expr
+ // | variable T_SL_EQUAL expr
+ // | variable T_SR_EQUAL expr
+ // | rw_variable T_INC
+ // | rw_variable T_DEC
+ case IDENTIFIER:
+ case VARIABLE:
+ case DOLLAR:
+ Expression lhs = null;
+ boolean rememberedVar = false;
+
+ if (token == TokenName.IDENTIFIER) {
+ lhs = identifier(true, true, bColonAllowed);
+
+ if (lhs != null) {
+ expression = lhs;
+ }
+ }
+ else {
+ lhs = variable (true, true);
+
+ if (lhs != null) {
+ expression = lhs;
+ }
+
+ if (lhs != null &&
+ lhs instanceof FieldReference &&
+ token != TokenName.EQUAL &&
+ token != TokenName.PLUS_EQUAL &&
+ token != TokenName.MINUS_EQUAL &&
+ token != TokenName.MULTIPLY_EQUAL &&
+ token != TokenName.DIVIDE_EQUAL &&
+ token != TokenName.DOT_EQUAL &&
+ token != TokenName.REMAINDER_EQUAL &&
+ token != TokenName.AND_EQUAL &&
+ token != TokenName.OR_EQUAL &&
+ token != TokenName.XOR_EQUAL &&
+ token != TokenName.RIGHT_SHIFT_EQUAL &&
+ token != TokenName.LEFT_SHIFT_EQUAL) {
+
+ FieldReference ref = (FieldReference) lhs;
+
+ if (!containsVariableSet(ref.token)) {
+ if (null == initHandler || initHandler.reportError()) {
+ problemReporter.uninitializedLocalVariable(
+ new String(ref.token), ref.sourceStart,
+ ref.sourceEnd, referenceContext,
+ compilationUnit.compilationResult);
+ }
+ addVariableSet(ref.token);
+ }
+ }
+ }
+
+ switch (token) {
+ case EQUAL:
+ if (lhs != null && lhs instanceof FieldReference) {
+ addVariableSet(((FieldReference) lhs).token);
+ }
+ getNextToken();
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ if (token == TokenName.NEW) {
+ // | variable '=' '&' T_NEW class_name_reference
+ // ctor_arguments
+ getNextToken();
+ SingleTypeReference classRef = class_name_reference();
+ ctor_arguments();
+ if (classRef != null) {
+ if (lhs != null
+ && lhs instanceof FieldReference) {
+ // example:
+ // $var = & new Object();
+ if (fMethodVariables != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = classRef;
+ lhsInfo.typeIdentifier = classRef.token;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ }
+ } else {
+ Expression rhs = variable(false, false);
+ if (rhs != null && rhs instanceof FieldReference
+ && lhs != null
+ && lhs instanceof FieldReference) {
+ // example:
+ // $var = &$ref;
+ if (fMethodVariables != null) {
+ VariableInfo rhsInfo = (VariableInfo) fMethodVariables
+ .get(((FieldReference) rhs).token);
+ if (rhsInfo != null
+ && rhsInfo.reference != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = rhsInfo.reference;
+ lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ }
+ }
+ } else {
+ Expression rhs = expr_without_variable (only_variable, initHandler, bColonAllowed);
+
+ if (lhs != null && lhs instanceof FieldReference) {
+ if (rhs != null && rhs instanceof FieldReference) {
+ // example:
+ // $var = $ref;
+ if (fMethodVariables != null) {
+ VariableInfo rhsInfo = (VariableInfo) fMethodVariables
+ .get(((FieldReference) rhs).token);
+ if (rhsInfo != null
+ && rhsInfo.reference != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = rhsInfo.reference;
+ lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ } else if (rhs != null
+ && rhs instanceof SingleTypeReference) {
+ // example:
+ // $var = new Object();
+ if (fMethodVariables != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = (SingleTypeReference) rhs;
+ lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ }
+ }
+ if (rememberedVar == false && lhs != null
+ && lhs instanceof FieldReference) {
+ if (fMethodVariables != null) {
+ VariableInfo lhsInfo = new VariableInfo (((FieldReference) lhs).sourceStart);
+ fMethodVariables.put (new String (((FieldReference) lhs).token), lhsInfo);
+ }
+ }
+ break;
+
+ case TERNARY_SHORT:
+ case PLUS_EQUAL:
+ case MINUS_EQUAL:
+ case MULTIPLY_EQUAL:
+ case DIVIDE_EQUAL:
+ case DOT_EQUAL:
+ case REMAINDER_EQUAL:
+ case AND_EQUAL:
+ case OR_EQUAL:
+ case XOR_EQUAL:
+ case RIGHT_SHIFT_EQUAL:
+ case LEFT_SHIFT_EQUAL:
+ if (lhs != null && lhs instanceof FieldReference) {
+ addVariableSet(((FieldReference) lhs).token);
+ }
+ getNextToken();
+ expr_without_variable (only_variable, initHandler, bColonAllowed);
+ break;
+ case PLUS_PLUS:
+ case MINUS_MINUS:
+ getNextToken();
+ break;
+ default:
+ if (!only_variable) {
+ throwSyntaxError("Variable expression not allowed (found token '"
+ + scanner.toStringAction(token) + "').");
+ }
+ if (lhs != null) {
+ expression = lhs;
+ }
+ } // case DOLLAR, VARIABLE, IDENTIFIER: switch token
+ break;
+
+ case FUNCTION:
+ MethodDeclaration methodDecl = new MethodDeclaration (this.compilationUnit.compilationResult);
+ methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
+ methodDecl.modifiers = AccDefault;
+ methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } finally {
+ int sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.declarationSourceEnd = sourceEnd;
+ methodDecl.sourceEnd = sourceEnd;
+ }
+ break;
+
+ default:
+ if (token != TokenName.INLINE_HTML) {
+ if (token.compareTo (TokenName.KEYWORD) > 0) {
+ getNextToken();
+ break;
+ } else {
+ // System.out.println(scanner.getCurrentTokenStartPosition());
+ // System.out.println(scanner.getCurrentTokenEndPosition());
+
+ throwSyntaxError("Error in expression (found token '"
+ + scanner.toStringAction(token) + "').");
+ }
+ }
+ return expression;
+ } // switch token
+
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: expr_without_variable() PART 2");
+ }
+
+ // | expr T_BOOLEAN_OR expr
+ // | expr T_BOOLEAN_AND expr
+ // | expr T_LOGICAL_OR expr
+ // | expr T_LOGICAL_AND expr
+ // | expr T_LOGICAL_XOR expr
+ // | expr '|' expr
+ // | expr '&' expr
+ // | expr '^' expr
+ // | expr '.' expr
+ // | expr '+' expr
+ // | expr '-' expr
+ // | expr '*' expr
+ // | expr '/' expr
+ // | expr '%' expr
+ // | expr T_SL expr
+ // | expr T_SR expr
+ // | expr T_IS_IDENTICAL expr
+ // | expr T_IS_NOT_IDENTICAL expr
+ // | expr T_IS_EQUAL expr
+ // | expr T_IS_NOT_EQUAL expr
+ // | expr '<' expr
+ // | expr T_IS_SMALLER_OR_EQUAL expr
+ // | expr '>' expr
+ // | expr T_IS_GREATER_OR_EQUAL expr
+ while (true) {
+ switch (token) {
+ case OR_OR:
+ getNextToken();
+ expression = new OR_OR_Expression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.OR_OR);
+ break;
+ case AND_AND:
+ getNextToken();
+ expression = new AND_AND_Expression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.AND_AND);
+ break;
+ case EQUAL_EQUAL:
+ getNextToken();
+ expression = new EqualExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.EQUAL_EQUAL);
+ break;
+ case OP_AND:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.AND);
+ break;
+ case OP_OR:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.OR);
+ break;
+ case OP_XOR:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.XOR);
+ break;
+ case OP_AND_OLD:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.AND);
+ break;
+ case OP_OR_OLD:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.OR);
+ break;
+ case OP_XOR_OLD:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.XOR);
+ break;
+ case DOT:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.TWIDDLE);
+ break;
+ case PLUS:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.PLUS);
+ break;
+ case MINUS:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.MINUS);
+ break;
+ case MULTIPLY:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.MULTIPLY);
+ break;
+ case DIVIDE:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.DIVIDE);
+ break;
+ case REMAINDER:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.REMAINDER);
+ break;
+ case LEFT_SHIFT:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.LEFT_SHIFT);
+ break;
+ case RIGHT_SHIFT:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.RIGHT_SHIFT);
+ break;
+ case EQUAL_EQUAL_EQUAL:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.EQUAL_EQUAL);
+ break;
+ case NOT_EQUAL_EQUAL:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.NOT_EQUAL);
+ break;
+ case NOT_EQUAL:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.NOT_EQUAL);
+ break;
+ case LESS:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.LESS);
+ break;
+ case LESS_EQUAL:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.LESS_EQUAL);
+ break;
+ case GREATER:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.GREATER);
+ break;
+ case GREATER_EQUAL:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.GREATER_EQUAL);
+ break;
+ // | expr T_INSTANCEOF class_name_reference
+ // | expr '?' expr ':' expr
+ case INSTANCEOF:
+ getNextToken();
+ TypeReference classRef = class_name_reference();
+
+ if (classRef != null) {
+ expression = new InstanceOfExpression (expression, classRef, OperatorIds.INSTANCEOF);
+ expression.sourceStart = exprSourceStart;
+ expression.sourceEnd = scanner.getCurrentTokenEndPosition();
+ }
+ break;
+
+ case TERNARY_SHORT:
+ getNextToken();
+ expression = new EqualExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.TERNARY_SHORT);
+ break;
+
+ case QUESTION:
+ getNextToken();
+ Expression valueIfTrue = expr_without_variable (true, null, true);
+ if (token != TokenName.COLON) {
+ throwSyntaxError("':' expected in conditional expression.");
+ }
+ getNextToken();
+ Expression valueIfFalse = expr();
+
+ expression = new ConditionalExpression (expression, valueIfTrue, valueIfFalse);
+ break;
+ default:
+ return expression;
+ } // switch
+ } // while (true)
+ } catch (SyntaxError e) {
+ // try to find next token after expression with errors:
+ if (token == TokenName.SEMICOLON) {
+ getNextToken();
+ return expression;
+ }
+
+ if (token == TokenName.RBRACE ||
+ token == TokenName.RPAREN ||
+ token == TokenName.RBRACKET) {
+ getNextToken();
+ return expression;
+ }
+ throw e;
+ }
+ }
+
+ /**
+ *
+ */
+ private SingleTypeReference class_name_reference() {
+ // class_name_reference:
+ // T_STRING
+ // | dynamic_class_name_reference
+ SingleTypeReference ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: class_name_reference()");
+ }
+ if (token == TokenName.IDENTIFIER) {
+ ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(),
+ scanner.getCurrentTokenStartPosition());
+ int pos = scanner.currentPosition;
+ getNextToken();
+ if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+ // Not terminated by T_STRING, reduce to dynamic_class_name_reference
+ scanner.currentPosition = pos;
+ token = TokenName.IDENTIFIER;
+ ref = null;
+ dynamic_class_name_reference();
+ }
+ } else {
+ ref = null;
+ dynamic_class_name_reference();
+ }
+ return ref;
+ }
+
+ private void dynamic_class_name_reference() {
+ // dynamic_class_name_reference:
+ // base_variable T_OBJECT_OPERATOR object_property
+ // dynamic_class_name_variable_properties
+ // | base_variable
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: dynamic_class_name_reference()");
+ }
+ base_variable(true);
+ if (token == TokenName.MINUS_GREATER) {
+ getNextToken();
+ object_property();
+ dynamic_class_name_variable_properties();
+ }
+ }
+
+ private void dynamic_class_name_variable_properties() {
+ // dynamic_class_name_variable_properties:
+ // dynamic_class_name_variable_properties
+ // dynamic_class_name_variable_property
+ // | /* empty */
+ if (Scanner.TRACE) {
+ System.out
+ .println("TRACE: dynamic_class_name_variable_properties()");
+ }
+ while (token == TokenName.MINUS_GREATER) {
+ dynamic_class_name_variable_property();
+ }
+ }
+
+ private void dynamic_class_name_variable_property() {
+ // dynamic_class_name_variable_property:
+ // T_OBJECT_OPERATOR object_property
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: dynamic_class_name_variable_property()");
+ }
+ if (token == TokenName.MINUS_GREATER) {
+ getNextToken();
+ object_property();
+ }
+ }
+
+ private void ctor_arguments() {
+ // ctor_arguments:
+ // /* empty */
+ // | '(' function_call_parameter_list ')'
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ return;
+ }
+ non_empty_function_call_parameter_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected in ctor_arguments.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void assignment_list() {
+ // assignment_list:
+ // assignment_list ',' assignment_list_element
+ // | assignment_list_element
+ while (true) {
+ assignment_list_element();
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void assignment_list_element() {
+ // assignment_list_element:
+ // variable
+ // | T_LIST '(' assignment_list ')'
+ // | /* empty */
+ if (token == TokenName.VARIABLE) {
+ variable(true, false);
+ } else if (token == TokenName.DOLLAR) {
+ variable(false, false);
+ } else if (token == TokenName.IDENTIFIER) {
+ identifier(true, true, false);
+ } else {
+ if (token == TokenName.LIST) {
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ assignment_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected after 'list' keyword.");
+ }
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'list' keyword.");
+ }
+ }
+ }
+ }
+
+ private void array_pair_list() {
+ // array_pair_list:
+ // /* empty */
+ // | non_empty_array_pair_list possible_comma
+ non_empty_array_pair_list();
+ if (token == TokenName.COMMA) {
+ getNextToken();
+ }
+ }
+
+ private void non_empty_array_pair_list() {
+ // non_empty_array_pair_list:
+ // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
+ // | non_empty_array_pair_list ',' expr
+ // | expr T_DOUBLE_ARROW expr
+ // | expr
+ // | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
+ // | non_empty_array_pair_list ',' '&' w_variable
+ // | expr T_DOUBLE_ARROW '&' w_variable
+ // | '&' w_variable
+ while (true) {
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ variable(true, false);
+ } else {
+ expr();
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ variable(true, false);
+ } else if (token == TokenName.EQUAL_GREATER) {
+ getNextToken();
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ variable(true, false);
+ } else {
+ expr();
+ }
+ }
+ }
+ if (token != TokenName.COMMA) {
+ return;
+ }
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ return;
+ }
+ }
+ }
+
+ // private void variableList() {
+ // do {
+ // variable();
+ // if (token == TokenName.COMMA) {
+ // getNextToken();
+ // } else {
+ // break;
+ // }
+ // } while (true);
+ // }
+ private Expression variable_without_objects(boolean lefthandside,
+ boolean ignoreVar) {
+ // variable_without_objects:
+ // reference_variable
+ // | simple_indirect_reference reference_variable
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: variable_without_objects()");
+ }
+ while (token == TokenName.DOLLAR) {
+ getNextToken();
+ }
+ return reference_variable(lefthandside, ignoreVar);
+ }
+
+ private Expression function_call(boolean lefthandside, boolean ignoreVar) {
+ // function_call:
+ // T_STRING '(' function_call_parameter_list ')'
+ // | class_constant '(' function_call_parameter_list ')'
+ // | static_member '(' function_call_parameter_list ')'
+ // | variable_without_objects '(' function_call_parameter_list ')'
+ char[] defineName = null;
+ char[] ident = null;
+ int startPos = 0;
+ int endPos = 0;
+ Expression ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: function_call()");
+ }
+ if (token == TokenName.IDENTIFIER) {
+ ident = scanner.getCurrentIdentifierSource();
+ defineName = ident;
+ startPos = scanner.getCurrentTokenStartPosition();
+ endPos = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ switch (token) {
+ case PAAMAYIM_NEKUDOTAYIM:
+ // static member:
+ defineName = null;
+ getNextToken();
+ if (token == TokenName.IDENTIFIER) {
+ // class _constant
+ getNextToken();
+ } else {
+ // static member:
+ variable_without_objects(true, false);
+ }
+ break;
+ }
+ } else {
+ ref = variable_without_objects(lefthandside, ignoreVar);
+ }
+ if (token != TokenName.LPAREN) {
+ if (defineName != null) {
+ // does this identifier contain only uppercase characters?
+ if (defineName.length == 3) {
+ if (defineName[0] == 'd' &&
+ defineName[1] == 'i' &&
+ defineName[2] == 'e') {
+ defineName = null;
+ }
+ } else if (defineName.length == 4) {
+ if (defineName[0] == 't' &&
+ defineName[1] == 'r' &&
+ defineName[2] == 'u' &&
+ defineName[3] == 'e') {
+ defineName = null;
+ } else if (defineName[0] == 'n' &&
+ defineName[1] == 'u' &&
+ defineName[2] == 'l' &&
+ defineName[3] == 'l') {
+ defineName = null;
+ }
+ } else if (defineName.length == 5) {
+ if (defineName[0] == 'f' &&
+ defineName[1] == 'a' &&
+ defineName[2] == 'l' &&
+ defineName[3] == 's' &&
+ defineName[4] == 'e') {
+ defineName = null;
+ }
+ }
+ if (defineName != null) {
+ for (int i = 0; i < defineName.length; i++) {
+ if (Character.isLowerCase(defineName[i])) {
+ problemReporter.phpUppercaseIdentifierWarning(
+ startPos, endPos, referenceContext,
+ compilationUnit.compilationResult);
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ return ref;
+ }
+
+ non_empty_function_call_parameter_list();
+
+ if (token != TokenName.RPAREN) {
+ String functionName;
+
+ if (ident == null) {
+ functionName = new String(" ");
+ } else {
+ functionName = new String(ident);
+ }
+
+ throwSyntaxError("')' expected in function call (" + functionName + ").");
+ }
+ getNextToken();
+ }
+ return ref;
+ }
+
+ private void non_empty_function_call_parameter_list() {
+ this.non_empty_function_call_parameter_list(null);
+ }
+
+ // private void function_call_parameter_list() {
+ // function_call_parameter_list:
+ // non_empty_function_call_parameter_list { $$ = $1; }
+ // | /* empty */
+ // }
+ private void non_empty_function_call_parameter_list(String functionName) {
+ // non_empty_function_call_parameter_list:
+ // expr_without_variable
+ // | variable
+ // | '&' w_variable
+ // | non_empty_function_call_parameter_list ',' expr_without_variable
+ // | non_empty_function_call_parameter_list ',' variable
+ // | non_empty_function_call_parameter_list ',' '&' w_variable
+ if (Scanner.TRACE) {
+ System.out
+ .println("TRACE: non_empty_function_call_parameter_list()");
+ }
+ UninitializedVariableHandler initHandler = new UninitializedVariableHandler();
+ initHandler.setFunctionName(functionName);
+ while (true) {
+ initHandler.incrementArgumentCount();
+ if (token == TokenName.OP_AND) {
+ getNextToken();
+ w_variable(true);
+ } else {
+ // if (token == TokenName.Identifier || token ==
+ // TokenName.Variable
+ // || token == TokenName.DOLLAR) {
+ // variable();
+ // } else {
+ expr_without_variable(true, initHandler, false);
+ // }
+ }
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void fully_qualified_class_name() {
+ if (token == TokenName.IDENTIFIER) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Class name expected.");
+ }
+ }
+
+ private void static_member() {
+ // static_member:
+ // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
+ // variable_without_objects
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: static_member()");
+ }
+ fully_qualified_class_name();
+ if (token != TokenName.PAAMAYIM_NEKUDOTAYIM) {
+ throwSyntaxError("'::' expected after class name (static_member).");
+ }
+ getNextToken();
+ variable_without_objects(false, false);
+ }
+
+ /**
+ * base_variable_with_function_calls:
+ * base_variable | function_call
+ *
+ * @param lefthandside
+ * @param ignoreVar
+ * @return
+ */
+ private Expression base_variable_with_function_calls (boolean lefthandside, boolean ignoreVar) {
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: base_variable_with_function_calls()");
+ }
+
+ return function_call(lefthandside, ignoreVar);
+ }
+
+ /**
+ * base_variable:
+ * reference_variable
+ * | simple_indirect_reference reference_variable
+ * | static_member
+ *
+ * @param lefthandside
+ * @return
+ */
+ private Expression base_variable (boolean lefthandside) {
+ Expression ref = null;
+
+ if (Scanner.TRACE) {
+ System.out.println ("TRACE: base_variable()");
+ }
+
+ if (token == TokenName.IDENTIFIER) {
+ static_member ();
+ }
+ else {
+ while (token == TokenName.DOLLAR) {
+ getNextToken ();
+ }
+
+ reference_variable (lefthandside, false);
+ }
+
+ return ref;
+ }
+
+ // private void simple_indirect_reference() {
+ // // simple_indirect_reference:
+ // // '$'
+ // //| simple_indirect_reference '$'
+ // }
+ private Expression reference_variable (boolean lefthandside, boolean ignoreVar) {
+ // reference_variable:
+ // reference_variable '[' dim_offset ']'
+ // | reference_variable '{' expr '}'
+ // | compound_variable
+ Expression ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: reference_variable()");
+ }
+ ref = compound_variable(lefthandside, ignoreVar);
+ while (true) {
+ if (token == TokenName.LBRACE) {
+ ref = null;
+ getNextToken();
+ expr();
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in reference variable.");
+ }
+ getNextToken();
+ } else if (token == TokenName.LBRACKET) {
+ // To remove "ref = null;" here, is probably better than the
+ // patch
+ // commented in #1368081 - axelcl
+ getNextToken();
+ if (token != TokenName.RBRACKET) {
+ expr();
+ // dim_offset();
+ if (token != TokenName.RBRACKET) {
+ throwSyntaxError("']' expected in reference variable.");
+ }
+ }
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ return ref;
+ }
+
+ private Expression compound_variable (boolean lefthandside, boolean ignoreVar) {
+ // compound_variable:
+ // T_VARIABLE
+ // | '$' '{' expr '}'
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: compound_variable()");
+ }
+
+ if (token == TokenName.VARIABLE) {
+ if (!lefthandside) {
+ if (!containsVariableSet()) {
+ // reportSyntaxError("The local variable " + new
+ // String(scanner.getCurrentIdentifierSource())
+ // + " may not have been initialized");
+ problemReporter.uninitializedLocalVariable (
+ new String (scanner.getCurrentIdentifierSource()),
+ scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition(),
+ referenceContext,
+ compilationUnit.compilationResult);
+ }
+ } else {
+ if (!ignoreVar) {
+ addVariableSet();
+ }
+ }
+
+ FieldReference ref = new FieldReference (scanner.getCurrentIdentifierSource(),
+ scanner.getCurrentTokenStartPosition());
+ getNextToken();
+ return ref;
+ }
+ else {
+ // because of simple_indirect_reference
+ while (token == TokenName.DOLLAR) {
+ getNextToken();
+ }
+
+ if (token != TokenName.LBRACE) {
+ reportSyntaxError("'{' expected after compound variable token '$'.");
+ return null;
+ }
+
+ getNextToken();
+ expr();
+
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected after compound variable token '$'.");
+ }
+
+ getNextToken();
+ }
+
+ return null;
+ } // private void dim_offset() { // // dim_offset: // // /* empty */
+
+ // // | expr
+ // expr();
+ // }
+ private void object_property() {
+ // object_property:
+ // object_dim_list
+ // | variable_without_objects
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: object_property()");
+ }
+
+ if ((token == TokenName.VARIABLE) ||
+ (token == TokenName.DOLLAR)) {
+ variable_without_objects (false, false);
+ }
+ else {
+ object_dim_list();
+ }
+ }
+
+ private void object_dim_list() {
+ // object_dim_list:
+ // object_dim_list '[' dim_offset ']'
+ // | object_dim_list '{' expr '}'
+ // | variable_name
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: object_dim_list()");
+ }
+
+ variable_name();
+
+ while (true) {
+ if (token == TokenName.LBRACE) {
+ getNextToken();
+ expr();
+
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in object_dim_list.");
+ }
+
+ getNextToken();
+ }
+ else if (token == TokenName.LBRACKET) {
+ getNextToken();
+
+ if (token == TokenName.RBRACKET) {
+ getNextToken();
+ continue;
+ }
+
+ expr();
+
+ if (token != TokenName.RBRACKET) {
+ throwSyntaxError("']' expected in object_dim_list.");
+ }
+
+ getNextToken();
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ private void variable_name() {
+ // variable_name:
+ // T_STRING
+ // | '{' expr '}'
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: variable_name()");
+ }
+
+ if ((token == TokenName.IDENTIFIER) ||
+ (token.compareTo (TokenName.KEYWORD) > 0)) {
+ if (token.compareTo (TokenName.KEYWORD) > 0) {
+ // TODO show a warning "Keyword used as variable" ?
+ }
+
+ getNextToken();
+ }
+ else if ((token == TokenName.OP_AND_OLD) || // If the found token is e.g $var->and
+ (token == TokenName.OP_OR_OLD) || // or is $var->or
+ (token == TokenName.OP_XOR_OLD)) { // or is $var->xor
+ getNextToken (); // get the next token. Maybe we should issue an warning?
+ }
+ else {
+ if (token != TokenName.LBRACE) {
+ throwSyntaxError("'{' expected in variable name.");
+ }
+
+ getNextToken();
+ expr();
+
+ if (token != TokenName.RBRACE) {
+ throwSyntaxError("'}' expected in variable name.");
+ }
+
+ getNextToken();
+ }
+ }
+
+ private void r_variable() {
+ variable(false, false);
+ }
+
+ private void w_variable(boolean lefthandside) {
+ variable(lefthandside, false);
+ }
+
+ private void rw_variable() {
+ variable(false, false);
+ }
+
+ /**
+ *
+ * variable:
+ * base_variable_with_function_calls T_OBJECT_OPERATOR
+ * object_property method_or_not variable_properties
+ * | base_variable_with_function_calls
+ *
+ * @param lefthandside
+ * @param ignoreVar
+ * @return
+ */
+ private Expression variable (boolean lefthandside, boolean ignoreVar) {
+ Expression ref = base_variable_with_function_calls (lefthandside, ignoreVar);
+
+ if ((token == TokenName.MINUS_GREATER) ||
+ (token == TokenName.PAAMAYIM_NEKUDOTAYIM)) {
+/* I don't know why ref was set to null, but if it is null, the variable will neither be added to the set of variable,
+ * nor would it be checked for beeing unitialized. So I don't set it to null!
+ */
+// ref = null;
+ getNextToken();
+ object_property();
+ method_or_not();
+ variable_properties();
+ }
+
+ return ref;
+ }
+
+ private void variable_properties() {
+ // variable_properties:
+ // variable_properties variable_property
+ // | /* empty */
+ while (token == TokenName.MINUS_GREATER) {
+ variable_property();
+ }
+ }
+
+ private void variable_property() {
+ // variable_property:
+ // T_OBJECT_OPERATOR object_property method_or_not
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: variable_property()");
+ }
+
+ if (token == TokenName.MINUS_GREATER) {
+ getNextToken();
+ object_property();
+ method_or_not();
+ }
+ else {
+ throwSyntaxError("'->' expected in variable_property.");
+ }
+ }
+
+ /**
+ *
+ * variable:
+ * base_variable_with_function_calls T_OBJECT_OPERATOR
+ * object_property method_or_not variable_properties
+ * | base_variable_with_function_calls
+ *
+ * Expression ref = function_call(lefthandside, ignoreVar);
+ *
+ * function_call:
+ * T_STRING '(' function_call_parameter_list ')'
+ * | class_constant '(' function_call_parameter_list ')'
+ * | static_member '(' function_call_parameter_list ')'
+ * | variable_without_objects '(' function_call_parameter_list ')'
+ *
+ * @param lefthandside
+ * @param ignoreVar
+ *
+ * @return
+ */
+ private Expression identifier (boolean lefthandside, boolean ignoreVar, boolean bColonAllowed) {
+ char[] defineName = null;
+ char[] ident = null;
+ int startPos = 0;
+ int endPos = 0;
+ Expression ref = null;
+
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: function_call()");
+ }
+
+ if (token == TokenName.IDENTIFIER) {
+ ident = scanner.getCurrentIdentifierSource();
+ defineName = ident;
+ startPos = scanner.getCurrentTokenStartPosition();
+ endPos = scanner.getCurrentTokenEndPosition();
+
+ getNextToken(); // Get the token after the identifier
+
+ switch (token) {
+ case EQUAL:
+ case PLUS_EQUAL:
+ case MINUS_EQUAL:
+ case MULTIPLY_EQUAL:
+ case DIVIDE_EQUAL:
+ case DOT_EQUAL:
+ case REMAINDER_EQUAL:
+ case AND_EQUAL:
+ case OR_EQUAL:
+ case XOR_EQUAL:
+ case RIGHT_SHIFT_EQUAL:
+ case LEFT_SHIFT_EQUAL:
+ String error = "Assignment operator '"
+ + scanner.toStringAction(token)
+ + "' not allowed after identifier '"
+ + new String(ident)
+ + "' (use 'define(...)' to define constants).";
+ reportSyntaxError(error);
+ break;
+ }
+
+ if (token == TokenName.COLON) { // If it's a ':', the identifier is a label
+ return ref;
+ }
+
+ do {
+ if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) { // '::'
+ defineName = null;
+
+ getNextToken (); // Read the identifier
+
+ if (token == TokenName.IDENTIFIER) { // class _constant
+ getNextToken ();
+ }
+ else { // static member:
+ variable_without_objects (true, false);
+ }
+ break;
+ }
+ else if (token == TokenName.BACKSLASH) { // '\' namespace path separator
+ getNextToken ();
+
+ if (token == TokenName.IDENTIFIER) { // If it's an identifier
+ getNextToken (); // go for the next token
+ }
+ else { // It's not an identifiere, something wrong
+ throwSyntaxError ("an identifier expected after '\\' ");
+ }
+ }
+ else {
+ break;
+ }
+ } while (true);
+ }
+ else { // Token is not an identifier
+ ref = variable_without_objects(lefthandside, ignoreVar);
+ }
+
+ if (token == TokenName.LPAREN) { // If token is '('
+ getNextToken();
+
+ if (token == TokenName.RPAREN) { // If token is ')'
+ getNextToken();
+ ref = null;
}
- } else {
- expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
- }
- } else {
- expressionStack[expressionPtr] =
- new BinaryExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
- }
- }
- }
- }
- protected void consumeBlock() {
- // Block ::= OpenBlock '{' BlockStatementsopt '}'
- // simpler action for empty blocks
-
- int length;
- if ((length = astLengthStack[astLengthPtr--]) == 0) { // empty block
- pushOnAstStack(Block.EmptyWith(intStack[intPtr--], endStatementPosition));
- realBlockPtr--; // still need to pop the block variable counter
- } else {
- Block bk = new Block(realBlockStack[realBlockPtr--]);
- astPtr -= length;
- System.arraycopy(astStack, astPtr + 1, bk.statements = new Statement[length], 0, length);
- pushOnAstStack(bk);
- bk.sourceStart = intStack[intPtr--];
- bk.sourceEnd = endStatementPosition;
- }
- }
- protected void consumeBlockStatements() {
- // BlockStatements ::= BlockStatements BlockStatement
- concatNodeLists();
- }
- protected void consumeCaseLabel() {
- // SwitchLabel ::= 'case' ConstantExpression ':'
- expressionLengthPtr--;
- pushOnAstStack(new Case(intStack[intPtr--], expressionStack[expressionPtr--]));
- }
- protected void consumeCastExpression() {
- // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
- // CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
-
- //intStack : posOfLeftParen dim posOfRightParen
-
- //optimize the push/pop
-
- Expression exp, cast, castType;
- int end = intStack[intPtr--];
- expressionStack[expressionPtr] =
- cast = new CastExpression(exp = expressionStack[expressionPtr], castType = getTypeReference(intStack[intPtr--]));
- castType.sourceEnd = end - 1;
- castType.sourceStart = (cast.sourceStart = intStack[intPtr--]) + 1;
- cast.sourceEnd = exp.sourceEnd;
- }
- protected void consumeCastExpressionLL1() {
- //CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus
- // Expression is used in order to make the grammar LL1
-
- //optimize push/pop
-
- Expression castType, cast, exp;
- expressionPtr--;
- expressionStack[expressionPtr] =
- cast =
- new CastExpression(exp = expressionStack[expressionPtr + 1], castType = getTypeReference(expressionStack[expressionPtr]));
- expressionLengthPtr--;
- updateSourcePosition(castType);
- cast.sourceStart = castType.sourceStart;
- cast.sourceEnd = exp.sourceEnd;
- castType.sourceStart++;
- castType.sourceEnd--;
- }
- protected void consumeCatches() {
- // Catches ::= Catches CatchClause
- optimizedConcatNodeLists();
- }
- protected void consumeCatchHeader() {
- // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
-
- if (currentElement == null) {
- return; // should never occur, this consumeRule is only used in recovery mode
- }
- // current element should be a block due to the presence of the opening brace
- if (!(currentElement instanceof RecoveredBlock)) {
- return;
- }
- // exception argument is already on astStack
- ((RecoveredBlock) currentElement).attach(new RecoveredLocalVariable((Argument) astStack[astPtr--], currentElement, 0));
- // insert catch variable in catch block
- lastCheckPoint = scanner.startPosition; // force to restart at this exact position
- restartRecovery = true; // request to restart from here on
- lastIgnoredToken = -1;
- }
- protected void consumeClassBodyDeclaration() {
- // ClassBodyDeclaration ::= Diet Block
- //push an Initializer
- //optimize the push/pop
- nestedMethod[nestedType]--;
- Initializer initializer = new Initializer((Block) astStack[astPtr], 0);
- intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
- realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
- int javadocCommentStart = intStack[intPtr--];
- if (javadocCommentStart != -1) {
- initializer.declarationSourceStart = javadocCommentStart;
- }
- astStack[astPtr] = initializer;
- initializer.sourceEnd = endStatementPosition;
- initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- }
- protected void consumeClassBodyDeclarations() {
- // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
- concatNodeLists();
- }
- protected void consumeClassBodyDeclarationsopt() {
- // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
- nestedType--;
- }
- protected void consumeClassBodyopt() {
- // ClassBodyopt ::= $empty
- pushOnAstStack(null);
- endPosition = scanner.startPosition - 1;
- }
- protected void consumeClassDeclaration() {
- // ClassDeclaration ::= ClassHeader ClassBody
-
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- //there are length declarations
- //dispatch according to the type of the declarations
- dispatchDeclarationInto(length);
- }
-
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
-
- // mark fields and initializer with local type mark if needed
- markFieldsWithLocalType(typeDecl);
-
- //convert constructor that do not have the type's name into methods
- boolean hasConstructor = typeDecl.checkConstructors(this);
-
- //add the default constructor when needed (interface don't have it)
- if (!hasConstructor) {
- boolean insideFieldInitializer = false;
- if (diet) {
- for (int i = nestedType; i > 0; i--) {
- if (variablesCounter[i] > 0) {
- insideFieldInitializer = true;
- break;
- }
- }
- }
- typeDecl.createsInternalConstructor(!diet || insideFieldInitializer, true);
- }
-
- //always add <clinit> (will be remove at code gen time if empty)
- if (this.scanner.containsAssertKeyword) {
- typeDecl.bits |= AstNode.AddAssertionMASK;
- }
- typeDecl.addClinit();
- typeDecl.bodyEnd = endStatementPosition;
- typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- }
- protected void consumeClassHeader() {
- // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
-
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- if (currentToken == TokenNameLBRACE) {
- typeDecl.bodyStart = scanner.currentPosition;
- }
- if (currentElement != null) {
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- // flush the comments related to the class header
- scanner.commentPtr = -1;
- }
- protected void consumeClassHeaderExtends() {
- // ClassHeaderExtends ::= 'extends' ClassType
- // There is a class declaration on the top of stack
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- //superclass
- typeDecl.superclass = getTypeReference(0);
- typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
- // recovery
- if (currentElement != null) {
- lastCheckPoint = typeDecl.bodyStart;
- }
- }
- protected void consumeClassHeaderImplements() {
- // ClassHeaderImplements ::= 'implements' InterfaceTypeList
- int length = astLengthStack[astLengthPtr--];
- //super interfaces
- astPtr -= length;
- // There is a class declaration on the top of stack
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- System.arraycopy(astStack, astPtr + 1, typeDecl.superInterfaces = new TypeReference[length], 0, length);
- typeDecl.bodyStart = typeDecl.superInterfaces[length - 1].sourceEnd + 1;
- listLength = 0; // reset after having read super-interfaces
- // recovery
- if (currentElement != null) { // is recovering
- lastCheckPoint = typeDecl.bodyStart;
- }
- }
- protected void consumeClassHeaderName() {
- // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
- TypeDeclaration typeDecl;
- if (nestedMethod[nestedType] == 0) {
- if (nestedType != 0) {
- typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
- } else {
- typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
- }
- } else {
- // Record that the block has a declaration for local types
- typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
- markCurrentMethodWithLocalType();
- blockReal();
- }
-
- //highlight the name of the type
- long pos = identifierPositionStack[identifierPtr];
- typeDecl.sourceEnd = (int) pos;
- typeDecl.sourceStart = (int) (pos >>> 32);
- typeDecl.name = identifierStack[identifierPtr--];
- identifierLengthPtr--;
-
- //compute the declaration source too
- // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
- // we want to keep the beginning position but get rid of the end position
- // it is only used for the ClassLiteralAccess positions.
- typeDecl.declarationSourceStart = intStack[intPtr--];
- intPtr--; // remove the end position of the class token
-
- typeDecl.modifiersSourceStart = intStack[intPtr--];
- typeDecl.modifiers = intStack[intPtr--];
- if (typeDecl.modifiersSourceStart >= 0) {
- typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
- }
- typeDecl.bodyStart = typeDecl.sourceEnd + 1;
- pushOnAstStack(typeDecl);
-
- listLength = 0; // will be updated when reading super-interfaces
- // recovery
- if (currentElement != null) {
- lastCheckPoint = typeDecl.bodyStart;
- currentElement = currentElement.add(typeDecl, 0);
- lastIgnoredToken = -1;
- }
- }
- protected void consumeClassInstanceCreationExpression() {
- // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
- classInstanceCreation(false);
- }
- protected void consumeClassInstanceCreationExpressionName() {
- // ClassInstanceCreationExpressionName ::= Name '.'
- pushOnExpressionStack(getUnspecifiedReferenceOptimized());
- }
- protected void consumeClassInstanceCreationExpressionQualified() {
- // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
- // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
-
- classInstanceCreation(true); // <-- push the Qualifed....
-
- expressionLengthPtr--;
- QualifiedAllocationExpression qae = (QualifiedAllocationExpression) expressionStack[expressionPtr--];
- qae.enclosingInstance = expressionStack[expressionPtr];
- expressionStack[expressionPtr] = qae;
- qae.sourceStart = qae.enclosingInstance.sourceStart;
- }
- protected void consumeClassTypeElt() {
- // ClassTypeElt ::= ClassType
- pushOnAstStack(getTypeReference(0));
- /* if incomplete thrown exception list, listLength counter will not have been reset,
- indicating that some items are available on the stack */
- listLength++;
- }
- protected void consumeClassTypeList() {
- // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
- optimizedConcatNodeLists();
- }
- protected void consumeCompilationUnit() {
- // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
- // do nothing by default
- }
- protected void consumeConditionalExpression(int op) {
- // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
- //optimize the push/pop
-
- expressionPtr -= 2;
- expressionLengthPtr -= 2;
- expressionStack[expressionPtr] =
- new ConditionalExpression(
- expressionStack[expressionPtr],
- expressionStack[expressionPtr + 1],
- expressionStack[expressionPtr + 2]);
- }
- protected void consumeConstructorBlockStatements() {
- // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
- concatNodeLists(); // explictly add the first statement into the list of statements
- }
- protected void consumeConstructorBody() {
- // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}'
- // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}'
- nestedMethod[nestedType]--;
- }
- protected void consumeConstructorDeclaration() {
- // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
-
- /*
- astStack : MethodDeclaration statements
- identifierStack : name
- ==>
- astStack : MethodDeclaration
- identifierStack :
- */
-
- //must provide a default constructor call when needed
-
- int length;
-
- // pop the position of the { (body of the method) pushed in block decl
- intPtr--;
-
- //statements
- realBlockPtr--;
- ExplicitConstructorCall constructorCall = null;
- Statement[] statements = null;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- astPtr -= length;
- if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) {
- //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
- System.arraycopy(astStack, astPtr + 2, statements = new Statement[length - 1], 0, length - 1);
- constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
- } else { //need to add explicitly the super();
- System.arraycopy(astStack, astPtr + 1, statements = new Statement[length], 0, length);
- constructorCall = SuperReference.implicitSuperConstructorCall();
- }
- } else {
- if (!diet) {
- // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
- constructorCall = SuperReference.implicitSuperConstructorCall();
- }
- }
-
- // now we know that the top of stack is a constructorDeclaration
- ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
- cd.constructorCall = constructorCall;
- cd.statements = statements;
-
- //highlight of the implicit call on the method name
- if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
- cd.constructorCall.sourceEnd = cd.sourceEnd;
- cd.constructorCall.sourceStart = cd.sourceStart;
- }
-
- //watch for } that could be given as a unicode ! ( u007D is '}' )
- // store the endPosition (position just before the '}') in case there is
- // a trailing comment behind the end of the method
- cd.bodyEnd = endPosition;
- cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- }
-
- protected void consumeInvalidConstructorDeclaration() {
- // ConstructorDeclaration ::= ConstructorHeader ';'
- // now we know that the top of stack is a constructorDeclaration
- ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
-
- cd.bodyEnd = endPosition; // position just before the trailing semi-colon
- cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- // report the problem and continue the parsing - narrowing the problem onto the method
- }
- protected void consumeConstructorHeader() {
- // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
-
- AbstractMethodDeclaration method = (AbstractMethodDeclaration) astStack[astPtr];
-
- if (currentToken == TokenNameLBRACE) {
- method.bodyStart = scanner.currentPosition;
- }
- // recovery
- if (currentElement != null) {
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- }
- protected void consumeConstructorHeaderName() {
-
- /* recovering - might be an empty message send */
- if (currentElement != null) {
- if (lastIgnoredToken == TokenNamenew) { // was an allocation expression
- lastCheckPoint = scanner.startPosition; // force to restart at this exact position
- restartRecovery = true;
- return;
- }
- }
-
- // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
- ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
-
- //name -- this is not really revelant but we do .....
- cd.selector = identifierStack[identifierPtr];
- long selectorSource = identifierPositionStack[identifierPtr--];
- identifierLengthPtr--;
-
- //modifiers
- cd.declarationSourceStart = intStack[intPtr--];
- cd.modifiers = intStack[intPtr--];
-
- //highlight starts at the selector starts
- cd.sourceStart = (int) (selectorSource >>> 32);
- pushOnAstStack(cd);
- cd.sourceEnd = lParenPos;
- cd.bodyStart = lParenPos + 1;
- listLength = 0; // initialize listLength before reading parameters/throws
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = cd.bodyStart;
- if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT) || cd.modifiers != 0) {
- currentElement = currentElement.add(cd, 0);
- lastIgnoredToken = -1;
- }
- }
- }
- protected void consumeDefaultLabel() {
- // SwitchLabel ::= 'default' ':'
- pushOnAstStack(new DefaultCase(intStack[intPtr--], intStack[intPtr--]));
- }
- protected void consumeDefaultModifiers() {
- checkAnnotation(); // might update modifiers with AccDeprecated
- pushOnIntStack(modifiers); // modifiers
- pushOnIntStack(modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
- resetModifiers();
- }
- protected void consumeDiet() {
- // Diet ::= $empty
- checkAnnotation();
- pushOnIntStack(modifiersSourceStart); // push the start position of a javadoc comment if there is one
- jumpOverMethodBody();
- }
- protected void consumeDims() {
- // Dims ::= DimsLoop
- pushOnIntStack(dimensions);
- dimensions = 0;
- }
- protected void consumeDimWithOrWithOutExpr() {
- // DimWithOrWithOutExpr ::= '[' ']'
- pushOnExpressionStack(null);
- }
- protected void consumeDimWithOrWithOutExprs() {
- // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
- concatExpressionLists();
- }
- protected void consumeEmptyArgumentListopt() {
- // ArgumentListopt ::= $empty
- pushOnExpressionStackLengthStack(0);
- }
- protected void consumeEmptyArrayInitializer() {
- // ArrayInitializer ::= '{' ,opt '}'
- arrayInitializer(0);
- }
- protected void consumeEmptyArrayInitializeropt() {
- // ArrayInitializeropt ::= $empty
- pushOnExpressionStackLengthStack(0);
- }
- protected void consumeEmptyBlockStatementsopt() {
- // BlockStatementsopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyCatchesopt() {
- // Catchesopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyClassBodyDeclarationsopt() {
- // ClassBodyDeclarationsopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyClassMemberDeclaration() {
- // ClassMemberDeclaration ::= ';'
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyDimsopt() {
- // Dimsopt ::= $empty
- pushOnIntStack(0);
- }
- protected void consumeEmptyExpression() {
- // Expressionopt ::= $empty
- pushOnExpressionStackLengthStack(0);
- }
- protected void consumeEmptyForInitopt() {
- // ForInitopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyForUpdateopt() {
- // ForUpdateopt ::= $empty
- pushOnExpressionStackLengthStack(0);
- }
- protected void consumeEmptyImportDeclarationsopt() {
- // ImportDeclarationsopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyInterfaceMemberDeclaration() {
- // InterfaceMemberDeclaration ::= ';'
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyInterfaceMemberDeclarationsopt() {
- // InterfaceMemberDeclarationsopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyStatement() {
- // EmptyStatement ::= ';'
- if (this.scanner.source[endStatementPosition] == ';') {
- pushOnAstStack(new EmptyStatement(endStatementPosition, endStatementPosition));
- } else {
- // we have a Unicode for the ';' (/u003B)
- pushOnAstStack(new EmptyStatement(endStatementPosition - 5, endStatementPosition));
- }
- }
- protected void consumeEmptySwitchBlock() {
- // SwitchBlock ::= '{' '}'
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyTypeDeclaration() {
- // TypeDeclaration ::= ';'
- pushOnAstLengthStack(0);
- }
- protected void consumeEmptyTypeDeclarationsopt() {
- // TypeDeclarationsopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeEnterAnonymousClassBody() {
- // EnterAnonymousClassBody ::= $empty
- QualifiedAllocationExpression alloc;
- AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
- alloc = anonymousType.allocation = new QualifiedAllocationExpression(anonymousType);
- markCurrentMethodWithLocalType();
- pushOnAstStack(anonymousType);
-
- alloc.sourceEnd = rParenPos; //the position has been stored explicitly
- int argumentLength;
- if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) {
- expressionPtr -= argumentLength;
- System.arraycopy(expressionStack, expressionPtr + 1, alloc.arguments = new Expression[argumentLength], 0, argumentLength);
- }
- alloc.type = getTypeReference(0);
-
- anonymousType.sourceEnd = alloc.sourceEnd;
- //position at the type while it impacts the anonymous declaration
- anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
- alloc.sourceStart = intStack[intPtr--];
- pushOnExpressionStack(alloc);
-
- anonymousType.bodyStart = scanner.currentPosition;
- listLength = 0; // will be updated when reading super-interfaces
- // recovery
- if (currentElement != null) {
- lastCheckPoint = anonymousType.bodyStart;
- // the recoveryTokenCheck will deal with the open brace
- currentElement = currentElement.add(anonymousType, 0);
- currentToken = 0; // opening brace already taken into account
- lastIgnoredToken = -1;
- }
- }
- protected void consumeEnterCompilationUnit() {
- // EnterCompilationUnit ::= $empty
- // do nothing by default
- }
- protected void consumeEnterVariable() {
- // EnterVariable ::= $empty
- // do nothing by default
-
- char[] name = identifierStack[identifierPtr];
- long namePosition = identifierPositionStack[identifierPtr];
- int extendedDimension = intStack[intPtr--];
- AbstractVariableDeclaration declaration;
- // create the ast node
- boolean isLocalDeclaration = nestedMethod[nestedType] != 0;
- if (isLocalDeclaration) {
- // create the local variable declarations
- declaration = this.createLocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
- } else {
- // create the field declaration
- declaration = this.createFieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
- }
-
- identifierPtr--;
- identifierLengthPtr--;
- TypeReference type;
- int variableIndex = variablesCounter[nestedType];
- int typeDim = 0;
- if (variableIndex == 0) {
- // first variable of the declaration (FieldDeclaration or LocalDeclaration)
- if (isLocalDeclaration) {
- declaration.declarationSourceStart = intStack[intPtr--];
- declaration.modifiers = intStack[intPtr--];
- type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
- if (declaration.declarationSourceStart == -1) {
- // this is true if there is no modifiers for the local variable declaration
- declaration.declarationSourceStart = type.sourceStart;
- }
- pushOnAstStack(type);
- } else {
- type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
- pushOnAstStack(type);
- declaration.declarationSourceStart = intStack[intPtr--];
- declaration.modifiers = intStack[intPtr--];
- }
- } else {
- type = (TypeReference) astStack[astPtr - variableIndex];
- typeDim = type.dimensions();
- AbstractVariableDeclaration previousVariable = (AbstractVariableDeclaration) astStack[astPtr];
- declaration.declarationSourceStart = previousVariable.declarationSourceStart;
- declaration.modifiers = previousVariable.modifiers;
- }
-
- if (extendedDimension == 0) {
- declaration.type = type;
- } else {
- int dimension = typeDim + extendedDimension;
- //on the identifierLengthStack there is the information about the type....
- int baseType;
- if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
- //it was a baseType
- int typeSourceStart = type.sourceStart;
- int typeSourceEnd = type.sourceEnd;
- type = TypeReference.baseTypeReference(-baseType, dimension);
- type.sourceStart = typeSourceStart;
- type.sourceEnd = typeSourceEnd;
- declaration.type = type;
- } else {
- declaration.type = this.copyDims(type, dimension);
- }
- }
- variablesCounter[nestedType]++;
- pushOnAstStack(declaration);
- // recovery
- if (currentElement != null) {
- if (!(currentElement instanceof RecoveredType)
- && (currentToken == TokenNameDOT //|| declaration.modifiers != 0
- || (scanner.getLineNumber(declaration.type.sourceStart) != scanner.getLineNumber((int) (namePosition >>> 32))))) {
- lastCheckPoint = (int) (namePosition >>> 32);
- restartRecovery = true;
- return;
- }
- if (isLocalDeclaration) {
- LocalDeclaration localDecl = (LocalDeclaration) astStack[astPtr];
- lastCheckPoint = localDecl.sourceEnd + 1;
- currentElement = currentElement.add(localDecl, 0);
- } else {
- FieldDeclaration fieldDecl = (FieldDeclaration) astStack[astPtr];
- lastCheckPoint = fieldDecl.sourceEnd + 1;
- currentElement = currentElement.add(fieldDecl, 0);
- }
- lastIgnoredToken = -1;
- }
- }
- protected void consumeEqualityExpression(int op) {
- // EqualityExpression ::= EqualityExpression '==' RelationalExpression
- // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
-
- //optimize the push/pop
-
- expressionPtr--;
- expressionLengthPtr--;
- expressionStack[expressionPtr] = new EqualExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
- }
- protected void consumeExitVariableWithInitialization() {
- // ExitVariableWithInitialization ::= $empty
- // do nothing by default
- expressionLengthPtr--;
- AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) astStack[astPtr];
- variableDecl.initialization = expressionStack[expressionPtr--];
- // we need to update the declarationSourceEnd of the local variable declaration to the
- // source end position of the initialization expression
- variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
- variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
- }
- protected void consumeExitVariableWithoutInitialization() {
- // ExitVariableWithoutInitialization ::= $empty
- // do nothing by default
- }
- protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
-
- /* flag allows to distinguish 3 cases :
- (0) :
- ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
- ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
- (1) :
- ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
- ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
- (2) :
- ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
- ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
- */
- int startPosition = intStack[intPtr--];
- ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
- int length;
- if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
- }
- switch (flag) {
- case 0 :
- ecc.sourceStart = startPosition;
- break;
- case 1 :
- expressionLengthPtr--;
- ecc.sourceStart = (ecc.qualification = expressionStack[expressionPtr--]).sourceStart;
- break;
- case 2 :
- ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
- break;
- };
- pushOnAstStack(ecc);
- ecc.sourceEnd = endPosition;
- }
- protected void consumeExpressionStatement() {
- // ExpressionStatement ::= StatementExpression ';'
- expressionLengthPtr--;
- pushOnAstStack(expressionStack[expressionPtr--]);
- }
- protected void consumeFieldAccess(boolean isSuperAccess) {
- // FieldAccess ::= Primary '.' 'Identifier'
- // FieldAccess ::= 'super' '.' 'Identifier'
-
- FieldReference fr = new FieldReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
- identifierLengthPtr--;
- if (isSuperAccess) {
- //considerates the fieldReference beginning at the 'super' ....
- fr.sourceStart = intStack[intPtr--];
- fr.receiver = new SuperReference(fr.sourceStart, endPosition);
- pushOnExpressionStack(fr);
- } else {
- //optimize push/pop
- if ((fr.receiver = expressionStack[expressionPtr]).isThis()) {
- //fieldreference begins at the this
- fr.sourceStart = fr.receiver.sourceStart;
- }
- expressionStack[expressionPtr] = fr;
- }
- }
- protected void consumeFieldDeclaration() {
- // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
- // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
-
- /*
- astStack :
- expressionStack: Expression Expression ...... Expression
- identifierStack : type identifier identifier ...... identifier
- intStack : typeDim dim dim dim
- ==>
- astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
- expressionStack :
- identifierStack :
- intStack :
-
- */
- int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
-
- for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
- FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
- fieldDeclaration.declarationSourceEnd = endStatementPosition;
- fieldDeclaration.declarationEnd = endStatementPosition; // semi-colon included
- }
- updateSourceDeclarationParts(variableDeclaratorsCounter);
- int endPos = flushAnnotationsDefinedPriorTo(endStatementPosition);
- if (endPos != endStatementPosition) {
- for (int i = 0; i < variableDeclaratorsCounter; i++) {
- FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
- fieldDeclaration.declarationSourceEnd = endPos;
- }
- }
- // update the astStack, astPtr and astLengthStack
- int startIndex = astPtr - variablesCounter[nestedType] + 1;
- System.arraycopy(astStack, startIndex, astStack, startIndex - 1, variableDeclaratorsCounter);
- astPtr--; // remove the type reference
- astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = endPos + 1;
- if (currentElement.parent != null && currentElement instanceof RecoveredField) {
- currentElement = currentElement.parent;
- }
- restartRecovery = true;
- }
- variablesCounter[nestedType] = 0;
- }
- protected void consumeForceNoDiet() {
- // ForceNoDiet ::= $empty
- dietInt++;
- }
- protected void consumeForInit() {
- // ForInit ::= StatementExpressionList
- pushOnAstLengthStack(-1);
- }
- protected void consumeFormalParameter() {
- // FormalParameter ::= Type VariableDeclaratorId ==> false
- // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
- /*
- astStack :
- identifierStack : type identifier
- intStack : dim dim
- ==>
- astStack : Argument
- identifierStack :
- intStack :
- */
-
- identifierLengthPtr--;
- char[] name = identifierStack[identifierPtr];
- long namePositions = identifierPositionStack[identifierPtr--];
- TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
- int modifierPositions = intStack[intPtr--];
- intPtr--;
- Argument arg = new Argument(name, namePositions, type, intStack[intPtr + 1] & ~AccDeprecated); // modifiers
- arg.declarationSourceStart = modifierPositions;
- pushOnAstStack(arg);
-
- /* if incomplete method header, listLength counter will not have been reset,
- indicating that some arguments are available on the stack */
- listLength++;
- }
- protected void consumeFormalParameterList() {
- // FormalParameterList ::= FormalParameterList ',' FormalParameter
- optimizedConcatNodeLists();
- }
- protected void consumeFormalParameterListopt() {
- // FormalParameterListopt ::= $empty
- pushOnAstLengthStack(0);
- }
- protected void consumeImportDeclarations() {
- // ImportDeclarations ::= ImportDeclarations ImportDeclaration
- optimizedConcatNodeLists();
- }
- protected void consumeImportDeclarationsopt() {
- // ImportDeclarationsopt ::= ImportDeclarations
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- astPtr -= length;
- System.arraycopy(astStack, astPtr + 1, compilationUnit.imports = new ImportReference[length], 0, length);
- }
- }
- protected void consumeInstanceOfExpression(int op) {
- // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
- //optimize the push/pop
-
- //by construction, no base type may be used in getTypeReference
- Expression exp;
- expressionStack[expressionPtr] =
- exp = new InstanceOfExpression(expressionStack[expressionPtr], getTypeReference(intStack[intPtr--]), op);
- if (exp.sourceEnd == 0) {
- //array on base type....
- exp.sourceEnd = scanner.startPosition - 1;
- }
- //the scanner is on the next token already....
- }
- protected void consumeInterfaceDeclaration() {
- // see consumeClassDeclaration in case of changes: duplicated code
- // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- //there are length declarations
- //dispatch.....according to the type of the declarations
- dispatchDeclarationInto(length);
- }
-
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
-
- // mark fields and initializer with local type mark if needed
- markFieldsWithLocalType(typeDecl);
-
- //convert constructor that do not have the type's name into methods
- typeDecl.checkConstructors(this);
-
- //always add <clinit> (will be remove at code gen time if empty)
- if (this.scanner.containsAssertKeyword) {
- typeDecl.bits |= AstNode.AddAssertionMASK;
- }
- typeDecl.addClinit();
- typeDecl.bodyEnd = endStatementPosition;
- typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- }
- protected void consumeInterfaceHeader() {
- // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
-
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- if (currentToken == TokenNameLBRACE) {
- typeDecl.bodyStart = scanner.currentPosition;
- }
- if (currentElement != null) {
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- // flush the comments related to the interface header
- scanner.commentPtr = -1;
- }
- protected void consumeInterfaceHeaderExtends() {
- // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
- int length = astLengthStack[astLengthPtr--];
- //super interfaces
- astPtr -= length;
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- System.arraycopy(astStack, astPtr + 1, typeDecl.superInterfaces = new TypeReference[length], 0, length);
- typeDecl.bodyStart = typeDecl.superInterfaces[length - 1].sourceEnd + 1;
- listLength = 0; // reset after having read super-interfaces
- // recovery
- if (currentElement != null) {
- lastCheckPoint = typeDecl.bodyStart;
- }
- }
- protected void consumeInterfaceHeaderName() {
- // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
- TypeDeclaration typeDecl;
- if (nestedMethod[nestedType] == 0) {
- if (nestedType != 0) {
- typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
- } else {
- typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
- }
- } else {
- // Record that the block has a declaration for local types
- typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
- markCurrentMethodWithLocalType();
- blockReal();
- }
-
- //highlight the name of the type
- long pos = identifierPositionStack[identifierPtr];
- typeDecl.sourceEnd = (int) pos;
- typeDecl.sourceStart = (int) (pos >>> 32);
- typeDecl.name = identifierStack[identifierPtr--];
- identifierLengthPtr--;
-
- //compute the declaration source too
- // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
- // we want to keep the beginning position but get rid of the end position
- // it is only used for the ClassLiteralAccess positions.
- typeDecl.declarationSourceStart = intStack[intPtr--];
- intPtr--; // remove the end position of the class token
- typeDecl.modifiersSourceStart = intStack[intPtr--];
- typeDecl.modifiers = intStack[intPtr--];
- if (typeDecl.modifiersSourceStart >= 0) {
- typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
- }
- typeDecl.bodyStart = typeDecl.sourceEnd + 1;
- pushOnAstStack(typeDecl);
- listLength = 0; // will be updated when reading super-interfaces
- // recovery
- if (currentElement != null) { // is recovering
- lastCheckPoint = typeDecl.bodyStart;
- currentElement = currentElement.add(typeDecl, 0);
- lastIgnoredToken = -1;
- }
- }
- protected void consumeInterfaceMemberDeclarations() {
- // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
- concatNodeLists();
- }
- protected void consumeInterfaceMemberDeclarationsopt() {
- // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
- nestedType--;
- }
- protected void consumeInterfaceType() {
- // InterfaceType ::= ClassOrInterfaceType
- pushOnAstStack(getTypeReference(0));
- /* if incomplete type header, listLength counter will not have been reset,
- indicating that some interfaces are available on the stack */
- listLength++;
- }
- protected void consumeInterfaceTypeList() {
- // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
- optimizedConcatNodeLists();
- }
- protected void consumeLeftHandSide() {
- // LeftHandSide ::= Name
-
- pushOnExpressionStack(getUnspecifiedReferenceOptimized());
- }
- protected void consumeLeftParen() {
- // PushLPAREN ::= '('
- pushOnIntStack(lParenPos);
- }
- protected void consumeLocalVariableDeclaration() {
- // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
-
- /*
- astStack :
- expressionStack: Expression Expression ...... Expression
- identifierStack : type identifier identifier ...... identifier
- intStack : typeDim dim dim dim
- ==>
- astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
- expressionStack :
- identifierStack :
- intStack :
-
- */
- int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
-
- // update the astStack, astPtr and astLengthStack
- int startIndex = astPtr - variablesCounter[nestedType] + 1;
- System.arraycopy(astStack, startIndex, astStack, startIndex - 1, variableDeclaratorsCounter);
- astPtr--; // remove the type reference
- astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
- variablesCounter[nestedType] = 0;
- }
- protected void consumeLocalVariableDeclarationStatement() {
- // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
- // see blockReal in case of change: duplicated code
- // increment the amount of declared variables for this block
- realBlockStack[realBlockPtr]++;
- }
- protected void consumeMethodBody() {
- // MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
- nestedMethod[nestedType]--;
- }
- protected void consumeMethodDeclaration(boolean isNotAbstract) {
- // MethodDeclaration ::= MethodHeader MethodBody
- // AbstractMethodDeclaration ::= MethodHeader ';'
-
- /*
- astStack : modifiers arguments throws statements
- identifierStack : type name
- intStack : dim dim dim
- ==>
- astStack : MethodDeclaration
- identifierStack :
- intStack :
- */
-
- int length;
- if (isNotAbstract) {
- // pop the position of the { (body of the method) pushed in block decl
- intPtr--;
- }
-
- int explicitDeclarations = 0;
- Statement[] statements = null;
- if (isNotAbstract) {
- //statements
- explicitDeclarations = realBlockStack[realBlockPtr--];
- if ((length = astLengthStack[astLengthPtr--]) != 0)
- System.arraycopy(astStack, (astPtr -= length) + 1, statements = new Statement[length], 0, length);
- }
-
- // now we know that we have a method declaration at the top of the ast stack
- MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
- md.statements = statements;
- md.explicitDeclarations = explicitDeclarations;
-
- // cannot be done in consumeMethodHeader because we have no idea whether or not there
- // is a body when we reduce the method header
- if (!isNotAbstract) { //remember the fact that the method has a semicolon body
- md.modifiers |= AccSemicolonBody;
- }
- // store the endPosition (position just before the '}') in case there is
- // a trailing comment behind the end of the method
- md.bodyEnd = endPosition;
- md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- }
- protected void consumeMethodHeader() {
- // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
- // retrieve end position of method declarator
- AbstractMethodDeclaration method = (AbstractMethodDeclaration) astStack[astPtr];
-
- if (currentToken == TokenNameLBRACE) {
- method.bodyStart = scanner.currentPosition;
- }
- // recovery
- if (currentElement != null) {
- if (currentToken == TokenNameSEMICOLON) {
- method.modifiers |= AccSemicolonBody;
- method.declarationSourceEnd = scanner.currentPosition - 1;
- method.bodyEnd = scanner.currentPosition - 1;
- if (currentElement.parent != null) {
- currentElement = currentElement.parent;
- }
- }
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- }
- protected void consumeMethodHeaderExtendedDims() {
- // MethodHeaderExtendedDims ::= Dimsopt
- // now we update the returnType of the method
- MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
- int extendedDims = intStack[intPtr--];
- if (extendedDims != 0) {
- TypeReference returnType = md.returnType;
- md.sourceEnd = endPosition;
- int dims = returnType.dimensions() + extendedDims;
- int baseType;
- if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
- //it was a baseType
- int sourceStart = returnType.sourceStart;
- int sourceEnd = returnType.sourceEnd;
- returnType = TypeReference.baseTypeReference(-baseType, dims);
- returnType.sourceStart = sourceStart;
- returnType.sourceEnd = sourceEnd;
- md.returnType = returnType;
- } else {
- md.returnType = this.copyDims(md.returnType, dims);
- }
- if (currentToken == TokenNameLBRACE) {
- md.bodyStart = endPosition + 1;
- }
- // recovery
- if (currentElement != null) {
- lastCheckPoint = md.bodyStart;
- }
- }
- }
- protected void consumeMethodHeaderName() {
- // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
- MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
-
- //name
- md.selector = identifierStack[identifierPtr];
- long selectorSource = identifierPositionStack[identifierPtr--];
- identifierLengthPtr--;
- //type
- md.returnType = getTypeReference(intStack[intPtr--]);
- //modifiers
- md.declarationSourceStart = intStack[intPtr--];
- md.modifiers = intStack[intPtr--];
-
- //highlight starts at selector start
- md.sourceStart = (int) (selectorSource >>> 32);
- pushOnAstStack(md);
- md.sourceEnd = lParenPos;
- md.bodyStart = lParenPos + 1;
- listLength = 0; // initialize listLength before reading parameters/throws
-
- // recovery
- if (currentElement != null) {
- if (currentElement instanceof RecoveredType //|| md.modifiers != 0
- || (scanner.getLineNumber(md.returnType.sourceStart) == scanner.getLineNumber(md.sourceStart))) {
- lastCheckPoint = md.bodyStart;
- currentElement = currentElement.add(md, 0);
- lastIgnoredToken = -1;
- } else {
- lastCheckPoint = md.sourceStart;
- restartRecovery = true;
- }
- }
- }
- protected void consumeMethodHeaderParameters() {
- // MethodHeaderParameters ::= FormalParameterListopt ')'
- int length = astLengthStack[astLengthPtr--];
- astPtr -= length;
- AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
- md.sourceEnd = rParenPos;
- //arguments
- if (length != 0) {
- System.arraycopy(astStack, astPtr + 1, md.arguments = new Argument[length], 0, length);
- }
- md.bodyStart = rParenPos + 1;
- listLength = 0; // reset listLength after having read all parameters
- // recovery
- if (currentElement != null) {
- lastCheckPoint = md.bodyStart;
- if (currentElement.parseTree() == md)
- return;
-
- // might not have been attached yet - in some constructor scenarii
- if (md.isConstructor()) {
- if ((length != 0) || (currentToken == TokenNameLBRACE) // || (currentToken == TokenNamethrows)
- ) {
- currentElement = currentElement.add(md, 0);
- lastIgnoredToken = -1;
- }
- }
- }
- }
- protected void consumeMethodHeaderThrowsClause() {
- // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
- int length = astLengthStack[astLengthPtr--];
- astPtr -= length;
- AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
- System.arraycopy(astStack, astPtr + 1, md.thrownExceptions = new TypeReference[length], 0, length);
- md.sourceEnd = md.thrownExceptions[length - 1].sourceEnd;
- md.bodyStart = md.thrownExceptions[length - 1].sourceEnd + 1;
- listLength = 0; // reset listLength after having read all thrown exceptions
- // recovery
- if (currentElement != null) {
- lastCheckPoint = md.bodyStart;
- }
- }
- protected void consumeMethodInvocationName() {
- // MethodInvocation ::= Name '(' ArgumentListopt ')'
-
- // when the name is only an identifier...we have a message send to "this" (implicit)
-
- MessageSend m = newMessageSend();
- m.sourceEnd = rParenPos;
- m.sourceStart = (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
- m.selector = identifierStack[identifierPtr--];
- if (identifierLengthStack[identifierLengthPtr] == 1) {
- m.receiver = ThisReference.ThisImplicit;
- identifierLengthPtr--;
- } else {
- identifierLengthStack[identifierLengthPtr]--;
- m.receiver = getUnspecifiedReference();
- m.sourceStart = m.receiver.sourceStart;
- }
- pushOnExpressionStack(m);
- }
- protected void consumeMethodInvocationPrimary() {
- //optimize the push/pop
- //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
-
- MessageSend m = newMessageSend();
- m.sourceStart = (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
- m.selector = identifierStack[identifierPtr--];
- identifierLengthPtr--;
- m.receiver = expressionStack[expressionPtr];
- m.sourceStart = m.receiver.sourceStart;
- m.sourceEnd = rParenPos;
- expressionStack[expressionPtr] = m;
- }
- protected void consumeMethodInvocationSuper() {
- // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
-
- MessageSend m = newMessageSend();
- m.sourceStart = intStack[intPtr--];
- m.sourceEnd = rParenPos;
- m.nameSourcePosition = identifierPositionStack[identifierPtr];
- m.selector = identifierStack[identifierPtr--];
- identifierLengthPtr--;
- m.receiver = new SuperReference(m.sourceStart, endPosition);
- pushOnExpressionStack(m);
- }
- protected void consumeMethodPushModifiersHeaderName() {
- // MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
- // MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
- MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
-
- //name
- md.selector = identifierStack[identifierPtr];
- long selectorSource = identifierPositionStack[identifierPtr--];
- identifierLengthPtr--;
-
- //modifiers
- md.declarationSourceStart = intStack[intPtr--];
- md.modifiers = intStack[intPtr--];
-
- //type
- md.returnType = getTypeReference(intStack[intPtr--]);
-
- //highlight starts at selector start
- md.sourceStart = (int) (selectorSource >>> 32);
- pushOnAstStack(md);
- md.sourceEnd = lParenPos;
- md.bodyStart = lParenPos + 1;
- listLength = 0; // initialize listLength before reading parameters/throws
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = md.bodyStart;
- currentElement = currentElement.add(md, 0);
- lastIgnoredToken = -1;
- }
- }
- protected void consumeModifiers() {
- int savedModifiersSourceStart = modifiersSourceStart;
- checkAnnotation(); // might update modifiers with AccDeprecated
- pushOnIntStack(modifiers); // modifiers
- if (modifiersSourceStart >= savedModifiersSourceStart) {
- modifiersSourceStart = savedModifiersSourceStart;
- }
- pushOnIntStack(modifiersSourceStart);
- resetModifiers();
- }
- protected void consumeNestedMethod() {
- // NestedMethod ::= $empty
- jumpOverMethodBody();
- nestedMethod[nestedType]++;
- consumeOpenBlock();
- }
- protected void consumeNestedType() {
- // NestedType ::= $empty
- nestedType++;
- try {
- nestedMethod[nestedType] = 0;
- } catch (IndexOutOfBoundsException e) {
- //except in test's cases, it should never raise
- int oldL = nestedMethod.length;
- System.arraycopy(nestedMethod, 0, (nestedMethod = new int[oldL + 30]), 0, oldL);
- nestedMethod[nestedType] = 0;
- // increase the size of the fieldsCounter as well. It has to be consistent with the size of the nestedMethod collection
- System.arraycopy(variablesCounter, 0, (variablesCounter = new int[oldL + 30]), 0, oldL);
- }
- variablesCounter[nestedType] = 0;
- }
- protected void consumeOneDimLoop() {
- // OneDimLoop ::= '[' ']'
- dimensions++;
- }
- protected void consumeOnlySynchronized() {
- // OnlySynchronized ::= 'synchronized'
- pushOnIntStack(this.synchronizedBlockSourceStart);
- resetModifiers();
- }
- protected void consumeOpenBlock() {
- // OpenBlock ::= $empty
-
- pushOnIntStack(scanner.startPosition);
- try {
- realBlockStack[++realBlockPtr] = 0;
- } catch (IndexOutOfBoundsException e) {
- //realBlockPtr is correct
- int oldStackLength = realBlockStack.length;
- int oldStack[] = realBlockStack;
- realBlockStack = new int[oldStackLength + StackIncrement];
- System.arraycopy(oldStack, 0, realBlockStack, 0, oldStackLength);
- realBlockStack[realBlockPtr] = 0;
- }
- }
- protected void consumePackageDeclaration() {
- // PackageDeclaration ::= 'package' Name ';'
- /* build an ImportRef build from the last name
- stored in the identifier stack. */
-
- ImportReference impt = compilationUnit.currentPackage;
- // flush annotations defined prior to import statements
- impt.declarationEnd = endStatementPosition;
- impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
- }
- protected void consumePackageDeclarationName() {
- // PackageDeclarationName ::= 'package' Name
- /* build an ImportRef build from the last name
- stored in the identifier stack. */
-
- ImportReference impt;
- int length;
- char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
- identifierPtr -= length;
- long[] positions = new long[length];
- System.arraycopy(identifierStack, ++identifierPtr, tokens, 0, length);
- System.arraycopy(identifierPositionStack, identifierPtr--, positions, 0, length);
- compilationUnit.currentPackage = impt = new ImportReference(tokens, positions, true);
-
- if (currentToken == TokenNameSEMICOLON) {
- impt.declarationSourceEnd = scanner.currentPosition - 1;
- } else {
- impt.declarationSourceEnd = impt.sourceEnd;
- }
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = intStack[intPtr--];
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = impt.declarationSourceEnd + 1;
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- }
- protected void consumePostfixExpression() {
- // PostfixExpression ::= Name
- pushOnExpressionStack(getUnspecifiedReferenceOptimized());
- }
- protected void consumePrimaryNoNewArray() {
- // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
- updateSourcePosition(expressionStack[expressionPtr]);
- }
- protected void consumePrimaryNoNewArrayArrayType() {
- // PrimaryNoNewArray ::= ArrayType '.' 'class'
- intPtr--;
- pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(intStack[intPtr--])));
- }
- protected void consumePrimaryNoNewArrayName() {
- // PrimaryNoNewArray ::= Name '.' 'class'
- intPtr--;
- pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(0)));
- }
- protected void consumePrimaryNoNewArrayNameSuper() {
- // PrimaryNoNewArray ::= Name '.' 'super'
- pushOnExpressionStack(new QualifiedSuperReference(getTypeReference(0), intStack[intPtr--], endPosition));
- }
- protected void consumePrimaryNoNewArrayNameThis() {
- // PrimaryNoNewArray ::= Name '.' 'this'
- pushOnExpressionStack(new QualifiedThisReference(getTypeReference(0), intStack[intPtr--], endPosition));
- }
- protected void consumePrimaryNoNewArrayPrimitiveType() {
- // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
- intPtr--;
- pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(0)));
- }
- protected void consumePrimaryNoNewArrayThis() {
- // PrimaryNoNewArray ::= 'this'
- pushOnExpressionStack(new ThisReference(intStack[intPtr--], endPosition));
- }
- protected void consumePrimitiveType() {
- // Type ::= PrimitiveType
- pushOnIntStack(0);
- }
- protected void consumePushModifiers() {
- if ((modifiers & AccSynchronized) != 0) {
- /* remove the starting position of the synchronized keyword
- * we don't need it when synchronized is part of the modifiers
- */
- intPtr--;
- }
- pushOnIntStack(modifiers); // modifiers
- pushOnIntStack(modifiersSourceStart);
- resetModifiers();
- }
- protected void consumePushPosition() {
- // for source managment purpose
- // PushPosition ::= $empty
- pushOnIntStack(endPosition);
- }
- protected void consumeQualifiedName() {
- // QualifiedName ::= Name '.' SimpleName
- /*back from the recursive loop of QualifiedName.
- Updates identifier length into the length stack*/
-
- identifierLengthStack[--identifierLengthPtr]++;
- }
- protected void consumeReferenceType() {
- // ReferenceType ::= ClassOrInterfaceType
- pushOnIntStack(0);
- }
- protected void consumeRestoreDiet() {
- // RestoreDiet ::= $empty
- dietInt--;
- }
- protected void consumeRightParen() {
- // PushRPAREN ::= ')'
- pushOnIntStack(rParenPos);
- }
- // This method is part of an automatic generation : do NOT edit-modify
- // This method is part of an automatic generation : do NOT edit-modify
- protected void consumeRule(int act) {
- switch (act) {
- case 29 : // System.out.println("Type ::= PrimitiveType");
- consumePrimitiveType();
- break;
-
- case 43 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");
- consumeReferenceType();
- break;
-
- case 52 : // System.out.println("QualifiedName ::= Name DOT SimpleName");
- consumeQualifiedName();
- break;
-
- case 53 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt");
- consumeCompilationUnit();
- break;
-
- case 54 : // System.out.println("EnterCompilationUnit ::=");
- consumeEnterCompilationUnit();
- break;
-
- case 66 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");
- consumeCatchHeader();
- break;
-
- case 68 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");
- consumeImportDeclarations();
- break;
-
- case 70 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");
- consumeTypeDeclarations();
- break;
-
- case 71 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");
- consumePackageDeclaration();
- break;
-
- case 72 : // System.out.println("PackageDeclarationName ::= package Name");
- consumePackageDeclarationName();
- break;
-
- case 75 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON");
- consumeSingleTypeImportDeclaration();
- break;
-
- case 76 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");
- consumeSingleTypeImportDeclarationName();
- break;
-
- case 77 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON");
- consumeTypeImportOnDemandDeclaration();
- break;
-
- case 78 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");
- consumeTypeImportOnDemandDeclarationName();
- break;
-
- case 81 : // System.out.println("TypeDeclaration ::= SEMICOLON");
- consumeEmptyTypeDeclaration();
- break;
-
- case 95 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");
- consumeClassDeclaration();
- break;
-
- case 96 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt");
- consumeClassHeader();
- break;
-
- case 97 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier");
- consumeClassHeaderName();
- break;
-
- case 98 : // System.out.println("ClassHeaderExtends ::= extends ClassType");
- consumeClassHeaderExtends();
- break;
-
- case 99 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");
- consumeClassHeaderImplements();
- break;
-
- case 101 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");
- consumeInterfaceTypeList();
- break;
-
- case 102 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");
- consumeInterfaceType();
- break;
-
- case 105 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");
- consumeClassBodyDeclarations();
- break;
-
- case 109 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");
- consumeClassBodyDeclaration();
- break;
-
- case 110 : // System.out.println("Diet ::=");
- consumeDiet();
- break;
-
- case 111 : // System.out.println("Initializer ::= Diet NestedMethod Block");
- consumeClassBodyDeclaration();
- break;
-
- case 118 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");
- consumeEmptyClassMemberDeclaration();
- break;
-
- case 119 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");
- consumeFieldDeclaration();
- break;
-
- case 121 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");
- consumeVariableDeclarators();
- break;
-
- case 124 : // System.out.println("EnterVariable ::=");
- consumeEnterVariable();
- break;
-
- case 125 : // System.out.println("ExitVariableWithInitialization ::=");
- consumeExitVariableWithInitialization();
- break;
-
- case 126 : // System.out.println("ExitVariableWithoutInitialization ::=");
- consumeExitVariableWithoutInitialization();
- break;
-
- case 127 : // System.out.println("ForceNoDiet ::=");
- consumeForceNoDiet();
- break;
-
- case 128 : // System.out.println("RestoreDiet ::=");
- consumeRestoreDiet();
- break;
-
- case 133 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");
- // set to true to consume a method with a body
- consumeMethodDeclaration(true);
- break;
-
- case 134 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");
- // set to false to consume a method without body
- consumeMethodDeclaration(false);
- break;
-
- case 135 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims");
- consumeMethodHeader();
- break;
-
- case 136 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters");
- consumeMethodHeader();
- break;
-
- case 137 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers Identifier LPAREN");
- consumeMethodPushModifiersHeaderName();
- break;
-
- case 138 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers Identifier LPAREN");
- consumeMethodPushModifiersHeaderName();
- break;
-
- case 139 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");
- consumeMethodHeaderName();
- break;
-
- case 140 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");
- consumeMethodHeaderParameters();
- break;
-
- case 141 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");
- consumeMethodHeaderExtendedDims();
- break;
-
- case 142 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");
- consumeMethodHeaderThrowsClause();
- break;
-
- case 143 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters...");
- consumeConstructorHeader();
- break;
-
- case 144 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");
- consumeConstructorHeaderName();
- break;
-
- case 146 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");
- consumeFormalParameterList();
- break;
-
- case 147 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");
- // the boolean is used to know if the modifiers should be reset
- consumeFormalParameter();
- break;
-
- case 149 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");
- consumeClassTypeList();
- break;
-
- case 150 : // System.out.println("ClassTypeElt ::= ClassType");
- consumeClassTypeElt();
- break;
-
- case 151 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");
- consumeMethodBody();
- break;
-
- case 152 : // System.out.println("NestedMethod ::=");
- consumeNestedMethod();
- break;
-
- case 153 : // System.out.println("StaticInitializer ::= StaticOnly Block");
- consumeStaticInitializer();
- break;
-
- case 154 : // System.out.println("StaticOnly ::= static");
- consumeStaticOnly();
- break;
-
- case 155 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody");
- consumeConstructorDeclaration();
- break;
-
- case 156 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");
- consumeInvalidConstructorDeclaration();
- break;
-
- case 157 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE");
- consumeConstructorBody();
- break;
-
- case 160 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements");
- consumeConstructorBlockStatements();
- break;
-
- case 161 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON");
- consumeExplicitConstructorInvocation(0, ExplicitConstructorCall.This);
- break;
-
- case 162 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON");
- consumeExplicitConstructorInvocation(0, ExplicitConstructorCall.Super);
- break;
-
- case 163 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN");
- consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);
- break;
-
- case 164 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN...");
- consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);
- break;
-
- case 165 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN...");
- consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);
- break;
-
- case 166 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN...");
- consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);
- break;
-
- case 167 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");
- consumeInterfaceDeclaration();
- break;
-
- case 168 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");
- consumeInterfaceHeader();
- break;
-
- case 169 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier");
- consumeInterfaceHeaderName();
- break;
-
- case 171 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");
- consumeInterfaceHeaderExtends();
- break;
-
- case 174 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");
- consumeInterfaceMemberDeclarations();
- break;
-
- case 175 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");
- consumeEmptyInterfaceMemberDeclaration();
- break;
-
- case 178 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");
- ignoreMethodBody();
- break;
-
- case 179 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody");
- ignoreInvalidConstructorDeclaration(true);
- break;
-
- case 180 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");
- ignoreInvalidConstructorDeclaration(false);
- break;
-
- case 186 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");
- consumeEmptyArrayInitializer();
- break;
-
- case 187 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");
- consumeArrayInitializer();
- break;
-
- case 188 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");
- consumeArrayInitializer();
- break;
-
- case 190 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer");
- consumeVariableInitializers();
- break;
-
- case 191 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");
- consumeBlock();
- break;
-
- case 192 : // System.out.println("OpenBlock ::=");
- consumeOpenBlock();
- break;
-
- case 194 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");
- consumeBlockStatements();
- break;
-
- case 198 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");
- ignoreInterfaceDeclaration();
- break;
-
- case 199 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON");
- consumeLocalVariableDeclarationStatement();
- break;
-
- case 200 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");
- consumeLocalVariableDeclaration();
- break;
-
- case 201 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators");
- consumeLocalVariableDeclaration();
- break;
-
- case 202 : // System.out.println("PushModifiers ::=");
- consumePushModifiers();
- break;
-
- case 226 : // System.out.println("EmptyStatement ::= SEMICOLON");
- consumeEmptyStatement();
- break;
-
- case 227 : // System.out.println("LabeledStatement ::= Identifier COLON Statement");
- consumeStatementLabel();
- break;
-
- case 228 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf");
- consumeStatementLabel();
- break;
-
- case 229 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");
- consumeExpressionStatement();
- break;
-
- case 237 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");
- consumeStatementIfNoElse();
- break;
-
- case 238 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else...");
- consumeStatementIfWithElse();
- break;
-
- case 239 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf...");
- consumeStatementIfWithElse();
- break;
-
- case 240 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock");
- consumeStatementSwitch();
- break;
-
- case 241 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");
- consumeEmptySwitchBlock();
- break;
-
- case 244 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");
- consumeSwitchBlock();
- break;
-
- case 246 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");
- consumeSwitchBlockStatements();
- break;
-
- case 247 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");
- consumeSwitchBlockStatement();
- break;
-
- case 249 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");
- consumeSwitchLabels();
- break;
-
- case 250 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");
- consumeCaseLabel();
- break;
-
- case 251 : // System.out.println("SwitchLabel ::= default COLON");
- consumeDefaultLabel();
- break;
-
- case 252 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");
- consumeStatementWhile();
- break;
-
- case 253 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf");
- consumeStatementWhile();
- break;
-
- case 254 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON");
- consumeStatementDo();
- break;
-
- case 255 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON...");
- consumeStatementFor();
- break;
-
- case 256 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON");
- consumeStatementFor();
- break;
-
- case 257 : // System.out.println("ForInit ::= StatementExpressionList");
- consumeForInit();
- break;
-
- case 261 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression");
- consumeStatementExpressionList();
- break;
-
- case 262 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");
- consumeSimpleAssertStatement();
- break;
-
- case 263 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");
- consumeAssertStatement();
- break;
-
- case 264 : // System.out.println("BreakStatement ::= break SEMICOLON");
- consumeStatementBreak();
- break;
-
- case 265 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");
- consumeStatementBreakWithLabel();
- break;
-
- case 266 : // System.out.println("ContinueStatement ::= continue SEMICOLON");
- consumeStatementContinue();
- break;
-
- case 267 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");
- consumeStatementContinueWithLabel();
- break;
-
- case 268 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");
- consumeStatementReturn();
- break;
-
- case 269 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");
- consumeStatementThrow();
-
- break;
-
- case 270 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block");
- consumeStatementSynchronized();
- break;
-
- case 271 : // System.out.println("OnlySynchronized ::= synchronized");
- consumeOnlySynchronized();
- break;
-
- case 272 : // System.out.println("TryStatement ::= try Block Catches");
- consumeStatementTry(false);
- break;
-
- case 273 : // System.out.println("TryStatement ::= try Block Catchesopt Finally");
- consumeStatementTry(true);
- break;
-
- case 275 : // System.out.println("Catches ::= Catches CatchClause");
- consumeCatches();
- break;
-
- case 276 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");
- consumeStatementCatch();
- break;
-
- case 278 : // System.out.println("PushLPAREN ::= LPAREN");
- consumeLeftParen();
- break;
-
- case 279 : // System.out.println("PushRPAREN ::= RPAREN");
- consumeRightParen();
- break;
+ else {
+ String functionName;
- case 283 : // System.out.println("PrimaryNoNewArray ::= this");
- consumePrimaryNoNewArrayThis();
- break;
-
- case 284 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");
- consumePrimaryNoNewArray();
- break;
-
- case 287 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");
- consumePrimaryNoNewArrayNameThis();
- break;
-
- case 288 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");
- consumePrimaryNoNewArrayNameSuper();
- break;
-
- case 289 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");
- consumePrimaryNoNewArrayName();
- break;
-
- case 290 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");
- consumePrimaryNoNewArrayArrayType();
- break;
-
- case 291 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");
- consumePrimaryNoNewArrayPrimitiveType();
- break;
-
- case 294 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");
- consumeAllocationHeader();
- break;
-
- case 295 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN...");
- consumeClassInstanceCreationExpression();
- break;
-
- case 296 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN...");
- consumeClassInstanceCreationExpressionQualified();
- break;
-
- case 297 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new...");
- consumeClassInstanceCreationExpressionQualified();
- break;
-
- case 298 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");
- consumeClassInstanceCreationExpressionName();
- break;
-
- case 299 : // System.out.println("ClassBodyopt ::=");
- consumeClassBodyopt();
- break;
-
- case 301 : // System.out.println("EnterAnonymousClassBody ::=");
- consumeEnterAnonymousClassBody();
- break;
-
- case 303 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");
- consumeArgumentList();
- break;
-
- case 304 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs...");
- consumeArrayCreationExpression();
- break;
-
- case 305 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs...");
- consumeArrayCreationExpression();
- break;
-
- case 307 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");
- consumeDimWithOrWithOutExprs();
- break;
-
- case 309 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");
- consumeDimWithOrWithOutExpr();
- break;
-
- case 310 : // System.out.println("Dims ::= DimsLoop");
- consumeDims();
- break;
-
- case 313 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");
- consumeOneDimLoop();
- break;
-
- case 314 : // System.out.println("FieldAccess ::= Primary DOT Identifier");
- consumeFieldAccess(false);
- break;
-
- case 315 : // System.out.println("FieldAccess ::= super DOT Identifier");
- consumeFieldAccess(true);
- break;
-
- case 316 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");
- consumeMethodInvocationName();
- break;
-
- case 317 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt RPAREN");
- consumeMethodInvocationPrimary();
- break;
-
- case 318 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt RPAREN");
- consumeMethodInvocationSuper();
- break;
-
- case 319 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");
- consumeArrayAccess(true);
- break;
-
- case 320 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");
- consumeArrayAccess(false);
- break;
-
- case 322 : // System.out.println("PostfixExpression ::= Name");
- consumePostfixExpression();
- break;
-
- case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");
- consumeUnaryExpression(OperatorExpression.PLUS, true);
- break;
-
- case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");
- consumeUnaryExpression(OperatorExpression.MINUS, true);
- break;
-
- case 327 : // System.out.println("PushPosition ::=");
- consumePushPosition();
- break;
-
- case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");
- consumeUnaryExpression(OperatorExpression.PLUS);
- break;
-
- case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");
- consumeUnaryExpression(OperatorExpression.MINUS);
- break;
-
- case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");
- consumeUnaryExpression(OperatorExpression.PLUS, false);
- break;
-
- case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");
- consumeUnaryExpression(OperatorExpression.MINUS, false);
- break;
-
- case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");
- consumeUnaryExpression(OperatorExpression.TWIDDLE);
- break;
-
- case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");
- consumeUnaryExpression(OperatorExpression.NOT);
- break;
-
- case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression");
- consumeCastExpression();
- break;
-
- case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus");
- consumeCastExpression();
- break;
-
- case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus");
- consumeCastExpressionLL1();
- break;
-
- case 343 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression");
- consumeBinaryExpression(OperatorExpression.MULTIPLY);
- break;
-
- case 344 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression");
- consumeBinaryExpression(OperatorExpression.DIVIDE);
- break;
-
- case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression");
- consumeBinaryExpression(OperatorExpression.REMAINDER);
- break;
-
- case 347 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression");
- consumeBinaryExpression(OperatorExpression.PLUS);
- break;
-
- case 348 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression");
- consumeBinaryExpression(OperatorExpression.MINUS);
- break;
-
- case 350 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");
- consumeBinaryExpression(OperatorExpression.LEFT_SHIFT);
- break;
-
- case 351 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");
- consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT);
- break;
-
- case 352 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression");
- consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT);
- break;
-
- case 354 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");
- consumeBinaryExpression(OperatorExpression.LESS);
- break;
-
- case 355 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression");
- consumeBinaryExpression(OperatorExpression.GREATER);
- break;
-
- case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression");
- consumeBinaryExpression(OperatorExpression.LESS_EQUAL);
- break;
-
- case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression");
- consumeBinaryExpression(OperatorExpression.GREATER_EQUAL);
- break;
-
- case 358 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType");
- consumeInstanceOfExpression(OperatorExpression.INSTANCEOF);
- break;
-
- case 360 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression");
- consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL);
- break;
-
- case 361 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression");
- consumeEqualityExpression(OperatorExpression.NOT_EQUAL);
- break;
-
- case 363 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");
- consumeBinaryExpression(OperatorExpression.AND);
- break;
-
- case 365 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");
- consumeBinaryExpression(OperatorExpression.XOR);
- break;
-
- case 367 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression");
- consumeBinaryExpression(OperatorExpression.OR);
- break;
-
- case 369 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression");
- consumeBinaryExpression(OperatorExpression.AND_AND);
- break;
-
- case 371 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression");
- consumeBinaryExpression(OperatorExpression.OR_OR);
- break;
-
- case 373 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON...");
- consumeConditionalExpression(OperatorExpression.QUESTIONCOLON);
- break;
-
- case 376 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression");
- consumeAssignment();
- break;
-
- case 378 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");
- ignoreExpressionAssignment();
- break;
-
- case 379 : // System.out.println("LeftHandSide ::= Name");
- consumeLeftHandSide();
- break;
-
- case 382 : // System.out.println("AssignmentOperator ::= EQUAL");
- consumeAssignmentOperator(EQUAL);
- break;
-
- case 383 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");
- consumeAssignmentOperator(MULTIPLY);
- break;
-
- case 384 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");
- consumeAssignmentOperator(DIVIDE);
- break;
-
- case 385 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");
- consumeAssignmentOperator(REMAINDER);
- break;
-
- case 386 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");
- consumeAssignmentOperator(PLUS);
- break;
-
- case 387 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");
- consumeAssignmentOperator(MINUS);
- break;
-
- case 388 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");
- consumeAssignmentOperator(LEFT_SHIFT);
- break;
-
- case 389 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");
- consumeAssignmentOperator(RIGHT_SHIFT);
- break;
-
- case 390 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");
- consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
- break;
-
- case 391 : // System.out.println("AssignmentOperator ::= AND_EQUAL");
- consumeAssignmentOperator(AND);
- break;
-
- case 392 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");
- consumeAssignmentOperator(XOR);
- break;
-
- case 393 : // System.out.println("AssignmentOperator ::= OR_EQUAL");
- consumeAssignmentOperator(OR);
- break;
-
- case 400 : // System.out.println("Expressionopt ::=");
- consumeEmptyExpression();
- break;
-
- case 404 : // System.out.println("ImportDeclarationsopt ::=");
- consumeEmptyImportDeclarationsopt();
- break;
-
- case 405 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");
- consumeImportDeclarationsopt();
- break;
-
- case 406 : // System.out.println("TypeDeclarationsopt ::=");
- consumeEmptyTypeDeclarationsopt();
- break;
-
- case 407 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");
- consumeTypeDeclarationsopt();
- break;
-
- case 408 : // System.out.println("ClassBodyDeclarationsopt ::=");
- consumeEmptyClassBodyDeclarationsopt();
- break;
-
- case 409 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");
- consumeClassBodyDeclarationsopt();
- break;
-
- case 410 : // System.out.println("Modifiersopt ::=");
- consumeDefaultModifiers();
- break;
-
- case 411 : // System.out.println("Modifiersopt ::= Modifiers");
- consumeModifiers();
- break;
-
- case 412 : // System.out.println("BlockStatementsopt ::=");
- consumeEmptyBlockStatementsopt();
- break;
-
- case 414 : // System.out.println("Dimsopt ::=");
- consumeEmptyDimsopt();
- break;
-
- case 416 : // System.out.println("ArgumentListopt ::=");
- consumeEmptyArgumentListopt();
- break;
-
- case 420 : // System.out.println("FormalParameterListopt ::=");
- consumeFormalParameterListopt();
- break;
-
- case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::=");
- consumeEmptyInterfaceMemberDeclarationsopt();
- break;
-
- case 425 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations");
- consumeInterfaceMemberDeclarationsopt();
- break;
-
- case 426 : // System.out.println("NestedType ::=");
- consumeNestedType();
- break;
-
- case 427 : // System.out.println("ForInitopt ::=");
- consumeEmptyForInitopt();
- break;
-
- case 429 : // System.out.println("ForUpdateopt ::=");
- consumeEmptyForUpdateopt();
- break;
-
- case 433 : // System.out.println("Catchesopt ::=");
- consumeEmptyCatchesopt();
- break;
-
- case 435 : // System.out.println("ArrayInitializeropt ::=");
- consumeEmptyArrayInitializeropt();
- break;
-
- }
- }
-
- protected void consumeSimpleAssertStatement() {
- // AssertStatement ::= 'assert' Expression ';'
- expressionLengthPtr--;
- pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
- }
-
- protected void consumeSingleTypeImportDeclaration() {
- // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
-
- ImportReference impt = (ImportReference) astStack[astPtr];
- // flush annotations defined prior to import statements
- impt.declarationEnd = endStatementPosition;
- impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = impt.declarationSourceEnd + 1;
- currentElement = currentElement.add(impt, 0);
- lastIgnoredToken = -1;
- restartRecovery = true;
- // used to avoid branching back into the regular automaton
- }
- }
- protected void consumeSingleTypeImportDeclarationName() {
- // SingleTypeImportDeclarationName ::= 'import' Name
- /* push an ImportRef build from the last name
- stored in the identifier stack. */
-
- ImportReference impt;
- int length;
- char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
- identifierPtr -= length;
- long[] positions = new long[length];
- System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
- System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
- pushOnAstStack(impt = new ImportReference(tokens, positions, false));
-
- if (currentToken == TokenNameSEMICOLON) {
- impt.declarationSourceEnd = scanner.currentPosition - 1;
- } else {
- impt.declarationSourceEnd = impt.sourceEnd;
- }
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = intStack[intPtr--];
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = impt.declarationSourceEnd + 1;
- currentElement = currentElement.add(impt, 0);
- lastIgnoredToken = -1;
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- }
- protected void consumeStatementBreak() {
- // BreakStatement ::= 'break' ';'
- // break pushs a position on intStack in case there is no label
-
- pushOnAstStack(new Break(null, intStack[intPtr--], endPosition));
- }
- protected void consumeStatementBreakWithLabel() {
- // BreakStatement ::= 'break' Identifier ';'
- // break pushs a position on intStack in case there is no label
-
- pushOnAstStack(new Break(identifierStack[identifierPtr--], intStack[intPtr--], endPosition));
- identifierLengthPtr--;
- }
- protected void consumeStatementCatch() {
- // CatchClause ::= 'catch' '(' FormalParameter ')' Block
-
- //catch are stored directly into the Try
- //has they always comes two by two....
- //we remove one entry from the astlengthPtr.
- //The construction of the try statement must
- //then fetch the catches using 2*i and 2*i + 1
-
- astLengthPtr--;
- listLength = 0; // reset formalParameter counter (incremented for catch variable)
- }
- protected void consumeStatementContinue() {
- // ContinueStatement ::= 'continue' ';'
- // continue pushs a position on intStack in case there is no label
-
- pushOnAstStack(new Continue(null, intStack[intPtr--], endPosition));
- }
- protected void consumeStatementContinueWithLabel() {
- // ContinueStatement ::= 'continue' Identifier ';'
- // continue pushs a position on intStack in case there is no label
-
- pushOnAstStack(new Continue(identifierStack[identifierPtr--], intStack[intPtr--], endPosition));
- identifierLengthPtr--;
- }
- protected void consumeStatementDo() {
- // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
-
- //the 'while' pushes a value on intStack that we need to remove
- intPtr--;
-
- //optimize the push/pop
- Statement action = (Statement) astStack[astPtr];
- if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
- expressionLengthPtr--;
- astStack[astPtr] = new DoStatement(expressionStack[expressionPtr--], null, intStack[intPtr--], endPosition);
- } else {
- expressionLengthPtr--;
- astStack[astPtr] = new DoStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition);
- }
- }
- protected void consumeStatementExpressionList() {
- // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
- concatExpressionLists();
- }
- protected void consumeStatementFor() {
- // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
- // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
-
- int length;
- Expression cond = null;
- Statement[] inits, updates;
- Statement action;
- boolean scope = true;
-
- //statements
- astLengthPtr--; // we need to consume it
- action = (Statement) astStack[astPtr--];
- if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
- action = null;
- }
-
- //updates are on the expresion stack
- if ((length = expressionLengthStack[expressionLengthPtr--]) == 0) {
- updates = null;
- } else {
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, updates = new Statement[length], 0, length);
- }
-
- if (expressionLengthStack[expressionLengthPtr--] != 0)
- cond = expressionStack[expressionPtr--];
-
- //inits may be on two different stacks
- if ((length = astLengthStack[astLengthPtr--]) == 0) {
- inits = null;
- scope = false;
- } else {
- if (length == -1) { //on expressionStack
- scope = false;
- length = expressionLengthStack[expressionLengthPtr--];
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, inits = new Statement[length], 0, length);
- } else { //on astStack
- astPtr -= length;
- System.arraycopy(astStack, astPtr + 1, inits = new Statement[length], 0, length);
- }
- };
- if (action instanceof Block) {
- pushOnAstStack(new ForStatement(inits, cond, updates, action, scope, intStack[intPtr--], endStatementPosition));
- } else {
- pushOnAstStack(new ForStatement(inits, cond, updates, action, scope, intStack[intPtr--], endPosition));
- }
- }
- protected void consumeStatementIfNoElse() {
- // IfThenStatement ::= 'if' '(' Expression ')' Statement
-
- //optimize the push/pop
- expressionLengthPtr--;
- Statement thenStatement = (Statement) astStack[astPtr];
- if (thenStatement instanceof Block) {
- astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], thenStatement, intStack[intPtr--], endStatementPosition);
- } else if (thenStatement instanceof EmptyStatement) {
- astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], Block.None, intStack[intPtr--], endStatementPosition);
- } else {
- astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], thenStatement, intStack[intPtr--], endStatementPosition);
- }
- }
- protected void consumeStatementIfWithElse() {
- // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
- // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
-
- astLengthPtr--; // optimized {..., Then, Else } ==> {..., If }
- expressionLengthPtr--;
- //optimize the push/pop
- Statement elseStatement = (Statement) astStack[astPtr--];
- Statement thenStatement = (Statement) astStack[astPtr];
- if (elseStatement instanceof EmptyStatement) {
- elseStatement = Block.None;
- }
- if (thenStatement instanceof EmptyStatement) {
- thenStatement = Block.None;
- }
- if (elseStatement instanceof Block) {
- astStack[astPtr] =
- new IfStatement(expressionStack[expressionPtr--], thenStatement, elseStatement, intStack[intPtr--], endStatementPosition);
- } else {
- astStack[astPtr] =
- new IfStatement(expressionStack[expressionPtr--], thenStatement, elseStatement, intStack[intPtr--], endStatementPosition);
- }
- }
- protected void consumeStatementLabel() {
- // LabeledStatement ::= 'Identifier' ':' Statement
- // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
-
- //optimize push/pop
-
- Statement stmt = (Statement) astStack[astPtr];
- if (stmt instanceof EmptyStatement) {
- astStack[astPtr] =
- new LabeledStatement(
- identifierStack[identifierPtr],
- Block.None,
- (int) (identifierPositionStack[identifierPtr--] >>> 32),
- endStatementPosition);
- } else {
- astStack[astPtr] =
- new LabeledStatement(
- identifierStack[identifierPtr],
- stmt,
- (int) (identifierPositionStack[identifierPtr--] >>> 32),
- endStatementPosition);
- }
- identifierLengthPtr--;
- }
- protected void consumeStatementReturn() {
- // ReturnStatement ::= 'return' Expressionopt ';'
- // return pushs a position on intStack in case there is no expression
-
- if (expressionLengthStack[expressionLengthPtr--] != 0) {
- pushOnAstStack(new ReturnStatement(expressionStack[expressionPtr--], intStack[intPtr--], endPosition));
- } else {
- pushOnAstStack(new ReturnStatement(null, intStack[intPtr--], endPosition));
- }
- }
- protected void consumeStatementSwitch() {
- // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
-
- //OpenBlock just makes the semantic action blockStart()
- //the block is inlined but a scope need to be created
- //if some declaration occurs.
-
- int length;
- SwitchStatement s = new SwitchStatement();
- expressionLengthPtr--;
- s.testExpression = expressionStack[expressionPtr--];
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- astPtr -= length;
- System.arraycopy(astStack, astPtr + 1, s.statements = new Statement[length], 0, length);
- }
- s.explicitDeclarations = realBlockStack[realBlockPtr--];
- pushOnAstStack(s);
- intPtr--; // because of OpenBlock
- s.sourceStart = intStack[intPtr--];
- s.sourceEnd = endStatementPosition;
- }
- protected void consumeStatementSynchronized() {
- // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
- //optimize the push/pop
-
- if (astLengthStack[astLengthPtr] == 0) {
- astLengthStack[astLengthPtr] = 1;
- expressionLengthPtr--;
- astStack[++astPtr] =
- new SynchronizedStatement(expressionStack[expressionPtr--], Block.None, intStack[intPtr--], endStatementPosition);
- } else {
- expressionLengthPtr--;
- astStack[astPtr] =
- new SynchronizedStatement(
- expressionStack[expressionPtr--],
- (Block) astStack[astPtr],
- intStack[intPtr--],
- endStatementPosition);
- }
- resetModifiers();
- }
- protected void consumeStatementThrow() {
- // ThrowStatement ::= 'throw' Expression ';'
- expressionLengthPtr--;
- pushOnAstStack(new ThrowStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
- }
- protected void consumeStatementTry(boolean withFinally) {
- //TryStatement ::= 'try' Block Catches
- //TryStatement ::= 'try' Block Catchesopt Finally
-
- int length;
- TryStatement tryStmt = new TryStatement();
- //finally
- if (withFinally) {
- astLengthPtr--;
- tryStmt.finallyBlock = (Block) astStack[astPtr--];
- }
- //catches are handle by two <argument-block> [see statementCatch]
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- if (length == 1) {
- tryStmt.catchBlocks = new Block[] {(Block) astStack[astPtr--] };
- tryStmt.catchArguments = new Argument[] {(Argument) astStack[astPtr--] };
- } else {
- Block[] bks = (tryStmt.catchBlocks = new Block[length]);
- Argument[] args = (tryStmt.catchArguments = new Argument[length]);
- while (length-- > 0) {
- bks[length] = (Block) astStack[astPtr--];
- args[length] = (Argument) astStack[astPtr--];
- }
- }
- }
- //try
- astLengthPtr--;
- tryStmt.tryBlock = (Block) astStack[astPtr--];
-
- //positions
- tryStmt.sourceEnd = endStatementPosition;
- tryStmt.sourceStart = intStack[intPtr--];
- pushOnAstStack(tryStmt);
- }
- protected void consumeStatementWhile() {
- // WhileStatement ::= 'while' '(' Expression ')' Statement
- // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
-
- Statement action = (Statement) astStack[astPtr];
- expressionLengthPtr--;
- if (action instanceof Block) {
- astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endStatementPosition);
- } else {
- if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
- astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], null, intStack[intPtr--], endPosition);
- } else {
- astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition);
- }
- }
- }
- protected void consumeStaticInitializer() {
- // StaticInitializer ::= StaticOnly Block
- //push an Initializer
- //optimize the push/pop
- Initializer initializer = new Initializer((Block) astStack[astPtr], AccStatic);
- astStack[astPtr] = initializer;
- initializer.sourceEnd = endStatementPosition;
- initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
- nestedMethod[nestedType]--;
- initializer.declarationSourceStart = intStack[intPtr--];
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = initializer.declarationSourceEnd;
- currentElement = currentElement.add(initializer, 0);
- lastIgnoredToken = -1;
- }
- }
- protected void consumeStaticOnly() {
- // StaticOnly ::= 'static'
- int savedModifiersSourceStart = modifiersSourceStart;
- checkAnnotation(); // might update declaration source start
- if (modifiersSourceStart >= savedModifiersSourceStart) {
- modifiersSourceStart = savedModifiersSourceStart;
- }
- pushOnIntStack(modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
- jumpOverMethodBody();
- nestedMethod[nestedType]++;
- resetModifiers();
-
- // recovery
- if (currentElement != null) {
- recoveredStaticInitializerStart = intStack[intPtr]; // remember start position only for static initializers
- }
- }
- protected void consumeSwitchBlock() {
- // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
- concatNodeLists();
- }
- protected void consumeSwitchBlockStatement() {
- // SwitchBlockStatement ::= SwitchLabels BlockStatements
- concatNodeLists();
- }
- protected void consumeSwitchBlockStatements() {
- // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
- concatNodeLists();
- }
- protected void consumeSwitchLabels() {
- // SwitchLabels ::= SwitchLabels SwitchLabel
- optimizedConcatNodeLists();
- }
- protected void consumeToken(int type) {
- /* remember the last consumed value */
- /* try to minimize the number of build values */
- if (scanner.wasNonExternalizedStringLiteral) {
- StringLiteral[] literals = this.scanner.nonNLSStrings;
- // could not reproduce, but this is the only NPE
- // added preventive null check see PR 9035
- if (literals != null) {
- for (int i = 0, max = literals.length; i < max; i++) {
- problemReporter().nonExternalizedStringLiteral(literals[i]);
- }
- }
- scanner.currentLine = null;
- scanner.wasNonExternalizedStringLiteral = false;
- }
- // clear the commentPtr of the scanner in case we read something different from a modifier
- switch (type) {
- // case TokenNameabstract :
- // case TokenNamestrictfp :
- // case TokenNamefinal :
- // case TokenNamenative :
- // case TokenNameprivate :
- // case TokenNameprotected :
- // case TokenNamepublic :
- // case TokenNametransient :
- // case TokenNamevolatile :
- case TokenNamestatic :
- // case TokenNamesynchronized :
- break;
- default :
- scanner.commentPtr = -1;
- }
- //System.out.println(scanner.toStringAction(type));
- switch (type) {
- case TokenNameIdentifier :
- pushIdentifier();
- if (scanner.useAssertAsAnIndentifier) {
- long positions = identifierPositionStack[identifierPtr];
- problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
- }
- scanner.commentPtr = -1;
- break;
- // case TokenNameinterface :
- // adjustInterfaceModifiers();
- // //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
- // pushOnIntStack(scanner.startPosition);
- // pushOnIntStack(scanner.currentPosition - 1);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNameabstract :
- // checkAndSetModifiers(AccAbstract);
- // break;
- // case TokenNamestrictfp :
- // checkAndSetModifiers(AccStrictfp);
- // break;
- // case TokenNamefinal :
- // checkAndSetModifiers(AccFinal);
- // break;
- // case TokenNamenative :
- // checkAndSetModifiers(AccNative);
- // break;
- // case TokenNameprivate :
- // checkAndSetModifiers(AccPrivate);
- // break;
- // case TokenNameprotected :
- // checkAndSetModifiers(AccProtected);
- // break;
- // case TokenNamepublic :
- // checkAndSetModifiers(AccPublic);
- // break;
- // case TokenNametransient :
- // checkAndSetModifiers(AccTransient);
- // break;
- // case TokenNamevolatile :
- // checkAndSetModifiers(AccVolatile);
- // break;
- case TokenNamestatic :
- checkAndSetModifiers(AccStatic);
- break;
- // case TokenNamesynchronized :
- // this.synchronizedBlockSourceStart = scanner.startPosition;
- // checkAndSetModifiers(AccSynchronized);
- // break;
- // //==============================
- // case TokenNamevoid :
- // pushIdentifier(-T_void);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // //push a default dimension while void is not part of the primitive
- // //declaration baseType and so takes the place of a type without getting into
- // //regular type parsing that generates a dimension on intStack
- // case TokenNameboolean :
- // pushIdentifier(-T_boolean);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNamebyte :
- // pushIdentifier(-T_byte);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNamechar :
- // pushIdentifier(-T_char);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNamedouble :
- // pushIdentifier(-T_double);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNamefloat :
- // pushIdentifier(-T_float);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNameint :
- // pushIdentifier(-T_int);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNamelong :
- // pushIdentifier(-T_long);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- // case TokenNameshort :
- // pushIdentifier(-T_short);
- // pushOnIntStack(scanner.currentPosition - 1);
- // pushOnIntStack(scanner.startPosition);
- // scanner.commentPtr = -1;
- // break;
- //==============================
- case TokenNameIntegerLiteral :
- pushOnExpressionStack(new IntLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
- scanner.commentPtr = -1;
- break;
- case TokenNameLongLiteral :
- pushOnExpressionStack(new LongLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
- scanner.commentPtr = -1;
- break;
- case TokenNameFloatingPointLiteral :
- pushOnExpressionStack(
- new FloatLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
- scanner.commentPtr = -1;
- break;
- case TokenNameDoubleLiteral :
- pushOnExpressionStack(
- new DoubleLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
- scanner.commentPtr = -1;
- break;
- case TokenNameCharacterLiteral :
- pushOnExpressionStack(new CharLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
- scanner.commentPtr = -1;
- break;
- case TokenNameStringLiteral :
- StringLiteral stringLiteral =
- new StringLiteral(scanner.getCurrentTokenSourceString(), scanner.startPosition, scanner.currentPosition - 1);
- pushOnExpressionStack(stringLiteral);
- scanner.commentPtr = -1;
- break;
- case TokenNamefalse :
- pushOnExpressionStack(new FalseLiteral(scanner.startPosition, scanner.currentPosition - 1));
- scanner.commentPtr = -1;
- break;
- case TokenNametrue :
- pushOnExpressionStack(new TrueLiteral(scanner.startPosition, scanner.currentPosition - 1));
- break;
- case TokenNamenull :
- pushOnExpressionStack(new NullLiteral(scanner.startPosition, scanner.currentPosition - 1));
- break;
- //============================
- // case TokenNamesuper :
- // case TokenNamethis :
- // endPosition = scanner.currentPosition - 1;
- // pushOnIntStack(scanner.startPosition);
- // break;
- // case TokenNameassert :
- // case TokenNameimport :
- // case TokenNamepackage :
- // case TokenNamethrow :
- case TokenNamenew :
- case TokenNamedo :
- case TokenNameif :
- case TokenNamefor :
- case TokenNameswitch :
- // case TokenNametry :
- case TokenNamewhile :
- case TokenNamebreak :
- case TokenNamecontinue :
- case TokenNamereturn :
- case TokenNamecase :
- pushOnIntStack(scanner.startPosition);
- break;
- case TokenNameclass :
- pushOnIntStack(scanner.currentPosition - 1);
- pushOnIntStack(scanner.startPosition);
- break;
- case TokenNamedefault :
- pushOnIntStack(scanner.startPosition);
- pushOnIntStack(scanner.currentPosition - 1);
- break;
- //let extra semantic action decide when to push
- case TokenNameRBRACKET :
- case TokenNamePLUS :
- case TokenNameMINUS :
- case TokenNameNOT :
- case TokenNameTWIDDLE :
- endPosition = scanner.startPosition;
- break;
- case TokenNamePLUS_PLUS :
- case TokenNameMINUS_MINUS :
- endPosition = scanner.startPosition;
- endStatementPosition = scanner.currentPosition - 1;
- break;
- case TokenNameRBRACE :
- case TokenNameSEMICOLON :
- endStatementPosition = scanner.currentPosition - 1;
- endPosition = scanner.startPosition - 1;
- //the item is not part of the potential futur expression/statement
- break;
- // in order to handle ( expression) ////// (cast)expression///// foo(x)
- case TokenNameRPAREN :
- rParenPos = scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
- break;
- case TokenNameLPAREN :
- lParenPos = scanner.startPosition;
- break;
- // case TokenNameQUESTION :
- // case TokenNameCOMMA :
- // case TokenNameCOLON :
- // case TokenNameEQUAL :
- // case TokenNameLBRACKET :
- // case TokenNameDOT :
- // case TokenNameERROR :
- // case TokenNameEOF :
- // case TokenNamecase :
- // case TokenNamecatch :
- // case TokenNameelse :
- // case TokenNameextends :
- // case TokenNamefinally :
- // case TokenNameimplements :
- // case TokenNamethrows :
- // case TokenNameinstanceof :
- // case TokenNameEQUAL_EQUAL :
- // case TokenNameLESS_EQUAL :
- // case TokenNameGREATER_EQUAL :
- // case TokenNameNOT_EQUAL :
- // case TokenNameLEFT_SHIFT :
- // case TokenNameRIGHT_SHIFT :
- // case TokenNameUNSIGNED_RIGHT_SHIFT :
- // case TokenNamePLUS_EQUAL :
- // case TokenNameMINUS_EQUAL :
- // case TokenNameMULTIPLY_EQUAL :
- // case TokenNameDIVIDE_EQUAL :
- // case TokenNameAND_EQUAL :
- // case TokenNameOR_EQUAL :
- // case TokenNameXOR_EQUAL :
- // case TokenNameREMAINDER_EQUAL :
- // case TokenNameLEFT_SHIFT_EQUAL :
- // case TokenNameRIGHT_SHIFT_EQUAL :
- // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
- // case TokenNameOR_OR :
- // case TokenNameAND_AND :
- // case TokenNameREMAINDER :
- // case TokenNameXOR :
- // case TokenNameAND :
- // case TokenNameMULTIPLY :
- // case TokenNameOR :
- // case TokenNameDIVIDE :
- // case TokenNameGREATER :
- // case TokenNameLESS :
- }
- }
- protected void consumeTypeDeclarations() {
- // TypeDeclarations ::= TypeDeclarations TypeDeclaration
- concatNodeLists();
- }
- protected void consumeTypeDeclarationsopt() {
- // TypeDeclarationsopt ::= TypeDeclarations
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- astPtr -= length;
- System.arraycopy(astStack, astPtr + 1, compilationUnit.types = new TypeDeclaration[length], 0, length);
- }
- }
- protected void consumeTypeImportOnDemandDeclaration() {
- // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
-
- ImportReference impt = (ImportReference) astStack[astPtr];
- // flush annotations defined prior to import statements
- impt.declarationEnd = endStatementPosition;
- impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = impt.declarationSourceEnd + 1;
- currentElement = currentElement.add(impt, 0);
- restartRecovery = true;
- lastIgnoredToken = -1;
- // used to avoid branching back into the regular automaton
- }
- }
- protected void consumeTypeImportOnDemandDeclarationName() {
- // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
- /* push an ImportRef build from the last name
- stored in the identifier stack. */
-
- ImportReference impt;
- int length;
- char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
- identifierPtr -= length;
- long[] positions = new long[length];
- System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
- System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
- pushOnAstStack(impt = new ImportReference(tokens, positions, true));
-
- if (currentToken == TokenNameSEMICOLON) {
- impt.declarationSourceEnd = scanner.currentPosition - 1;
- } else {
- impt.declarationSourceEnd = impt.sourceEnd;
- }
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = intStack[intPtr--];
-
- // recovery
- if (currentElement != null) {
- lastCheckPoint = impt.declarationSourceEnd + 1;
- currentElement = currentElement.add(impt, 0);
- lastIgnoredToken = -1;
- restartRecovery = true; // used to avoid branching back into the regular automaton
- }
- }
- protected void consumeUnaryExpression(int op) {
- // UnaryExpression ::= '+' PushPosition UnaryExpression
- // UnaryExpression ::= '-' PushPosition UnaryExpression
- // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
- // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
-
- //optimize the push/pop
-
- //handle manually the -2147483648 while it is not a real
- //computation of an - and 2147483648 (notice that 2147483648
- //is Integer.MAX_VALUE+1.....)
- //Same for -9223372036854775808L ............
-
- //intStack have the position of the operator
-
- Expression r, exp = expressionStack[expressionPtr];
- if (op == MINUS) {
- if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
- r = expressionStack[expressionPtr] = new IntLiteralMinValue();
- } else {
- if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
- r = expressionStack[expressionPtr] = new LongLiteralMinValue();
- } else {
- r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
- }
- }
- } else {
- r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
- }
- r.sourceStart = intStack[intPtr--];
- r.sourceEnd = exp.sourceEnd;
- }
- protected void consumeUnaryExpression(int op, boolean post) {
- // PreIncrementExpression ::= '++' PushPosition UnaryExpression
- // PreDecrementExpression ::= '--' PushPosition UnaryExpression
-
- // ++ and -- operators
- //optimize the push/pop
-
- //intStack has the position of the operator when prefix
-
- Expression leftHandSide = expressionStack[expressionPtr];
- if (leftHandSide instanceof Reference) {
- // ++foo()++ is unvalid
- if (post) {
- expressionStack[expressionPtr] = new PostfixExpression(leftHandSide, IntLiteral.One, op, endStatementPosition);
- } else {
- expressionStack[expressionPtr] = new PrefixExpression(leftHandSide, IntLiteral.One, op, intStack[intPtr--]);
- }
- } else {
- //the ++ or the -- is NOT taken into account if code gen proceeds
- if (!post) {
- intPtr--;
- }
- problemReporter().invalidUnaryExpression(leftHandSide);
- }
- }
- protected void consumeVariableDeclarators() {
- // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
- optimizedConcatNodeLists();
- }
- protected void consumeVariableInitializers() {
- // VariableInitializers ::= VariableInitializers ',' VariableInitializer
- concatExpressionLists();
- }
- protected TypeReference copyDims(TypeReference typeRef, int dim) {
- return typeRef.copyDims(dim);
- }
- protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
- return new FieldDeclaration(null, name, sourceStart, sourceEnd);
- }
-
- protected LocalDeclaration createLocalDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
- return new LocalDeclaration(null, name, sourceStart, sourceEnd);
- }
-
- public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
-
- CompilationUnitDeclaration parsedUnit;
- boolean old = diet;
- try {
- diet = true;
- parsedUnit = parse(sourceUnit, compilationResult);
- } finally {
- diet = old;
- }
- return parsedUnit;
- }
- protected void dispatchDeclarationInto(int length) {
- /* they are length on astStack that should go into
- methods fields constructors lists of the typeDecl
-
- Return if there is a constructor declaration in the methods declaration */
-
- // Looks for the size of each array .
-
- if (length == 0)
- return;
- int[] flag = new int[length + 1]; //plus one -- see <HERE>
- int size1 = 0, size2 = 0, size3 = 0;
- for (int i = length - 1; i >= 0; i--) {
- AstNode astNode = astStack[astPtr--];
- if (astNode instanceof AbstractMethodDeclaration) {
- //methods and constructors have been regrouped into one single list
- flag[i] = 3;
- size2++;
- } else {
- if (astNode instanceof TypeDeclaration) {
- flag[i] = 4;
- size3++;
- } else {
- //field
- flag[i] = 1;
- size1++;
- }
- }
- }
-
- //arrays creation
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- if (size1 != 0)
- typeDecl.fields = new FieldDeclaration[size1];
- if (size2 != 0)
- typeDecl.methods = new AbstractMethodDeclaration[size2];
- if (size3 != 0)
- typeDecl.memberTypes = new MemberTypeDeclaration[size3];
-
- //arrays fill up
- size1 = size2 = size3 = 0;
- int flagI = flag[0], start = 0;
- int length2;
- for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
- {
- if (flagI != flag[end]) //treat the last element as a ended flag.....
- { //array copy
- switch (flagI) {
- case 1 :
- size1 += (length2 = end - start);
- System.arraycopy(astStack, astPtr + start + 1, typeDecl.fields, size1 - length2, length2);
- break;
- case 3 :
- size2 += (length2 = end - start);
- System.arraycopy(astStack, astPtr + start + 1, typeDecl.methods, size2 - length2, length2);
- break;
- case 4 :
- size3 += (length2 = end - start);
- System.arraycopy(astStack, astPtr + start + 1, typeDecl.memberTypes, size3 - length2, length2);
- break;
- };
- flagI = flag[start = end];
- }
- }
-
- if (typeDecl.memberTypes != null) {
- for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
- typeDecl.memberTypes[i].enclosingType = typeDecl;
- }
- }
- }
- protected CompilationUnitDeclaration endParse(int act) {
-
- this.lastAct = act;
-
- if (currentElement != null) {
- currentElement.topElement().updateParseTree();
- if (VERBOSE_RECOVERY) {
- System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
- System.out.println("--------------------------"); //$NON-NLS-1$
- System.out.println(compilationUnit);
- System.out.println("----------------------------------"); //$NON-NLS-1$
- }
- } else {
- if (diet & VERBOSE_RECOVERY) {
- System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
- System.out.println("--------------------------"); //$NON-NLS-1$
- System.out.println(compilationUnit);
- System.out.println("----------------------------------"); //$NON-NLS-1$
- }
- }
- if (scanner.recordLineSeparator) {
- compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
- }
- return compilationUnit;
- }
- /*
- * Flush annotations defined prior to a given positions.
- *
- * Note: annotations are stacked in syntactical order
- *
- * Either answer given <position>, or the end position of a comment line
- * immediately following the <position> (same line)
- *
- * e.g.
- * void foo(){
- * } // end of method foo
- */
-
- public int flushAnnotationsDefinedPriorTo(int position) {
-
- int lastAnnotationIndex = scanner.commentPtr;
- if (lastAnnotationIndex < 0)
- return position; // no comment
-
- // compute the index of the first obsolete comment
- int index = lastAnnotationIndex;
- int validCount = 0;
- while (index >= 0) {
- int commentEnd = scanner.commentStops[index];
- if (commentEnd < 0)
- commentEnd = -commentEnd; // negative end position for non-javadoc comments
- if (commentEnd <= position) {
- break;
- }
- index--;
- validCount++;
- }
- // if the source at <position> is immediately followed by a line comment, then
- // flush this comment and shift <position> to the comment end.
- if (validCount > 0) {
- int immediateCommentEnd = -scanner.commentStops[index + 1]; //non-javadoc comment end positions are negative
- if (immediateCommentEnd > 0) { // only tolerating non-javadoc comments
- // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
- immediateCommentEnd--; // comment end in one char too far
- if (scanner.getLineNumber(position) == scanner.getLineNumber(immediateCommentEnd)) {
- position = immediateCommentEnd;
- validCount--; // flush this comment
- index++;
- }
- }
- }
- // position can be located in the middle of a line break
- // this is a bug on Windows platform only.
- // http://dev.eclipse.org/bugs/show_bug.cgi?id=10557
- char[] source = scanner.source;
-
- if ((position < source.length)
- && (source[position] == '\r')
- && ((position + 1) < source.length)
- && (source[position + 1] == '\n')) {
- position++;
- }
- if (index < 0)
- return position; // no obsolete comment
-
- if (validCount > 0) { // move valid comment infos, overriding obsolete comment infos
- System.arraycopy(scanner.commentStarts, index + 1, scanner.commentStarts, 0, validCount);
- System.arraycopy(scanner.commentStops, index + 1, scanner.commentStops, 0, validCount);
- }
- scanner.commentPtr = validCount - 1;
- return position;
- }
- public final int getFirstToken() {
- // the first token is a virtual token that
- // allows the parser to parse several goals
- // even if they aren't LALR(1)....
- // Goal ::= '++' CompilationUnit
- // Goal ::= '--' MethodBody
- // Goal ::= '==' ConstructorBody
- // -- Initializer
- // Goal ::= '>>' StaticInitializer
- // Goal ::= '>>' Block
- // -- error recovery
- // Goal ::= '>>>' Headers
- // Goal ::= '*' BlockStatements
- // Goal ::= '*' MethodPushModifiersHeader
- // -- JDOM
- // Goal ::= '&&' FieldDeclaration
- // Goal ::= '||' ImportDeclaration
- // Goal ::= '?' PackageDeclaration
- // Goal ::= '+' TypeDeclaration
- // Goal ::= '/' GenericMethodDeclaration
- // Goal ::= '&' ClassBodyDeclaration
- // -- code snippet
- // Goal ::= '%' Expression
- // -- completion parser
- // Goal ::= '!' ConstructorBlockStatementsopt
- // Goal ::= '~' BlockStatementsopt
-
- return firstToken;
- }
- /*
- * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
- * The array is a flattened structure: 2*n entries with consecutives start and end positions.
- *
- * If no JavaDoc is available, then null is answered instead of an empty array.
- *
- * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
- */
- public int[] getJavaDocPositions() {
-
- int javadocCount = 0;
- for (int i = 0, max = scanner.commentPtr; i <= max; i++) {
- // javadoc only (non javadoc comment have negative end positions.)
- if (scanner.commentStops[i] > 0) {
- javadocCount++;
- }
- }
- if (javadocCount == 0)
- return null;
-
- int[] positions = new int[2 * javadocCount];
- int index = 0;
- for (int i = 0, max = scanner.commentPtr; i <= max; i++) {
- // javadoc only (non javadoc comment have negative end positions.)
- if (scanner.commentStops[i] > 0) {
- positions[index++] = scanner.commentStarts[i];
- positions[index++] = scanner.commentStops[i] - 1; //stop is one over
- }
- }
- return positions;
- }
- protected void getMethodBodies(CompilationUnitDeclaration unit) {
- //fill the methods bodies in order for the code to be generated
-
- if (unit == null)
- return;
-
- if (unit.ignoreMethodBodies) {
- unit.ignoreFurtherInvestigation = true;
- return;
- // if initial diet parse did not work, no need to dig into method bodies.
- }
-
- //real parse of the method....
- this.scanner.setSource(unit.compilationResult.compilationUnit.getContents());
- if (unit.types != null) {
- for (int i = unit.types.length; --i >= 0;)
- unit.types[i].parseMethod(this, unit);
- }
- }
- protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
- This variable is a type reference and dim will be its dimensions*/
-
- int length;
- TypeReference ref;
- if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
- // single variable reference
- if (dim == 0) {
- ref = new SingleTypeReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
- } else {
- ref = new ArrayTypeReference(identifierStack[identifierPtr], dim, identifierPositionStack[identifierPtr--]);
- ref.sourceEnd = endPosition;
- }
- } else {
- if (length < 0) { //flag for precompiled type reference on base types
- ref = TypeReference.baseTypeReference(-length, dim);
- ref.sourceStart = intStack[intPtr--];
- if (dim == 0) {
- ref.sourceEnd = intStack[intPtr--];
- } else {
- intPtr--;
- ref.sourceEnd = endPosition;
- }
- } else { //Qualified variable reference
- char[][] tokens = new char[length][];
- identifierPtr -= length;
- long[] positions = new long[length];
- System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
- System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
- if (dim == 0) {
- ref = new QualifiedTypeReference(tokens, positions);
- } else {
- ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
- ref.sourceEnd = endPosition;
- }
- }
- };
- return ref;
- }
- protected Expression getTypeReference(Expression exp) {
-
- exp.bits &= ~AstNode.RestrictiveFlagMASK;
- exp.bits |= TYPE;
- return exp;
- }
- protected NameReference getUnspecifiedReference() {
- /* build a (unspecified) NameReference which may be qualified*/
-
- int length;
- NameReference ref;
- if ((length = identifierLengthStack[identifierLengthPtr--]) == 1)
- // single variable reference
- ref = new SingleNameReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
- else
- //Qualified variable reference
- {
- char[][] tokens = new char[length][];
- identifierPtr -= length;
- System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
- ref = new QualifiedNameReference(tokens, (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
- (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
- };
- return ref;
- }
- protected NameReference getUnspecifiedReferenceOptimized() {
- /* build a (unspecified) NameReference which may be qualified
- The optimization occurs for qualified reference while we are
- certain in this case the last item of the qualified name is
- a field access. This optimization is IMPORTANT while it results
- that when a NameReference is build, the type checker should always
- look for that it is not a type reference */
-
- int length;
- NameReference ref;
- if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
- // single variable reference
- ref = new SingleNameReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
- ref.bits &= ~AstNode.RestrictiveFlagMASK;
- ref.bits |= LOCAL | FIELD;
- return ref;
- }
-
- //Qualified-variable-reference
- //In fact it is variable-reference DOT field-ref , but it would result in a type
- //conflict tha can be only reduce by making a superclass (or inetrface ) between
- //nameReference and FiledReference or putting FieldReference under NameReference
- //or else..........This optimisation is not really relevant so just leave as it is
-
- char[][] tokens = new char[length][];
- identifierPtr -= length;
- System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
- ref = new QualifiedNameReference(tokens, (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
- (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
- ref.bits &= ~AstNode.RestrictiveFlagMASK;
- ref.bits |= LOCAL | FIELD;
- return ref;
- }
- public void goForBlockStatementsOrMethodHeaders() {
- //tells the scanner to go for block statements or method headers parsing
-
- firstToken = TokenNameMULTIPLY;
- scanner.recordLineSeparator = false;
- }
- public void goForClassBodyDeclarations() {
- //tells the scanner to go for any body declarations parsing
-
- firstToken = TokenNameAND;
- scanner.recordLineSeparator = true;
- }
- public void goForCompilationUnit() {
- //tells the scanner to go for compilation unit parsing
-
- firstToken = TokenNamePLUS_PLUS;
- scanner.linePtr = -1;
- scanner.recordLineSeparator = true;
- scanner.currentLine = null;
- scanner.lines = new ArrayList();
- }
- public void goForConstructorBody() {
- //tells the scanner to go for compilation unit parsing
-
- firstToken = TokenNameEQUAL_EQUAL;
- scanner.recordLineSeparator = false;
- }
- public void goForExpression() {
- //tells the scanner to go for an expression parsing
-
- firstToken = TokenNameREMAINDER;
- scanner.recordLineSeparator = false;
- }
- public void goForFieldDeclaration() {
- //tells the scanner to go for field declaration parsing
-
- firstToken = TokenNameAND_AND;
- scanner.recordLineSeparator = true;
- }
- public void goForGenericMethodDeclaration() {
- //tells the scanner to go for generic method declarations parsing
-
- firstToken = TokenNameDIVIDE;
- scanner.recordLineSeparator = true;
- }
- public void goForHeaders() {
- //tells the scanner to go for headers only parsing
-
- firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
- scanner.recordLineSeparator = true;
- }
- public void goForImportDeclaration() {
- //tells the scanner to go for import declaration parsing
-
- firstToken = TokenNameOR_OR;
- scanner.recordLineSeparator = true;
- }
- public void goForInitializer() {
- //tells the scanner to go for initializer parsing
-
- firstToken = TokenNameRIGHT_SHIFT;
- scanner.recordLineSeparator = false;
- }
- public void goForMethodBody() {
- //tells the scanner to go for method body parsing
-
- firstToken = TokenNameMINUS_MINUS;
- scanner.recordLineSeparator = false;
- }
- public void goForPackageDeclaration() {
- //tells the scanner to go for package declaration parsing
-
- firstToken = TokenNameQUESTION;
- scanner.recordLineSeparator = true;
- }
- public void goForTypeDeclaration() {
- //tells the scanner to go for type (interface or class) declaration parsing
-
- firstToken = TokenNamePLUS;
- scanner.recordLineSeparator = true;
- }
- public final static void grammar() {
- /*
- --main options
- %options ACTION, AN=JavaAction.java, GP=java,
- %options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 ,
- %options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE=TIME ,
-
- --error recovering options.....
- %options ERROR_MAPS
-
- --grammar understanding options
- %options first follow
- %options TRACE=FULL ,
- %options VERBOSE
-
- --Usefull macros helping reading/writing semantic actions
- $Define
- $putCase
- /. case $rule_number : // System.out.println("$rule_text");
- ./
-
- $break
- /.
- break ;
- ./
-
- -- here it starts really ------------------------------------------
- $Terminals
-
- Identifier
-
- abstract assert boolean break byte case catch char class
- continue default do double else extends false final finally float
- for if implements import instanceof int
- interface long native new null package private
- protected public return short static strictfp super switch
- synchronized this throw throws transient true try void
- volatile while
-
- IntegerLiteral
- LongLiteral
- FloatingPointLiteral
- DoubleLiteral
- CharacterLiteral
- StringLiteral
-
- PLUS_PLUS
- MINUS_MINUS
- EQUAL_EQUAL
- LESS_EQUAL
- GREATER_EQUAL
- NOT_EQUAL
- LEFT_SHIFT
- RIGHT_SHIFT
- UNSIGNED_RIGHT_SHIFT
- PLUS_EQUAL
- MINUS_EQUAL
- MULTIPLY_EQUAL
- DIVIDE_EQUAL
- AND_EQUAL
- OR_EQUAL
- XOR_EQUAL
- REMAINDER_EQUAL
- LEFT_SHIFT_EQUAL
- RIGHT_SHIFT_EQUAL
- UNSIGNED_RIGHT_SHIFT_EQUAL
- OR_OR
- AND_AND
- PLUS
- MINUS
- NOT
- REMAINDER
- XOR
- AND
- MULTIPLY
- OR
- TWIDDLE
- DIVIDE
- GREATER
- LESS
- LPAREN
- RPAREN
- LBRACE
- RBRACE
- LBRACKET
- RBRACKET
- SEMICOLON
- QUESTION
- COLON
- COMMA
- DOT
- EQUAL
-
- -- BodyMarker
-
- $Alias
-
- '++' ::= PLUS_PLUS
- '--' ::= MINUS_MINUS
- '==' ::= EQUAL_EQUAL
- '<=' ::= LESS_EQUAL
- '>=' ::= GREATER_EQUAL
- '!=' ::= NOT_EQUAL
- '<<' ::= LEFT_SHIFT
- '>>' ::= RIGHT_SHIFT
- '>>>' ::= UNSIGNED_RIGHT_SHIFT
- '+=' ::= PLUS_EQUAL
- '-=' ::= MINUS_EQUAL
- '*=' ::= MULTIPLY_EQUAL
- '/=' ::= DIVIDE_EQUAL
- '&=' ::= AND_EQUAL
- '|=' ::= OR_EQUAL
- '^=' ::= XOR_EQUAL
- '%=' ::= REMAINDER_EQUAL
- '<<=' ::= LEFT_SHIFT_EQUAL
- '>>=' ::= RIGHT_SHIFT_EQUAL
- '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL
- '||' ::= OR_OR
- '&&' ::= AND_AND
-
- '+' ::= PLUS
- '-' ::= MINUS
- '!' ::= NOT
- '%' ::= REMAINDER
- '^' ::= XOR
- '&' ::= AND
- '*' ::= MULTIPLY
- '|' ::= OR
- '~' ::= TWIDDLE
- '/' ::= DIVIDE
- '>' ::= GREATER
- '<' ::= LESS
- '(' ::= LPAREN
- ')' ::= RPAREN
- '{' ::= LBRACE
- '}' ::= RBRACE
- '[' ::= LBRACKET
- ']' ::= RBRACKET
- ';' ::= SEMICOLON
- '?' ::= QUESTION
- ':' ::= COLON
- ',' ::= COMMA
- '.' ::= DOT
- '=' ::= EQUAL
-
- $Start
- Goal
-
- $Rules
-
- /. // This method is part of an automatic generation : do NOT edit-modify
- protected void consumeRule(int act) {
- switch ( act ) {
- ./
-
-
-
- Goal ::= '++' CompilationUnit
- Goal ::= '--' MethodBody
- Goal ::= '==' ConstructorBody
- -- Initializer
- Goal ::= '>>' StaticInitializer
- Goal ::= '>>' Initializer
- -- error recovery
- Goal ::= '>>>' Headers
- Goal ::= '*' BlockStatements
- Goal ::= '*' MethodPushModifiersHeader
- Goal ::= '*' CatchHeader
- -- JDOM
- Goal ::= '&&' FieldDeclaration
- Goal ::= '||' ImportDeclaration
- Goal ::= '?' PackageDeclaration
- Goal ::= '+' TypeDeclaration
- Goal ::= '/' GenericMethodDeclaration
- Goal ::= '&' ClassBodyDeclaration
- -- code snippet
- Goal ::= '%' Expression
- -- completion parser
- Goal ::= '!' ConstructorBlockStatementsopt
- Goal ::= '~' BlockStatementsopt
-
- Literal -> IntegerLiteral
- Literal -> LongLiteral
- Literal -> FloatingPointLiteral
- Literal -> DoubleLiteral
- Literal -> CharacterLiteral
- Literal -> StringLiteral
- Literal -> null
- Literal -> BooleanLiteral
- BooleanLiteral -> true
- BooleanLiteral -> false
-
- -------------------------------------------------------------
- -------------------------------------------------------------
- --a Type results in both a push of its dimension(s) and its name(s).
-
- Type ::= PrimitiveType
- /.$putCase consumePrimitiveType(); $break ./
- Type -> ReferenceType
-
- PrimitiveType -> NumericType
- NumericType -> IntegralType
- NumericType -> FloatingPointType
-
- PrimitiveType -> 'boolean'
- PrimitiveType -> 'void'
- IntegralType -> 'byte'
- IntegralType -> 'short'
- IntegralType -> 'int'
- IntegralType -> 'long'
- IntegralType -> 'char'
- FloatingPointType -> 'float'
- FloatingPointType -> 'double'
-
- ReferenceType ::= ClassOrInterfaceType
- /.$putCase consumeReferenceType(); $break ./
- ReferenceType -> ArrayType -- here a push of dimensions is done, that explains the two previous push 0
-
- ClassOrInterfaceType -> Name
-
- --
- -- These rules have been rewritten to avoid some conflicts introduced
- -- by adding the 1.1 features
- --
- -- ArrayType ::= PrimitiveType '[' ']'
- -- ArrayType ::= Name '[' ']'
- -- ArrayType ::= ArrayType '[' ']'
- --
-
- ArrayType ::= PrimitiveType Dims
- ArrayType ::= Name Dims
-
- ClassType -> ClassOrInterfaceType
-
-
- --------------------------------------------------------------
- --------------------------------------------------------------
-
- Name -> SimpleName
- Name -> QualifiedName
-
- SimpleName -> 'Identifier'
-
- QualifiedName ::= Name '.' SimpleName
- /.$putCase consumeQualifiedName(); $break ./
-
- CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt
- /.$putCase consumeCompilationUnit(); $break ./
-
- EnterCompilationUnit ::= $empty
- /.$putCase consumeEnterCompilationUnit(); $break ./
-
- Headers -> Header
- Headers ::= Headers Header
-
- Header -> ImportDeclaration
- Header -> PackageDeclaration
- Header -> ClassHeader
- Header -> InterfaceHeader
- Header -> StaticInitializer
- Header -> MethodHeader
- Header -> ConstructorHeader
- Header -> FieldDeclaration
- Header -> AllocationHeader
-
- CatchHeader ::= 'catch' '(' FormalParameter ')' '{'
- /.$putCase consumeCatchHeader(); $break ./
-
- ImportDeclarations -> ImportDeclaration
- ImportDeclarations ::= ImportDeclarations ImportDeclaration
- /.$putCase consumeImportDeclarations(); $break ./
-
- TypeDeclarations -> TypeDeclaration
- TypeDeclarations ::= TypeDeclarations TypeDeclaration
- /.$putCase consumeTypeDeclarations(); $break ./
-
- PackageDeclaration ::= PackageDeclarationName ';'
- /.$putCase consumePackageDeclaration(); $break ./
-
- PackageDeclarationName ::= 'package' Name
- /.$putCase consumePackageDeclarationName(); $break ./
-
- ImportDeclaration -> SingleTypeImportDeclaration
- ImportDeclaration -> TypeImportOnDemandDeclaration
-
- SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
- /.$putCase consumeSingleTypeImportDeclaration(); $break ./
-
- SingleTypeImportDeclarationName ::= 'import' Name
- /.$putCase consumeSingleTypeImportDeclarationName(); $break ./
-
- TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
- /.$putCase consumeTypeImportOnDemandDeclaration(); $break ./
-
- TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
- /.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./
-
- TypeDeclaration -> ClassDeclaration
- TypeDeclaration -> InterfaceDeclaration
- -- this declaration in part of a list od declaration and we will
- -- use and optimized list length calculation process
- -- thus we decrement the number while it will be incremend.....
- TypeDeclaration ::= ';'
- /. $putCase consumeEmptyTypeDeclaration(); $break ./
-
- --18.7 Only in the LALR(1) Grammar
-
- Modifiers ::= Modifier
- Modifiers ::= Modifiers Modifier
-
- Modifier -> 'public'
- Modifier -> 'protected'
- Modifier -> 'private'
- Modifier -> 'static'
- Modifier -> 'abstract'
- Modifier -> 'final'
- Modifier -> 'native'
- Modifier -> 'synchronized'
- Modifier -> 'transient'
- Modifier -> 'volatile'
- Modifier -> 'strictfp'
-
- --18.8 Productions from 8: Class Declarations
- --ClassModifier ::=
- -- 'abstract'
- -- | 'final'
- -- | 'public'
- --18.8.1 Productions from 8.1: Class Declarations
-
- ClassDeclaration ::= ClassHeader ClassBody
- /.$putCase consumeClassDeclaration(); $break ./
-
- ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
- /.$putCase consumeClassHeader(); $break ./
-
- ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
- /.$putCase consumeClassHeaderName(); $break ./
-
- ClassHeaderExtends ::= 'extends' ClassType
- /.$putCase consumeClassHeaderExtends(); $break ./
-
- ClassHeaderImplements ::= 'implements' InterfaceTypeList
- /.$putCase consumeClassHeaderImplements(); $break ./
-
- InterfaceTypeList -> InterfaceType
- InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
- /.$putCase consumeInterfaceTypeList(); $break ./
-
- InterfaceType ::= ClassOrInterfaceType
- /.$putCase consumeInterfaceType(); $break ./
-
- ClassBody ::= '{' ClassBodyDeclarationsopt '}'
-
- ClassBodyDeclarations ::= ClassBodyDeclaration
- ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
- /.$putCase consumeClassBodyDeclarations(); $break ./
-
- ClassBodyDeclaration -> ClassMemberDeclaration
- ClassBodyDeclaration -> StaticInitializer
- ClassBodyDeclaration -> ConstructorDeclaration
- --1.1 feature
- ClassBodyDeclaration ::= Diet NestedMethod Block
- /.$putCase consumeClassBodyDeclaration(); $break ./
- Diet ::= $empty
- /.$putCase consumeDiet(); $break./
-
- Initializer ::= Diet NestedMethod Block
- /.$putCase consumeClassBodyDeclaration(); $break ./
-
- ClassMemberDeclaration -> FieldDeclaration
- ClassMemberDeclaration -> MethodDeclaration
- --1.1 feature
- ClassMemberDeclaration -> ClassDeclaration
- --1.1 feature
- ClassMemberDeclaration -> InterfaceDeclaration
-
- -- Empty declarations are not valid Java ClassMemberDeclarations.
- -- However, since the current (2/14/97) Java compiler accepts them
- -- (in fact, some of the official tests contain this erroneous
- -- syntax)
-
- GenericMethodDeclaration -> MethodDeclaration
- GenericMethodDeclaration -> ConstructorDeclaration
-
- ClassMemberDeclaration ::= ';'
- /.$putCase consumeEmptyClassMemberDeclaration(); $break./
-
- --18.8.2 Productions from 8.3: Field Declarations
- --VariableModifier ::=
- -- 'public'
- -- | 'protected'
- -- | 'private'
- -- | 'static'
- -- | 'final'
- -- | 'transient'
- -- | 'volatile'
-
- FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
- /.$putCase consumeFieldDeclaration(); $break ./
-
- VariableDeclarators -> VariableDeclarator
- VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
- /.$putCase consumeVariableDeclarators(); $break ./
-
- VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization
-
- VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
-
- EnterVariable ::= $empty
- /.$putCase consumeEnterVariable(); $break ./
-
- ExitVariableWithInitialization ::= $empty
- /.$putCase consumeExitVariableWithInitialization(); $break ./
-
- ExitVariableWithoutInitialization ::= $empty
- /.$putCase consumeExitVariableWithoutInitialization(); $break ./
-
- ForceNoDiet ::= $empty
- /.$putCase consumeForceNoDiet(); $break ./
- RestoreDiet ::= $empty
- /.$putCase consumeRestoreDiet(); $break ./
-
- VariableDeclaratorId ::= 'Identifier' Dimsopt
-
- VariableInitializer -> Expression
- VariableInitializer -> ArrayInitializer
-
- --18.8.3 Productions from 8.4: Method Declarations
- --MethodModifier ::=
- -- 'public'
- -- | 'protected'
- -- | 'private'
- -- | 'static'
- -- | 'abstract'
- -- | 'final'
- -- | 'native'
- -- | 'synchronized'
- --
-
- MethodDeclaration -> AbstractMethodDeclaration
- MethodDeclaration ::= MethodHeader MethodBody
- /.$putCase // set to true to consume a method with a body
- consumeMethodDeclaration(true); $break ./
-
- AbstractMethodDeclaration ::= MethodHeader ';'
- /.$putCase // set to false to consume a method without body
- consumeMethodDeclaration(false); $break ./
-
- MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
- /.$putCase consumeMethodHeader(); $break ./
-
- MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
- /.$putCase consumeMethodHeader(); $break ./
-
- MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
- /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
-
- MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
- /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
-
- MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
- /.$putCase consumeMethodHeaderName(); $break ./
-
- MethodHeaderParameters ::= FormalParameterListopt ')'
- /.$putCase consumeMethodHeaderParameters(); $break ./
-
- MethodHeaderExtendedDims ::= Dimsopt
- /.$putCase consumeMethodHeaderExtendedDims(); $break ./
-
- MethodHeaderThrowsClause ::= 'throws' ClassTypeList
- /.$putCase consumeMethodHeaderThrowsClause(); $break ./
-
- ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
- /.$putCase consumeConstructorHeader(); $break ./
-
- ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
- /.$putCase consumeConstructorHeaderName(); $break ./
-
- FormalParameterList -> FormalParameter
- FormalParameterList ::= FormalParameterList ',' FormalParameter
- /.$putCase consumeFormalParameterList(); $break ./
-
- --1.1 feature
- FormalParameter ::= Modifiersopt Type VariableDeclaratorId
- /.$putCase // the boolean is used to know if the modifiers should be reset
- consumeFormalParameter(); $break ./
-
- ClassTypeList -> ClassTypeElt
- ClassTypeList ::= ClassTypeList ',' ClassTypeElt
- /.$putCase consumeClassTypeList(); $break ./
-
- ClassTypeElt ::= ClassType
- /.$putCase consumeClassTypeElt(); $break ./
-
-
- MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
- /.$putCase consumeMethodBody(); $break ./
-
- NestedMethod ::= $empty
- /.$putCase consumeNestedMethod(); $break ./
-
- --18.8.4 Productions from 8.5: Static Initializers
-
- StaticInitializer ::= StaticOnly Block
- /.$putCase consumeStaticInitializer(); $break./
-
- StaticOnly ::= 'static'
- /.$putCase consumeStaticOnly(); $break ./
-
- --18.8.5 Productions from 8.6: Constructor Declarations
- --ConstructorModifier ::=
- -- 'public'
- -- | 'protected'
- -- | 'private'
- --
- --
- ConstructorDeclaration ::= ConstructorHeader ConstructorBody
- /.$putCase consumeConstructorDeclaration() ; $break ./
-
- -- These rules are added to be able to parse constructors with no body
- ConstructorDeclaration ::= ConstructorHeader ';'
- /.$putCase consumeInvalidConstructorDeclaration() ; $break ./
-
- -- the rules ExplicitConstructorInvocationopt has been expanded
- -- in the rule below in order to make the grammar lalr(1).
- -- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}'
- -- Other inlining has occured into the next rule too....
-
- ConstructorBody ::= NestedMethod '{' ConstructorBlockStatementsopt '}'
- /.$putCase consumeConstructorBody(); $break ./
-
- ConstructorBlockStatementsopt -> BlockStatementsopt
-
- ConstructorBlockStatementsopt -> ExplicitConstructorInvocation
-
- ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements
- /.$putCase consumeConstructorBlockStatements(); $break ./
-
- ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
- /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); $break ./
-
- ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
- /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); $break ./
-
- --1.1 feature
- ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
- /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); $break ./
-
- --1.1 feature
- ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
- /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); $break ./
-
- --1.1 feature
- ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
- /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); $break ./
-
- --1.1 feature
- ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
- /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); $break ./
-
- --18.9 Productions from 9: Interface Declarations
-
- --18.9.1 Productions from 9.1: Interface Declarations
- --InterfaceModifier ::=
- -- 'public'
- -- | 'abstract'
- --
- InterfaceDeclaration ::= InterfaceHeader InterfaceBody
- /.$putCase consumeInterfaceDeclaration(); $break ./
-
- InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
- /.$putCase consumeInterfaceHeader(); $break ./
-
- InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
- /.$putCase consumeInterfaceHeaderName(); $break ./
-
- -- This rule will be used to accept inner local interface and then report a relevant error message
- InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody
-
- InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
- /.$putCase consumeInterfaceHeaderExtends(); $break ./
-
- InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}'
-
- InterfaceMemberDeclarations -> InterfaceMemberDeclaration
- InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
- /.$putCase consumeInterfaceMemberDeclarations(); $break ./
-
- --same as for class members
- InterfaceMemberDeclaration ::= ';'
- /.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./
-
- -- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message
- InvalidMethodDeclaration -> MethodHeader MethodBody
-
- InterfaceMemberDeclaration -> ConstantDeclaration
- InterfaceMemberDeclaration ::= InvalidMethodDeclaration
- /.$putCase ignoreMethodBody(); $break ./
-
- -- These rules are added to be able to parse constructors inside interface and then report a relevent error message
- InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody
- /.$putCase ignoreInvalidConstructorDeclaration(true); $break ./
-
- InvalidConstructorDeclaration ::= ConstructorHeader ';'
- /.$putCase ignoreInvalidConstructorDeclaration(false); $break ./
-
- InterfaceMemberDeclaration -> AbstractMethodDeclaration
- InterfaceMemberDeclaration -> InvalidConstructorDeclaration
-
- --1.1 feature
- InterfaceMemberDeclaration -> ClassDeclaration
- --1.1 feature
- InterfaceMemberDeclaration -> InterfaceDeclaration
-
- ConstantDeclaration -> FieldDeclaration
-
- ArrayInitializer ::= '{' ,opt '}'
- /.$putCase consumeEmptyArrayInitializer(); $break ./
- ArrayInitializer ::= '{' VariableInitializers '}'
- /.$putCase consumeArrayInitializer(); $break ./
- ArrayInitializer ::= '{' VariableInitializers , '}'
- /.$putCase consumeArrayInitializer(); $break ./
-
- VariableInitializers ::= VariableInitializer
- VariableInitializers ::= VariableInitializers ',' VariableInitializer
- /.$putCase consumeVariableInitializers(); $break ./
-
- Block ::= OpenBlock '{' BlockStatementsopt '}'
- /.$putCase consumeBlock(); $break ./
- OpenBlock ::= $empty
- /.$putCase consumeOpenBlock() ; $break ./
-
- BlockStatements -> BlockStatement
- BlockStatements ::= BlockStatements BlockStatement
- /.$putCase consumeBlockStatements() ; $break ./
-
- BlockStatement -> LocalVariableDeclarationStatement
- BlockStatement -> Statement
- --1.1 feature
- BlockStatement -> ClassDeclaration
- BlockStatement ::= InvalidInterfaceDeclaration
- /.$putCase ignoreInterfaceDeclaration(); $break ./
-
- LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
- /.$putCase consumeLocalVariableDeclarationStatement(); $break ./
-
- LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators
- /.$putCase consumeLocalVariableDeclaration(); $break ./
-
- -- 1.1 feature
- -- The modifiers part of this rule makes the grammar more permissive.
- -- The only modifier here is final. We put Modifiers to allow multiple modifiers
- -- This will require to check the validity of the modifier
-
- LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators
- /.$putCase consumeLocalVariableDeclaration(); $break ./
-
- PushModifiers ::= $empty
- /.$putCase consumePushModifiers(); $break ./
-
- Statement -> StatementWithoutTrailingSubstatement
- Statement -> LabeledStatement
- Statement -> IfThenStatement
- Statement -> IfThenElseStatement
- Statement -> WhileStatement
- Statement -> ForStatement
-
- StatementNoShortIf -> StatementWithoutTrailingSubstatement
- StatementNoShortIf -> LabeledStatementNoShortIf
- StatementNoShortIf -> IfThenElseStatementNoShortIf
- StatementNoShortIf -> WhileStatementNoShortIf
- StatementNoShortIf -> ForStatementNoShortIf
-
- StatementWithoutTrailingSubstatement -> AssertStatement
- StatementWithoutTrailingSubstatement -> Block
- StatementWithoutTrailingSubstatement -> EmptyStatement
- StatementWithoutTrailingSubstatement -> ExpressionStatement
- StatementWithoutTrailingSubstatement -> SwitchStatement
- StatementWithoutTrailingSubstatement -> DoStatement
- StatementWithoutTrailingSubstatement -> BreakStatement
- StatementWithoutTrailingSubstatement -> ContinueStatement
- StatementWithoutTrailingSubstatement -> ReturnStatement
- StatementWithoutTrailingSubstatement -> SynchronizedStatement
- StatementWithoutTrailingSubstatement -> ThrowStatement
- StatementWithoutTrailingSubstatement -> TryStatement
-
- EmptyStatement ::= ';'
- /.$putCase consumeEmptyStatement(); $break ./
-
- LabeledStatement ::= 'Identifier' ':' Statement
- /.$putCase consumeStatementLabel() ; $break ./
-
- LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
- /.$putCase consumeStatementLabel() ; $break ./
-
- ExpressionStatement ::= StatementExpression ';'
- /. $putCase consumeExpressionStatement(); $break ./
-
- StatementExpression ::= Assignment
- StatementExpression ::= PreIncrementExpression
- StatementExpression ::= PreDecrementExpression
- StatementExpression ::= PostIncrementExpression
- StatementExpression ::= PostDecrementExpression
- StatementExpression ::= MethodInvocation
- StatementExpression ::= ClassInstanceCreationExpression
-
- IfThenStatement ::= 'if' '(' Expression ')' Statement
- /.$putCase consumeStatementIfNoElse(); $break ./
-
- IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
- /.$putCase consumeStatementIfWithElse(); $break ./
-
- IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
- /.$putCase consumeStatementIfWithElse(); $break ./
-
- SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
- /.$putCase consumeStatementSwitch() ; $break ./
-
- SwitchBlock ::= '{' '}'
- /.$putCase consumeEmptySwitchBlock() ; $break ./
-
- SwitchBlock ::= '{' SwitchBlockStatements '}'
- SwitchBlock ::= '{' SwitchLabels '}'
- SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
- /.$putCase consumeSwitchBlock() ; $break ./
-
- SwitchBlockStatements -> SwitchBlockStatement
- SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
- /.$putCase consumeSwitchBlockStatements() ; $break ./
-
- SwitchBlockStatement ::= SwitchLabels BlockStatements
- /.$putCase consumeSwitchBlockStatement() ; $break ./
-
- SwitchLabels -> SwitchLabel
- SwitchLabels ::= SwitchLabels SwitchLabel
- /.$putCase consumeSwitchLabels() ; $break ./
-
- SwitchLabel ::= 'case' ConstantExpression ':'
- /. $putCase consumeCaseLabel(); $break ./
-
- SwitchLabel ::= 'default' ':'
- /. $putCase consumeDefaultLabel(); $break ./
-
- WhileStatement ::= 'while' '(' Expression ')' Statement
- /.$putCase consumeStatementWhile() ; $break ./
-
- WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
- /.$putCase consumeStatementWhile() ; $break ./
-
- DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
- /.$putCase consumeStatementDo() ; $break ./
-
- ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
- /.$putCase consumeStatementFor() ; $break ./
- ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
- /.$putCase consumeStatementFor() ; $break ./
-
- --the minus one allows to avoid a stack-to-stack transfer
- ForInit ::= StatementExpressionList
- /.$putCase consumeForInit() ; $break ./
- ForInit -> LocalVariableDeclaration
-
- ForUpdate -> StatementExpressionList
-
- StatementExpressionList -> StatementExpression
- StatementExpressionList ::= StatementExpressionList ',' StatementExpression
- /.$putCase consumeStatementExpressionList() ; $break ./
-
- -- 1.4 feature
- AssertStatement ::= 'assert' Expression ';'
- /.$putCase consumeSimpleAssertStatement() ; $break ./
-
- AssertStatement ::= 'assert' Expression ':' Expression ';'
- /.$putCase consumeAssertStatement() ; $break ./
-
- BreakStatement ::= 'break' ';'
- /.$putCase consumeStatementBreak() ; $break ./
-
- BreakStatement ::= 'break' Identifier ';'
- /.$putCase consumeStatementBreakWithLabel() ; $break ./
-
- ContinueStatement ::= 'continue' ';'
- /.$putCase consumeStatementContinue() ; $break ./
-
- ContinueStatement ::= 'continue' Identifier ';'
- /.$putCase consumeStatementContinueWithLabel() ; $break ./
-
- ReturnStatement ::= 'return' Expressionopt ';'
- /.$putCase consumeStatementReturn() ; $break ./
-
- ThrowStatement ::= 'throw' Expression ';'
- /.$putCase consumeStatementThrow();
- $break ./
-
- SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
- /.$putCase consumeStatementSynchronized(); $break ./
- OnlySynchronized ::= 'synchronized'
- /.$putCase consumeOnlySynchronized(); $break ./
-
-
- TryStatement ::= 'try' Block Catches
- /.$putCase consumeStatementTry(false); $break ./
- TryStatement ::= 'try' Block Catchesopt Finally
- /.$putCase consumeStatementTry(true); $break ./
-
- Catches -> CatchClause
- Catches ::= Catches CatchClause
- /.$putCase consumeCatches(); $break ./
-
- CatchClause ::= 'catch' '(' FormalParameter ')' Block
- /.$putCase consumeStatementCatch() ; $break ./
-
- Finally ::= 'finally' Block
-
- --18.12 Productions from 14: Expressions
-
- --for source positionning purpose
- PushLPAREN ::= '('
- /.$putCase consumeLeftParen(); $break ./
- PushRPAREN ::= ')'
- /.$putCase consumeRightParen(); $break ./
-
- Primary -> PrimaryNoNewArray
- Primary -> ArrayCreationExpression
-
- PrimaryNoNewArray -> Literal
- PrimaryNoNewArray ::= 'this'
- /.$putCase consumePrimaryNoNewArrayThis(); $break ./
-
- PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
- /.$putCase consumePrimaryNoNewArray(); $break ./
-
- PrimaryNoNewArray -> ClassInstanceCreationExpression
- PrimaryNoNewArray -> FieldAccess
- --1.1 feature
- PrimaryNoNewArray ::= Name '.' 'this'
- /.$putCase consumePrimaryNoNewArrayNameThis(); $break ./
- PrimaryNoNewArray ::= Name '.' 'super'
- /.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./
-
- --1.1 feature
- --PrimaryNoNewArray ::= Type '.' 'class'
- --inline Type in the previous rule in order to make the grammar LL1 instead
- -- of LL2. The result is the 3 next rules.
- PrimaryNoNewArray ::= Name '.' 'class'
- /.$putCase consumePrimaryNoNewArrayName(); $break ./
-
- PrimaryNoNewArray ::= ArrayType '.' 'class'
- /.$putCase consumePrimaryNoNewArrayArrayType(); $break ./
-
- PrimaryNoNewArray ::= PrimitiveType '.' 'class'
- /.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./
-
- PrimaryNoNewArray -> MethodInvocation
- PrimaryNoNewArray -> ArrayAccess
-
- --1.1 feature
- --
- -- In Java 1.0 a ClassBody could not appear at all in a
- -- ClassInstanceCreationExpression.
- --
-
- AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')'
- /.$putCase consumeAllocationHeader(); $break ./
-
- ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
- /.$putCase consumeClassInstanceCreationExpression(); $break ./
- --1.1 feature
-
- ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
- /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
-
- --1.1 feature
- ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
- /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
-
- ClassInstanceCreationExpressionName ::= Name '.'
- /.$putCase consumeClassInstanceCreationExpressionName() ; $break ./
-
- ClassBodyopt ::= $empty --test made using null as contents
- /.$putCase consumeClassBodyopt(); $break ./
- ClassBodyopt ::= EnterAnonymousClassBody ClassBody
-
- EnterAnonymousClassBody ::= $empty
- /.$putCase consumeEnterAnonymousClassBody(); $break ./
-
- ArgumentList ::= Expression
- ArgumentList ::= ArgumentList ',' Expression
- /.$putCase consumeArgumentList(); $break ./
-
- --Thess rules are re-written in order to be ll1
- --ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer
- --ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt
- --ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt
- --DimExprs ::= DimExpr
- --DimExprs ::= DimExprs DimExpr
-
- ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
- /.$putCase consumeArrayCreationExpression(); $break ./
- ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
- /.$putCase consumeArrayCreationExpression(); $break ./
-
- DimWithOrWithOutExprs ::= DimWithOrWithOutExpr
- DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
- /.$putCase consumeDimWithOrWithOutExprs(); $break ./
-
- DimWithOrWithOutExpr ::= '[' Expression ']'
- DimWithOrWithOutExpr ::= '[' ']'
- /. $putCase consumeDimWithOrWithOutExpr(); $break ./
- -- -----------------------------------------------
-
- Dims ::= DimsLoop
- /. $putCase consumeDims(); $break ./
- DimsLoop -> OneDimLoop
- DimsLoop ::= DimsLoop OneDimLoop
- OneDimLoop ::= '[' ']'
- /. $putCase consumeOneDimLoop(); $break ./
-
- FieldAccess ::= Primary '.' 'Identifier'
- /.$putCase consumeFieldAccess(false); $break ./
-
- FieldAccess ::= 'super' '.' 'Identifier'
- /.$putCase consumeFieldAccess(true); $break ./
-
- MethodInvocation ::= Name '(' ArgumentListopt ')'
- /.$putCase consumeMethodInvocationName(); $break ./
-
- MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
- /.$putCase consumeMethodInvocationPrimary(); $break ./
-
- MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
- /.$putCase consumeMethodInvocationSuper(); $break ./
-
- ArrayAccess ::= Name '[' Expression ']'
- /.$putCase consumeArrayAccess(true); $break ./
- ArrayAccess ::= PrimaryNoNewArray '[' Expression ']'
- /.$putCase consumeArrayAccess(false); $break ./
-
- PostfixExpression -> Primary
- PostfixExpression ::= Name
- /.$putCase consumePostfixExpression(); $break ./
- PostfixExpression -> PostIncrementExpression
- PostfixExpression -> PostDecrementExpression
-
- PostIncrementExpression ::= PostfixExpression '++'
- /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,true); $break ./
-
- PostDecrementExpression ::= PostfixExpression '--'
- /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,true); $break ./
-
- --for source managment purpose
- PushPosition ::= $empty
- /.$putCase consumePushPosition(); $break ./
-
- UnaryExpression -> PreIncrementExpression
- UnaryExpression -> PreDecrementExpression
- UnaryExpression ::= '+' PushPosition UnaryExpression
- /.$putCase consumeUnaryExpression(OperatorExpression.PLUS); $break ./
- UnaryExpression ::= '-' PushPosition UnaryExpression
- /.$putCase consumeUnaryExpression(OperatorExpression.MINUS); $break ./
- UnaryExpression -> UnaryExpressionNotPlusMinus
-
- PreIncrementExpression ::= '++' PushPosition UnaryExpression
- /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,false); $break ./
-
- PreDecrementExpression ::= '--' PushPosition UnaryExpression
- /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,false); $break ./
-
- UnaryExpressionNotPlusMinus -> PostfixExpression
- UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
- /.$putCase consumeUnaryExpression(OperatorExpression.TWIDDLE); $break ./
- UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
- /.$putCase consumeUnaryExpression(OperatorExpression.NOT); $break ./
- UnaryExpressionNotPlusMinus -> CastExpression
-
- CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
- /.$putCase consumeCastExpression(); $break ./
- CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
- /.$putCase consumeCastExpression(); $break ./
- -- Expression is here only in order to make the grammar LL1
- CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus
- /.$putCase consumeCastExpressionLL1(); $break ./
-
- MultiplicativeExpression -> UnaryExpression
- MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.MULTIPLY); $break ./
- MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.DIVIDE); $break ./
- MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.REMAINDER); $break ./
-
- AdditiveExpression -> MultiplicativeExpression
- AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.PLUS); $break ./
- AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.MINUS); $break ./
-
- ShiftExpression -> AdditiveExpression
- ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); $break ./
- ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); $break ./
- ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); $break ./
-
- RelationalExpression -> ShiftExpression
- RelationalExpression ::= RelationalExpression '<' ShiftExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.LESS); $break ./
- RelationalExpression ::= RelationalExpression '>' ShiftExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.GREATER); $break ./
- RelationalExpression ::= RelationalExpression '<=' ShiftExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.LESS_EQUAL); $break ./
- RelationalExpression ::= RelationalExpression '>=' ShiftExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); $break ./
- RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
- /.$putCase consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); $break ./
-
- EqualityExpression -> RelationalExpression
- EqualityExpression ::= EqualityExpression '==' RelationalExpression
- /.$putCase consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); $break ./
- EqualityExpression ::= EqualityExpression '!=' RelationalExpression
- /.$putCase consumeEqualityExpression(OperatorExpression.NOT_EQUAL); $break ./
-
- AndExpression -> EqualityExpression
- AndExpression ::= AndExpression '&' EqualityExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.AND); $break ./
-
- ExclusiveOrExpression -> AndExpression
- ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.XOR); $break ./
-
- InclusiveOrExpression -> ExclusiveOrExpression
- InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.OR); $break ./
-
- ConditionalAndExpression -> InclusiveOrExpression
- ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.AND_AND); $break ./
-
- ConditionalOrExpression -> ConditionalAndExpression
- ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
- /.$putCase consumeBinaryExpression(OperatorExpression.OR_OR); $break ./
-
- ConditionalExpression -> ConditionalOrExpression
- ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
- /.$putCase consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; $break ./
-
- AssignmentExpression -> ConditionalExpression
- AssignmentExpression -> Assignment
-
- Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
- /.$putCase consumeAssignment(); $break ./
-
- -- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario
- InvalidArrayInitializerAssignement ::= LeftHandSide AssignmentOperator ArrayInitializer
- Assignment ::= InvalidArrayInitializerAssignement
- /.$putcase ignoreExpressionAssignment();$break ./
-
- LeftHandSide ::= Name
- /.$putCase consumeLeftHandSide(); $break ./
- LeftHandSide -> FieldAccess
- LeftHandSide -> ArrayAccess
-
- AssignmentOperator ::= '='
- /.$putCase consumeAssignmentOperator(EQUAL); $break ./
- AssignmentOperator ::= '*='
- /.$putCase consumeAssignmentOperator(MULTIPLY); $break ./
- AssignmentOperator ::= '/='
- /.$putCase consumeAssignmentOperator(DIVIDE); $break ./
- AssignmentOperator ::= '%='
- /.$putCase consumeAssignmentOperator(REMAINDER); $break ./
- AssignmentOperator ::= '+='
- /.$putCase consumeAssignmentOperator(PLUS); $break ./
- AssignmentOperator ::= '-='
- /.$putCase consumeAssignmentOperator(MINUS); $break ./
- AssignmentOperator ::= '<<='
- /.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./
- AssignmentOperator ::= '>>='
- /.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./
- AssignmentOperator ::= '>>>='
- /.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./
- AssignmentOperator ::= '&='
- /.$putCase consumeAssignmentOperator(AND); $break ./
- AssignmentOperator ::= '^='
- /.$putCase consumeAssignmentOperator(XOR); $break ./
- AssignmentOperator ::= '|='
- /.$putCase consumeAssignmentOperator(OR); $break ./
-
- Expression -> AssignmentExpression
-
- ConstantExpression -> Expression
-
- -- The following rules are for optional nonterminals.
- --
-
- PackageDeclarationopt -> $empty
- PackageDeclarationopt -> PackageDeclaration
-
- ClassHeaderExtendsopt ::= $empty
- ClassHeaderExtendsopt -> ClassHeaderExtends
-
- Expressionopt ::= $empty
- /.$putCase consumeEmptyExpression(); $break ./
- Expressionopt -> Expression
-
-
- ---------------------------------------------------------------------------------------
- --
- -- The rules below are for optional terminal symbols. An optional comma,
- -- is only used in the context of an array initializer - It is a
- -- "syntactic sugar" that otherwise serves no other purpose. By contrast,
- -- an optional identifier is used in the definition of a break and
- -- continue statement. When the identifier does not appear, a NULL
- -- is produced. When the identifier is present, the user should use the
- -- corresponding TOKEN(i) method. See break statement as an example.
- --
- ---------------------------------------------------------------------------------------
-
- ,opt -> $empty
- ,opt -> ,
-
- ImportDeclarationsopt ::= $empty
- /.$putCase consumeEmptyImportDeclarationsopt(); $break ./
- ImportDeclarationsopt ::= ImportDeclarations
- /.$putCase consumeImportDeclarationsopt(); $break ./
-
-
- TypeDeclarationsopt ::= $empty
- /.$putCase consumeEmptyTypeDeclarationsopt(); $break ./
- TypeDeclarationsopt ::= TypeDeclarations
- /.$putCase consumeTypeDeclarationsopt(); $break ./
-
- ClassBodyDeclarationsopt ::= $empty
- /.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./
- ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
- /.$putCase consumeClassBodyDeclarationsopt(); $break ./
-
- Modifiersopt ::= $empty
- /. $putCase consumeDefaultModifiers(); $break ./
- Modifiersopt ::= Modifiers
- /.$putCase consumeModifiers(); $break ./
-
- BlockStatementsopt ::= $empty
- /.$putCase consumeEmptyBlockStatementsopt(); $break ./
- BlockStatementsopt -> BlockStatements
-
- Dimsopt ::= $empty
- /. $putCase consumeEmptyDimsopt(); $break ./
- Dimsopt -> Dims
-
- ArgumentListopt ::= $empty
- /. $putCase consumeEmptyArgumentListopt(); $break ./
- ArgumentListopt -> ArgumentList
-
- MethodHeaderThrowsClauseopt ::= $empty
- MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause
-
- FormalParameterListopt ::= $empty
- /.$putcase consumeFormalParameterListopt(); $break ./
- FormalParameterListopt -> FormalParameterList
-
- ClassHeaderImplementsopt ::= $empty
- ClassHeaderImplementsopt -> ClassHeaderImplements
-
- InterfaceMemberDeclarationsopt ::= $empty
- /. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
- InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
- /. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./
-
- NestedType ::= $empty
- /.$putCase consumeNestedType(); $break./
-
- ForInitopt ::= $empty
- /. $putCase consumeEmptyForInitopt(); $break ./
- ForInitopt -> ForInit
-
- ForUpdateopt ::= $empty
- /. $putCase consumeEmptyForUpdateopt(); $break ./
- ForUpdateopt -> ForUpdate
-
- InterfaceHeaderExtendsopt ::= $empty
- InterfaceHeaderExtendsopt -> InterfaceHeaderExtends
-
- Catchesopt ::= $empty
- /. $putCase consumeEmptyCatchesopt(); $break ./
- Catchesopt -> Catches
-
- ArrayInitializeropt ::= $empty
- /. $putCase consumeEmptyArrayInitializeropt(); $break ./
- ArrayInitializeropt -> ArrayInitializer
-
- /. }
- } ./
-
- ---------------------------------------------------------------------------------------
-
- $names
-
- -- BodyMarker ::= '"class Identifier { ... MethodHeader "'
-
- -- void ::= 'void'
-
- PLUS_PLUS ::= '++'
- MINUS_MINUS ::= '--'
- EQUAL_EQUAL ::= '=='
- LESS_EQUAL ::= '<='
- GREATER_EQUAL ::= '>='
- NOT_EQUAL ::= '!='
- LEFT_SHIFT ::= '<<'
- RIGHT_SHIFT ::= '>>'
- UNSIGNED_RIGHT_SHIFT ::= '>>>'
- PLUS_EQUAL ::= '+='
- MINUS_EQUAL ::= '-='
- MULTIPLY_EQUAL ::= '*='
- DIVIDE_EQUAL ::= '/='
- AND_EQUAL ::= '&='
- OR_EQUAL ::= '|='
- XOR_EQUAL ::= '^='
- REMAINDER_EQUAL ::= '%='
- LEFT_SHIFT_EQUAL ::= '<<='
- RIGHT_SHIFT_EQUAL ::= '>>='
- UNSIGNED_RIGHT_SHIFT_EQUAL ::= '>>>='
- OR_OR ::= '||'
- AND_AND ::= '&&'
-
- PLUS ::= '+'
- MINUS ::= '-'
- NOT ::= '!'
- REMAINDER ::= '%'
- XOR ::= '^'
- AND ::= '&'
- MULTIPLY ::= '*'
- OR ::= '|'
- TWIDDLE ::= '~'
- DIVIDE ::= '/'
- GREATER ::= '>'
- LESS ::= '<'
- LPAREN ::= '('
- RPAREN ::= ')'
- LBRACE ::= '{'
- RBRACE ::= '}'
- LBRACKET ::= '['
- RBRACKET ::= ']'
- SEMICOLON ::= ';'
- QUESTION ::= '?'
- COLON ::= ':'
- COMMA ::= ','
- DOT ::= '.'
- EQUAL ::= '='
-
- $end
- -- need a carriage return after the $end
- */
- }
- protected void ignoreExpressionAssignment() {
- // Assignment ::= InvalidArrayInitializerAssignement
- // encoded operator would be: intStack[intPtr]
- intPtr--;
- ArrayInitializer arrayInitializer = (ArrayInitializer) expressionStack[expressionPtr--];
- expressionLengthPtr--;
- // report a syntax error and abort parsing
- problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);
- }
- protected void ignoreInterfaceDeclaration() {
- // BlockStatement ::= InvalidInterfaceDeclaration
- //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
-
- // length declarations
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- //there are length declarations
- //dispatch according to the type of the declarations
- dispatchDeclarationInto(length);
- }
-
- flushAnnotationsDefinedPriorTo(endStatementPosition);
-
- // report the problem and continue parsing
- TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
- typeDecl.bodyEnd = endStatementPosition;
- problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
-
- // mark fields and initializer with local type mark if needed
- markFieldsWithLocalType(typeDecl);
-
- // remove the ast node created in interface header
- astPtr--;
- // Don't create an astnode for this inner interface, but have to push
- // a 0 on the astLengthStack to be consistent with the reduction made
- // at the end of the method:
- // public void parse(MethodDeclaration md, CompilationUnitDeclaration unit)
- pushOnAstLengthStack(0);
- }
- protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
- // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
- // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
-
- /*
- astStack : modifiers arguments throws statements
- identifierStack : name
- ==>
- astStack : MethodDeclaration
- identifierStack :
- */
-
- //must provide a default constructor call when needed
-
- if (hasBody) {
- // pop the position of the { (body of the method) pushed in block decl
- intPtr--;
- }
-
- //statements
- if (hasBody) {
- realBlockPtr--;
- }
-
- int length;
- if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) {
- astPtr -= length;
- }
- }
- protected void ignoreMethodBody() {
- // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
-
- /*
- astStack : modifiers arguments throws statements
- identifierStack : type name
- intStack : dim dim dim
- ==>
- astStack : MethodDeclaration
- identifierStack :
- intStack :
- */
-
- // pop the position of the { (body of the method) pushed in block decl
- intPtr--;
- // retrieve end position of method declarator
-
- //statements
- realBlockPtr--;
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- astPtr -= length;
- }
-
- //watch for } that could be given as a unicode ! ( u007D is '}' )
- MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
- md.bodyEnd = endPosition;
- md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
-
- // report the problem and continue the parsing - narrowing the problem onto the method
- problemReporter().abstractMethodNeedingNoBody(md);
- }
- public void initialize() {
- //positionning the parser for a new compilation unit
- //avoiding stack reallocation and all that....
- astPtr = -1;
- astLengthPtr = -1;
- expressionPtr = -1;
- expressionLengthPtr = -1;
- identifierPtr = -1;
- identifierLengthPtr = -1;
- intPtr = -1;
- nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
- variablesCounter[nestedType] = 0;
- dimensions = 0;
- realBlockPtr = -1;
- compilationUnit = null;
- referenceContext = null;
- endStatementPosition = 0;
-
- //remove objects from stack too, while the same parser/compiler couple is
- //re-used between two compilations ....
-
- int astLength = astStack.length;
- if (noAstNodes.length < astLength) {
- noAstNodes = new AstNode[astLength];
- //System.out.println("Resized AST stacks : "+ astLength);
-
- }
- System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
-
- int expressionLength = expressionStack.length;
- if (noExpressions.length < expressionLength) {
- noExpressions = new Expression[expressionLength];
- //System.out.println("Resized EXPR stacks : "+ expressionLength);
- }
- System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
-
- // reset scanner state
- scanner.commentPtr = -1;
- scanner.eofPosition = Integer.MAX_VALUE;
-
- resetModifiers();
-
- // recovery
- lastCheckPoint = -1;
- currentElement = null;
- restartRecovery = false;
- hasReportedError = false;
- recoveredStaticInitializerStart = 0;
- lastIgnoredToken = -1;
- lastErrorEndPosition = -1;
- listLength = 0;
- }
- public void initializeScanner() {
- this.scanner =
- new Scanner(
- false,
- false,
- this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore,
- this.assertMode);
- }
- public final static void initTables() throws java.io.IOException {
-
- final String prefix = FILEPREFIX;
- int i = 0;
- lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
- char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
- check_table = new short[chars.length];
- for (int c = chars.length; c-- > 0;) {
- check_table[c] = (short) (chars[c] - 32768);
- }
- asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
- asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
- symbol_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
- action = lhs;
- }
- public final void jumpOverMethodBody() {
- //on diet parsing.....do not buffer method statements
-
- //the scanner.diet is reinitialized to false
- //automatically by the scanner once it has jumped over
- //the statements
-
- if (diet && (dietInt == 0))
- scanner.diet = true;
- }
- protected void markCurrentMethodWithLocalType() {
- if (this.currentElement != null)
- return; // this is already done in the recovery code
- for (int i = this.astPtr; i >= 0; i--) {
- AstNode node = this.astStack[i];
- if (node instanceof AbstractMethodDeclaration
- || node instanceof TypeDeclaration) { // mark type for now: all fields will be marked when added to this type
- node.bits |= AstNode.HasLocalTypeMASK;
- return;
- }
- }
- // default to reference context (case of parse method body)
- if (this.referenceContext instanceof AbstractMethodDeclaration || this.referenceContext instanceof TypeDeclaration) {
- ((AstNode) this.referenceContext).bits |= AstNode.HasLocalTypeMASK;
- }
- }
- protected void markFieldsWithLocalType(TypeDeclaration type) {
- if (type.fields == null || (type.bits & AstNode.HasLocalTypeMASK) == 0)
- return;
- for (int i = 0, length = type.fields.length; i < length; i++) {
- type.fields[i].bits |= AstNode.HasLocalTypeMASK;
- }
- }
- /*
- * Move checkpoint location (current implementation is moving it by one token)
- *
- * Answers true if successfully moved checkpoint (i.e. did not attempt to move it
- * beyond end of file).
- */
- protected boolean moveRecoveryCheckpoint() {
-
- int pos = lastCheckPoint;
- /* reset scanner, and move checkpoint by one token */
- scanner.startPosition = pos;
- scanner.currentPosition = pos;
- scanner.diet = false; // quit jumping over method bodies
-
- /* if about to restart, then no need to shift token */
- if (restartRecovery) {
- lastIgnoredToken = -1;
- return true;
- }
-
- /* protect against shifting on an invalid token */
- lastIgnoredToken = nextIgnoredToken;
- nextIgnoredToken = -1;
- do {
- try {
- nextIgnoredToken = scanner.getNextToken();
- if (scanner.currentPosition == scanner.startPosition) {
- scanner.currentPosition++; // on fake completion identifier
- nextIgnoredToken = -1;
- }
-
- } catch (InvalidInputException e) {
- pos = scanner.currentPosition;
- }
- } while (nextIgnoredToken < 0);
-
- if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
- if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
- return false;
- }
- }
- lastCheckPoint = scanner.currentPosition;
-
- /* reset scanner again to previous checkpoint location*/
- scanner.startPosition = pos;
- scanner.currentPosition = pos;
- scanner.commentPtr = -1;
-
- return true;
-
- /*
- The following implementation moves the checkpoint location by one line:
-
- int pos = lastCheckPoint;
- // reset scanner, and move checkpoint by one token
- scanner.startPosition = pos;
- scanner.currentPosition = pos;
- scanner.diet = false; // quit jumping over method bodies
-
- // if about to restart, then no need to shift token
- if (restartRecovery){
- lastIgnoredToken = -1;
- return true;
- }
-
- // protect against shifting on an invalid token
- lastIgnoredToken = nextIgnoredToken;
- nextIgnoredToken = -1;
-
- boolean wasTokenizingWhiteSpace = scanner.tokenizeWhiteSpace;
- scanner.tokenizeWhiteSpace = true;
- checkpointMove:
- do {
- try {
- nextIgnoredToken = scanner.getNextToken();
- switch(nextIgnoredToken){
- case Scanner.TokenNameWHITESPACE :
- if(scanner.getLineNumber(scanner.startPosition)
- == scanner.getLineNumber(scanner.currentPosition)){
- nextIgnoredToken = -1;
- }
- break;
- case TokenNameSEMICOLON :
- case TokenNameLBRACE :
- case TokenNameRBRACE :
- break;
- case TokenNameIdentifier :
- if(scanner.currentPosition == scanner.startPosition){
- scanner.currentPosition++; // on fake completion identifier
- }
- default:
- nextIgnoredToken = -1;
- break;
- case TokenNameEOF :
- break checkpointMove;
- }
- } catch(InvalidInputException e){
- pos = scanner.currentPosition;
- }
- } while (nextIgnoredToken < 0);
- scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
-
- if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
- if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
- return false;
- }
- }
- lastCheckPoint = scanner.currentPosition;
-
- // reset scanner again to previous checkpoint location
- scanner.startPosition = pos;
- scanner.currentPosition = pos;
- scanner.commentPtr = -1;
-
- return true;
- */
- }
- protected MessageSend newMessageSend() {
- // '(' ArgumentListopt ')'
- // the arguments are on the expression stack
-
- MessageSend m = new MessageSend();
- int length;
- if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
- expressionPtr -= length;
- System.arraycopy(expressionStack, expressionPtr + 1, m.arguments = new Expression[length], 0, length);
- };
- return m;
- }
- protected static int ntAction(int state, int sym) {
- return action[state + sym];
- }
- private final void optimizedConcatNodeLists() {
- /*back from a recursive loop. Virtualy group the
- astNode into an array using astLengthStack*/
-
- /*
- * This is a case where you have two sublists into the astStack that you want
- * to merge in one list. There is no action required on the astStack. The only
- * thing you need to do is merge the two lengths specified on the astStackLength.
- * The top two length are for example:
- * ... p n
- * and you want to result in a list like:
- * ... n+p
- * This means that the p could be equals to 0 in case there is no astNode pushed
- * on the astStack.
- * Look at the InterfaceMemberDeclarations for an example.
- * This case optimizes the fact that p == 1.
- */
-
- astLengthStack[--astLengthPtr]++;
- }
- protected static int original_state(int state) {
- return -check(state);
- }
- /*main loop of the automat
- When a rule is reduced, the method consumeRule(int) is called with the number
- of the consumed rule. When a terminal is consumed, the method consumeToken(int) is
- called in order to remember (when needed) the consumed token */
- // (int)asr[asi(act)]
- // name[symbol_index[currentKind]]
- protected void parse() {
-
- hasReportedError = false;
- int act = START_STATE;
- stateStackTop = -1;
- currentToken = getFirstToken();
- ProcessTerminals : for (;;) {
- try {
- stack[++stateStackTop] = act;
- } catch (IndexOutOfBoundsException e) {
- int oldStackLength = stack.length;
- int oldStack[] = stack;
- stack = new int[oldStackLength + StackIncrement];
- System.arraycopy(oldStack, 0, stack, 0, oldStackLength);
- stack[stateStackTop] = act;
- };
-
- act = tAction(act, currentToken);
-
- if (act == ERROR_ACTION || restartRecovery) {
- int errorPos = scanner.currentPosition;
- if (!hasReportedError) {
- this.reportSyntaxError(ERROR_ACTION, currentToken, stateStackTop);
- hasReportedError = true;
- }
- if (resumeOnSyntaxError()) {
- if (act == ERROR_ACTION)
- lastErrorEndPosition = errorPos;
- act = START_STATE;
- stateStackTop = -1;
- currentToken = getFirstToken();
- continue ProcessTerminals;
- } else {
- act = ERROR_ACTION;
- }
- break ProcessTerminals;
- }
- if (act <= NUM_RULES)
- stateStackTop--;
- else if (act > ERROR_ACTION) { /* shift-reduce */
- consumeToken(currentToken);
- if (currentElement != null)
- this.recoveryTokenCheck();
- try {
- currentToken = scanner.getNextToken();
- } catch (InvalidInputException e) {
- if (!hasReportedError) {
- this.problemReporter().scannerError(this, e.getMessage());
- hasReportedError = true;
- }
- lastCheckPoint = scanner.currentPosition;
- restartRecovery = true;
- }
- act -= ERROR_ACTION;
- } else if (act < ACCEPT_ACTION) { /* shift */
- consumeToken(currentToken);
- if (currentElement != null)
- this.recoveryTokenCheck();
- try {
- currentToken = scanner.getNextToken();
- } catch (InvalidInputException e) {
- if (!hasReportedError) {
- this.problemReporter().scannerError(this, e.getMessage());
- hasReportedError = true;
- }
- lastCheckPoint = scanner.currentPosition;
- restartRecovery = true;
- }
- continue ProcessTerminals;
- } else
- break ProcessTerminals;
-
- ProcessNonTerminals : do { /* reduce */
- consumeRule(act);
- stateStackTop -= (rhs[act] - 1);
- act = ntAction(stack[stateStackTop], lhs[act]);
- } while (act <= NUM_RULES);
- }
- endParse(act);
- }
- // A P I
-
- public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
- //only parse the method body of cd
- //fill out its statements
-
- //convert bugs into parse error
-
- initialize();
- goForConstructorBody();
- nestedMethod[nestedType]++;
-
- referenceContext = cd;
- compilationUnit = unit;
-
- scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
- try {
- parse();
- } catch (AbortCompilation ex) {
- lastAct = ERROR_ACTION;
- } finally {
- nestedMethod[nestedType]--;
- }
-
- if (lastAct == ERROR_ACTION) {
- initialize();
- return;
- }
-
- //statements
- cd.explicitDeclarations = realBlockStack[realBlockPtr--];
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0) {
- astPtr -= length;
- if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
- //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
- {
- System.arraycopy(astStack, astPtr + 2, cd.statements = new Statement[length - 1], 0, length - 1);
- cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
- } else { //need to add explicitly the super();
- System.arraycopy(astStack, astPtr + 1, cd.statements = new Statement[length], 0, length);
- cd.constructorCall = SuperReference.implicitSuperConstructorCall();
- }
- } else {
- cd.constructorCall = SuperReference.implicitSuperConstructorCall();
- }
-
- if (cd.constructorCall.sourceEnd == 0) {
- cd.constructorCall.sourceEnd = cd.sourceEnd;
- cd.constructorCall.sourceStart = cd.sourceStart;
- }
- }
- // A P I
-
- public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
- //only parse the method body of md
- //fill out method statements
-
- //convert bugs into parse error
-
- initialize();
- goForInitializer();
- nestedMethod[nestedType]++;
-
- referenceContext = type;
- compilationUnit = unit;
-
- scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
- try {
- parse();
- } catch (AbortCompilation ex) {
- lastAct = ERROR_ACTION;
- } finally {
- nestedMethod[nestedType]--;
- }
-
- if (lastAct == ERROR_ACTION) {
- return;
- }
-
- ini.block = ((Initializer) astStack[astPtr]).block;
-
- // mark initializer with local type if one was found during parsing
- if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
- ini.bits |= AstNode.HasLocalTypeMASK;
- }
- }
- // A P I
-
- public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
- //only parse the method body of md
- //fill out method statements
-
- //convert bugs into parse error
-
- if (md.isAbstract())
- return;
- if (md.isNative())
- return;
- if ((md.modifiers & AccSemicolonBody) != 0)
- return;
-
- initialize();
- goForMethodBody();
- nestedMethod[nestedType]++;
-
- referenceContext = md;
- compilationUnit = unit;
-
- scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
- // reset the scanner to parser from { down to }
- try {
- parse();
- } catch (AbortCompilation ex) {
- lastAct = ERROR_ACTION;
- } finally {
- nestedMethod[nestedType]--;
- }
-
- if (lastAct == ERROR_ACTION) {
- return;
- }
-
- //refill statements
- md.explicitDeclarations = realBlockStack[realBlockPtr--];
- int length;
- if ((length = astLengthStack[astLengthPtr--]) != 0)
- System.arraycopy(astStack, (astPtr -= length) + 1, md.statements = new Statement[length], 0, length);
- }
- // A P I
-
- public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
- // parses a compilation unit and manages error handling (even bugs....)
-
- CompilationUnitDeclaration unit;
- try {
- /* automaton initialization */
- initialize();
- goForCompilationUnit();
-
- /* scanner initialization */
- scanner.setSource(sourceUnit.getContents());
-
- /* unit creation */
- referenceContext =
- compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
- /* run automaton */
- parse();
- } finally {
- unit = compilationUnit;
- compilationUnit = null; // reset parser
- }
- return unit;
- }
- // A P I
-
- public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
- // parses a compilation unit and manages error handling (even bugs....)
-
- CompilationUnitDeclaration unit;
- try {
- /* automaton initialization */
- initialize();
- goForCompilationUnit();
-
- /* scanner initialization */
- scanner.setSource(sourceUnit.getContents());
- scanner.resetTo(start, end);
- /* unit creation */
- referenceContext =
- compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
- /* run automaton */
- parse();
- } finally {
- unit = compilationUnit;
- compilationUnit = null; // reset parser
- }
- return unit;
- }
- /**
- * Returns this parser's problem reporter initialized with its reference context.
- * Also it is assumed that a problem is going to be reported, so initializes
- * the compilation result's line positions.
- */
- public ProblemReporter problemReporter() {
- if (scanner.recordLineSeparator) {
- compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
- }
- problemReporter.referenceContext = referenceContext;
- return problemReporter;
- }
- protected void pushIdentifier() {
- /*push the consumeToken on the identifier stack.
- Increase the total number of identifier in the stack.
- identifierPtr points on the next top */
-
- try {
- identifierStack[++identifierPtr] = scanner.getCurrentIdentifierSource();
- identifierPositionStack[identifierPtr] = (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
- } catch (IndexOutOfBoundsException e) {
- /*---stack reallaocation (identifierPtr is correct)---*/
- int oldStackLength = identifierStack.length;
- char[][] oldStack = identifierStack;
- identifierStack = new char[oldStackLength + 20][];
- System.arraycopy(oldStack, 0, identifierStack, 0, oldStackLength);
- identifierStack[identifierPtr] = scanner.getCurrentTokenSource();
- /*identifier position stack*/
- long[] oldPos = identifierPositionStack;
- identifierPositionStack = new long[oldStackLength + 20];
- System.arraycopy(oldPos, 0, identifierPositionStack, 0, oldStackLength);
- identifierPositionStack[identifierPtr] = (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
- };
-
- try {
- identifierLengthStack[++identifierLengthPtr] = 1;
- } catch (IndexOutOfBoundsException e) {
- /*---stack reallocation (identifierLengthPtr is correct)---*/
- int oldStackLength = identifierLengthStack.length;
- int oldStack[] = identifierLengthStack;
- identifierLengthStack = new int[oldStackLength + 10];
- System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
- identifierLengthStack[identifierLengthPtr] = 1;
- };
-
- }
- protected void pushIdentifier(int flag) {
- /*push a special flag on the stack :
- -zero stands for optional Name
- -negative number for direct ref to base types.
- identifierLengthPtr points on the top */
-
- try {
- identifierLengthStack[++identifierLengthPtr] = flag;
- } catch (IndexOutOfBoundsException e) {
- /*---stack reallaocation (identifierLengthPtr is correct)---*/
- int oldStackLength = identifierLengthStack.length;
- int oldStack[] = identifierLengthStack;
- identifierLengthStack = new int[oldStackLength + 10];
- System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
- identifierLengthStack[identifierLengthPtr] = flag;
- };
-
- }
- protected void pushOnAstLengthStack(int pos) {
- try {
- astLengthStack[++astLengthPtr] = pos;
- } catch (IndexOutOfBoundsException e) {
- int oldStackLength = astLengthStack.length;
- int[] oldPos = astLengthStack;
- astLengthStack = new int[oldStackLength + StackIncrement];
- System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
- astLengthStack[astLengthPtr] = pos;
- }
- }
- protected void pushOnAstStack(AstNode node) {
- /*add a new obj on top of the ast stack
- astPtr points on the top*/
-
- try {
- astStack[++astPtr] = node;
- } catch (IndexOutOfBoundsException e) {
- int oldStackLength = astStack.length;
- AstNode[] oldStack = astStack;
- astStack = new AstNode[oldStackLength + AstStackIncrement];
- System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
- astPtr = oldStackLength;
- astStack[astPtr] = node;
- }
-
- try {
- astLengthStack[++astLengthPtr] = 1;
- } catch (IndexOutOfBoundsException e) {
- int oldStackLength = astLengthStack.length;
- int[] oldPos = astLengthStack;
- astLengthStack = new int[oldStackLength + AstStackIncrement];
- System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
- astLengthStack[astLengthPtr] = 1;
- }
- }
- protected void pushOnExpressionStack(Expression expr) {
-
- try {
- expressionStack[++expressionPtr] = expr;
- } catch (IndexOutOfBoundsException e) {
- //expressionPtr is correct
- int oldStackLength = expressionStack.length;
- Expression[] oldStack = expressionStack;
- expressionStack = new Expression[oldStackLength + ExpressionStackIncrement];
- System.arraycopy(oldStack, 0, expressionStack, 0, oldStackLength);
- expressionStack[expressionPtr] = expr;
- }
-
- try {
- expressionLengthStack[++expressionLengthPtr] = 1;
- } catch (IndexOutOfBoundsException e) {
- int oldStackLength = expressionLengthStack.length;
- int[] oldPos = expressionLengthStack;
- expressionLengthStack = new int[oldStackLength + ExpressionStackIncrement];
- System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
- expressionLengthStack[expressionLengthPtr] = 1;
- }
- }
- protected void pushOnExpressionStackLengthStack(int pos) {
- try {
- expressionLengthStack[++expressionLengthPtr] = pos;
- } catch (IndexOutOfBoundsException e) {
- int oldStackLength = expressionLengthStack.length;
- int[] oldPos = expressionLengthStack;
- expressionLengthStack = new int[oldStackLength + StackIncrement];
- System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
- expressionLengthStack[expressionLengthPtr] = pos;
- }
- }
- protected void pushOnIntStack(int pos) {
-
- try {
- intStack[++intPtr] = pos;
- } catch (IndexOutOfBoundsException e) {
- //intPtr is correct
- int oldStackLength = intStack.length;
- int oldStack[] = intStack;
- intStack = new int[oldStackLength + StackIncrement];
- System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
- intStack[intPtr] = pos;
- }
- }
- protected static char[] readTable(String filename) throws java.io.IOException {
-
- //files are located at Parser.class directory
-
- InputStream stream = new BufferedInputStream(Parser.class.getResourceAsStream(filename));
- if (stream == null) {
- throw new java.io.IOException(Util.bind("parser.missingFile", filename)); //$NON-NLS-1$
- }
- byte[] bytes = null;
- try {
- bytes = Util.getInputStreamAsByteArray(stream, -1);
- } finally {
- try {
- stream.close();
- } catch (IOException e) {
- }
- }
-
- //minimal integrity check (even size expected)
- int length = bytes.length;
- if (length % 2 != 0)
- throw new java.io.IOException(Util.bind("parser.corruptedFile", filename)); //$NON-NLS-1$
-
- // convert bytes into chars
- char[] chars = new char[length / 2];
- int i = 0;
- int charIndex = 0;
-
- while (true) {
- chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
- if (i == length)
- break;
- }
- return chars;
- }
- /* Token check performed on every token shift once having entered
- * recovery mode.
- */
- public void recoveryTokenCheck() {
- switch (currentToken) {
- case TokenNameLBRACE :
- {
- RecoveredElement newElement = currentElement.updateOnOpeningBrace(scanner.currentPosition - 1);
- lastCheckPoint = scanner.currentPosition;
- if (newElement != null) { // null means nothing happened
- restartRecovery = true; // opening brace detected
- currentElement = newElement;
- }
- break;
- }
- case TokenNameRBRACE :
- {
- endPosition = this.flushAnnotationsDefinedPriorTo(scanner.currentPosition - 1);
- RecoveredElement newElement = currentElement.updateOnClosingBrace(scanner.startPosition, scanner.currentPosition - 1);
- lastCheckPoint = scanner.currentPosition;
- if (newElement != currentElement) {
- currentElement = newElement;
- }
- }
- }
- }
- protected void reportSyntaxError(int act, int currentKind, int stateStackTop) {
-
- /* remember current scanner position */
- int startPos = scanner.startPosition;
- int currentPos = scanner.currentPosition;
-
- String[] expectings;
- String tokenName = name[symbol_index[currentKind]];
-
- //fetch all "accurate" possible terminals that could recover the error
- int start, end = start = asi(stack[stateStackTop]);
- while (asr[end] != 0)
- end++;
- int length = end - start;
- expectings = new String[length];
- if (length != 0) {
- char[] indexes = new char[length];
- System.arraycopy(asr, start, indexes, 0, length);
- for (int i = 0; i < length; i++) {
- expectings[i] = name[symbol_index[indexes[i]]];
- }
- }
-
- //if the pb is an EOF, try to tell the user that they are some
- if (tokenName.equals(UNEXPECTED_EOF)) {
- if (!this.checkAndReportBracketAnomalies(problemReporter())) {
- char[] tokenSource;
- try {
- tokenSource = this.scanner.getCurrentTokenSource();
- } catch (Exception e) {
- tokenSource = new char[] {
- };
- }
- problemReporter().parseError(
- this.scanner.startPosition,
- this.scanner.currentPosition - 1,
- tokenSource,
- tokenName,
- expectings);
- }
- } else { //the next test is HEAVILY grammar DEPENDENT.
- if ((length == 2) && (tokenName.equals(";")) //$NON-NLS-1$
- && (expectings[0] == "++") //$NON-NLS-1$
- && (expectings[1] == "--") //$NON-NLS-1$
- && (expressionPtr > -1)) {
- // the ; is not the expected token ==> it ends a statement when an expression is not ended
- problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
- } else {
- char[] tokenSource;
- try {
- tokenSource = this.scanner.getCurrentTokenSource();
- } catch (Exception e) {
- tokenSource = new char[] {
- };
- }
- problemReporter().parseError(
- this.scanner.startPosition,
- this.scanner.currentPosition - 1,
- tokenSource,
- tokenName,
- expectings);
- this.checkAndReportBracketAnomalies(problemReporter());
- }
- }
- /* reset scanner where it was */
- scanner.startPosition = startPos;
- scanner.currentPosition = currentPos;
- }
- protected void resetModifiers() {
- modifiers = AccDefault;
- modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
- scanner.commentPtr = -1;
- }
- /*
- * Reset context so as to resume to regular parse loop
- */
- protected void resetStacks() {
-
- astPtr = -1;
- astLengthPtr = -1;
- expressionPtr = -1;
- expressionLengthPtr = -1;
- identifierPtr = -1;
- identifierLengthPtr = -1;
- intPtr = -1;
- nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
- variablesCounter[nestedType] = 0;
- dimensions = 0;
- realBlockStack[realBlockPtr = 0] = 0;
- recoveredStaticInitializerStart = 0;
- listLength = 0;
- }
- /*
- * Reset context so as to resume to regular parse loop
- * If unable to reset for resuming, answers false.
- *
- * Move checkpoint location, reset internal stacks and
- * decide which grammar goal is activated.
- */
- protected boolean resumeAfterRecovery() {
-
- // reset internal stacks
- this.resetStacks();
-
- /* attempt to move checkpoint location */
- if (!this.moveRecoveryCheckpoint())
- return false;
-
- // only look for headers
- if (referenceContext instanceof CompilationUnitDeclaration) {
- goForHeaders();
- diet = true; // passed this point, will not consider method bodies
- return true;
- }
- // does not know how to restart
- return false;
- }
- /*
- * Syntax error was detected. Will attempt to perform some recovery action in order
- * to resume to the regular parse loop.
- */
- protected boolean resumeOnSyntaxError() {
-
- /* request recovery initialization */
- if (currentElement == null) {
- currentElement = this.buildInitialRecoveryState(); // build some recovered elements
- }
- /* do not investigate deeper in recovery when no recovered element */
- if (currentElement == null)
- return false;
-
- /* manual forced recovery restart - after headers */
- if (restartRecovery) {
- restartRecovery = false;
- }
- /* update recovery state with current error state of the parser */
- this.updateRecoveryState();
-
- /* attempt to reset state in order to resume to parse loop */
- return this.resumeAfterRecovery();
- }
- protected static int tAction(int state, int sym) {
- return action[check(state + sym) == sym ? state + sym : state];
- }
- public String toString() {
-
- String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
- for (int i = 0; i <= identifierPtr; i++) {
- s = s + "\"" + String.valueOf(identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
- };
- s = s + "}\n"; //$NON-NLS-1$
-
- s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
- for (int i = 0; i <= identifierLengthPtr; i++) {
- s = s + identifierLengthStack[i] + ","; //$NON-NLS-1$
- };
- s = s + "}\n"; //$NON-NLS-1$
-
- s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
- for (int i = 0; i <= astLengthPtr; i++) {
- s = s + astLengthStack[i] + ","; //$NON-NLS-1$
- };
- s = s + "}\n"; //$NON-NLS-1$
- s = s + "astPtr : int = " + String.valueOf(astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
-
- s = s + "intStack : int[] = {"; //$NON-NLS-1$
- for (int i = 0; i <= intPtr; i++) {
- s = s + intStack[i] + ","; //$NON-NLS-1$
- };
- s = s + "}\n"; //$NON-NLS-1$
-
- s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
- for (int i = 0; i <= expressionLengthPtr; i++) {
- s = s + expressionLengthStack[i] + ","; //$NON-NLS-1$
- };
- s = s + "}\n"; //$NON-NLS-1$
-
- s = s + "expressionPtr : int = " + String.valueOf(expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
-
- s = s + "\n\n\n----------------Scanner--------------\n" + scanner.toString(); //$NON-NLS-1$
- return s;
-
- }
- /*
- * Update recovery state based on current parser/scanner state
- */
- protected void updateRecoveryState() {
-
- /* expose parser state to recovery state */
- currentElement.updateFromParserState();
-
- /* check and update recovered state based on current token,
- this action is also performed when shifting token after recovery
- got activated once.
- */
- this.recoveryTokenCheck();
- }
- protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
- //fields is a definition of fields that are grouped together like in
- //public int[] a, b[], c
- //which results into 3 fields.
-
- FieldDeclaration field;
- int endTypeDeclarationPosition = -1 + astStack[astPtr - variableDeclaratorsCounter + 1].sourceStart;
- for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
- //last one is special(see below)
- field = (FieldDeclaration) astStack[astPtr - i - 1];
- field.endPart1Position = endTypeDeclarationPosition;
- field.endPart2Position = -1 + astStack[astPtr - i].sourceStart;
- }
- //last one
- (field = (FieldDeclaration) astStack[astPtr]).endPart1Position = endTypeDeclarationPosition;
- field.endPart2Position = field.declarationSourceEnd;
+ if (ident == null) {
+ functionName = new String(" ");
+ } else {
+ functionName = new String(ident);
+ }
- }
- protected void updateSourcePosition(Expression exp) {
- //update the source Position of the expression
+ non_empty_function_call_parameter_list(functionName); // Get the parameter list for the given function name
- //intStack : int int
- //-->
- //intStack :
+ if (token != TokenName.RPAREN) { // If token is not a ')', throw error
+ throwSyntaxError ("')' expected in function call (" + functionName + ").");
+ }
- exp.sourceEnd = intStack[intPtr--];
- exp.sourceStart = intStack[intPtr--];
- }
+ getNextToken(); // Get the token after ')'
+ }
+ }
+ else { // It's not an '('
+ if (defineName != null) { // does this identifier contain only uppercase characters?
+ if (defineName.length == 3) { // If it's a 'die'
+ if (defineName[0] == 'd' &&
+ defineName[1] == 'i' &&
+ defineName[2] == 'e') {
+ defineName = null;
+ }
+ }
+ else if (defineName.length == 4) { // If it's a 'true'
+ if (defineName[0] == 't' &&
+ defineName[1] == 'r' &&
+ defineName[2] == 'u' &&
+ defineName[3] == 'e') {
+ defineName = null;
+ }
+ else if (defineName[0] == 'n' && // If it's a 'null'
+ defineName[1] == 'u' &&
+ defineName[2] == 'l' &&
+ defineName[3] == 'l') {
+ defineName = null;
+ }
+ }
+ else if (defineName.length == 5) { // If it's a 'false'
+ if (defineName[0] == 'f' &&
+ defineName[1] == 'a' &&
+ defineName[2] == 'l' &&
+ defineName[3] == 's' &&
+ defineName[4] == 'e') {
+ defineName = null;
+ }
+ }
+
+ if (defineName != null) {
+ for (int i = 0; i < defineName.length; i++) {
+ if (Character.isLowerCase (defineName[i])) {
+ problemReporter.phpUppercaseIdentifierWarning (startPos, endPos, referenceContext,
+ compilationUnit.compilationResult);
+ break;
+ }
+ }
+ }
+ }
+ // TODO is this ok ?
+ // return ref;
+ // throwSyntaxError("'(' expected in function call.");
+ }
+
+ if (token == TokenName.MINUS_GREATER) {
+ ref = null;
+ getNextToken();
+ object_property();
+ method_or_not();
+ variable_properties();
+ }
+
+ // A colon is only allowed here if it is an expression read after a '?'
+
+ if ((token == TokenName.COLON) &&
+ (!bColonAllowed)) {
+ throwSyntaxError ("No ':' allowed");
+ }
+
+ return ref;
+ }
+
+ private void method_or_not() {
+ // method_or_not:
+ // '(' function_call_parameter_list ')'
+ // | /* empty */
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: method_or_not()");
+ }
+ if (token == TokenName.LPAREN) {
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ return;
+ }
+ non_empty_function_call_parameter_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected in method_or_not.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void exit_expr() {
+ // /* empty */
+ // | '(' ')'
+ // | '(' expr ')'
+ if (token != TokenName.LPAREN) {
+ return;
+ }
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ return;
+ }
+ expr();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected after keyword 'exit'");
+ }
+ getNextToken();
+ }
+
+ // private void encaps_list() {
+ // // encaps_list encaps_var
+ // // | encaps_list T_STRING
+ // // | encaps_list T_NUM_STRING
+ // // | encaps_list T_ENCAPSED_AND_WHITESPACE
+ // // | encaps_list T_CHARACTER
+ // // | encaps_list T_BAD_CHARACTER
+ // // | encaps_list '['
+ // // | encaps_list ']'
+ // // | encaps_list '{'
+ // // | encaps_list '}'
+ // // | encaps_list T_OBJECT_OPERATOR
+ // // | /* empty */
+ // while (true) {
+ // switch (token) {
+ // case TokenName.STRING:
+ // getNextToken();
+ // break;
+ // case TokenName.LBRACE:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenName.RBRACE:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenName.LBRACKET:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenName.RBRACKET:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenName.MINUS_GREATER:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenName.Variable:
+ // case TokenName.DOLLAR_LBRACE:
+ // case TokenName.LBRACE_DOLLAR:
+ // encaps_var();
+ // break;
+ // default:
+ // char encapsedChar = ((Character)
+ // scanner.encapsedStringStack.peek()).charValue();
+ // if (encapsedChar == '$') {
+ // scanner.encapsedStringStack.pop();
+ // encapsedChar = ((Character)
+ // scanner.encapsedStringStack.peek()).charValue();
+ // switch (encapsedChar) {
+ // case '`':
+ // if (token == TokenName.EncapsedString0) {
+ // return;
+ // }
+ // token = TokenName.STRING;
+ // continue;
+ // case '\'':
+ // if (token == TokenName.EncapsedString1) {
+ // return;
+ // }
+ // token = TokenName.STRING;
+ // continue;
+ // case '"':
+ // if (token == TokenName.EncapsedString2) {
+ // return;
+ // }
+ // token = TokenName.STRING;
+ // continue;
+ // }
+ // }
+ // return;
+ // }
+ // }
+ // }
+
+ // private void encaps_var() {
+ // // T_VARIABLE
+ // // | T_VARIABLE '[' encaps_var_offset ']'
+ // // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
+ // // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
+ // // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
+ // // | T_CURLY_OPEN variable '}'
+ // switch (token) {
+ // case TokenName.Variable:
+ // getNextToken();
+ // if (token == TokenName.LBRACKET) {
+ // getNextToken();
+ // expr(); //encaps_var_offset();
+ // if (token != TokenName.RBRACKET) {
+ // throwSyntaxError("']' expected after variable.");
+ // }
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // // }
+ // } else if (token == TokenName.MINUS_GREATER) {
+ // getNextToken();
+ // if (token != TokenName.Identifier) {
+ // throwSyntaxError("Identifier expected after '->'.");
+ // }
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // // else {
+ // // // scanner.encapsedStringStack.pop();
+ // // int tempToken = TokenName.STRING;
+ // // if (!scanner.encapsedStringStack.isEmpty()
+ // // && (token == TokenName.EncapsedString0
+ // // || token == TokenName.EncapsedString1
+ // // || token == TokenName.EncapsedString2 || token ==
+ // // TokenName.ERROR)) {
+ // // char encapsedChar = ((Character)
+ // // scanner.encapsedStringStack.peek())
+ // // .charValue();
+ // // switch (token) {
+ // // case TokenName.EncapsedString0 :
+ // // if (encapsedChar == '`') {
+ // // tempToken = TokenName.EncapsedString0;
+ // // }
+ // // break;
+ // // case TokenName.EncapsedString1 :
+ // // if (encapsedChar == '\'') {
+ // // tempToken = TokenName.EncapsedString1;
+ // // }
+ // // break;
+ // // case TokenName.EncapsedString2 :
+ // // if (encapsedChar == '"') {
+ // // tempToken = TokenName.EncapsedString2;
+ // // }
+ // // break;
+ // // case TokenName.ERROR :
+ // // if (scanner.source[scanner.currentPosition - 1] == '\\') {
+ // // scanner.currentPosition--;
+ // // getNextToken();
+ // // }
+ // // break;
+ // // }
+ // // }
+ // // token = tempToken;
+ // // }
+ // break;
+ // case TokenName.DOLLAR_LBRACE:
+ // getNextToken();
+ // if (token == TokenName.DOLLAR_LBRACE) {
+ // encaps_var();
+ // } else if (token == TokenName.Identifier) {
+ // getNextToken();
+ // if (token == TokenName.LBRACKET) {
+ // getNextToken();
+ // // if (token == TokenName.RBRACKET) {
+ // // getNextToken();
+ // // } else {
+ // expr();
+ // if (token != TokenName.RBRACKET) {
+ // throwSyntaxError("']' expected after '${'.");
+ // }
+ // getNextToken();
+ // // }
+ // }
+ // } else {
+ // expr();
+ // }
+ // if (token != TokenName.RBRACE) {
+ // throwSyntaxError("'}' expected.");
+ // }
+ // getNextToken();
+ // break;
+ // case TokenName.LBRACE_DOLLAR:
+ // getNextToken();
+ // if (token == TokenName.LBRACE_DOLLAR) {
+ // encaps_var();
+ // } else if (token == TokenName.Identifier || token > TokenName.KEYWORD) {
+ // getNextToken();
+ // if (token == TokenName.LBRACKET) {
+ // getNextToken();
+ // // if (token == TokenName.RBRACKET) {
+ // // getNextToken();
+ // // } else {
+ // expr();
+ // if (token != TokenName.RBRACKET) {
+ // throwSyntaxError("']' expected.");
+ // }
+ // getNextToken();
+ // // }
+ // } else if (token == TokenName.MINUS_GREATER) {
+ // getNextToken();
+ // if (token != TokenName.Identifier && token != TokenName.Variable) {
+ // throwSyntaxError("String or Variable token expected.");
+ // }
+ // getNextToken();
+ // if (token == TokenName.LBRACKET) {
+ // getNextToken();
+ // // if (token == TokenName.RBRACKET) {
+ // // getNextToken();
+ // // } else {
+ // expr();
+ // if (token != TokenName.RBRACKET) {
+ // throwSyntaxError("']' expected after '${'.");
+ // }
+ // getNextToken();
+ // // }
+ // }
+ // }
+ // // if (token != TokenName.RBRACE) {
+ // // throwSyntaxError("'}' expected after '{$'.");
+ // // }
+ // // // scanner.encapsedStringStack.pop();
+ // // getNextToken();
+ // } else {
+ // expr();
+ // if (token != TokenName.RBRACE) {
+ // throwSyntaxError("'}' expected.");
+ // }
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ // }
+ // }
+
+ // private void encaps_var_offset() {
+ // // T_STRING
+ // // | T_NUM_STRING
+ // // | T_VARIABLE
+ // switch (token) {
+ // case TokenName.STRING:
+ // getNextToken();
+ // break;
+ // case TokenName.IntegerLiteral:
+ // getNextToken();
+ // break;
+ // case TokenName.Variable:
+ // getNextToken();
+ // break;
+ // case TokenName.Identifier:
+ // getNextToken();
+ // break;
+ // default:
+ // throwSyntaxError("Variable or String token expected.");
+ // break;
+ // }
+ // }
+
+ /**
+ *
+ */
+ private void internal_functions_in_yacc() {
+ // int start = 0;
+ switch (token) {
+ // case TokenName.isset:
+ // // T_ISSET '(' isset_variables ')'
+ // getNextToken();
+ // if (token != TokenName.LPAREN) {
+ // throwSyntaxError("'(' expected after keyword 'isset'");
+ // }
+ // getNextToken();
+ // isset_variables();
+ // if (token != TokenName.RPAREN) {
+ // throwSyntaxError("')' expected after keyword 'isset'");
+ // }
+ // getNextToken();
+ // break;
+ // case TokenName.empty:
+ // // T_EMPTY '(' variable ')'
+ // getNextToken();
+ // if (token != TokenName.LPAREN) {
+ // throwSyntaxError("'(' expected after keyword 'empty'");
+ // }
+ // getNextToken();
+ // variable(false);
+ // if (token != TokenName.RPAREN) {
+ // throwSyntaxError("')' expected after keyword 'empty'");
+ // }
+ // getNextToken();
+ // break;
+ case INCLUDE:
+ // T_INCLUDE expr
+ checkFileName(token);
+ break;
+ case INCLUDE_ONCE:
+ // T_INCLUDE_ONCE expr
+ checkFileName(token);
+ break;
+ case EVAL:
+ // T_EVAL '(' expr ')'
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected after keyword 'eval'");
+ }
+ getNextToken();
+ expr();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' expected after keyword 'eval'");
+ }
+ getNextToken();
+ break;
+ case REQUIRE:
+ // T_REQUIRE expr
+ checkFileName(token);
+ break;
+ case REQUIRE_ONCE:
+ // T_REQUIRE_ONCE expr
+ checkFileName(token);
+ break;
+ }
+ }
+
+ /**
+ * Parse and check the include file name
+ *
+ * @param includeToken
+ */
+ private void checkFileName(TokenName includeToken) {
+ // <include-token> expr
+ int start = scanner.getCurrentTokenStartPosition();
+ boolean hasLPAREN = false;
+ getNextToken();
+ if (token == TokenName.LPAREN) {
+ hasLPAREN = true;
+ getNextToken();
+ }
+ Expression expression = expr();
+ if (hasLPAREN) {
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected for keyword '"
+ + scanner.toStringAction(includeToken) + "'");
+ }
+ }
+ char[] currTokenSource = scanner.getCurrentTokenSource(start);
+ IFile file = null;
+ if (scanner.compilationUnit != null) {
+ IResource resource = scanner.compilationUnit.getResource();
+ if (resource != null && resource instanceof IFile) {
+ file = (IFile) resource;
+ }
+ }
+ char[][] tokens;
+ tokens = new char[1][];
+ tokens[0] = currTokenSource;
+
+ ImportReference impt = new ImportReference(tokens, currTokenSource,
+ start, scanner.getCurrentTokenEndPosition(), false);
+ impt.declarationSourceEnd = impt.sourceEnd;
+ impt.declarationEnd = impt.declarationSourceEnd;
+ // endPosition is just before the ;
+ impt.declarationSourceStart = start;
+ includesList.add(impt);
+
+ if (expression instanceof StringLiteral) {
+ StringLiteral literal = (StringLiteral) expression;
+ char[] includeName = literal.source();
+ if (includeName.length == 0) {
+ reportSyntaxError("Empty filename after keyword '"
+ + scanner.toStringAction(includeToken) + "'",
+ literal.sourceStart, literal.sourceStart + 1);
+ }
+ String includeNameString = new String(includeName);
+ if (literal instanceof StringLiteralDQ) {
+ if (includeNameString.indexOf('$') >= 0) {
+ // assuming that the filename contains a variable => no
+ // filename check
+ return;
+ }
+ }
+ if (includeNameString.startsWith("http://")) {
+ // assuming external include location
+ return;
+ }
+ if (file != null) {
+ // check the filename:
+ // System.out.println(new
+ // String(compilationUnit.getFileName())+" - "+
+ // expression.toStringExpression());
+ IProject project = file.getProject();
+ if (project != null) {
+ IPath path = PHPFileUtil.determineFilePath(
+ includeNameString, file, project);
+
+ if (path == null) {
+ // SyntaxError: "File: << >> doesn't exist in project."
+ String[] args = { expression.toStringExpression(),
+ project.getFullPath().toString() };
+ problemReporter.phpIncludeNotExistWarning(args,
+ literal.sourceStart, literal.sourceEnd,
+ referenceContext,
+ compilationUnit.compilationResult);
+ } else {
+ try {
+ String filePath = path.toString();
+ String ext = file.getRawLocation()
+ .getFileExtension();
+ int fileExtensionLength = ext == null ? 0 : ext
+ .length() + 1;
+
+ IFile f = PHPFileUtil.createFile(path, project);
+
+ impt.tokens = CharOperation.splitOn('/', filePath
+ .toCharArray(), 0, filePath.length()
+ - fileExtensionLength);
+ impt.setFile(f);
+ } catch (Exception e) {
+ // the file is outside of the workspace
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void isset_variables() {
+ // variable
+ // | isset_variables ','
+ if (token == TokenName.RPAREN) {
+ throwSyntaxError("Variable expected after keyword 'isset'");
+ }
+ while (true) {
+ variable(true, false);
+ if (token == TokenName.COMMA) {
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ }
+
+ private boolean common_scalar() {
+ // common_scalar:
+ // T_LNUMBER
+ // | T_DNUMBER
+ // | T_CONSTANT_ENCAPSED_STRING
+ // | T_LINE
+ // | T_FILE
+ // | T_CLASS_C
+ // | T_METHOD_C
+ // | T_FUNC_C
+ switch (token) {
+ case INTEGERLITERAL:
+ getNextToken();
+ return true;
+ case DOUBLELITERAL:
+ getNextToken();
+ return true;
+ case STRINGDOUBLEQUOTE:
+ getNextToken();
+ return true;
+ case STRINGSINGLEQUOTE:
+ getNextToken();
+ return true;
+ case STRINGINTERPOLATED:
+ getNextToken();
+ return true;
+ case FILE:
+ getNextToken();
+ return true;
+ case LINE:
+ getNextToken();
+ return true;
+ case CLASS_C:
+ getNextToken();
+ return true;
+ case METHOD_C:
+ getNextToken();
+ return true;
+ case FUNC_C:
+ getNextToken();
+ return true;
+ }
+ return false;
+ }
+
+// private void scalar() {
+// // scalar:
+// // T_STRING
+// // | T_STRING_VARNAME
+// // | class_constant
+// // | common_scalar
+// // | '"' encaps_list '"'
+// // | '\'' encaps_list '\''
+// // | T_START_HEREDOC encaps_list T_END_HEREDOC
+// throwSyntaxError("Not yet implemented (scalar).");
+// }
+
+ private void static_scalar() {
+ // static_scalar: /* compile-time evaluated scalars */
+ // common_scalar
+ // | T_STRING
+ // | '+' static_scalar
+ // | '-' static_scalar
+ // | T_ARRAY '(' static_array_pair_list ')'
+ // | static_class_constant
+ if (common_scalar()) {
+ return;
+ }
+ switch (token) {
+ case IDENTIFIER:
+ getNextToken();
+ // static_class_constant:
+ // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
+ if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+ getNextToken();
+ if (token == TokenName.IDENTIFIER) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Identifier expected after '::' operator.");
+ }
+ }
+ break;
+ case ENCAPSEDSTRING0:
+ try {
+ scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ while (scanner.currentCharacter != '`') {
+ if (scanner.currentCharacter == '\\') {
+ scanner.currentPosition++;
+ }
+ scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ }
+ getNextToken();
+ } catch (IndexOutOfBoundsException e) {
+ throwSyntaxError("'`' expected at end of static string.");
+ }
+ break;
+ // case TokenName.EncapsedString1:
+ // try {
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // while (scanner.currentCharacter != '\'') {
+ // if (scanner.currentCharacter == '\\') {
+ // scanner.currentPosition++;
+ // }
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // }
+ // getNextToken();
+ // } catch (IndexOutOfBoundsException e) {
+ // throwSyntaxError("'\'' expected at end of static string.");
+ // }
+ // break;
+ // case TokenName.EncapsedString2:
+ // try {
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // while (scanner.currentCharacter != '"') {
+ // if (scanner.currentCharacter == '\\') {
+ // scanner.currentPosition++;
+ // }
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // }
+ // getNextToken();
+ // } catch (IndexOutOfBoundsException e) {
+ // throwSyntaxError("'\"' expected at end of static string.");
+ // }
+ // break;
+ case STRINGSINGLEQUOTE:
+ getNextToken();
+ break;
+ case STRINGDOUBLEQUOTE:
+ getNextToken();
+ break;
+ case PLUS:
+ getNextToken();
+ static_scalar();
+ break;
+ case MINUS:
+ getNextToken();
+ static_scalar();
+ break;
+ case ARRAY:
+ getNextToken();
+ if (token != TokenName.LPAREN) {
+ throwSyntaxError("'(' expected after keyword 'array'");
+ }
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ getNextToken();
+ break;
+ }
+ non_empty_static_array_pair_list();
+ if (token != TokenName.RPAREN) {
+ throwSyntaxError("')' or ',' expected after keyword 'array'");
+ }
+ getNextToken();
+ break;
+ // case TokenName.null :
+ // getNextToken();
+ // break;
+ // case TokenName.false :
+ // getNextToken();
+ // break;
+ // case TokenName.true :
+ // getNextToken();
+ // break;
+ default:
+ throwSyntaxError("Static scalar/constant expected.");
+ }
+ }
+
+ private void non_empty_static_array_pair_list() {
+ // non_empty_static_array_pair_list:
+ // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
+ // static_scalar
+ // | non_empty_static_array_pair_list ',' static_scalar
+ // | static_scalar T_DOUBLE_ARROW static_scalar
+ // | static_scalar
+ while (true) {
+ static_scalar();
+ if (token == TokenName.EQUAL_GREATER) {
+ getNextToken();
+ static_scalar();
+ }
+ if (token != TokenName.COMMA) {
+ break;
+ }
+ getNextToken();
+ if (token == TokenName.RPAREN) {
+ break;
+ }
+ }
+ }
+
+ // public void reportSyntaxError() { //int act, int currentKind, int
+ // // stateStackTop) {
+ // /* remember current scanner position */
+ // int startPos = scanner.startPosition;
+ // int currentPos = scanner.currentPosition;
+ //
+ // this.checkAndReportBracketAnomalies(problemReporter());
+ // /* reset scanner where it was */
+ // scanner.startPosition = startPos;
+ // scanner.currentPosition = currentPos;
+ // }
+
+ public static final int RoundBracket = 0;
+
+ public static final int SquareBracket = 1;
+
+ public static final int CurlyBracket = 2;
+
+ public static final int BracketKinds = 3;
+
+ protected int[] nestedMethod; // the ptr is nestedType
+
+ protected int nestedType, dimensions;
+
+ // variable set stack
+ final static int VariableStackIncrement = 10;
+
+ HashMap fTypeVariables = null;
+
+ HashMap fMethodVariables = null;
+
+ ArrayList fStackUnassigned = new ArrayList();
+
+ // ast stack
+ final static int AstStackIncrement = 100;
+
+ protected int astPtr;
+
+ protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
+
+ protected int astLengthPtr;
+
+ protected int[] astLengthStack;
+
+ ASTNode[] noAstNodes = new ASTNode[AstStackIncrement];
+
+ public CompilationUnitDeclaration compilationUnit; /*
+ * the result from
+ * parse()
+ */
+
+ protected ReferenceContext referenceContext;
+
+ protected ProblemReporter problemReporter;
+
+ protected CompilerOptions options;
+
+ private ArrayList includesList;
+
+ // protected CompilationResult compilationResult;
+ /**
+ * Returns this parser's problem reporter initialized with its reference
+ * context. Also it is assumed that a problem is going to be reported, so
+ * initializes the compilation result's line positions.
+ */
+ public ProblemReporter problemReporter() {
+ if (scanner.recordLineSeparator) {
+ compilationUnit.compilationResult.lineSeparatorPositions = scanner
+ .getLineEnds();
+ }
+ problemReporter.referenceContext = referenceContext;
+ return problemReporter;
+ }
+
+ /*
+ * Reconsider the entire source looking for inconsistencies in {} () []
+ */
+ // public boolean checkAndReportBracketAnomalies(ProblemReporter
+ // problemReporter) {
+ // scanner.wasAcr = false;
+ // boolean anomaliesDetected = false;
+ // try {
+ // char[] source = scanner.source;
+ // int[] leftCount = { 0, 0, 0 };
+ // int[] rightCount = { 0, 0, 0 };
+ // int[] depths = { 0, 0, 0 };
+ // int[][] leftPositions = new int[][] { new int[10], new int[10], new
+ // int[10]
+ // };
+ // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10]
+ // };
+ // int[][] rightPositions = new int[][] { new int[10], new int[10], new
+ // int[10] };
+ // int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10]
+ // };
+ // scanner.currentPosition = scanner.initialPosition; //starting
+ // // point
+ // // (first-zero-based
+ // // char)
+ // while (scanner.currentPosition < scanner.eofPosition) { //loop for
+ // // jumping
+ // // over
+ // // comments
+ // try {
+ // // ---------Consume white space and handles
+ // // startPosition---------
+ // boolean isWhiteSpace;
+ // do {
+ // scanner.startPosition = scanner.currentPosition;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) == '\\') &&
+ // // (source[scanner.currentPosition] == 'u')) {
+ // // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
+ // // } else {
+ // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
+ // (scanner.currentCharacter == '\n'))) {
+ // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
+ // // only record line positions we have not
+ // // recorded yet
+ // scanner.pushLineSeparator();
+ // }
+ // }
+ // isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
+ // // }
+ // } while (isWhiteSpace && (scanner.currentPosition <
+ // scanner.eofPosition));
+ // // -------consume token until } is found---------
+ // switch (scanner.currentCharacter) {
+ // case '{': {
+ // int index = leftCount[CurlyBracket]++;
+ // if (index == leftPositions[CurlyBracket].length) {
+ // System.arraycopy(leftPositions[CurlyBracket], 0,
+ // (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] =
+ // new int[index * 2]), 0, index);
+ // }
+ // leftPositions[CurlyBracket][index] = scanner.startPosition;
+ // leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
+ // }
+ // break;
+ // case '}': {
+ // int index = rightCount[CurlyBracket]++;
+ // if (index == rightPositions[CurlyBracket].length) {
+ // System.arraycopy(rightPositions[CurlyBracket], 0,
+ // (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket]
+ // =
+ // new int[index * 2]), 0, index);
+ // }
+ // rightPositions[CurlyBracket][index] = scanner.startPosition;
+ // rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
+ // }
+ // break;
+ // case '(': {
+ // int index = leftCount[RoundBracket]++;
+ // if (index == leftPositions[RoundBracket].length) {
+ // System.arraycopy(leftPositions[RoundBracket], 0,
+ // (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] =
+ // new int[index * 2]), 0, index);
+ // }
+ // leftPositions[RoundBracket][index] = scanner.startPosition;
+ // leftDepths[RoundBracket][index] = depths[RoundBracket]++;
+ // }
+ // break;
+ // case ')': {
+ // int index = rightCount[RoundBracket]++;
+ // if (index == rightPositions[RoundBracket].length) {
+ // System.arraycopy(rightPositions[RoundBracket], 0,
+ // (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket]
+ // =
+ // new int[index * 2]), 0, index);
+ // }
+ // rightPositions[RoundBracket][index] = scanner.startPosition;
+ // rightDepths[RoundBracket][index] = --depths[RoundBracket];
+ // }
+ // break;
+ // case '[': {
+ // int index = leftCount[SquareBracket]++;
+ // if (index == leftPositions[SquareBracket].length) {
+ // System.arraycopy(leftPositions[SquareBracket], 0,
+ // (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket]
+ // =
+ // new int[index * 2]), 0, index);
+ // }
+ // leftPositions[SquareBracket][index] = scanner.startPosition;
+ // leftDepths[SquareBracket][index] = depths[SquareBracket]++;
+ // }
+ // break;
+ // case ']': {
+ // int index = rightCount[SquareBracket]++;
+ // if (index == rightPositions[SquareBracket].length) {
+ // System.arraycopy(rightPositions[SquareBracket], 0,
+ // (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(rightDepths[SquareBracket], 0,
+ // (rightDepths[SquareBracket]
+ // = new int[index * 2]), 0, index);
+ // }
+ // rightPositions[SquareBracket][index] = scanner.startPosition;
+ // rightDepths[SquareBracket][index] = --depths[SquareBracket];
+ // }
+ // break;
+ // case '\'': {
+ // if (scanner.getNextChar('\\')) {
+ // scanner.scanEscapeCharacter();
+ // } else { // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) ==
+ // // '\\') &&
+ // // (source[scanner.currentPosition] ==
+ // // 'u')) {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // }
+ // scanner.getNextChar('\'');
+ // break;
+ // }
+ // case '"':
+ // // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) == '\\') &&
+ // // (source[scanner.currentPosition] == 'u')) {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // while (scanner.currentCharacter != '"') {
+ // if (scanner.currentCharacter == '\r') {
+ // if (source[scanner.currentPosition] == '\n')
+ // scanner.currentPosition++;
+ // break; // the string cannot go further that
+ // // the line
+ // }
+ // if (scanner.currentCharacter == '\n') {
+ // break; // the string cannot go further that
+ // // the line
+ // }
+ // if (scanner.currentCharacter == '\\') {
+ // scanner.scanEscapeCharacter();
+ // }
+ // // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) == '\\')
+ // // && (source[scanner.currentPosition] == 'u'))
+ // // {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // }
+ // break;
+ // case '/': {
+ // int test;
+ // if ((test = scanner.getNextChar('/', '*')) == 0) { //line
+ // // comment
+ // //get the next char
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from \n and \r
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // while (scanner.currentCharacter != '\r' && scanner.currentCharacter !=
+ // '\n') {
+ // //get the next char
+ // scanner.startPosition = scanner.currentPosition;
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from \n
+ // // and \r
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // }
+ // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
+ // (scanner.currentCharacter == '\n'))) {
+ // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
+ // // only record line positions we
+ // // have not recorded yet
+ // scanner.pushLineSeparator();
+ // if (this.scanner.taskTags != null) {
+ // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
+ // this.scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ // }
+ // }
+ // break;
+ // }
+ // if (test > 0) { //traditional and annotation
+ // // comment
+ // boolean star = false;
+ // // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) ==
+ // // '\\') &&
+ // // (source[scanner.currentPosition] ==
+ // // 'u')) {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // if (scanner.currentCharacter == '*') {
+ // star = true;
+ // }
+ // //get the next char
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from * and /
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // //loop until end of comment */
+ // while ((scanner.currentCharacter != '/') || (!star)) {
+ // star = scanner.currentCharacter == '*';
+ // //get next char
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from * and
+ // // /
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // }
+ // if (this.scanner.taskTags != null) {
+ // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
+ // this.scanner.getCurrentTokenEndPosition());
+ // }
+ // break;
+ // }
+ // break;
+ // }
+ // default:
+ // if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
+ // scanner.scanIdentifierOrKeyword(false);
+ // break;
+ // }
+ // if (Character.isDigit(scanner.currentCharacter)) {
+ // scanner.scanNumber(false);
+ // break;
+ // }
+ // }
+ // //-----------------end switch while
+ // // try--------------------
+ // } catch (IndexOutOfBoundsException e) {
+ // break; // read until EOF
+ // } catch (InvalidInputException e) {
+ // return false; // no clue
+ // }
+ // }
+ // if (scanner.recordLineSeparator) {
+ // compilationUnit.compilationResult.lineSeparatorPositions =
+ // scanner.getLineEnds();
+ // }
+ // // check placement anomalies against other kinds of brackets
+ // for (int kind = 0; kind < BracketKinds; kind++) {
+ // for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
+ // int start = leftPositions[kind][leftIndex]; // deepest
+ // // first
+ // // find matching closing bracket
+ // int depth = leftDepths[kind][leftIndex];
+ // int end = -1;
+ // for (int i = 0; i < rightCount[kind]; i++) {
+ // int pos = rightPositions[kind][i];
+ // // want matching bracket further in source with same
+ // // depth
+ // if ((pos > start) && (depth == rightDepths[kind][i])) {
+ // end = pos;
+ // break;
+ // }
+ // }
+ // if (end < 0) { // did not find a good closing match
+ // problemReporter.unmatchedBracket(start, referenceContext,
+ // compilationUnit.compilationResult);
+ // return true;
+ // }
+ // // check if even number of opening/closing other brackets
+ // // in between this pair of brackets
+ // int balance = 0;
+ // for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds);
+ // otherKind++) {
+ // for (int i = 0; i < leftCount[otherKind]; i++) {
+ // int pos = leftPositions[otherKind][i];
+ // if ((pos > start) && (pos < end))
+ // balance++;
+ // }
+ // for (int i = 0; i < rightCount[otherKind]; i++) {
+ // int pos = rightPositions[otherKind][i];
+ // if ((pos > start) && (pos < end))
+ // balance--;
+ // }
+ // if (balance != 0) {
+ // problemReporter.unmatchedBracket(start, referenceContext,
+ // compilationUnit.compilationResult); //bracket
+ // // anomaly
+ // return true;
+ // }
+ // }
+ // }
+ // // too many opening brackets ?
+ // for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
+ // anomaliesDetected = true;
+ // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i
+ // -
+ // 1], referenceContext,
+ // compilationUnit.compilationResult);
+ // }
+ // // too many closing brackets ?
+ // for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
+ // anomaliesDetected = true;
+ // problemReporter.unmatchedBracket(rightPositions[kind][i],
+ // referenceContext,
+ // compilationUnit.compilationResult);
+ // }
+ // if (anomaliesDetected)
+ // return true;
+ // }
+ // return anomaliesDetected;
+ // } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
+ // return anomaliesDetected;
+ // } catch (NullPointerException e) { // jdk1.2.2 jit bug
+ // return anomaliesDetected;
+ // }
+ // }
+// protected void pushOnAstLengthStack(int pos) {
+// try {
+// astLengthStack[++astLengthPtr] = pos;
+// } catch (IndexOutOfBoundsException e) {
+// int oldStackLength = astLengthStack.length;
+// int[] oldPos = astLengthStack;
+// astLengthStack = new int[oldStackLength + StackIncrement];
+// System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
+// astLengthStack[astLengthPtr] = pos;
+// }
+// }
+
+ protected void pushOnAstStack(ASTNode node) {
+ /*
+ * add a new obj on top of the ast stack
+ */
+ try {
+ astStack[++astPtr] = node;
+ } catch (IndexOutOfBoundsException e) {
+ int oldStackLength = astStack.length;
+ ASTNode[] oldStack = astStack;
+ astStack = new ASTNode[oldStackLength + AstStackIncrement];
+ System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
+ astPtr = oldStackLength;
+ astStack[astPtr] = node;
+ }
+ try {
+ astLengthStack[++astLengthPtr] = 1;
+ } catch (IndexOutOfBoundsException e) {
+ int oldStackLength = astLengthStack.length;
+ int[] oldPos = astLengthStack;
+ astLengthStack = new int[oldStackLength + AstStackIncrement];
+ System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
+ astLengthStack[astLengthPtr] = 1;
+ }
+ }
+
+ protected void resetModifiers() {
+ this.modifiers = AccDefault;
+ this.modifiersSourceStart = -1; // <-- see comment into
+ // modifiersFlag(int)
+ this.scanner.commentPtr = -1;
+ }
+
+ protected void consumePackageDeclarationName(IFile file) {
+ // create a package name similar to java package names
+ // incastrix
+ //String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject())
+ // .toString();
+ //String filePath = file.getFullPath().toString();
+
+ String ext = file.getFileExtension();
+ int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
+ ImportReference impt;
+ char[][] tokens;
+
+ /*if (filePath.startsWith(projectPath)) {
+ tokens = CharOperation.splitOn('/', filePath.toCharArray(),
+ projectPath.length() + 1, filePath.length()
+ - fileExtensionLength);
+ } else {*/
+ String name = file.getName();
+ tokens = new char[1][];
+ tokens[0] = name.substring(0, name.length() - fileExtensionLength)
+ .toCharArray();
+ //}
+
+ this.compilationUnit.currentPackage = impt = new ImportReference(
+ tokens, new char[0], 0, 0, true);
+
+ impt.declarationSourceStart = 0;
+ impt.declarationSourceEnd = 0;
+ impt.declarationEnd = 0;
+ // endPosition is just before the ;
+
+ }
+
+ public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV",
+ "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", "$_SESSION",
+ "$_SERVER" };
+
+ /**
+ *
+ */
+ private void pushFunctionVariableSet() {
+ HashSet set = new HashSet();
+ if (fStackUnassigned.isEmpty()) {
+ for (int i = 0; i < GLOBALS.length; i++) {
+ set.add(GLOBALS[i]);
+ }
+ }
+ fStackUnassigned.add(set);
+ }
+
+ private void pushIfVariableSet() {
+ if (!fStackUnassigned.isEmpty()) {
+ HashSet set = new HashSet();
+ fStackUnassigned.add(set);
+ }
+ }
+
+ private HashSet removeIfVariableSet() {
+ if (!fStackUnassigned.isEmpty()) {
+ return (HashSet) fStackUnassigned
+ .remove(fStackUnassigned.size() - 1);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <i>set of assigned variables </i> returns null if no Set is
+ * defined at the current scanner position
+ */
+ private HashSet peekVariableSet() {
+ if (!fStackUnassigned.isEmpty()) {
+ return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1);
+ }
+ return null;
+ }
+
+ /**
+ * add the current identifier source to the <i>set of assigned variables
+ * </i>
+ *
+ * @param set
+ */
+ private void addVariableSet(HashSet set) {
+ if (set != null) {
+ set.add(new String(scanner.getCurrentTokenSource()));
+ }
+ }
+
+ /**
+ * add the current identifier source to the <i>set of assigned variables
+ * </i>
+ *
+ */
+ private void addVariableSet() {
+ HashSet set = peekVariableSet();
+ if (set != null) {
+ set.add(new String(scanner.getCurrentTokenSource()));
+ }
+ }
+
+ /**
+ * add the current identifier source to the <i>set of assigned variables
+ * </i>
+ *
+ */
+ private void addVariableSet(char[] token) {
+ HashSet set = peekVariableSet();
+ if (set != null) {
+ set.add(new String(token));
+ }
+ }
+
+ /**
+ * check if the current identifier source is in the <i>set of assigned
+ * variables </i> Returns true, if no set is defined for the current scanner
+ * position
+ *
+ */
+ private boolean containsVariableSet() {
+ return containsVariableSet(scanner.getCurrentTokenSource());
+ }
+
+ private boolean containsVariableSet(char[] token) {
+
+ if (!fStackUnassigned.isEmpty()) {
+ HashSet set;
+ String str = new String(token);
+ for (int i = 0; i < fStackUnassigned.size(); i++) {
+ set = (HashSet) fStackUnassigned.get(i);
+ if (set.contains(str)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
}