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.phpdt.internal.core.BasicCompilationUnit;
11 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
12 import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
13 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
14 import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer;
15 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
16 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
18 import org.eclipse.core.resources.IMarker;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.runtime.CoreException;
27 public class UnitParser extends Parser {
29 public UnitParser(ProblemReporter problemReporter) { //, boolean optimizeStringLiterals, boolean assertMode) {
31 nestedMethod = new int[30];
32 this.problemReporter = problemReporter;
33 // this.optimizeStringLiterals = optimizeStringLiterals;
34 // this.assertMode = assertMode;
35 // this.initializeScanner();
36 astLengthStack = new int[50];
37 // expressionLengthStack = new int[30];
38 // intStack = new int[50];
39 // identifierStack = new char[30][];
40 // identifierLengthStack = new int[30];
41 // nestedMethod = new int[30];
42 // realBlockStack = new int[30];
43 // identifierPositionStack = new long[30];
44 // variablesCounter = new int[30];
47 public void goForConstructorBody() {
48 //tells the scanner to go for compilation unit parsing
50 firstToken = TokenNameEQUAL_EQUAL;
51 scanner.recordLineSeparator = false;
53 public void goForExpression() {
54 //tells the scanner to go for an expression parsing
56 firstToken = TokenNameREMAINDER;
57 scanner.recordLineSeparator = false;
59 public void goForCompilationUnit() {
60 //tells the scanner to go for compilation unit parsing
62 firstToken = TokenNamePLUS_PLUS;
64 scanner.foundTaskCount = 0;
65 scanner.recordLineSeparator = true;
66 // scanner.currentLine= null;
68 public void goForInitializer() {
69 //tells the scanner to go for initializer parsing
71 firstToken = TokenNameRIGHT_SHIFT;
72 scanner.recordLineSeparator = false;
74 public void goForMethodBody() {
75 //tells the scanner to go for method body parsing
77 firstToken = TokenNameMINUS_MINUS;
78 scanner.recordLineSeparator = false;
80 public void initialize(boolean phpMode) {
81 super.initialize(phpMode);
82 //positionning the parser for a new compilation unit
83 //avoiding stack reallocation and all that....
86 // expressionPtr = -1;
87 // expressionLengthPtr = -1;
88 // identifierPtr = -1;
89 // identifierLengthPtr = -1;
91 // nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
92 // variablesCounter[nestedType] = 0;
95 // endStatementPosition = 0;
97 //remove objects from stack too, while the same parser/compiler couple is
98 //re-used between two compilations ....
100 // int astLength = astStack.length;
101 // if (noAstNodes.length < astLength){
102 // noAstNodes = new AstNode[astLength];
103 // //System.out.println("Resized AST stacks : "+ astLength);
106 // System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
108 // int expressionLength = expressionStack.length;
109 // if (noExpressions.length < expressionLength){
110 // noExpressions = new Expression[expressionLength];
111 // //System.out.println("Resized EXPR stacks : "+ expressionLength);
113 // System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
115 // reset scanner state
116 scanner.commentPtr = -1;
117 scanner.foundTaskCount = 0;
118 scanner.eofPosition = Integer.MAX_VALUE;
123 // lastCheckPoint = -1;
124 // currentElement = null;
125 // restartRecovery = false;
126 // hasReportedError = false;
127 // recoveredStaticInitializerStart = 0;
128 // lastIgnoredToken = -1;
129 // lastErrorEndPosition = -1;
135 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
136 // parses a compilation unit and manages error handling (even bugs....)
138 CompilationUnitDeclaration unit;
140 /* automaton initialization */
142 goForCompilationUnit();
144 /* scanner initialization */
145 scanner.setSource(sourceUnit.getContents());
149 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
150 // TODO TypeDeclaration test
151 // TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
152 // typeDecl.sourceStart = 0;
153 // typeDecl.sourceEnd = 10;
154 // typeDecl.name = new char[]{'t', 'e','s','t'};
155 // this.compilationUnit.types = new ArrayList();
156 // this.compilationUnit.types.add(typeDecl);
159 // // TODO jsurfer start
160 // if (sourceUnit instanceof BasicCompilationUnit) {
161 // storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(), compilationResult.getAllProblems());
164 } catch (CoreException e) {
167 unit = compilationUnit;
168 compilationUnit = null; // reset parser
173 * Creates a marker from each problem and adds it to the resource.
174 * The marker is as follows:
175 * - its type is T_PROBLEM
176 * - its plugin ID is the JavaBuilder's plugin ID
177 * - its message is the problem's message
178 * - its priority reflects the severity of the problem
179 * - its range is the problem's range
180 * - it has an extra attribute "ID" which holds the problem's id
182 protected void storeProblemsFor(IResource resource, IProblem[] problems) throws CoreException {
183 if (resource == null || problems == null || problems.length == 0)
186 for (int i = 0, l = problems.length; i < l; i++) {
187 IProblem problem = problems[i];
188 int id = problem.getID();
189 if (id != IProblem.Task) {
190 IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
191 marker.setAttributes(
199 IJavaModelMarker.ARGUMENTS },
201 problem.getMessage(),
202 new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING),
204 new Integer(problem.getSourceStart()),
205 new Integer(problem.getSourceEnd() + 1),
206 new Integer(problem.getSourceLineNumber()),
207 net.sourceforge.phpdt.internal.core.Util.getProblemArgumentsForMarker(problem.getArguments())});
212 protected CompilationUnitDeclaration endParse(int act) {
216 if (currentElement != null) {
217 currentElement.topElement().updateParseTree();
218 if (VERBOSE_RECOVERY) {
219 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
220 System.out.println("--------------------------"); //$NON-NLS-1$
221 System.out.println(compilationUnit);
222 System.out.println("----------------------------------"); //$NON-NLS-1$
225 if (diet & VERBOSE_RECOVERY) {
226 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
227 System.out.println("--------------------------"); //$NON-NLS-1$
228 System.out.println(compilationUnit);
229 System.out.println("----------------------------------"); //$NON-NLS-1$
232 if (scanner.recordLineSeparator) {
233 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
235 if (scanner.taskTags != null) {
236 for (int i = 0; i < scanner.foundTaskCount; i++) {
237 problemReporter().task(
238 new String(scanner.foundTaskTags[i]),
239 new String(scanner.foundTaskMessages[i]),
240 scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
241 scanner.foundTaskPositions[i][0],
242 scanner.foundTaskPositions[i][1]);
245 return compilationUnit;
250 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
251 //only parse the method body of cd
252 //fill out its statements
254 //convert bugs into parse error
257 goForConstructorBody();
258 nestedMethod[nestedType]++;
260 referenceContext = cd;
261 compilationUnit = unit;
263 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
266 } catch (AbortCompilation ex) {
267 lastAct = ERROR_ACTION;
268 } catch (CoreException e) {
269 // TODO Auto-generated catch block
272 nestedMethod[nestedType]--;
275 if (lastAct == ERROR_ACTION) {
281 // cd.explicitDeclarations = realBlockStack[realBlockPtr--];
283 // if ((length = astLengthStack[astLengthPtr--]) != 0) {
285 // if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
286 // //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
291 // cd.statements = new Statement[length - 1],
294 // cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
295 // } else { //need to add explicitly the super();
299 // cd.statements = new Statement[length],
302 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
305 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
308 // if (cd.constructorCall.sourceEnd == 0) {
309 // cd.constructorCall.sourceEnd = cd.sourceEnd;
310 // cd.constructorCall.sourceStart = cd.sourceStart;
315 public void parse(FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) {
316 //only parse the initializationSource of the given field
318 //convert bugs into parse error
322 nestedMethod[nestedType]++;
324 referenceContext = type;
325 compilationUnit = unit;
327 scanner.setSource(initializationSource);
328 scanner.resetTo(0, initializationSource.length - 1);
331 } catch (AbortCompilation ex) {
332 lastAct = ERROR_ACTION;
333 } catch (CoreException e) {
334 // TODO Auto-generated catch block
337 nestedMethod[nestedType]--;
340 // if (lastAct == ERROR_ACTION) {
344 // field.initialization = expressionStack[expressionPtr];
346 // // mark field with local type if one was found during parsing
347 // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
348 // field.bits |= AstNode.HasLocalTypeMASK;
353 public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
354 //only parse the method body of md
355 //fill out method statements
357 //convert bugs into parse error
361 nestedMethod[nestedType]++;
363 referenceContext = type;
364 compilationUnit = unit;
366 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
369 } catch (AbortCompilation ex) {
370 lastAct = ERROR_ACTION;
371 } catch (CoreException e) {
372 // TODO Auto-generated catch block
375 nestedMethod[nestedType]--;
378 // if (lastAct == ERROR_ACTION) {
382 // ini.block = ((Initializer) astStack[astPtr]).block;
384 // // mark initializer with local type if one was found during parsing
385 // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
386 // ini.bits |= AstNode.HasLocalTypeMASK;
391 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
392 //only parse the method body of md
393 //fill out method statements
395 //convert bugs into parse error
399 // if (md.isNative())
401 // if ((md.modifiers & AccSemicolonBody) != 0)
406 nestedMethod[nestedType]++;
408 referenceContext = md;
409 compilationUnit = unit;
411 scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
412 // reset the scanner to parser from { down to }
415 } catch (AbortCompilation ex) {
416 lastAct = ERROR_ACTION;
417 } catch (CoreException e) {
418 // TODO Auto-generated catch block
421 nestedMethod[nestedType]--;
424 // if (lastAct == ERROR_ACTION) {
428 // //refill statements
429 // md.explicitDeclarations = realBlockStack[realBlockPtr--];
431 // if ((length = astLengthStack[astLengthPtr--]) != 0)
434 // (astPtr -= length) + 1,
435 // md.statements = new Statement[length],
442 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
443 // parses a compilation unit and manages error handling (even bugs....)
445 CompilationUnitDeclaration unit;
447 /* automaton initialization */
449 goForCompilationUnit();
451 /* scanner initialization */
452 scanner.setSource(sourceUnit.getContents());
453 scanner.resetTo(start, end);
456 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
459 } catch (CoreException e) {
460 // TODO Auto-generated catch block
462 } catch (SyntaxError syntaxError) {
465 unit = compilationUnit;
466 compilationUnit = null; // reset parser
471 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
472 return dietParse(sourceUnit, compilationResult, false);
474 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
476 CompilationUnitDeclaration parsedUnit;
480 parsedUnit = parse(sourceUnit, compilationResult, phpMode);