new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / UnitParser.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/UnitParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/UnitParser.java
new file mode 100644 (file)
index 0000000..2da0761
--- /dev/null
@@ -0,0 +1,483 @@
+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;
+  }
+}