1 package net.sourceforge.phpdt.internal.compiler.parser;
3 import java.util.Stack;
5 import net.sourceforge.phpdt.core.IJavaModelMarker;
6 import net.sourceforge.phpdt.core.compiler.IProblem;
7 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
8 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
9 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
10 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
11 import net.sourceforge.phpdt.internal.compiler.util.Util;
12 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
13 import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
14 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
15 import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer;
16 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
17 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
19 import org.eclipse.core.resources.IMarker;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.CoreException;
28 public class UnitParser extends Parser {
30 public UnitParser(ProblemReporter problemReporter) { //, boolean optimizeStringLiterals, boolean assertMode) {
32 nestedMethod = new int[30];
33 this.problemReporter = problemReporter;
34 // this.optimizeStringLiterals = optimizeStringLiterals;
35 // this.assertMode = assertMode;
36 // this.initializeScanner();
37 astLengthStack = new int[50];
38 // expressionLengthStack = new int[30];
39 // intStack = new int[50];
40 // identifierStack = new char[30][];
41 // identifierLengthStack = new int[30];
42 // nestedMethod = new int[30];
43 // realBlockStack = new int[30];
44 // identifierPositionStack = new long[30];
45 // variablesCounter = new int[30];
48 public void goForConstructorBody() {
49 //tells the scanner to go for compilation unit parsing
51 firstToken = TokenNameEQUAL_EQUAL;
52 scanner.recordLineSeparator = false;
54 public void goForExpression() {
55 //tells the scanner to go for an expression parsing
57 firstToken = TokenNameREMAINDER;
58 scanner.recordLineSeparator = false;
60 public void goForCompilationUnit() {
61 //tells the scanner to go for compilation unit parsing
63 firstToken = TokenNamePLUS_PLUS;
65 scanner.foundTaskCount = 0;
66 scanner.recordLineSeparator = true;
67 // scanner.currentLine= null;
69 public void goForInitializer() {
70 //tells the scanner to go for initializer parsing
72 firstToken = TokenNameRIGHT_SHIFT;
73 scanner.recordLineSeparator = false;
75 public void goForMethodBody() {
76 //tells the scanner to go for method body parsing
78 firstToken = TokenNameMINUS_MINUS;
79 scanner.recordLineSeparator = false;
81 public void initialize(boolean phpMode) {
82 super.initialize(phpMode);
83 //positionning the parser for a new compilation unit
84 //avoiding stack reallocation and all that....
87 // expressionPtr = -1;
88 // expressionLengthPtr = -1;
89 // identifierPtr = -1;
90 // identifierLengthPtr = -1;
92 // nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
93 // variablesCounter[nestedType] = 0;
96 // endStatementPosition = 0;
98 //remove objects from stack too, while the same parser/compiler couple is
99 //re-used between two compilations ....
101 // int astLength = astStack.length;
102 // if (noAstNodes.length < astLength){
103 // noAstNodes = new AstNode[astLength];
104 // //System.out.println("Resized AST stacks : "+ astLength);
107 // System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
109 // int expressionLength = expressionStack.length;
110 // if (noExpressions.length < expressionLength){
111 // noExpressions = new Expression[expressionLength];
112 // //System.out.println("Resized EXPR stacks : "+ expressionLength);
114 // System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
116 // reset scanner state
117 scanner.commentPtr = -1;
118 scanner.foundTaskCount = 0;
119 scanner.eofPosition = Integer.MAX_VALUE;
124 // lastCheckPoint = -1;
125 // currentElement = null;
126 // restartRecovery = false;
127 // hasReportedError = false;
128 // recoveredStaticInitializerStart = 0;
129 // lastIgnoredToken = -1;
130 // lastErrorEndPosition = -1;
136 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
137 // parses a compilation unit and manages error handling (even bugs....)
139 CompilationUnitDeclaration unit;
141 /* automaton initialization */
143 goForCompilationUnit();
145 /* scanner initialization */
146 scanner.setSource(sourceUnit.getContents());
150 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
151 // TODO TypeDeclaration test
152 // TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
153 // typeDecl.sourceStart = 0;
154 // typeDecl.sourceEnd = 10;
155 // typeDecl.name = new char[]{'t', 'e','s','t'};
156 // this.compilationUnit.types = new ArrayList();
157 // this.compilationUnit.types.add(typeDecl);
160 // // TODO jsurfer start
161 // if (sourceUnit instanceof BasicCompilationUnit) {
162 // storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(), compilationResult.getAllProblems());
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;
270 nestedMethod[nestedType]--;
273 if (lastAct == ERROR_ACTION) {
279 // cd.explicitDeclarations = realBlockStack[realBlockPtr--];
281 // if ((length = astLengthStack[astLengthPtr--]) != 0) {
283 // if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
284 // //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
289 // cd.statements = new Statement[length - 1],
292 // cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
293 // } else { //need to add explicitly the super();
297 // cd.statements = new Statement[length],
300 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
303 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
306 // if (cd.constructorCall.sourceEnd == 0) {
307 // cd.constructorCall.sourceEnd = cd.sourceEnd;
308 // cd.constructorCall.sourceStart = cd.sourceStart;
313 public void parse(FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) {
314 //only parse the initializationSource of the given field
316 //convert bugs into parse error
320 nestedMethod[nestedType]++;
322 referenceContext = type;
323 compilationUnit = unit;
325 scanner.setSource(initializationSource);
326 scanner.resetTo(0, initializationSource.length - 1);
329 } catch (AbortCompilation ex) {
330 lastAct = ERROR_ACTION;
332 nestedMethod[nestedType]--;
335 // if (lastAct == ERROR_ACTION) {
339 // field.initialization = expressionStack[expressionPtr];
341 // // mark field with local type if one was found during parsing
342 // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
343 // field.bits |= AstNode.HasLocalTypeMASK;
348 public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
349 //only parse the method body of md
350 //fill out method statements
352 //convert bugs into parse error
356 nestedMethod[nestedType]++;
358 referenceContext = type;
359 compilationUnit = unit;
361 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
364 } catch (AbortCompilation ex) {
365 lastAct = ERROR_ACTION;
367 nestedMethod[nestedType]--;
370 // if (lastAct == ERROR_ACTION) {
374 // ini.block = ((Initializer) astStack[astPtr]).block;
376 // // mark initializer with local type if one was found during parsing
377 // if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
378 // ini.bits |= AstNode.HasLocalTypeMASK;
383 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
384 // TODO jsurfer - make the parse process work on methods ?
387 // //only parse the method body of md
388 // //fill out method statements
390 // //convert bugs into parse error
392 // if (md.isAbstract())
394 // // if (md.isNative())
396 // // if ((md.modifiers & AccSemicolonBody) != 0)
399 // initialize(false);
400 // goForMethodBody();
401 // nestedMethod[nestedType]++;
403 // referenceContext = md;
404 // compilationUnit = unit;
406 // scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
408 // // reset the scanner to parser from { down to }
411 // } catch (AbortCompilation ex) {
412 // lastAct = ERROR_ACTION;
414 // nestedMethod[nestedType]--;
417 // // if (lastAct == ERROR_ACTION) {
421 // // //refill statements
422 // // md.explicitDeclarations = realBlockStack[realBlockPtr--];
424 // // if ((length = astLengthStack[astLengthPtr--]) != 0)
425 // // System.arraycopy(
427 // // (astPtr -= length) + 1,
428 // // md.statements = new Statement[length],
435 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
436 // parses a compilation unit and manages error handling (even bugs....)
438 CompilationUnitDeclaration unit;
440 /* automaton initialization */
442 goForCompilationUnit();
444 /* scanner initialization */
445 scanner.setSource(sourceUnit.getContents());
446 scanner.resetTo(start, end);
449 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
452 } catch (SyntaxError syntaxError) {
455 unit = compilationUnit;
456 compilationUnit = null; // reset parser
461 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
462 return dietParse(sourceUnit, compilationResult, false);
464 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
466 CompilationUnitDeclaration parsedUnit;
470 parsedUnit = parse(sourceUnit, compilationResult, phpMode);