1 package net.sourceforge.phpdt.internal.compiler.parser;
3 import net.sourceforge.phpdt.core.IJavaModelMarker;
4 import net.sourceforge.phpdt.core.compiler.IProblem;
5 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
6 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
7 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
8 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
9 import net.sourceforge.phpdt.internal.compiler.util.Util;
10 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
11 import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
12 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
13 import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer;
14 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
15 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
17 import org.eclipse.core.resources.IMarker;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.runtime.CoreException;
26 public class UnitParser extends Parser {
28 public UnitParser(ProblemReporter problemReporter) { //, boolean optimizeStringLiterals, boolean assertMode) {
30 nestedMethod = new int[30];
31 this.problemReporter = problemReporter;
32 // this.optimizeStringLiterals = optimizeStringLiterals;
33 // this.assertMode = assertMode;
34 // this.initializeScanner();
35 astLengthStack = new int[50];
36 // expressionLengthStack = new int[30];
37 // intStack = new int[50];
38 // identifierStack = new char[30][];
39 // identifierLengthStack = new int[30];
40 // nestedMethod = new int[30];
41 // realBlockStack = new int[30];
42 // identifierPositionStack = new long[30];
43 // variablesCounter = new int[30];
46 public void goForConstructorBody() {
47 //tells the scanner to go for compilation unit parsing
49 firstToken = TokenNameEQUAL_EQUAL;
50 scanner.recordLineSeparator = false;
52 public void goForExpression() {
53 //tells the scanner to go for an expression parsing
55 firstToken = TokenNameREMAINDER;
56 scanner.recordLineSeparator = false;
58 public void goForCompilationUnit() {
59 //tells the scanner to go for compilation unit parsing
61 firstToken = TokenNamePLUS_PLUS;
63 scanner.foundTaskCount = 0;
64 scanner.recordLineSeparator = true;
65 // scanner.currentLine= null;
67 public void goForInitializer() {
68 //tells the scanner to go for initializer parsing
70 firstToken = TokenNameRIGHT_SHIFT;
71 scanner.recordLineSeparator = false;
73 public void goForMethodBody() {
74 //tells the scanner to go for method body parsing
76 firstToken = TokenNameMINUS_MINUS;
77 scanner.recordLineSeparator = false;
79 public void initialize(boolean phpMode) {
80 super.initialize(phpMode);
81 //positionning the parser for a new compilation unit
82 //avoiding stack reallocation and all that....
85 // expressionPtr = -1;
86 // expressionLengthPtr = -1;
87 // identifierPtr = -1;
88 // identifierLengthPtr = -1;
90 // nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
91 // variablesCounter[nestedType] = 0;
94 // endStatementPosition = 0;
96 //remove objects from stack too, while the same parser/compiler couple is
97 //re-used between two compilations ....
99 // int astLength = astStack.length;
100 // if (noAstNodes.length < astLength){
101 // noAstNodes = new AstNode[astLength];
102 // //System.out.println("Resized AST stacks : "+ astLength);
105 // System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
107 // int expressionLength = expressionStack.length;
108 // if (noExpressions.length < expressionLength){
109 // noExpressions = new Expression[expressionLength];
110 // //System.out.println("Resized EXPR stacks : "+ expressionLength);
112 // System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
114 // reset scanner state
115 scanner.commentPtr = -1;
116 scanner.foundTaskCount = 0;
117 scanner.eofPosition = Integer.MAX_VALUE;
122 // lastCheckPoint = -1;
123 // currentElement = null;
124 // restartRecovery = false;
125 // hasReportedError = false;
126 // recoveredStaticInitializerStart = 0;
127 // lastIgnoredToken = -1;
128 // lastErrorEndPosition = -1;
134 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
135 // parses a compilation unit and manages error handling (even bugs....)
137 CompilationUnitDeclaration unit;
139 /* automaton initialization */
141 goForCompilationUnit();
143 /* scanner initialization */
144 scanner.setSource(sourceUnit.getContents());
148 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
149 // TODO TypeDeclaration test
150 // TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
151 // typeDecl.sourceStart = 0;
152 // typeDecl.sourceEnd = 10;
153 // typeDecl.name = new char[]{'t', 'e','s','t'};
154 // this.compilationUnit.types = new ArrayList();
155 // this.compilationUnit.types.add(typeDecl);
158 // // TODO jsurfer start
159 // if (sourceUnit instanceof BasicCompilationUnit) {
160 // storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(), compilationResult.getAllProblems());
165 unit = compilationUnit;
166 compilationUnit = null; // reset parser
171 * Creates a marker from each problem and adds it to the resource.
172 * The marker is as follows:
173 * - its type is T_PROBLEM
174 * - its plugin ID is the JavaBuilder's plugin ID
175 * - its message is the problem's message
176 * - its priority reflects the severity of the problem
177 * - its range is the problem's range
178 * - it has an extra attribute "ID" which holds the problem's id
180 protected void storeProblemsFor(IResource resource, IProblem[] problems) throws CoreException {
181 if (resource == null || problems == null || problems.length == 0)
184 for (int i = 0, l = problems.length; i < l; i++) {
185 IProblem problem = problems[i];
186 int id = problem.getID();
187 if (id != IProblem.Task) {
188 IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
189 marker.setAttributes(
197 IJavaModelMarker.ARGUMENTS },
199 problem.getMessage(),
200 new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING),
202 new Integer(problem.getSourceStart()),
203 new Integer(problem.getSourceEnd() + 1),
204 new Integer(problem.getSourceLineNumber()),
205 net.sourceforge.phpdt.internal.core.Util.getProblemArgumentsForMarker(problem.getArguments())});
210 protected CompilationUnitDeclaration endParse(int act) {
214 if (currentElement != null) {
215 currentElement.topElement().updateParseTree();
216 if (VERBOSE_RECOVERY) {
217 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
218 System.out.println("--------------------------"); //$NON-NLS-1$
219 System.out.println(compilationUnit);
220 System.out.println("----------------------------------"); //$NON-NLS-1$
223 if (diet & VERBOSE_RECOVERY) {
224 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
225 System.out.println("--------------------------"); //$NON-NLS-1$
226 System.out.println(compilationUnit);
227 System.out.println("----------------------------------"); //$NON-NLS-1$
230 if (scanner.recordLineSeparator) {
231 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
233 if (scanner.taskTags != null) {
234 for (int i = 0; i < scanner.foundTaskCount; i++) {
235 problemReporter().task(
236 new String(scanner.foundTaskTags[i]),
237 new String(scanner.foundTaskMessages[i]),
238 scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
239 scanner.foundTaskPositions[i][0],
240 scanner.foundTaskPositions[i][1]);
243 return compilationUnit;
248 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
249 //only parse the method body of cd
250 //fill out its statements
252 //convert bugs into parse error
255 goForConstructorBody();
256 nestedMethod[nestedType]++;
258 referenceContext = cd;
259 compilationUnit = unit;
261 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
264 } catch (AbortCompilation ex) {
265 lastAct = ERROR_ACTION;
268 nestedMethod[nestedType]--;
271 if (lastAct == ERROR_ACTION) {
277 // cd.explicitDeclarations = realBlockStack[realBlockPtr--];
279 // if ((length = astLengthStack[astLengthPtr--]) != 0) {
281 // if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
282 // //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
287 // cd.statements = new Statement[length - 1],
290 // cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
291 // } else { //need to add explicitly the super();
295 // cd.statements = new Statement[length],
298 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
301 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
304 // if (cd.constructorCall.sourceEnd == 0) {
305 // cd.constructorCall.sourceEnd = cd.sourceEnd;
306 // cd.constructorCall.sourceStart = cd.sourceStart;
311 public void parse(FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) {
312 //only parse the initializationSource of the given field
314 //convert bugs into parse error
318 nestedMethod[nestedType]++;
320 referenceContext = type;
321 compilationUnit = unit;
323 scanner.setSource(initializationSource);
324 scanner.resetTo(0, initializationSource.length - 1);
327 } catch (AbortCompilation ex) {
328 lastAct = ERROR_ACTION;
330 nestedMethod[nestedType]--;
333 // if (lastAct == ERROR_ACTION) {
337 // field.initialization = expressionStack[expressionPtr];
339 // // mark field with local type if one was found during parsing
340 // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
341 // field.bits |= AstNode.HasLocalTypeMASK;
346 public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
347 //only parse the method body of md
348 //fill out method statements
350 //convert bugs into parse error
354 nestedMethod[nestedType]++;
356 referenceContext = type;
357 compilationUnit = unit;
359 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
362 } catch (AbortCompilation ex) {
363 lastAct = ERROR_ACTION;
365 nestedMethod[nestedType]--;
368 // if (lastAct == ERROR_ACTION) {
372 // ini.block = ((Initializer) astStack[astPtr]).block;
374 // // mark initializer with local type if one was found during parsing
375 // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
376 // ini.bits |= AstNode.HasLocalTypeMASK;
381 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
382 //only parse the method body of md
383 //fill out method statements
385 //convert bugs into parse error
389 // if (md.isNative())
391 // if ((md.modifiers & AccSemicolonBody) != 0)
396 nestedMethod[nestedType]++;
398 referenceContext = md;
399 compilationUnit = unit;
401 scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
402 // reset the scanner to parser from { down to }
405 } catch (AbortCompilation ex) {
406 lastAct = ERROR_ACTION;
408 nestedMethod[nestedType]--;
411 // if (lastAct == ERROR_ACTION) {
415 // //refill statements
416 // md.explicitDeclarations = realBlockStack[realBlockPtr--];
418 // if ((length = astLengthStack[astLengthPtr--]) != 0)
421 // (astPtr -= length) + 1,
422 // md.statements = new Statement[length],
429 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
430 // parses a compilation unit and manages error handling (even bugs....)
432 CompilationUnitDeclaration unit;
434 /* automaton initialization */
436 goForCompilationUnit();
438 /* scanner initialization */
439 scanner.setSource(sourceUnit.getContents());
440 scanner.resetTo(start, end);
443 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
446 } catch (SyntaxError syntaxError) {
449 unit = compilationUnit;
450 compilationUnit = null; // reset parser
455 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
456 return dietParse(sourceUnit, compilationResult, false);
458 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
460 CompilationUnitDeclaration parsedUnit;
464 parsedUnit = parse(sourceUnit, compilationResult, phpMode);