1 /*******************************************************************************
2  * Copyright (c) 2000, 2013 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.core.jdom;
15 
16 import java.util.ArrayList;
17 import java.util.Map;
18 
19 import org.eclipse.jdt.core.JavaCore;
20 import org.eclipse.jdt.core.compiler.CategorizedProblem;
21 import org.eclipse.jdt.core.compiler.CharOperation;
22 import org.eclipse.jdt.core.jdom.*;
23 import org.eclipse.jdt.internal.compiler.DocumentElementParser;
24 import org.eclipse.jdt.internal.compiler.IDocumentElementRequestor;
25 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
26 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
27 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
28 /**
29  * The DOMBuilder constructs each type of JDOM document fragment,
30  * for the DOMFactory. The DOMBuilder has been separated from the
31  * DOMFactory to hide the implmentation of node creation and the
32  * public Requestor API methods.
33  *
34  * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
35  * powerful, fine-grained DOM/AST API found in the
36  * org.eclipse.jdt.core.dom package.
37  */
38 @SuppressWarnings({"rawtypes", "unchecked"})
39 public class DOMBuilder extends AbstractDOMBuilder implements IDocumentElementRequestor {
40 
41 	/**
42 	 * True when parsing a single member - ignore any problems
43 	 * encountered after the member.
44 	 */
45 	protected boolean fBuildingSingleMember= false;
46 
47 	/**
48 	 * True when the single member being built has been
49 	 * exited.
50 	 */
51 	protected boolean fFinishedSingleMember = false;
52 
53 	/**
54 	 * Collection of multiple fields in one declaration
55 	 */
56 	protected ArrayList fFields;
57 
58 	Map options = JavaCore.getOptions();
59 
60 /**
61  * Creates a new DOMBuilder
62  */
DOMBuilder()63 public DOMBuilder() {
64 	// Creates a new DOMBuilder
65 }
66 /**
67  * @see IDocumentElementRequestor#acceptImport(int, int, int[], char[], int, boolean, int)
68  */
69 @Override
acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStart, boolean onDemand, int modifiers)70 public void acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name,
71 	int nameStart, boolean onDemand, int modifiers) {
72 	int[] sourceRange = {declarationStart, declarationEnd};
73 	int[] nameRange = {nameStart, declarationEnd - 1};
74 
75 	/* See 1FVII1P */
76 	String importName = new String(this.fDocument, nameRange[0], nameRange[1] + 1 - nameRange[0]);
77 
78 	this.fNode= new DOMImport(this.fDocument, sourceRange, importName, nameRange, onDemand, modifiers);
79 	addChild(this.fNode);
80 	if (this.fBuildingSingleMember) {
81 		this.fFinishedSingleMember= true;
82 	}
83 }
84 /**
85  * @see IDocumentElementRequestor#acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, int modifiersStart, int bodyStart, int bodyEnd)
86  */
87 @Override
acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, int modifiersStart, int bodyStart, int bodyEnd)88 public void acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers,
89 	int modifiersStart, int bodyStart, int bodyEnd) {
90 	int[] sourceRange = {declarationStart, declarationEnd};
91 	int[] commentRange = {-1, -1};
92 	if (javaDocPositions != null) {
93 		int length = javaDocPositions.length;
94 		commentRange[0] = javaDocPositions[length - 2];
95 		commentRange[1] = javaDocPositions[length - 1];
96 	}
97 
98 	int[] modifiersRange = {-1, -1};
99 	if (modifiersStart >= declarationStart) {
100 		modifiersRange[0] = modifiersStart;
101 		modifiersRange[1] = bodyStart - 1;
102 	}
103 	this.fNode = new DOMInitializer(this.fDocument, sourceRange, commentRange, modifiers,
104 		modifiersRange, bodyStart);
105 	addChild(this.fNode);
106 	if (this.fBuildingSingleMember) {
107 		this.fFinishedSingleMember= true;
108 	}
109 }
110 /**
111  * @see IDocumentElementRequestor#acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition)
112  */
113 @Override
acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition)114 public void acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name,
115 	int nameStartPosition) {
116 	int[] sourceRange = null;
117 	if (javaDocPositions != null) {
118 		int length = javaDocPositions.length;
119 		// get last javadoc comment (see bug 68772)
120 		sourceRange = new int[] {javaDocPositions[length - 2], declarationEnd};
121 	} else {
122 		sourceRange = new int[] {declarationStart, declarationEnd};
123 	}
124 	int[] nameRange = {nameStartPosition, declarationEnd - 1};
125 	this.fNode= new DOMPackage(this.fDocument, sourceRange, CharOperation.charToString(name), nameRange);
126 	addChild(this.fNode);
127 	if (this.fBuildingSingleMember) {
128 		this.fFinishedSingleMember= true;
129 	}
130 }
131 /**
132  * Sets the abort flag to true. The parser has encountered an error
133  * in the current document. If we are only building a single member, and
134  * we are done with the member - don't worry about the error.
135  *
136  * @see IDocumentElementRequestor
137  */
138 @Override
acceptProblem(CategorizedProblem problem)139 public void acceptProblem(CategorizedProblem problem){
140 	if (this.fBuildingSingleMember && this.fFinishedSingleMember) {
141 		return;
142 	}
143 	this.fAbort= true;
144 }
145 /**
146  * Adds the given node to the current enclosing scope, building the JDOM
147  * tree. Nodes are only added to an enclosing scope when a compilation unit or type
148  * is being built (since those are the only nodes that have children).
149  *
150  * <p>NOTE: nodes are added to the JDOM via the method #basicAddChild such that
151  * the nodes in the newly created JDOM are not fragmented.
152  */
153 @Override
addChild(IDOMNode child)154 protected void addChild(IDOMNode child) {
155 	super.addChild(child);
156 	if (this.fStack.isEmpty() && this.fFields != null) {
157 		this.fFields.add(child);
158 	}
159 }
160 /**
161  * @see IDOMFactory#createCompilationUnit()
162  */
createCompilationUnit()163 public IDOMCompilationUnit createCompilationUnit() {
164 	return new DOMCompilationUnit();
165 }
166 /**
167  * @see IDOMFactory#createCompilationUnit(String, String)
168  */
169 @Override
createCompilationUnit(ICompilationUnit compilationUnit)170 public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
171 	initializeBuild(compilationUnit.getContents(), true, true, false);
172 	getParser(this.options).parseCompilationUnit(compilationUnit);
173 	return super.createCompilationUnit(compilationUnit);
174 }
175 /**
176  * @see IDOMFactory#createField(String)
177  */
createField(char[] sourceCode)178 public IDOMField createField(char[] sourceCode) {
179 	initializeBuild(sourceCode, false, false, true);
180 	getParser(this.options).parseField(sourceCode);
181 	if (this.fAbort || this.fNode == null) {
182 		return null;
183 	}
184 
185 	// we only accept field declarations with one field
186 	if (this.fFieldCount > 1) {
187 		return null;
188 	}
189 
190 	this.fNode.normalize(this);
191 	return (IDOMField)this.fNode;
192 }
193 /**
194  *
195  */
createFields(char[] sourceCode)196 public IDOMField[] createFields(char[] sourceCode) {
197 	initializeBuild(sourceCode, false, false, false);
198 	this.fFields= new ArrayList();
199 	getParser(this.options).parseField(sourceCode);
200 	if (this.fAbort) {
201 		return null;
202 	}
203 	IDOMField[] fields= new IDOMField[this.fFields.size()];
204 	this.fFields.toArray(fields);
205 	for (int i= 0; i < fields.length; i++) {
206 		DOMNode node= (DOMNode)fields[i];
207 		if (i < (fields.length - 1)) {
208 			DOMNode next= (DOMNode)fields[i + 1];
209 			node.fNextNode= next;
210 			next.fPreviousNode= node;
211 		}
212 		((DOMNode)fields[i]).normalize(this);
213 	}
214 	return fields;
215 }
216 /**
217  * @see IDOMFactory#createImport()
218  */
createImport()219 public IDOMImport createImport() {
220 	return new DOMImport();
221 }
222 /**
223  * @see IDOMFactory#createImport(String)
224  */
createImport(char[] sourceCode)225 public IDOMImport createImport(char[] sourceCode) {
226 	initializeBuild(sourceCode, false, false, true);
227 	getParser(this.options).parseImport(sourceCode);
228 	if (this.fAbort || this.fNode == null) {
229 		return null;
230 	}
231 	this.fNode.normalize(this);
232 	return (IDOMImport)this.fNode;
233 }
234 /**
235  * Creates an INITIALIZER document fragment from the given source.
236  *
237  * @see IDOMFactory#createInitializer(String)
238  */
createInitializer(char[] sourceCode)239 public IDOMInitializer createInitializer(char[] sourceCode) {
240 	initializeBuild(sourceCode, false, false, true);
241 	getParser(this.options).parseInitializer(sourceCode);
242 	if (this.fAbort || this.fNode == null || !(this.fNode instanceof IDOMInitializer)) {
243 		return null;
244 	}
245 	this.fNode.normalize(this);
246 	return (IDOMInitializer)this.fNode;
247 }
248 /**
249  * @see IDOMFactory#createMethod(String)
250  */
createMethod(char[] sourceCode)251 public IDOMMethod createMethod(char[] sourceCode) {
252 	initializeBuild(sourceCode, false, false, true);
253 	getParser(this.options).parseMethod(sourceCode);
254 	if (this.fAbort || this.fNode == null) {
255 		return null;
256 	}
257 	this.fNode.normalize(this);
258 	return (IDOMMethod)this.fNode;
259 }
260 /**
261  * @see IDOMFactory#createPackage()
262  */
createPackage()263 public IDOMPackage createPackage() {
264 	return new DOMPackage();
265 }
266 /**
267  * @see IDOMFactory#createPackage(String)
268  */
createPackage(char[] sourceCode)269 public IDOMPackage createPackage(char[] sourceCode) {
270 	initializeBuild(sourceCode, false, false, true);
271 	getParser(this.options).parsePackage(sourceCode);
272 	if (this.fAbort || this.fNode == null) {
273 		return null;
274 	}
275 	this.fNode.normalize(this);
276 	return (IDOMPackage)this.fNode;
277 }
278 /**
279  * @see IDOMFactory#createType(String)
280  */
createType(char[] sourceCode)281 public IDOMType createType(char[] sourceCode) {
282 	initializeBuild(sourceCode, false, true, false);
283 	getParser(this.options).parseType(sourceCode);
284 	if (this.fAbort) {
285 		return null;
286 	}
287 	if (this.fNode != null) this.fNode.normalize(this);
288 	if (this.fNode instanceof IDOMType) {
289 		return (IDOMType) this.fNode;
290 	}
291 	return null;
292 }
293 /**
294  * Creates a new DOMMethod and inizializes.
295  *
296  * @param declarationStart - a source position corresponding to the first character
297  *		of this constructor declaration
298  * @param modifiers - the modifiers for this constructor converted to a flag
299  * @param modifiersStart - a source position corresponding to the first character of the
300  *		textual modifiers
301  * @param returnType - the name of the return type
302  * @param returnTypeStart - a source position corresponding to the first character
303  *		of the return type
304  * @param returnTypeEnd - a source position corresponding to the last character
305  *		of the return type
306  * @param returnTypeDimensionCount - the array dimension count as supplied on the
307  *		return type (for instance, 'public int[] foo() {}')
308  * @param name - the name of this constructor
309  * @param nameStart - a source position corresponding to the first character of the name
310  * @param nameEnd - a source position corresponding to the last character of the name
311  * @param parameterTypes - a list of parameter type names
312  * @param parameterTypeStarts - a list of source positions corresponding to the
313  *		first character of each parameter type name
314  * @param parameterTypeEnds - a list of source positions corresponding to the
315  *		last character of each parameter type name
316  * @param parameterNames - a list of the names of the parameters
317  * @param parametersEnd - a source position corresponding to the last character of the
318  *		parameter list
319  * @extendedReturnTypeDimensionCount - the array dimension count as supplied on the
320  *		end of the parameter list (for instance, 'public int foo()[] {}')
321  * @extendedReturnTypeDimensionEnd - a source position corresponding to the last character
322  *		of the extended return type dimension
323  * @param exceptionTypes - a list of the exception types
324  * @param exceptionTypeStarts - a list of source positions corresponding to the first
325  *		character of the respective exception types
326  * @param exceptionTypeEnds - a list of source positions corresponding to the last
327  *		character of the respective exception types
328  * @param bodyStart - a source position corresponding to the start of this
329  *		constructor's body
330  */
enterAbstractMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds, int bodyStart, boolean isConstructor)331 protected void enterAbstractMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
332 	char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount,
333 	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
334 	int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts,
335 	int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount,
336 	int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts,
337 	int[] exceptionTypeEnds, int bodyStart, boolean isConstructor) {
338 	int[] sourceRange = {declarationStart, -1}; // will be fixed up on exit
339 	int[] nameRange = {nameStart, nameEnd};
340 	int[] commentRange = {-1, -1};
341 	if (javaDocPositions != null) {
342 		int length = javaDocPositions.length;
343 		commentRange[0] = javaDocPositions[length - 2]; // get last javadoc comment (see bug 68772)
344 		commentRange[1] = javaDocPositions[length - 1];
345 	}
346 	int[] modifiersRange = {-1, -1};
347 	if (modifiersStart > -1) {
348 		modifiersRange[0] = modifiersStart;
349 		if (isConstructor) {
350 			modifiersRange[1] = nameStart - 1;
351 		} else {
352 			modifiersRange[1] = returnTypeStart - 1;
353 		}
354 	}
355 	int[] returnTypeRange = null;
356 
357 	if (extendedReturnTypeDimensionCount > 0)
358 		returnTypeRange = new int[] {returnTypeStart, returnTypeEnd,
359 			parametersEnd + 1, extendedReturnTypeDimensionEnd};
360 	else
361 		returnTypeRange = new int[] {returnTypeStart, returnTypeEnd};
362 	int[] parameterRange = {nameEnd + 1, parametersEnd};
363 	int[] exceptionRange = {-1, -1};
364 	if (exceptionTypes != null && exceptionTypes.length > 0) {
365 		int exceptionCount = exceptionTypes.length;
366 		exceptionRange[0] = exceptionTypeStarts[0];
367 		exceptionRange[1] = exceptionTypeEnds[exceptionCount - 1];
368 	}
369 	int[] bodyRange = null;
370 	if (exceptionRange[1] > -1) {
371 		bodyRange = new int[] {exceptionRange[1] + 1, -1}; // will be fixed up on exit
372 	} else {
373 		bodyRange = new int[] {parametersEnd + 1, -1};
374 	}
375 	this.fNode = new DOMMethod(this.fDocument, sourceRange, CharOperation.charToString(name), nameRange, commentRange, modifiers,
376 		modifiersRange, isConstructor, CharOperation.charToString(returnType), returnTypeRange,
377 		CharOperation.charArrayToStringArray(parameterTypes),
378 		CharOperation.charArrayToStringArray(parameterNames),
379 		parameterRange, CharOperation.charArrayToStringArray(exceptionTypes), exceptionRange, bodyRange);
380 	addChild(this.fNode);
381 	this.fStack.push(this.fNode);
382 }
383 /**
384  * @see IDocumentElementRequestor#enterClass(
385 	int declarationStart,
386 	int[] javaDocPositions,
387 	int modifiers,
388 	int modifiersStart,
389 	int classStart,
390 	char[] name,
391 	int nameStart,
392 	int nameEnd,
393 	char[] superclass,
394 	int superclassStart,
395 	int superclassEnd,
396 	char[][] superinterfaces,
397 	int[] superinterfaceStarts,
398 	int[] superinterfaceEnds,
399 	int bodyStart)
400  */
401 @Override
enterClass(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart, int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart)402 public void enterClass(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart,
403 	char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart,
404 	int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts,
405 	int[] superinterfaceEnds, int bodyStart) {
406 
407 	enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
408 		name, nameStart, nameEnd, superclass, superclassStart,
409 		superclassEnd, superinterfaces, superinterfaceStarts,
410 		superinterfaceEnds, bodyStart, true);
411 }
412 /**
413  * @see IDocumentElementRequestor#enterConstructor(
414 	int declarationStart,
415 	int[] javaDocPositions,
416 	int modifiers,
417 	int modifiersStart,
418 	char[] name,
419 	int nameStart,
420 	int nameEnd,
421 	char[][] parameterTypes,
422 	int [] parameterTypeStarts,
423 	int [] parameterTypeEnds,
424 	char[][] parameterNames,
425 	int [] parameterNameStarts,
426 	int [] parameterNameEnds,
427 	int parametersEnd,
428 	char[][] exceptionTypes,
429 	int [] exceptionTypeStarts,
430 	int [] exceptionTypeEnds,
431 	int bodyStart)
432  */
433 @Override
enterConstructor(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds, int bodyStart)434 public void enterConstructor(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
435 	char[] name, int nameStart, int nameEnd, char[][] parameterTypes,
436 	int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames,
437 	int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd,
438 	char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds,
439 	int bodyStart) {
440 
441 	/* see 1FVIIQZ */
442 	String nameString = new String(this.fDocument, nameStart, nameEnd - nameStart);
443 	int openParenPosition = nameString.indexOf('(');
444 	if (openParenPosition > -1)
445 		nameEnd = nameStart + openParenPosition - 1;
446 
447 	enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart,
448 		null, -1, -1, 0,
449 		name, nameStart, nameEnd, parameterTypes, parameterTypeStarts,
450 		parameterTypeEnds, parameterNames, parameterNameStarts,
451 		parameterNameEnds, parametersEnd, 0,
452 		-1, exceptionTypes, exceptionTypeStarts,
453 		exceptionTypeEnds, bodyStart,true);
454 }
455 /**
456  * @see IDocumentElementRequestor#enterField(
457 	int declarationStart,
458 	int[] javaDocPositions,
459 	int modifiers,
460 	int modifiersStart,
461 	char[] type,
462 	int typeStart,
463 	int typeEnd,
464  	int typeDimensionCount,
465 	char[] name,
466 	int nameStart,
467 	int nameEnd,
468 	int extendedTypeDimensionCount,
469 	int extendedTypeDimensionEnd)
470  */
471 @Override
enterField(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, char[] type, int typeStart, int typeEnd, int typeDimensionCount, char[] name, int nameStart, int nameEnd, int extendedTypeDimensionCount, int extendedTypeDimensionEnd)472 public void enterField(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
473 	char[] type, int typeStart, int typeEnd, int typeDimensionCount, char[] name,
474 	int nameStart, int nameEnd, int extendedTypeDimensionCount,
475 	int extendedTypeDimensionEnd) {
476 	int[] sourceRange = {declarationStart,
477 		(extendedTypeDimensionEnd > nameEnd) ? extendedTypeDimensionEnd : nameEnd};
478 	int[] nameRange = {nameStart, nameEnd};
479 	int[] commentRange = {-1, -1};
480 	if (javaDocPositions != null) {
481 		int length = javaDocPositions.length;
482 		commentRange[0] = javaDocPositions[length - 2]; // get last javadoc comment (see bug 68772)
483 		commentRange[1] = javaDocPositions[length - 1];
484 	}
485 	int[] modifiersRange = {-1, -1};
486 	if (modifiersStart > -1) {
487 		modifiersRange[0] = modifiersStart;
488 		modifiersRange[1] = typeStart - 1;
489 	}
490 	int[] typeRange = {typeStart, typeEnd};
491 	boolean hasInitializer = false; // fixed on exitField
492 	int[] initializerRange = {-1, -1}; // fixed on exitField
493 	boolean isVariableDeclarator = false;
494 	if (this.fNode instanceof DOMField) {
495 		DOMField field = (DOMField)this.fNode;
496 		if (field.fTypeRange[0] == typeStart)
497 			isVariableDeclarator = true;
498 	}
499 	this.fNode = new DOMField(this.fDocument, sourceRange, CharOperation.charToString(name), nameRange, commentRange,
500 		modifiers, modifiersRange, typeRange, CharOperation.charToString(type), hasInitializer,
501 		initializerRange, isVariableDeclarator);
502 	addChild(this.fNode);
503 	this.fStack.push(this.fNode);
504 }
505 /**
506  * @see IDocumentElementRequestor#enterInterface(
507 	int declarationStart,
508 	int[] javaDocPositions,
509 	int modifiers,
510 	int modifiersStart,
511 	int interfaceStart,
512 	char[] name,
513 	int nameStart,
514 	int nameEnd,
515 	char[][] superinterfaces,
516 	int[] superinterfaceStarts,
517 	int[] superinterfaceEnds,
518 	int bodyStart)
519  */
520 @Override
enterInterface(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, char[] name, int nameStart, int nameEnd, char[][] superinterfaces, int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart)521 public void enterInterface(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart,
522 	char[] name, int nameStart, int nameEnd, char[][] superinterfaces,
523 	int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) {
524 
525 	enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
526 		name, nameStart, nameEnd, null, -1, -1, superinterfaces,
527 		superinterfaceStarts, superinterfaceEnds, bodyStart, false);
528 }
529 /**
530  * @see IDocumentElementRequestor#enterMethod(
531 	int declarationStart,
532 	int[] javaDocPositions,
533 	int modifiers,
534 	int modifiersStart,
535 	char[] returnType,
536 	int returnTypeStart,
537 	int returnTypeEnd,
538  	int returnTypeDimensionCount,
539 	char[] name,
540 	int nameStart,
541 	int nameEnd,
542 	char[][] parameterTypes,
543 	int [] parameterTypeStarts,
544 	int [] parameterTypeEnds,
545 	char[][] parameterNames,
546 	int [] parameterNameStarts,
547 	int [] parameterNameEnds,
548 	int parametersEnd,
549 	int extendedReturnTypeDimensionCount,
550 	int extendedReturnTypeDimensionEnd,
551 	char[][] exceptionTypes,
552 	int [] exceptionTypeStarts,
553 	int [] exceptionTypeEnds,
554 	int bodyStart)
555  */
556 @Override
enterMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds, int bodyStart)557 public void enterMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
558 	char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount,
559 	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
560 	int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts,
561 	int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount,
562 	int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts,
563 	int[] exceptionTypeEnds, int bodyStart) {
564 	enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart,
565 		returnType, returnTypeStart, returnTypeEnd, returnTypeDimensionCount,
566 		name, nameStart, nameEnd, parameterTypes, parameterTypeStarts,
567 		parameterTypeEnds, parameterNames, parameterNameStarts,
568 		parameterNameEnds, parametersEnd, extendedReturnTypeDimensionCount,
569 		extendedReturnTypeDimensionEnd, exceptionTypes, exceptionTypeStarts,
570 		exceptionTypeEnds, bodyStart,false);
571 }
572 
enterType(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart, int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart, boolean isClass)573 protected void enterType(int declarationStart, int[] javaDocPositions,
574 	int modifiers, int modifiersStart, int keywordStart, char[] name,
575 	int nameStart, int nameEnd, char[] superclass, int superclassStart,
576 	int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts,
577 	int[] superinterfaceEnds, int bodyStart, boolean isClass) {
578 	if (this.fBuildingType) {
579 		int[] sourceRange = {declarationStart, -1}; // will be fixed in the exit
580 		int[] commentRange = {-1, -1};
581 		if (javaDocPositions != null) {
582 			int length = javaDocPositions.length;
583 			commentRange[0] = javaDocPositions[length - 2];  // get last javadoc comment (see bug 68772)
584 			commentRange[1] = javaDocPositions[length - 1];
585 		}
586 		int[] modifiersRange = {-1, -1};
587 		if (modifiersStart > -1) {
588 			modifiersRange[0] = modifiersStart;
589 			modifiersRange[1] = (modifiersStart > -1) ? keywordStart - 1 : -1;
590 		}
591 		int[] typeKeywordRange = {keywordStart, nameStart - 1};
592 		int[] nameRange = new int[] {nameStart, nameEnd};
593 		int[] extendsKeywordRange = {-1, -1};
594 		int[] superclassRange = {-1, -1};
595 		int[] implementsKeywordRange = {-1, -1};
596 		int[] interfacesRange = {-1, -1};
597 		if (isClass) {
598 			if (superclass != null) {
599 				extendsKeywordRange[0] = nameEnd + 1;
600 				extendsKeywordRange[1] = superclassStart - 1;
601 				superclassRange[0] = superclassStart;
602 				superclassRange[1] = superclassEnd;
603 			}
604 			if (superinterfaces != null && superinterfaces.length > 0) {
605 				superclassRange[1] = superclassEnd;
606 				if (superclassEnd > -1) {
607 					implementsKeywordRange[0] = superclassEnd + 1;
608 				} else {
609 					implementsKeywordRange[0] = nameEnd + 1;
610 				}
611 				implementsKeywordRange[1] = superinterfaceStarts[0] - 1;
612 				interfacesRange[0] = superinterfaceStarts[0];
613 				interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
614 			}
615 		} else {
616 			if (superinterfaces != null && superinterfaces.length > 0) {
617 				extendsKeywordRange[0] = nameEnd + 1;
618 				extendsKeywordRange[1] = superinterfaceStarts[0] - 1;
619 				interfacesRange[0] = superinterfaceStarts[0];
620 				interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
621 			}
622 		}
623 		int[] openBodyRange = {bodyStart, -1}; // fixed by setTypeRanges(DOMNode)
624 		int[] closeBodyRange = {-1, -1}; // will be fixed in exit
625 		this.fNode = new DOMType(this.fDocument, sourceRange, new String(name), nameRange, commentRange,
626 			modifiers, modifiersRange, typeKeywordRange, superclassRange, extendsKeywordRange,
627 			CharOperation.charArrayToStringArray(superinterfaces), interfacesRange,
628 			implementsKeywordRange, openBodyRange,
629 			closeBodyRange, isClass);
630 		addChild(this.fNode);
631 		this.fStack.push(this.fNode);
632 	}
633 }
634 /**
635  * Finishes the configuration of the constructors and methods.
636  *
637  * @param bodyEnd - a source position corresponding to the closing bracket of the method
638  * @param declarationEnd - a source position corresponding to the end of the method
639  *		declaration.  This can include whitespace and comments following the closing bracket.
640  */
exitAbstractMethod(int bodyEnd, int declarationEnd)641 protected void exitAbstractMethod(int bodyEnd, int declarationEnd) {
642 	DOMMethod method = (DOMMethod) this.fStack.pop();
643 	method.setSourceRangeEnd(declarationEnd);
644 	method.setBodyRangeEnd(bodyEnd + 1);
645 	this.fNode = method;
646 	if (this.fBuildingSingleMember) {
647 		this.fFinishedSingleMember= true;
648 	}
649 }
650 /**
651  * Finishes the configuration of the class DOM object which
652  * was created by a previous enterClass call.
653  *
654  * @see IDocumentElementRequestor#exitClass(int, int)
655  */
656 @Override
exitClass(int bodyEnd, int declarationEnd)657 public void exitClass(int bodyEnd, int declarationEnd) {
658 	exitType(bodyEnd, declarationEnd);
659 }
660 /**
661  * Finishes the configuration of the method DOM object which
662  * was created by a previous enterConstructor call.
663  *
664  * @see IDocumentElementRequestor#exitConstructor(int, int)
665  */
666 @Override
exitConstructor(int bodyEnd, int declarationEnd)667 public void exitConstructor(int bodyEnd, int declarationEnd) {
668 	exitAbstractMethod(bodyEnd, declarationEnd);
669 }
670 /**
671  * Finishes the configuration of the field DOM object which
672  * was created by a previous enterField call.
673  *
674  * @see IDocumentElementRequestor#exitField(int, int)
675  */
676 @Override
exitField(int bodyEnd, int declarationEnd)677 public void exitField(int bodyEnd, int declarationEnd) {
678 	DOMField field = (DOMField)this.fStack.pop();
679 	if (field.getEndPosition() < declarationEnd) {
680 		field.setSourceRangeEnd(declarationEnd);
681 		int nameEnd = field.fNameRange[1];
682 		if (nameEnd < bodyEnd) {
683 			/* see 1FVIIV8 - obtain initializer range */
684 			String initializer = new String(this.fDocument, nameEnd + 1, bodyEnd - nameEnd);
685 			int index = initializer.indexOf('=');
686 			if (index > -1) {
687 				field.setHasInitializer(true);
688 				field.setInitializerRange(nameEnd + index + 2, bodyEnd);
689 			}
690 		}
691 	}
692 	this.fFieldCount++;
693 	this.fNode = field;
694 	if (this.fBuildingSingleMember) {
695 		this.fFinishedSingleMember= true;
696 	}
697 }
698 /**
699  * Finishes the configuration of the interface DOM object which
700  * was created by a previous enterInterface call.
701  *
702  * @see IDocumentElementRequestor#exitInterface(int, int)
703  */
704 @Override
exitInterface(int bodyEnd, int declarationEnd)705 public void exitInterface(int bodyEnd, int declarationEnd) {
706 	exitType(bodyEnd, declarationEnd);
707 }
708 /**
709  * Finishes the configuration of the method DOM object which
710  * was created by a previous enterMethod call.
711  *
712  * @see IDocumentElementRequestor#exitMethod(int, int)
713  */
714 @Override
exitMethod(int bodyEnd, int declarationEnd)715 public void exitMethod(int bodyEnd, int declarationEnd) {
716 	exitAbstractMethod(bodyEnd, declarationEnd);
717 }
718 /**
719  * Creates a new parser.
720  */
getParser(Map settings)721 protected DocumentElementParser getParser(Map settings) {
722 	return new DocumentElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings));
723 }
724 /**
725  * Initializes the builder to create a document fragment.
726  *
727  * @param sourceCode - the document containing the source code to be analyzed
728  * @param buildingCompilationUnit - true if a the document is being analyzed to
729  *		create a compilation unit, otherwise false
730  * @param buildingType - true if the document is being analyzed to create a
731  *		type or compilation unit
732  * @param singleMember - true if building a single member
733  */
initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType, boolean singleMember)734 protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType, boolean singleMember) {
735 	super.initializeBuild(sourceCode, buildingCompilationUnit, buildingType);
736 	this.fBuildingSingleMember= singleMember;
737 	this.fFinishedSingleMember= false;
738 
739 }
740 }
741