--- /dev/null
+package net.sourceforge.phpdt.internal.compiler.parser;
+
+import net.sourceforge.phpdt.core.IJavaModelMarker;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.compiler.CompilationResult;
+import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
+import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.core.BasicCompilationUnit;
+import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer;
+import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * @author jsurfer
+ *
+ *
+ */
+public class UnitParser extends Parser {
+
+ public UnitParser(ProblemReporter problemReporter) { //, boolean optimizeStringLiterals, boolean assertMode) {
+ super();
+ nestedMethod = new int[30];
+ 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];
+ }
+
+ 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 goForCompilationUnit() {
+ //tells the scanner to go for compilation unit parsing
+
+ firstToken = TokenNamePLUS_PLUS;
+ scanner.linePtr = -1;
+ scanner.foundTaskCount = 0;
+ scanner.recordLineSeparator = true;
+ // scanner.currentLine= null;
+ }
+ 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 initialize() {
+ super.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;
+ // 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.foundTaskCount = 0;
+ scanner.eofPosition = Integer.MAX_VALUE;
+
+ // resetModifiers();
+ //
+ // // recovery
+ // lastCheckPoint = -1;
+ // currentElement = null;
+ // restartRecovery = false;
+ // hasReportedError = false;
+ // recoveredStaticInitializerStart = 0;
+ // lastIgnoredToken = -1;
+ // lastErrorEndPosition = -1;
+ // listLength = 0;
+ }
+
+ // 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);
+ // TODO TypeDeclaration test
+ // TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+ // typeDecl.sourceStart = 0;
+ // typeDecl.sourceEnd = 10;
+ // typeDecl.name = new char[]{'t', 'e','s','t'};
+ // this.compilationUnit.types = new ArrayList();
+ // this.compilationUnit.types.add(typeDecl);
+ /* run automaton */
+ super.parse();
+// // TODO jsurfer start
+// if (sourceUnit instanceof BasicCompilationUnit) {
+// storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(), compilationResult.getAllProblems());
+// }
+// // jsurfer end
+ } catch (CoreException e) {
+ e.printStackTrace();
+ } finally {
+ unit = compilationUnit;
+ compilationUnit = null; // reset parser
+ }
+ return unit;
+ }
+ /**
+ * Creates a marker from each problem and adds it to the resource.
+ * The marker is as follows:
+ * - its type is T_PROBLEM
+ * - its plugin ID is the JavaBuilder's plugin ID
+ * - its message is the problem's message
+ * - its priority reflects the severity of the problem
+ * - its range is the problem's range
+ * - it has an extra attribute "ID" which holds the problem's id
+ */
+ protected void storeProblemsFor(IResource resource, IProblem[] problems) throws CoreException {
+ if (resource == null || problems == null || problems.length == 0)
+ return;
+
+ for (int i = 0, l = problems.length; i < l; i++) {
+ IProblem problem = problems[i];
+ int id = problem.getID();
+ if (id != IProblem.Task) {
+ IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+ marker.setAttributes(
+ new String[] {
+ IMarker.MESSAGE,
+ IMarker.SEVERITY,
+ IJavaModelMarker.ID,
+ IMarker.CHAR_START,
+ IMarker.CHAR_END,
+ IMarker.LINE_NUMBER,
+ IJavaModelMarker.ARGUMENTS },
+ new Object[] {
+ problem.getMessage(),
+ new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING),
+ new Integer(id),
+ new Integer(problem.getSourceStart()),
+ new Integer(problem.getSourceEnd() + 1),
+ new Integer(problem.getSourceLineNumber()),
+ net.sourceforge.phpdt.internal.core.Util.getProblemArgumentsForMarker(problem.getArguments())});
+ }
+
+ }
+ }
+ 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]);
+ }
+ }
+ return compilationUnit;
+ }
+
+ // 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;
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } 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(FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) {
+ //only parse the initializationSource of the given field
+
+ //convert bugs into parse error
+
+ initialize();
+ goForExpression();
+ nestedMethod[nestedType]++;
+
+ referenceContext = type;
+ compilationUnit = unit;
+
+ scanner.setSource(initializationSource);
+ scanner.resetTo(0, initializationSource.length - 1);
+ try {
+ parse();
+ } catch (AbortCompilation ex) {
+ lastAct = ERROR_ACTION;
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ nestedMethod[nestedType]--;
+ }
+
+ // if (lastAct == ERROR_ACTION) {
+ // return;
+ // }
+ //
+ // field.initialization = expressionStack[expressionPtr];
+ //
+ // // mark field with local type if one was found during parsing
+ // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
+ // field.bits |= AstNode.HasLocalTypeMASK;
+ // }
+ }
+ // 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;
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } 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;
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } 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, 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();
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SyntaxError syntaxError) {
+ //
+ } finally {
+ unit = compilationUnit;
+ compilationUnit = null; // reset parser
+ }
+ return unit;
+ }
+
+ public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
+
+ CompilationUnitDeclaration parsedUnit;
+ boolean old = diet;
+ try {
+ diet = true;
+ parsedUnit = parse(sourceUnit, compilationResult);
+ } finally {
+ diet = old;
+ }
+ return parsedUnit;
+ }
+}