KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > ASTConverter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.core.dom;
13
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.OperationCanceledException;
22 import org.eclipse.jdt.core.JavaCore;
23 import org.eclipse.jdt.core.compiler.CategorizedProblem;
24 import org.eclipse.jdt.core.compiler.CharOperation;
25 import org.eclipse.jdt.core.compiler.IProblem;
26 import org.eclipse.jdt.core.compiler.InvalidInputException;
27 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
28 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
29 import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
30 import org.eclipse.jdt.internal.compiler.ast.Argument;
31 import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
32 import org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression;
33 import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
34 import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
35 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
36 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
37 import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
38 import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
39 import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
40 import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
41 import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
42 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
43 import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
44 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
45 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
46 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
47 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
48 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
49 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
50 import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
51 import org.eclipse.jdt.internal.compiler.parser.Scanner;
52 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
53
54 /**
55  * Internal class for converting internal compiler ASTs into public ASTs.
56  */

57 class ASTConverter {
58
59     protected AST ast;
60     protected Comment[] commentsTable;
61     char[] compilationUnitSource;
62     int compilationUnitSourceLength;
63     protected DocCommentParser docParser;
64     // comments
65
protected boolean insideComments;
66     protected IProgressMonitor monitor;
67     protected Set JavaDoc pendingNameScopeResolution;
68     protected Set JavaDoc pendingThisExpressionScopeResolution;
69     protected boolean resolveBindings;
70     Scanner scanner;
71     private DefaultCommentMapper commentMapper;
72
73     public ASTConverter(Map JavaDoc options, boolean resolveBindings, IProgressMonitor monitor) {
74         this.resolveBindings = resolveBindings;
75         Object JavaDoc sourceModeSetting = options.get(JavaCore.COMPILER_SOURCE);
76         long sourceLevel = ClassFileConstants.JDK1_3;
77         if (JavaCore.VERSION_1_4.equals(sourceModeSetting)) {
78             sourceLevel = ClassFileConstants.JDK1_4;
79         } else if (JavaCore.VERSION_1_5.equals(sourceModeSetting)) {
80             sourceLevel = ClassFileConstants.JDK1_5;
81         }
82
83         this.scanner = new Scanner(
84             true /*comment*/,
85             false /*whitespace*/,
86             false /*nls*/,
87             sourceLevel /*sourceLevel*/,
88             null /*taskTags*/,
89             null/*taskPriorities*/,
90             true/*taskCaseSensitive*/);
91         this.monitor = monitor;
92         this.insideComments = JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_DOC_COMMENT_SUPPORT));
93     }
94     
95     protected void adjustSourcePositionsForParent(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
96         int start = expression.sourceStart;
97         int end = expression.sourceEnd;
98         int leftParentCount = 1;
99         int rightParentCount = 0;
100         this.scanner.resetTo(start, end);
101         try {
102             int token = this.scanner.getNextToken();
103             expression.sourceStart = this.scanner.currentPosition;
104             boolean stop = false;
105             while (!stop && ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) {
106                 switch(token) {
107                     case TerminalTokens.TokenNameLPAREN:
108                         leftParentCount++;
109                         break;
110                     case TerminalTokens.TokenNameRPAREN:
111                         rightParentCount++;
112                         if (rightParentCount == leftParentCount) {
113                             // we found the matching parenthesis
114
stop = true;
115                         }
116                 }
117             }
118             expression.sourceEnd = this.scanner.startPosition - 1;
119         } catch(InvalidInputException e) {
120             // ignore
121
}
122     }
123
124     protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration, AbstractTypeDeclaration typeDecl) {
125         // add body declaration in the lexical order
126
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = typeDeclaration.memberTypes;
127         org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = typeDeclaration.fields;
128         org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = typeDeclaration.methods;
129         
130         int fieldsLength = fields == null? 0 : fields.length;
131         int methodsLength = methods == null? 0 : methods.length;
132         int membersLength = members == null ? 0 : members.length;
133         int fieldsIndex = 0;
134         int methodsIndex = 0;
135         int membersIndex = 0;
136         
137         while ((fieldsIndex < fieldsLength)
138             || (membersIndex < membersLength)
139             || (methodsIndex < methodsLength)) {
140             org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
141             org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
142             org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
143         
144             int position = Integer.MAX_VALUE;
145             int nextDeclarationType = -1;
146             if (fieldsIndex < fieldsLength) {
147                 nextFieldDeclaration = fields[fieldsIndex];
148                 if (nextFieldDeclaration.declarationSourceStart < position) {
149                     position = nextFieldDeclaration.declarationSourceStart;
150                     nextDeclarationType = 0; // FIELD
151
}
152             }
153             if (methodsIndex < methodsLength) {
154                 nextMethodDeclaration = methods[methodsIndex];
155                 if (nextMethodDeclaration.declarationSourceStart < position) {
156                     position = nextMethodDeclaration.declarationSourceStart;
157                     nextDeclarationType = 1; // METHOD
158
}
159             }
160             if (membersIndex < membersLength) {
161                 nextMemberDeclaration = members[membersIndex];
162                 if (nextMemberDeclaration.declarationSourceStart < position) {
163                     position = nextMemberDeclaration.declarationSourceStart;
164                     nextDeclarationType = 2; // MEMBER
165
}
166             }
167             switch (nextDeclarationType) {
168                 case 0 :
169                     if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
170                         typeDecl.bodyDeclarations().add(convert(nextFieldDeclaration));
171                     } else {
172                         checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, typeDecl.bodyDeclarations());
173                     }
174                     fieldsIndex++;
175                     break;
176                 case 1 :
177                     methodsIndex++;
178                     if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
179                         typeDecl.bodyDeclarations().add(convert(nextMethodDeclaration));
180                     }
181                     break;
182                 case 2 :
183                     membersIndex++;
184                     ASTNode node = convert(nextMemberDeclaration);
185                     if (node == null) {
186                         typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
187                     } else {
188                         typeDecl.bodyDeclarations().add(node);
189                     }
190             }
191         }
192         // Convert javadoc
193
convert(typeDeclaration.javadoc, typeDecl);
194     }
195     
196     protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enumDeclaration2, EnumDeclaration enumDeclaration) {
197         // add body declaration in the lexical order
198
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = enumDeclaration2.memberTypes;
199         org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = enumDeclaration2.fields;
200         org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = enumDeclaration2.methods;
201         
202         int fieldsLength = fields == null? 0 : fields.length;
203         int methodsLength = methods == null? 0 : methods.length;
204         int membersLength = members == null ? 0 : members.length;
205         int fieldsIndex = 0;
206         int methodsIndex = 0;
207         int membersIndex = 0;
208         
209         while ((fieldsIndex < fieldsLength)
210             || (membersIndex < membersLength)
211             || (methodsIndex < methodsLength)) {
212             org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
213             org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
214             org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
215         
216             int position = Integer.MAX_VALUE;
217             int nextDeclarationType = -1;
218             if (fieldsIndex < fieldsLength) {
219                 nextFieldDeclaration = fields[fieldsIndex];
220                 if (nextFieldDeclaration.declarationSourceStart < position) {
221                     position = nextFieldDeclaration.declarationSourceStart;
222                     nextDeclarationType = 0; // FIELD
223
}
224             }
225             if (methodsIndex < methodsLength) {
226                 nextMethodDeclaration = methods[methodsIndex];
227                 if (nextMethodDeclaration.declarationSourceStart < position) {
228                     position = nextMethodDeclaration.declarationSourceStart;
229                     nextDeclarationType = 1; // METHOD
230
}
231             }
232             if (membersIndex < membersLength) {
233                 nextMemberDeclaration = members[membersIndex];
234                 if (nextMemberDeclaration.declarationSourceStart < position) {
235                     position = nextMemberDeclaration.declarationSourceStart;
236                     nextDeclarationType = 2; // MEMBER
237
}
238             }
239             switch (nextDeclarationType) {
240                 case 0 :
241                     if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
242                         enumDeclaration.enumConstants().add(convert(nextFieldDeclaration));
243                     } else {
244                         checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, enumDeclaration.bodyDeclarations());
245                     }
246                     fieldsIndex++;
247                     break;
248                 case 1 :
249                     methodsIndex++;
250                     if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
251                         enumDeclaration.bodyDeclarations().add(convert(nextMethodDeclaration));
252                     }
253                     break;
254                 case 2 :
255                     membersIndex++;
256                     enumDeclaration.bodyDeclarations().add(convert(nextMemberDeclaration));
257                     break;
258             }
259         }
260         convert(enumDeclaration2.javadoc, enumDeclaration);
261     }
262     
263     protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration expression, AnonymousClassDeclaration anonymousClassDeclaration) {
264         // add body declaration in the lexical order
265
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = expression.memberTypes;
266         org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = expression.fields;
267         org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = expression.methods;
268         
269         int fieldsLength = fields == null? 0 : fields.length;
270         int methodsLength = methods == null? 0 : methods.length;
271         int membersLength = members == null ? 0 : members.length;
272         int fieldsIndex = 0;
273         int methodsIndex = 0;
274         int membersIndex = 0;
275         
276         while ((fieldsIndex < fieldsLength)
277             || (membersIndex < membersLength)
278             || (methodsIndex < methodsLength)) {
279             org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
280             org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
281             org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
282         
283             int position = Integer.MAX_VALUE;
284             int nextDeclarationType = -1;
285             if (fieldsIndex < fieldsLength) {
286                 nextFieldDeclaration = fields[fieldsIndex];
287                 if (nextFieldDeclaration.declarationSourceStart < position) {
288                     position = nextFieldDeclaration.declarationSourceStart;
289                     nextDeclarationType = 0; // FIELD
290
}
291             }
292             if (methodsIndex < methodsLength) {
293                 nextMethodDeclaration = methods[methodsIndex];
294                 if (nextMethodDeclaration.declarationSourceStart < position) {
295                     position = nextMethodDeclaration.declarationSourceStart;
296                     nextDeclarationType = 1; // METHOD
297
}
298             }
299             if (membersIndex < membersLength) {
300                 nextMemberDeclaration = members[membersIndex];
301                 if (nextMemberDeclaration.declarationSourceStart < position) {
302                     position = nextMemberDeclaration.declarationSourceStart;
303                     nextDeclarationType = 2; // MEMBER
304
}
305             }
306             switch (nextDeclarationType) {
307                 case 0 :
308                     if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
309                         anonymousClassDeclaration.bodyDeclarations().add(convert(nextFieldDeclaration));
310                     } else {
311                         checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, anonymousClassDeclaration.bodyDeclarations());
312                     }
313                     fieldsIndex++;
314                     break;
315                 case 1 :
316                     methodsIndex++;
317                     if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
318                         anonymousClassDeclaration.bodyDeclarations().add(convert(nextMethodDeclaration));
319                     }
320                     break;
321                 case 2 :
322                     membersIndex++;
323                     ASTNode node = convert(nextMemberDeclaration);
324                     if (node == null) {
325                         anonymousClassDeclaration.setFlags(anonymousClassDeclaration.getFlags() | ASTNode.MALFORMED);
326                     } else {
327                         anonymousClassDeclaration.bodyDeclarations().add(node);
328                     }
329             }
330         }
331     }
332     
333     /**
334      * @param compilationUnit
335      * @param comments
336      */

337     void buildCommentsTable(CompilationUnit compilationUnit, int[][] comments) {
338         // Build comment table
339
this.commentsTable = new Comment[comments.length];
340         int nbr = 0;
341         for (int i = 0; i < comments.length; i++) {
342             Comment comment = createComment(comments[i]);
343             if (comment != null) {
344                 comment.setAlternateRoot(compilationUnit);
345                 this.commentsTable[nbr++] = comment;
346             }
347         }
348         // Resize table if necessary
349
if (nbr<comments.length) {
350             Comment[] newCommentsTable = new Comment[nbr];
351             System.arraycopy(this.commentsTable, 0, newCommentsTable, 0, nbr);
352             this.commentsTable = newCommentsTable;
353         }
354         compilationUnit.setCommentTable(this.commentsTable);
355     }
356     
357     protected void checkAndAddMultipleFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields, int index, List JavaDoc bodyDeclarations) {
358         if (fields[index] instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
359             org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) fields[index];
360             Initializer initializer = new Initializer(this.ast);
361             initializer.setBody(convert(oldInitializer.block));
362             setModifiers(initializer, oldInitializer);
363             initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
364             // The javadoc comment is now got from list store in compilation unit declaration
365
convert(oldInitializer.javadoc, initializer);
366             bodyDeclarations.add(initializer);
367             return;
368         }
369         if (index > 0 && fields[index - 1].declarationSourceStart == fields[index].declarationSourceStart) {
370             // we have a multiple field declaration
371
// We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
372
FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclarations.get(bodyDeclarations.size() - 1);
373             fieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fields[index]));
374         } else {
375             // we can create a new FieldDeclaration
376
bodyDeclarations.add(convertToFieldDeclaration(fields[index]));
377         }
378     }
379
380     protected void checkAndAddMultipleLocalDeclaration(org.eclipse.jdt.internal.compiler.ast.Statement[] stmts, int index, List JavaDoc blockStatements) {
381         if (index > 0
382             && stmts[index - 1] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
383                 org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local1 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index - 1];
384                 org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local2 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index];
385                if (local1.declarationSourceStart == local2.declarationSourceStart) {
386                     // we have a multiple local declarations
387
// We retrieve the existing VariableDeclarationStatement to add the new VariableDeclarationFragment
388
VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) blockStatements.get(blockStatements.size() - 1);
389                     variableDeclarationStatement.fragments().add(convertToVariableDeclarationFragment((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
390                } else {
391                     // we can create a new FieldDeclaration
392
blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
393                }
394         } else {
395             // we can create a new FieldDeclaration
396
blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
397         }
398     }
399
400     protected void checkCanceled() {
401         if (this.monitor != null && this.monitor.isCanceled())
402             throw new OperationCanceledException();
403     }
404
405     protected void completeRecord(ArrayType arrayType, org.eclipse.jdt.internal.compiler.ast.ASTNode astNode) {
406         ArrayType array = arrayType;
407         int dimensions = array.getDimensions();
408         for (int i = 0; i < dimensions; i++) {
409             Type componentType = array.getComponentType();
410             this.recordNodes(componentType, astNode);
411             if (componentType.isArrayType()) {
412                 array = (ArrayType) componentType;
413             }
414         }
415     }
416         
417     public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) {
418         checkCanceled();
419         if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) {
420             return convert((org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) methodDeclaration);
421         }
422         MethodDeclaration methodDecl = new MethodDeclaration(this.ast);
423         setModifiers(methodDecl, methodDeclaration);
424         boolean isConstructor = methodDeclaration.isConstructor();
425         methodDecl.setConstructor(isConstructor);
426         final SimpleName methodName = new SimpleName(this.ast);
427         methodName.internalSetIdentifier(new String JavaDoc(methodDeclaration.selector));
428         int start = methodDeclaration.sourceStart;
429         int end = retrieveIdentifierEndPosition(start, methodDeclaration.sourceEnd);
430         methodName.setSourceRange(start, end - start + 1);
431         methodDecl.setName(methodName);
432         org.eclipse.jdt.internal.compiler.ast.TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
433         if (thrownExceptions != null) {
434             int thrownExceptionsLength = thrownExceptions.length;
435             for (int i = 0; i < thrownExceptionsLength; i++) {
436                 methodDecl.thrownExceptions().add(convert(thrownExceptions[i]));
437             }
438         }
439         org.eclipse.jdt.internal.compiler.ast.Argument[] parameters = methodDeclaration.arguments;
440         if (parameters != null) {
441             int parametersLength = parameters.length;
442             for (int i = 0; i < parametersLength; i++) {
443                 methodDecl.parameters().add(convert(parameters[i]));
444             }
445         }
446         org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall explicitConstructorCall = null;
447         if (isConstructor) {
448             org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration constructorDeclaration = (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) methodDeclaration;
449             explicitConstructorCall = constructorDeclaration.constructorCall;
450             switch(this.ast.apiLevel) {
451                 case AST.JLS2_INTERNAL :
452                     // set the return type to VOID
453
PrimitiveType returnType = new PrimitiveType(this.ast);
454                     returnType.setPrimitiveTypeCode(PrimitiveType.VOID);
455                     returnType.setSourceRange(methodDeclaration.sourceStart, 0);
456                     methodDecl.internalSetReturnType(returnType);
457                     break;
458                 case AST.JLS3 :
459                     methodDecl.setReturnType2(null);
460             }
461         } else if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) {
462             org.eclipse.jdt.internal.compiler.ast.MethodDeclaration method = (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) methodDeclaration;
463             org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = method.returnType;
464             if (typeReference != null) {
465                 Type returnType = convertType(typeReference);
466                 // get the positions of the right parenthesis
467
int rightParenthesisPosition = retrieveEndOfRightParenthesisPosition(end, method.bodyEnd);
468                 int extraDimensions = retrieveExtraDimension(rightParenthesisPosition, method.bodyEnd);
469                 methodDecl.setExtraDimensions(extraDimensions);
470                 setTypeForMethodDeclaration(methodDecl, returnType, extraDimensions);
471             } else {
472                 switch(this.ast.apiLevel) {
473                     case AST.JLS2_INTERNAL :
474                         methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
475                         break;
476                     case AST.JLS3 :
477                         methodDecl.setReturnType2(null);
478                 }
479             }
480         }
481         int declarationSourceStart = methodDeclaration.declarationSourceStart;
482         int declarationSourceEnd = methodDeclaration.bodyEnd;
483         methodDecl.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
484         int closingPosition = retrieveRightBraceOrSemiColonPosition(methodDeclaration.bodyEnd + 1, methodDeclaration.declarationSourceEnd);
485         if (closingPosition != -1) {
486             int startPosition = methodDecl.getStartPosition();
487             methodDecl.setSourceRange(startPosition, closingPosition - startPosition + 1);
488
489             org.eclipse.jdt.internal.compiler.ast.Statement[] statements = methodDeclaration.statements;
490             
491             start = retrieveStartBlockPosition(methodDeclaration.sourceStart, declarationSourceEnd);
492             end = retrieveEndBlockPosition(methodDeclaration.sourceStart, methodDeclaration.declarationSourceEnd);
493             Block block = null;
494             if (start != -1 && end != -1) {
495                 /*
496                  * start or end can be equal to -1 if we have an interface's method.
497                  */

498                 block = new Block(this.ast);
499                 block.setSourceRange(start, end - start + 1);
500                 methodDecl.setBody(block);
501             }
502             if (block != null && (statements != null || explicitConstructorCall != null)) {
503                 if (explicitConstructorCall != null && explicitConstructorCall.accessMode != org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall.ImplicitSuper) {
504                     block.statements().add(convert(explicitConstructorCall));
505                 }
506                 int statementsLength = statements == null ? 0 : statements.length;
507                 for (int i = 0; i < statementsLength; i++) {
508                     if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
509                         checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
510                     } else {
511                         final Statement statement = convert(statements[i]);
512                         if (statement != null) {
513                             block.statements().add(statement);
514                         }
515                     }
516                 }
517             }
518             if (block != null && (Modifier.isAbstract(methodDecl.getModifiers()) || Modifier.isNative(methodDecl.getModifiers()))) {
519                 methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
520             }
521         } else {
522             // syntax error in this method declaration
523
if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract()) {
524                 start = retrieveStartBlockPosition(methodDeclaration.sourceStart, declarationSourceEnd);
525                 end = methodDeclaration.bodyEnd;
526                 // try to get the best end position
527
CategorizedProblem[] problems = methodDeclaration.compilationResult().problems;
528                 if (problems != null) {
529                     for (int i = 0, max = methodDeclaration.compilationResult().problemCount; i < max; i++) {
530                         CategorizedProblem currentProblem = problems[i];
531                         if (currentProblem.getSourceStart() == start && currentProblem.getID() == IProblem.ParsingErrorInsertToComplete) {
532                             end = currentProblem.getSourceEnd();
533                             break;
534                         }
535                     }
536                 }
537                 int startPosition = methodDecl.getStartPosition();
538                 methodDecl.setSourceRange(startPosition, end - startPosition + 1);
539                 if (start != -1 && end != -1) {
540                     /*
541                      * start or end can be equal to -1 if we have an interface's method.
542                      */

543                     Block block = new Block(this.ast);
544                     block.setSourceRange(start, end - start + 1);
545                     methodDecl.setBody(block);
546                 }
547             }
548         }
549
550         org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = methodDeclaration.typeParameters();
551         if (typeParameters != null) {
552             switch(this.ast.apiLevel) {
553                 case AST.JLS2_INTERNAL :
554                     methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
555                     break;
556                 case AST.JLS3 :
557                     for (int i = 0, max = typeParameters.length; i < max; i++) {
558                         methodDecl.typeParameters().add(convert(typeParameters[i]));
559                     }
560             }
561         }
562         
563         // The javadoc comment is now got from list store in compilation unit declaration
564
convert(methodDeclaration.javadoc, methodDecl);
565         if (this.resolveBindings) {
566             recordNodes(methodDecl, methodDeclaration);
567             recordNodes(methodName, methodDeclaration);
568             methodDecl.resolveBinding();
569         }
570         return methodDecl;
571     }
572     
573     public ClassInstanceCreation convert(org.eclipse.jdt.internal.compiler.ast.AllocationExpression expression) {
574         ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
575         if (this.resolveBindings) {
576             recordNodes(classInstanceCreation, expression);
577         }
578         if (expression.typeArguments != null) {
579             switch(this.ast.apiLevel) {
580                 case AST.JLS2_INTERNAL :
581                     classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
582                     break;
583                 case AST.JLS3 :
584                     for (int i = 0, max = expression.typeArguments.length; i < max; i++) {
585                         classInstanceCreation.typeArguments().add(convertType(expression.typeArguments[i]));
586                     }
587             }
588         }
589         switch(this.ast.apiLevel) {
590             case AST.JLS2_INTERNAL :
591                 classInstanceCreation.internalSetName(convert(expression.type));
592                 break;
593             case AST.JLS3 :
594                 classInstanceCreation.setType(convertType(expression.type));
595         }
596         classInstanceCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
597         org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
598         if (arguments != null) {
599             int length = arguments.length;
600             for (int i = 0; i < length; i++) {
601                 classInstanceCreation.arguments().add(convert(arguments[i]));
602             }
603         }
604         removeTrailingCommentFromExpressionEndingWithAParen(classInstanceCreation);
605         return classInstanceCreation;
606     }
607
608     public Expression convert(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression expression) {
609         InfixExpression infixExpression = new InfixExpression(this.ast);
610         infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
611         if (this.resolveBindings) {
612             this.recordNodes(infixExpression, expression);
613         }
614         final int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
615         if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
616                 && ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
617             // create an extended string literal equivalent => use the extended operands list
618
infixExpression.extendedOperands().add(convert(expression.right));
619             org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
620             org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
621             do {
622                 rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
623                 if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
624                             && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
625                      || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
626                             && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
627                             && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
628                     List JavaDoc extendedOperands = infixExpression.extendedOperands();
629                     InfixExpression temp = new InfixExpression(this.ast);
630                     if (this.resolveBindings) {
631                         this.recordNodes(temp, expression);
632                     }
633                     temp.setOperator(getOperatorFor(expressionOperatorID));
634                     Expression leftSide = convert(leftOperand);
635                     temp.setLeftOperand(leftSide);
636                     temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
637                     int size = extendedOperands.size();
638                     for (int i = 0; i < size - 1; i++) {
639                         Expression expr = temp;
640                         temp = new InfixExpression(this.ast);
641                         
642                         if (this.resolveBindings) {
643                             this.recordNodes(temp, expression);
644                         }
645                         temp.setLeftOperand(expr);
646                         temp.setOperator(getOperatorFor(expressionOperatorID));
647                         temp.setSourceRange(expr.getStartPosition(), expr.getLength());
648                     }
649                     infixExpression = temp;
650                     for (int i = 0; i < size; i++) {
651                         Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
652                         temp.setRightOperand(extendedOperand);
653                         int startPosition = temp.getLeftOperand().getStartPosition();
654                         temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
655                         if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
656                             temp = (InfixExpression) temp.getLeftOperand();
657                         }
658                     }
659                     int startPosition = infixExpression.getLeftOperand().getStartPosition();
660                     infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
661                     if (this.resolveBindings) {
662                         this.recordNodes(infixExpression, expression);
663                     }
664                     return infixExpression;
665                 }
666                 infixExpression.extendedOperands().add(0, convert(rightOperand));
667                 leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
668             } while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
669             Expression leftExpression = convert(leftOperand);
670             infixExpression.setLeftOperand(leftExpression);
671             infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
672             int startPosition = leftExpression.getStartPosition();
673             infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
674             return infixExpression;
675         }
676         Expression leftExpression = convert(expression.left);
677         infixExpression.setLeftOperand(leftExpression);
678         infixExpression.setRightOperand(convert(expression.right));
679         infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
680         int startPosition = leftExpression.getStartPosition();
681         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
682         return infixExpression;
683     }
684
685     public AnnotationTypeDeclaration convertToAnnotationDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
686         checkCanceled();
687         AnnotationTypeDeclaration typeDecl = this.ast.newAnnotationTypeDeclaration();
688         setModifiers(typeDecl, typeDeclaration);
689         final SimpleName typeName = new SimpleName(this.ast);
690         typeName.internalSetIdentifier(new String JavaDoc(typeDeclaration.name));
691         typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
692         typeDecl.setName(typeName);
693         typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
694         
695         buildBodyDeclarations(typeDeclaration, typeDecl);
696         // The javadoc comment is now got from list store in compilation unit declaration
697
if (this.resolveBindings) {
698             recordNodes(typeDecl, typeDeclaration);
699             recordNodes(typeName, typeDeclaration);
700             typeDecl.resolveBinding();
701         }
702         return typeDecl;
703     }
704     
705     public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
706         checkCanceled();
707         if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
708             return null;
709         }
710         AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration2 = new AnnotationTypeMemberDeclaration(this.ast);
711         setModifiers(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
712         final SimpleName methodName = new SimpleName(this.ast);
713         methodName.internalSetIdentifier(new String JavaDoc(annotationTypeMemberDeclaration.selector));
714         int start = annotationTypeMemberDeclaration.sourceStart;
715         int end = retrieveIdentifierEndPosition(start, annotationTypeMemberDeclaration.sourceEnd);
716         methodName.setSourceRange(start, end - start + 1);
717         annotationTypeMemberDeclaration2.setName(methodName);
718         org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = annotationTypeMemberDeclaration.returnType;
719         if (typeReference != null) {
720             Type returnType = convertType(typeReference);
721             setTypeForMethodDeclaration(annotationTypeMemberDeclaration2, returnType, 0);
722         }
723         int declarationSourceStart = annotationTypeMemberDeclaration.declarationSourceStart;
724         int declarationSourceEnd = annotationTypeMemberDeclaration.bodyEnd;
725         annotationTypeMemberDeclaration2.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
726         // The javadoc comment is now got from list store in compilation unit declaration
727
convert(annotationTypeMemberDeclaration.javadoc, annotationTypeMemberDeclaration2);
728         org.eclipse.jdt.internal.compiler.ast.Expression memberValue = annotationTypeMemberDeclaration.defaultValue;
729         if (memberValue != null) {
730             annotationTypeMemberDeclaration2.setDefault(convert(memberValue));
731         }
732         if (this.resolveBindings) {
733             recordNodes(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
734             recordNodes(methodName, annotationTypeMemberDeclaration);
735             annotationTypeMemberDeclaration2.resolveBinding();
736         }
737         return annotationTypeMemberDeclaration2;
738     }
739     
740     public SingleVariableDeclaration convert(org.eclipse.jdt.internal.compiler.ast.Argument argument) {
741         SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
742         setModifiers(variableDecl, argument);
743         final SimpleName name = new SimpleName(this.ast);
744         name.internalSetIdentifier(new String JavaDoc(argument.name));
745         int start = argument.sourceStart;
746         int nameEnd = argument.sourceEnd;
747         name.setSourceRange(start, nameEnd - start + 1);
748         variableDecl.setName(name);
749         final int typeSourceEnd = argument.type.sourceEnd;
750         final int extraDimensions = retrieveExtraDimension(nameEnd + 1, typeSourceEnd);
751         variableDecl.setExtraDimensions(extraDimensions);
752         final boolean isVarArgs = argument.isVarArgs();
753         if (isVarArgs && extraDimensions == 0) {
754             // remove the ellipsis from the type source end
755
argument.type.sourceEnd = retrieveEllipsisStartPosition(argument.type.sourceStart, typeSourceEnd);
756         }
757         Type type = convertType(argument.type);
758         int typeEnd = type.getStartPosition() + type.getLength() - 1;
759         int rightEnd = Math.max(typeEnd, argument.declarationSourceEnd);
760         /*
761          * There is extra work to do to set the proper type positions
762          * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
763          */

764         if (isVarArgs) {
765             setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions + 1);
766             if (extraDimensions != 0) {
767                 variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
768             }
769         } else {
770             setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
771         }
772         variableDecl.setSourceRange(argument.declarationSourceStart, rightEnd - argument.declarationSourceStart + 1);
773         
774         if (isVarArgs) {
775             switch(this.ast.apiLevel) {
776                 case AST.JLS2_INTERNAL :
777                     variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
778                     break;
779                 case AST.JLS3 :
780                     variableDecl.setVarargs(true);
781             }
782         }
783         if (this.resolveBindings) {
784             recordNodes(name, argument);
785             recordNodes(variableDecl, argument);
786             variableDecl.resolveBinding();
787         }
788         return variableDecl;
789     }
790
791     
792     public Annotation convert(org.eclipse.jdt.internal.compiler.ast.Annotation annotation) {
793         if (annotation instanceof org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) {
794             return convert((org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) annotation);
795         } else if (annotation instanceof org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) {
796             return convert((org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) annotation);
797         } else {
798             return convert((org.eclipse.jdt.internal.compiler.ast.NormalAnnotation) annotation);
799         }
800     }
801
802     public ArrayCreation convert(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression expression) {
803         ArrayCreation arrayCreation = new ArrayCreation(this.ast);
804         if (this.resolveBindings) {
805             recordNodes(arrayCreation, expression);
806         }
807         arrayCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
808         org.eclipse.jdt.internal.compiler.ast.Expression[] dimensions = expression.dimensions;
809         
810         int dimensionsLength = dimensions.length;
811         for (int i = 0; i < dimensionsLength; i++) {
812             if (dimensions[i] != null) {
813                 Expression dimension = convert(dimensions[i]);
814                 if (this.resolveBindings) {
815                     recordNodes(dimension, dimensions[i]);
816                 }
817                 arrayCreation.dimensions().add(dimension);
818             }
819         }
820         Type type = convertType(expression.type);
821         if (this.resolveBindings) {
822             recordNodes(type, expression.type);
823         }
824         ArrayType arrayType = null;
825         if (type.isArrayType()) {
826             arrayType = (ArrayType) type;
827         } else {
828             arrayType = this.ast.newArrayType(type, dimensionsLength);
829             if (this.resolveBindings) {
830                 completeRecord(arrayType, expression);
831             }
832             int start = type.getStartPosition();
833             int end = type.getStartPosition() + type.getLength();
834             int previousSearchStart = end;
835             ArrayType componentType = (ArrayType) type.getParent();
836             for (int i = 0; i < dimensionsLength; i++) {
837                 previousSearchStart = retrieveRightBracketPosition(previousSearchStart + 1, this.compilationUnitSourceLength);
838                 componentType.setSourceRange(start, previousSearchStart - start + 1);
839                 componentType = (ArrayType) componentType.getParent();
840             }
841         }
842         arrayCreation.setType(arrayType);
843         if (this.resolveBindings) {
844             recordNodes(arrayType, expression);
845         }
846         if (expression.initializer != null) {
847             arrayCreation.setInitializer(convert(expression.initializer));
848         }
849         return arrayCreation;
850     }
851
852     public ArrayInitializer convert(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer expression) {
853         ArrayInitializer arrayInitializer = new ArrayInitializer(this.ast);
854         if (this.resolveBindings) {
855             recordNodes(arrayInitializer, expression);
856         }
857         arrayInitializer.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
858         org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = expression.expressions;
859         if (expressions != null) {
860             int length = expressions.length;
861             for (int i = 0; i < length; i++) {
862                 Expression expr = convert(expressions[i]);
863                 if (this.resolveBindings) {
864                     recordNodes(expr, expressions[i]);
865                 }
866                 arrayInitializer.expressions().add(expr);
867             }
868         }
869         return arrayInitializer;
870     }
871
872     public ArrayAccess convert(org.eclipse.jdt.internal.compiler.ast.ArrayReference reference) {
873         ArrayAccess arrayAccess = new ArrayAccess(this.ast);
874         if (this.resolveBindings) {
875             recordNodes(arrayAccess, reference);
876         }
877         arrayAccess.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
878         arrayAccess.setArray(convert(reference.receiver));
879         arrayAccess.setIndex(convert(reference.position));
880         return arrayAccess;
881     }
882
883     public AssertStatement convert(org.eclipse.jdt.internal.compiler.ast.AssertStatement statement) {
884         AssertStatement assertStatement = new AssertStatement(this.ast);
885         final Expression assertExpression = convert(statement.assertExpression);
886         Expression searchingNode = assertExpression;
887         assertStatement.setExpression(assertExpression);
888         org.eclipse.jdt.internal.compiler.ast.Expression exceptionArgument = statement.exceptionArgument;
889         if (exceptionArgument != null) {
890             final Expression exceptionMessage = convert(exceptionArgument);
891             assertStatement.setMessage(exceptionMessage);
892             searchingNode = exceptionMessage;
893         }
894         int start = statement.sourceStart;
895         int sourceEnd = retrieveSemiColonPosition(searchingNode);
896         if (sourceEnd == -1) {
897             sourceEnd = searchingNode.getStartPosition() + searchingNode.getLength() - 1;
898             assertStatement.setSourceRange(start, sourceEnd - start + 1);
899         } else {
900             assertStatement.setSourceRange(start, sourceEnd - start + 1);
901         }
902         return assertStatement;
903     }
904     
905     public Assignment convert(org.eclipse.jdt.internal.compiler.ast.Assignment expression) {
906         Assignment assignment = new Assignment(this.ast);
907         if (this.resolveBindings) {
908             recordNodes(assignment, expression);
909         }
910         Expression lhs = convert(expression.lhs);
911         assignment.setLeftHandSide(lhs);
912         assignment.setOperator(Assignment.Operator.ASSIGN);
913         assignment.setRightHandSide(convert(expression.expression));
914         int start = lhs.getStartPosition();
915         assignment.setSourceRange(start, expression.sourceEnd - start + 1);
916         return assignment;
917     }
918
919     /*
920      * Internal use only
921      * Used to convert class body declarations
922      */

923     public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes) {
924         final TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
925         typeDecl.setInterface(false);
926         int nodesLength = nodes.length;
927         for (int i = 0; i < nodesLength; i++) {
928             org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodes[i];
929             if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
930                 org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) node;
931                 Initializer initializer = new Initializer(this.ast);
932                 initializer.setBody(convert(oldInitializer.block));
933                 setModifiers(initializer, oldInitializer);
934                 initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
935 // setJavaDocComment(initializer);
936
// initializer.setJavadoc(convert(oldInitializer.javadoc));
937
convert(oldInitializer.javadoc, initializer);
938                 typeDecl.bodyDeclarations().add(initializer);
939             } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
940                 org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
941                 if (i > 0
942                     && (nodes[i - 1] instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)
943                     && ((org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)nodes[i - 1]).declarationSourceStart == fieldDeclaration.declarationSourceStart) {
944                     // we have a multiple field declaration
945
// We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
946
FieldDeclaration currentFieldDeclaration = (FieldDeclaration) typeDecl.bodyDeclarations().get(typeDecl.bodyDeclarations().size() - 1);
947                     currentFieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fieldDeclaration));
948                 } else {
949                     // we can create a new FieldDeclaration
950
typeDecl.bodyDeclarations().add(convertToFieldDeclaration(fieldDeclaration));
951                 }
952             } else if(node instanceof org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) {
953                 AbstractMethodDeclaration nextMethodDeclaration = (AbstractMethodDeclaration) node;
954                 if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
955                     typeDecl.bodyDeclarations().add(convert(nextMethodDeclaration));
956                 }
957             } else if(node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
958                 org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
959                 ASTNode nextMemberDeclarationNode = convert(nextMemberDeclaration);
960                 if (nextMemberDeclarationNode == null) {
961                     typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
962                 } else {
963                     typeDecl.bodyDeclarations().add(nextMemberDeclarationNode);
964                 }
965             }
966         }
967         return typeDecl;
968     }
969     
970     public Expression convert(org.eclipse.jdt.internal.compiler.ast.BinaryExpression expression) {
971         InfixExpression infixExpression = new InfixExpression(this.ast);
972         if (this.resolveBindings) {
973             this.recordNodes(infixExpression, expression);
974         }
975
976         int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
977         switch (expressionOperatorID) {
978             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
979                 infixExpression.setOperator(InfixExpression.Operator.EQUALS);
980                 break;
981             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
982                 infixExpression.setOperator(InfixExpression.Operator.LESS_EQUALS);
983                 break;
984             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
985                 infixExpression.setOperator(InfixExpression.Operator.GREATER_EQUALS);
986                 break;
987             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
988                 infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
989                 break;
990             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
991                 infixExpression.setOperator(InfixExpression.Operator.LEFT_SHIFT);
992                 break;
993             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
994                 infixExpression.setOperator(InfixExpression.Operator.RIGHT_SHIFT_SIGNED);
995                 break;
996             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
997                 infixExpression.setOperator(InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED);
998                 break;
999             case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR_OR :
1000                infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
1001                break;
1002            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND_AND :
1003                infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
1004                break;
1005            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1006                infixExpression.setOperator(InfixExpression.Operator.PLUS);
1007                break;
1008            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1009                infixExpression.setOperator(InfixExpression.Operator.MINUS);
1010                break;
1011            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
1012                infixExpression.setOperator(InfixExpression.Operator.REMAINDER);
1013                break;
1014            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
1015                infixExpression.setOperator(InfixExpression.Operator.XOR);
1016                break;
1017            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
1018                infixExpression.setOperator(InfixExpression.Operator.AND);
1019                break;
1020            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
1021                infixExpression.setOperator(InfixExpression.Operator.TIMES);
1022                break;
1023            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
1024                infixExpression.setOperator(InfixExpression.Operator.OR);
1025                break;
1026            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
1027                infixExpression.setOperator(InfixExpression.Operator.DIVIDE);
1028                break;
1029            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER :
1030                infixExpression.setOperator(InfixExpression.Operator.GREATER);
1031                break;
1032            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS :
1033                infixExpression.setOperator(InfixExpression.Operator.LESS);
1034        }
1035        
1036        if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
1037                && ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
1038            // create an extended string literal equivalent => use the extended operands list
1039
infixExpression.extendedOperands().add(convert(expression.right));
1040            org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
1041            org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
1042            do {
1043                rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
1044                if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
1045                            && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
1046                     || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
1047                            && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
1048                            && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
1049                    List JavaDoc extendedOperands = infixExpression.extendedOperands();
1050                    InfixExpression temp = new InfixExpression(this.ast);
1051                    if (this.resolveBindings) {
1052                        this.recordNodes(temp, expression);
1053                    }
1054                    temp.setOperator(getOperatorFor(expressionOperatorID));
1055                    Expression leftSide = convert(leftOperand);
1056                    temp.setLeftOperand(leftSide);
1057                    temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
1058                    int size = extendedOperands.size();
1059                    for (int i = 0; i < size - 1; i++) {
1060                        Expression expr = temp;
1061                        temp = new InfixExpression(this.ast);
1062                        
1063                        if (this.resolveBindings) {
1064                            this.recordNodes(temp, expression);
1065                        }
1066                        temp.setLeftOperand(expr);
1067                        temp.setOperator(getOperatorFor(expressionOperatorID));
1068                        temp.setSourceRange(expr.getStartPosition(), expr.getLength());
1069                    }
1070                    infixExpression = temp;
1071                    for (int i = 0; i < size; i++) {
1072                        Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
1073                        temp.setRightOperand(extendedOperand);
1074                        int startPosition = temp.getLeftOperand().getStartPosition();
1075                        temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
1076                        if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
1077                            temp = (InfixExpression) temp.getLeftOperand();
1078                        }
1079                    }
1080                    int startPosition = infixExpression.getLeftOperand().getStartPosition();
1081                    infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1082                    if (this.resolveBindings) {
1083                        this.recordNodes(infixExpression, expression);
1084                    }
1085                    return infixExpression;
1086                }
1087                infixExpression.extendedOperands().add(0, convert(rightOperand));
1088                leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
1089            } while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
1090            Expression leftExpression = convert(leftOperand);
1091            infixExpression.setLeftOperand(leftExpression);
1092            infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
1093            int startPosition = leftExpression.getStartPosition();
1094            infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1095            return infixExpression;
1096        } else if (expression.left instanceof StringLiteralConcatenation
1097                && ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)
1098                && (OperatorIds.PLUS == expressionOperatorID)) {
1099            StringLiteralConcatenation literal = (StringLiteralConcatenation) expression.left;
1100            final org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = literal.literals;
1101            infixExpression.setLeftOperand(convert(stringLiterals[0]));
1102            infixExpression.setRightOperand(convert(stringLiterals[1]));
1103            for (int i = 2; i < literal.counter; i++) {
1104                infixExpression.extendedOperands().add(convert(stringLiterals[i]));
1105            }
1106            infixExpression.extendedOperands().add(convert(expression.right));
1107            int startPosition = literal.sourceStart;
1108            infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1109            return infixExpression;
1110        }
1111        Expression leftExpression = convert(expression.left);
1112        infixExpression.setLeftOperand(leftExpression);
1113        infixExpression.setRightOperand(convert(expression.right));
1114        int startPosition = leftExpression.getStartPosition();
1115        infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1116        return infixExpression;
1117    }
1118
1119    public Block convert(org.eclipse.jdt.internal.compiler.ast.Block statement) {
1120        Block block = new Block(this.ast);
1121        if (statement.sourceEnd > 0) {
1122            block.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1123        }
1124        org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
1125        if (statements != null) {
1126            int statementsLength = statements.length;
1127            for (int i = 0; i < statementsLength; i++) {
1128                if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
1129                    checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
1130                } else {
1131                    Statement statement2 = convert(statements[i]);
1132                    if (statement2 != null) {
1133                        block.statements().add(statement2);
1134                    }
1135                }
1136            }
1137        }
1138        return block;
1139    }
1140    
1141    public BreakStatement convert(org.eclipse.jdt.internal.compiler.ast.BreakStatement statement) {
1142        BreakStatement breakStatement = new BreakStatement(this.ast);
1143        breakStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1144        if (statement.label != null) {
1145            final SimpleName name = new SimpleName(this.ast);
1146            name.internalSetIdentifier(new String JavaDoc(statement.label));
1147            retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
1148            breakStatement.setLabel(name);
1149        }
1150        return breakStatement;
1151    }
1152        
1153        
1154    public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) {
1155        SwitchCase switchCase = new SwitchCase(this.ast);
1156        org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
1157        if (constantExpression == null) {
1158            switchCase.setExpression(null);
1159        } else {
1160            switchCase.setExpression(convert(constantExpression));
1161        }
1162        switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1163        retrieveColonPosition(switchCase);
1164        return switchCase;
1165    }
1166
1167    public CastExpression convert(org.eclipse.jdt.internal.compiler.ast.CastExpression expression) {
1168        CastExpression castExpression = new CastExpression(this.ast);
1169        castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1170        org.eclipse.jdt.internal.compiler.ast.Expression type = expression.type;
1171        trimWhiteSpacesAndComments(type);
1172        if (type instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference ) {
1173            castExpression.setType(convertType((org.eclipse.jdt.internal.compiler.ast.TypeReference)type));
1174        } else if (type instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
1175            castExpression.setType(convertToType((org.eclipse.jdt.internal.compiler.ast.NameReference)type));
1176        }
1177        castExpression.setExpression(convert(expression.expression));
1178        if (this.resolveBindings) {
1179            recordNodes(castExpression, expression);
1180        }
1181        return castExpression;
1182    }
1183
1184    public CharacterLiteral convert(org.eclipse.jdt.internal.compiler.ast.CharLiteral expression) {
1185        int length = expression.sourceEnd - expression.sourceStart + 1;
1186        int sourceStart = expression.sourceStart;
1187        CharacterLiteral literal = new CharacterLiteral(this.ast);
1188        if (this.resolveBindings) {
1189            this.recordNodes(literal, expression);
1190        }
1191        literal.internalSetEscapedValue(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1192        literal.setSourceRange(sourceStart, length);
1193        removeLeadingAndTrailingCommentsFromLiteral(literal);
1194        return literal;
1195    }
1196    public Expression convert(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess expression) {
1197        TypeLiteral typeLiteral = new TypeLiteral(this.ast);
1198        if (this.resolveBindings) {
1199            this.recordNodes(typeLiteral, expression);
1200        }
1201        typeLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1202        typeLiteral.setType(convertType(expression.type));
1203        return typeLiteral;
1204    }
1205    
1206    public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
1207        if(unit.compilationResult.recoveryScannerData != null) {
1208            RecoveryScanner recoveryScanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused());
1209            this.scanner = recoveryScanner;
1210            this.docParser.scanner = this.scanner;
1211        }
1212        this.compilationUnitSource = source;
1213        this.compilationUnitSourceLength = source.length;
1214        this.scanner.setSource(source, unit.compilationResult);
1215        CompilationUnit compilationUnit = new CompilationUnit(this.ast);
1216
1217        // Parse comments
1218
int[][] comments = unit.comments;
1219        if (comments != null) {
1220            buildCommentsTable(compilationUnit, comments);
1221        }
1222
1223        // handle the package declaration immediately
1224
// There is no node corresponding to the package declaration
1225
if (this.resolveBindings) {
1226            recordNodes(compilationUnit, unit);
1227        }
1228        if (unit.currentPackage != null) {
1229            PackageDeclaration packageDeclaration = convertPackage(unit);
1230            compilationUnit.setPackage(packageDeclaration);
1231        }
1232        org.eclipse.jdt.internal.compiler.ast.ImportReference[] imports = unit.imports;
1233        if (imports != null) {
1234            int importLength = imports.length;
1235            for (int i = 0; i < importLength; i++) {
1236                compilationUnit.imports().add(convertImport(imports[i]));
1237            }
1238        }
1239
1240        org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit.types;
1241        if (types != null) {
1242            int typesLength = types.length;
1243            for (int i = 0; i < typesLength; i++) {
1244                org.eclipse.jdt.internal.compiler.ast.TypeDeclaration declaration = types[i];
1245                if (CharOperation.equals(declaration.name, TypeConstants.PACKAGE_INFO_NAME)) {
1246                    continue;
1247                }
1248                ASTNode type = convert(declaration);
1249                if (type == null) {
1250                    compilationUnit.setFlags(compilationUnit.getFlags() | ASTNode.MALFORMED);
1251                } else {
1252                    compilationUnit.types().add(type);
1253                }
1254            }
1255        }
1256        compilationUnit.setSourceRange(unit.sourceStart, unit.sourceEnd - unit.sourceStart + 1);
1257        
1258        int problemLength = unit.compilationResult.problemCount;
1259        if (problemLength != 0) {
1260            CategorizedProblem[] resizedProblems = null;
1261            final CategorizedProblem[] problems = unit.compilationResult.getProblems();
1262            final int realProblemLength=problems.length;
1263            if (realProblemLength == problemLength) {
1264                resizedProblems = problems;
1265            } else {
1266                System.arraycopy(problems, 0, (resizedProblems = new CategorizedProblem[realProblemLength]), 0, realProblemLength);
1267            }
1268            ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
1269            compilationUnit.accept(syntaxErrorPropagator);
1270            ASTRecoveryPropagator recoveryPropagator =
1271                new ASTRecoveryPropagator(resizedProblems, unit.compilationResult.recoveryScannerData);
1272            compilationUnit.accept(recoveryPropagator);
1273            compilationUnit.setProblems(resizedProblems);
1274        }
1275        if (this.resolveBindings) {
1276            lookupForScopes();
1277        }
1278        compilationUnit.initCommentMapper(this.scanner);
1279        return compilationUnit;
1280    }
1281
1282    public Assignment convert(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment expression) {
1283        Assignment assignment = new Assignment(this.ast);
1284        Expression lhs = convert(expression.lhs);
1285        assignment.setLeftHandSide(lhs);
1286        int start = lhs.getStartPosition();
1287        assignment.setSourceRange(start, expression.sourceEnd - start + 1);
1288        switch (expression.operator) {
1289            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1290                assignment.setOperator(Assignment.Operator.PLUS_ASSIGN);
1291                break;
1292            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1293                assignment.setOperator(Assignment.Operator.MINUS_ASSIGN);
1294                break;
1295            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
1296                assignment.setOperator(Assignment.Operator.TIMES_ASSIGN);
1297                break;
1298            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
1299                assignment.setOperator(Assignment.Operator.DIVIDE_ASSIGN);
1300                break;
1301            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
1302                assignment.setOperator(Assignment.Operator.BIT_AND_ASSIGN);
1303                break;
1304            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
1305                assignment.setOperator(Assignment.Operator.BIT_OR_ASSIGN);
1306                break;
1307            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
1308                assignment.setOperator(Assignment.Operator.BIT_XOR_ASSIGN);
1309                break;
1310            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
1311                assignment.setOperator(Assignment.Operator.REMAINDER_ASSIGN);
1312                break;
1313            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
1314                assignment.setOperator(Assignment.Operator.LEFT_SHIFT_ASSIGN);
1315                break;
1316            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
1317                assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN);
1318                break;
1319            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
1320                assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN);
1321                break;
1322        }
1323        assignment.setRightHandSide(convert(expression.expression));
1324        if (this.resolveBindings) {
1325            recordNodes(assignment, expression);
1326        }
1327        return assignment;
1328    }
1329
1330    public ConditionalExpression convert(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression expression) {
1331        ConditionalExpression conditionalExpression = new ConditionalExpression(this.ast);
1332        if (this.resolveBindings) {
1333            recordNodes(conditionalExpression, expression);
1334        }
1335        conditionalExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1336        conditionalExpression.setExpression(convert(expression.condition));
1337        conditionalExpression.setThenExpression(convert(expression.valueIfTrue));
1338        conditionalExpression.setElseExpression(convert(expression.valueIfFalse));
1339        return conditionalExpression;
1340    }
1341
1342    public ContinueStatement convert(org.eclipse.jdt.internal.compiler.ast.ContinueStatement statement) {
1343        ContinueStatement continueStatement = new ContinueStatement(this.ast);
1344        continueStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1345        if (statement.label != null) {
1346            final SimpleName name = new SimpleName(this.ast);
1347            name.internalSetIdentifier(new String JavaDoc(statement.label));
1348            retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
1349            continueStatement.setLabel(name);
1350        }
1351        return continueStatement;
1352    }
1353    
1354    public DoStatement convert(org.eclipse.jdt.internal.compiler.ast.DoStatement statement) {
1355        DoStatement doStatement = new DoStatement(this.ast);
1356        doStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1357        doStatement.setExpression(convert(statement.condition));
1358        final Statement action = convert(statement.action);
1359        if (action == null) return null;
1360        doStatement.setBody(action);
1361        return doStatement;
1362    }
1363
1364    public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral expression) {
1365        int length = expression.sourceEnd - expression.sourceStart + 1;
1366        int sourceStart = expression.sourceStart;
1367        NumberLiteral literal = new NumberLiteral(this.ast);
1368        literal.internalSetToken(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1369        if (this.resolveBindings) {
1370            this.recordNodes(literal, expression);
1371        }
1372        literal.setSourceRange(sourceStart, length);
1373        removeLeadingAndTrailingCommentsFromLiteral(literal);
1374        return literal;
1375    }
1376    
1377    public EmptyStatement convert(org.eclipse.jdt.internal.compiler.ast.EmptyStatement statement) {
1378        EmptyStatement emptyStatement = new EmptyStatement(this.ast);
1379        emptyStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1380        return emptyStatement;
1381    }
1382    
1383    // field is an enum constant
1384
public EnumConstantDeclaration convert(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration enumConstant) {
1385        checkCanceled();
1386        EnumConstantDeclaration enumConstantDeclaration = new EnumConstantDeclaration(this.ast);
1387        final SimpleName typeName = new SimpleName(this.ast);
1388        typeName.internalSetIdentifier(new String JavaDoc(enumConstant.name));
1389        typeName.setSourceRange(enumConstant.sourceStart, enumConstant.sourceEnd - enumConstant.sourceStart + 1);
1390        enumConstantDeclaration.setName(typeName);
1391        int declarationSourceStart = enumConstant.declarationSourceStart;
1392        int declarationSourceEnd = enumConstant.declarationSourceEnd;
1393        final org.eclipse.jdt.internal.compiler.ast.Expression initialization = enumConstant.initialization;
1394        if (initialization != null) {
1395            if (initialization instanceof QualifiedAllocationExpression) {
1396                org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousType = ((QualifiedAllocationExpression) initialization).anonymousType;
1397                if (anonymousType != null) {
1398                    AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
1399                    int start = retrieveStartBlockPosition(anonymousType.sourceEnd, anonymousType.bodyEnd);
1400                    int end = retrieveRightBrace(anonymousType.bodyEnd, declarationSourceEnd);
1401                    if (end == -1) end = anonymousType.bodyEnd;
1402                    anonymousClassDeclaration.setSourceRange(start, end - start + 1);
1403                    enumConstantDeclaration.setAnonymousClassDeclaration(anonymousClassDeclaration);
1404                    buildBodyDeclarations(anonymousType, anonymousClassDeclaration);
1405                    if (this.resolveBindings) {
1406                        recordNodes(anonymousClassDeclaration, anonymousType);
1407                        anonymousClassDeclaration.resolveBinding();
1408                    }
1409                    enumConstantDeclaration.setSourceRange(declarationSourceStart, end - declarationSourceStart + 1);
1410                }
1411            } else {
1412                enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
1413            }
1414            final org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = ((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) initialization).arguments;
1415            if (arguments != null) {
1416                for (int i = 0, max = arguments.length; i < max; i++) {
1417                    enumConstantDeclaration.arguments().add(convert(arguments[i]));
1418                }
1419            }
1420        } else {
1421            enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
1422        }
1423        setModifiers(enumConstantDeclaration, enumConstant);
1424        if (this.resolveBindings) {
1425            recordNodes(enumConstantDeclaration, enumConstant);
1426            recordNodes(typeName, enumConstant);
1427            enumConstantDeclaration.resolveVariable();
1428        }
1429        convert(enumConstant.javadoc, enumConstantDeclaration);
1430        return enumConstantDeclaration;
1431    }
1432
1433    public Expression convert(org.eclipse.jdt.internal.compiler.ast.EqualExpression expression) {
1434        InfixExpression infixExpression = new InfixExpression(this.ast);
1435        if (this.resolveBindings) {
1436            recordNodes(infixExpression, expression);
1437        }
1438        Expression leftExpression = convert(expression.left);
1439        infixExpression.setLeftOperand(leftExpression);
1440        infixExpression.setRightOperand(convert(expression.right));
1441        int startPosition = leftExpression.getStartPosition();
1442        infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1443        switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
1444            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
1445                infixExpression.setOperator(InfixExpression.Operator.EQUALS);
1446                break;
1447            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
1448                infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
1449        }
1450        return infixExpression;
1451    
1452    }
1453    
1454    public Statement convert(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall statement) {
1455        Statement newStatement;
1456        int sourceStart = statement.sourceStart;
1457        if (statement.isSuperAccess() || statement.isSuper()) {
1458            SuperConstructorInvocation superConstructorInvocation = new SuperConstructorInvocation(this.ast);
1459            if (statement.qualification != null) {
1460                superConstructorInvocation.setExpression(convert(statement.qualification));
1461            }
1462            org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
1463            if (arguments != null) {
1464                int length = arguments.length;
1465                for (int i = 0; i < length; i++) {
1466                    superConstructorInvocation.arguments().add(convert(arguments[i]));
1467                }
1468            }
1469            if (statement.typeArguments != null) {
1470                if (sourceStart > statement.typeArgumentsSourceStart) {
1471                    sourceStart = statement.typeArgumentsSourceStart;
1472                }
1473                switch(this.ast.apiLevel) {
1474                    case AST.JLS2_INTERNAL :
1475                        superConstructorInvocation.setFlags(superConstructorInvocation.getFlags() | ASTNode.MALFORMED);
1476                        break;
1477                    case AST.JLS3 :
1478                        for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
1479                            superConstructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
1480                        }
1481                        break;
1482                }
1483            }
1484            newStatement = superConstructorInvocation;
1485        } else {
1486            ConstructorInvocation constructorInvocation = new ConstructorInvocation(this.ast);
1487            org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
1488            if (arguments != null) {
1489                int length = arguments.length;
1490                for (int i = 0; i < length; i++) {
1491                    constructorInvocation.arguments().add(convert(arguments[i]));
1492                }
1493            }
1494            if (statement.typeArguments != null) {
1495                if (sourceStart > statement.typeArgumentsSourceStart) {
1496                    sourceStart = statement.typeArgumentsSourceStart;
1497                }
1498                switch(this.ast.apiLevel) {
1499                    case AST.JLS2_INTERNAL :
1500                        constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
1501                        break;
1502                    case AST.JLS3 :
1503                        for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
1504                            constructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
1505                        }
1506                    break;
1507                }
1508            }
1509            if (statement.qualification != null) {
1510                // this is an error
1511
constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
1512            }
1513            newStatement = constructorInvocation;
1514        }
1515        newStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
1516        if (this.resolveBindings) {
1517            recordNodes(newStatement, statement);
1518        }
1519        return newStatement;
1520    }
1521
1522    public Expression convert(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
1523        if ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
1524            return convertToParenthesizedExpression(expression);
1525        }
1526        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
1527            return convert((org.eclipse.jdt.internal.compiler.ast.Annotation) expression);
1528        }
1529        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CastExpression) {
1530            return convert((org.eclipse.jdt.internal.compiler.ast.CastExpression) expression);
1531        }
1532        // switch between all types of expression
1533
if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) {
1534            return convert((org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) expression);
1535        }
1536        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) {
1537            return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) expression);
1538        }
1539        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AllocationExpression) {
1540            return convert((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) expression);
1541        }
1542        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) {
1543            return convert((org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) expression);
1544        }
1545        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PrefixExpression) {
1546            return convert((org.eclipse.jdt.internal.compiler.ast.PrefixExpression) expression);
1547        }
1548        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PostfixExpression) {
1549            return convert((org.eclipse.jdt.internal.compiler.ast.PostfixExpression) expression);
1550        }
1551        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) {
1552            return convert((org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) expression);
1553        }
1554        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Assignment) {
1555            return convert((org.eclipse.jdt.internal.compiler.ast.Assignment) expression);
1556        }
1557        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) {
1558            return convert((org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) expression);
1559        }
1560        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FalseLiteral) {
1561            return convert((org.eclipse.jdt.internal.compiler.ast.FalseLiteral) expression);
1562        }
1563        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TrueLiteral) {
1564            return convert((org.eclipse.jdt.internal.compiler.ast.TrueLiteral) expression);
1565        }
1566        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.NullLiteral) {
1567            return convert((org.eclipse.jdt.internal.compiler.ast.NullLiteral) expression);
1568        }
1569        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CharLiteral) {
1570            return convert((org.eclipse.jdt.internal.compiler.ast.CharLiteral) expression);
1571        }
1572        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) {
1573            return convert((org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) expression);
1574        }
1575        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FloatLiteral) {
1576            return convert((org.eclipse.jdt.internal.compiler.ast.FloatLiteral) expression);
1577        }
1578        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) {
1579            return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) expression);
1580        }
1581        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteral) {
1582            return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteral) expression);
1583        }
1584        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) {
1585            return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) expression);
1586        }
1587        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteral) {
1588            return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteral) expression);
1589        }
1590        if (expression instanceof StringLiteralConcatenation) {
1591            return convert((StringLiteralConcatenation) expression);
1592        }
1593        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) {
1594            return convert((org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) expression);
1595        }
1596        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.StringLiteral) {
1597            return convert((org.eclipse.jdt.internal.compiler.ast.StringLiteral) expression);
1598        }
1599        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) {
1600            return convert((org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) expression);
1601        }
1602        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) {
1603            return convert((org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) expression);
1604        }
1605        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.EqualExpression) {
1606            return convert((org.eclipse.jdt.internal.compiler.ast.EqualExpression) expression);
1607        }
1608        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression) {
1609            return convert((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) expression);
1610        }
1611        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) {
1612            return convert((org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) expression);
1613        }
1614        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.UnaryExpression) {
1615            return convert((org.eclipse.jdt.internal.compiler.ast.UnaryExpression) expression);
1616        }
1617        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) {
1618            return convert((org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) expression);
1619        }
1620        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.MessageSend) {
1621            return convert((org.eclipse.jdt.internal.compiler.ast.MessageSend) expression);
1622        }
1623        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Reference) {
1624            return convert((org.eclipse.jdt.internal.compiler.ast.Reference) expression);
1625        }
1626        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
1627            return convert((org.eclipse.jdt.internal.compiler.ast.TypeReference) expression);
1628        }
1629        return null;
1630    }
1631
1632    public StringLiteral convert(org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral expression) {
1633        expression.computeConstant();
1634        StringLiteral literal = new StringLiteral(this.ast);
1635        if (this.resolveBindings) {
1636            this.recordNodes(literal, expression);
1637        }
1638        literal.setLiteralValue(expression.constant.stringValue());
1639        literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1640        return literal;
1641    }
1642
1643    public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.FalseLiteral expression) {
1644        final BooleanLiteral literal = new BooleanLiteral(this.ast);
1645        literal.setBooleanValue(false);
1646        if (this.resolveBindings) {
1647            this.recordNodes(literal, expression);
1648        }
1649        literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1650        return literal;
1651    }
1652    
1653    public Expression convert(org.eclipse.jdt.internal.compiler.ast.FieldReference reference) {
1654        if (reference.receiver.isSuper()) {
1655            final SuperFieldAccess superFieldAccess = new SuperFieldAccess(this.ast);
1656            if (this.resolveBindings) {
1657                recordNodes(superFieldAccess, reference);
1658            }
1659            if (reference.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
1660                Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference.receiver);
1661                superFieldAccess.setQualifier(qualifier);
1662                if (this.resolveBindings) {
1663                    recordNodes(qualifier, reference.receiver);
1664                }
1665            }
1666            final SimpleName simpleName = new SimpleName(this.ast);
1667            simpleName.internalSetIdentifier(new String JavaDoc(reference.token));
1668            int sourceStart = (int)(reference.nameSourcePosition>>>32);
1669            int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
1670            simpleName.setSourceRange(sourceStart, length);
1671            superFieldAccess.setName(simpleName);
1672            if (this.resolveBindings) {
1673                recordNodes(simpleName, reference);
1674            }
1675            superFieldAccess.setSourceRange(reference.receiver.sourceStart, reference.sourceEnd - reference.receiver.sourceStart + 1);
1676            return superFieldAccess;
1677        } else {
1678            final FieldAccess fieldAccess = new FieldAccess(this.ast);
1679            if (this.resolveBindings) {
1680                recordNodes(fieldAccess, reference);
1681            }
1682            Expression receiver = convert(reference.receiver);
1683            fieldAccess.setExpression(receiver);
1684            final SimpleName simpleName = new SimpleName(this.ast);
1685            simpleName.internalSetIdentifier(new String JavaDoc(reference.token));
1686            int sourceStart = (int)(reference.nameSourcePosition>>>32);
1687            int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
1688            simpleName.setSourceRange(sourceStart, length);
1689            fieldAccess.setName(simpleName);
1690            if (this.resolveBindings) {
1691                recordNodes(simpleName, reference);
1692            }
1693            fieldAccess.setSourceRange(receiver.getStartPosition(), reference.sourceEnd - receiver.getStartPosition() + 1);
1694            return fieldAccess;
1695        }
1696    }
1697
1698    public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.FloatLiteral expression) {
1699        int length = expression.sourceEnd - expression.sourceStart + 1;
1700        int sourceStart = expression.sourceStart;
1701        NumberLiteral literal = new NumberLiteral(this.ast);
1702        literal.internalSetToken(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1703        if (this.resolveBindings) {
1704            this.recordNodes(literal, expression);
1705        }
1706        literal.setSourceRange(sourceStart, length);
1707        removeLeadingAndTrailingCommentsFromLiteral(literal);
1708        return literal;
1709    }
1710    
1711    public Statement convert(ForeachStatement statement) {
1712        switch(this.ast.apiLevel) {
1713            case AST.JLS2_INTERNAL :
1714                return createFakeEmptyStatement(statement);
1715            case AST.JLS3 :
1716                EnhancedForStatement enhancedForStatement = new EnhancedForStatement(this.ast);
1717                enhancedForStatement.setParameter(convertToSingleVariableDeclaration(statement.elementVariable));
1718                org.eclipse.jdt.internal.compiler.ast.Expression collection = statement.collection;
1719                if (collection == null) return null;
1720                enhancedForStatement.setExpression(convert(collection));
1721                final Statement action = convert(statement.action);
1722                if (action == null) return null;
1723                enhancedForStatement.setBody(action);
1724                int start = statement.sourceStart;
1725                int end = statement.sourceEnd;
1726                enhancedForStatement.setSourceRange(start, end - start + 1);
1727                return enhancedForStatement;
1728            default:
1729                return createFakeEmptyStatement(statement);
1730        }
1731    }
1732    
1733    public ForStatement convert(org.eclipse.jdt.internal.compiler.ast.ForStatement statement) {
1734        ForStatement forStatement = new ForStatement(this.ast);
1735        forStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1736        org.eclipse.jdt.internal.compiler.ast.Statement[] initializations = statement.initializations;
1737        if (initializations != null) {
1738            // we know that we have at least one initialization
1739
if (initializations[0] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
1740                VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[0]);
1741                int initializationsLength = initializations.length;
1742                for (int i = 1; i < initializationsLength; i++) {
1743                    variableDeclarationExpression.fragments().add(convertToVariableDeclarationFragment((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)initializations[i]));
1744                }
1745                if (initializationsLength != 1) {
1746                    int start = variableDeclarationExpression.getStartPosition();
1747                    int end = ((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[initializationsLength - 1]).declarationSourceEnd;
1748                    variableDeclarationExpression.setSourceRange(start, end - start + 1);
1749                }
1750                forStatement.initializers().add(variableDeclarationExpression);
1751            } else {
1752                int initializationsLength = initializations.length;
1753                for (int i = 0; i < initializationsLength; i++) {
1754                    Expression initializer = convertToExpression(initializations[i]);
1755                    if (initializer != null) {
1756                        forStatement.initializers().add(initializer);
1757                    } else {
1758                        forStatement.setFlags(forStatement.getFlags() | ASTNode.MALFORMED);
1759                    }
1760                }
1761            }
1762        }
1763        if (statement.condition != null) {
1764            forStatement.setExpression(convert(statement.condition));
1765        }
1766        org.eclipse.jdt.internal.compiler.ast.Statement[] increments = statement.increments;
1767        if (increments != null) {
1768            int incrementsLength = increments.length;
1769            for (int i = 0; i < incrementsLength; i++) {
1770                forStatement.updaters().add(convertToExpression(increments[i]));
1771            }
1772        }
1773        final Statement action = convert(statement.action);
1774        if (action == null) return null;
1775        forStatement.setBody(action);
1776        return forStatement;
1777    }
1778    
1779    public IfStatement convert(org.eclipse.jdt.internal.compiler.ast.IfStatement statement) {
1780        IfStatement ifStatement = new IfStatement(this.ast);
1781        ifStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1782        ifStatement.setExpression(convert(statement.condition));
1783        final Statement thenStatement = convert(statement.thenStatement);
1784        if (thenStatement == null) return null;
1785        ifStatement.setThenStatement(thenStatement);
1786        org.eclipse.jdt.internal.compiler.ast.Statement statement2 = statement.elseStatement;
1787        if (statement2 != null) {
1788            final Statement elseStatement = convert(statement2);
1789            if (elseStatement != null) {
1790                ifStatement.setElseStatement(elseStatement);
1791            }
1792        }
1793        return ifStatement;
1794    }
1795    
1796    public InstanceofExpression convert(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression expression) {
1797        InstanceofExpression instanceOfExpression = new InstanceofExpression(this.ast);
1798        if (this.resolveBindings) {
1799            recordNodes(instanceOfExpression, expression);
1800        }
1801        Expression leftExpression = convert(expression.expression);
1802        instanceOfExpression.setLeftOperand(leftExpression);
1803        final Type convertType = convertType(expression.type);
1804        instanceOfExpression.setRightOperand(convertType);
1805        int startPosition = leftExpression.getStartPosition();
1806        int sourceEnd = convertType.getStartPosition() + convertType.getLength() - 1;
1807        instanceOfExpression.setSourceRange(startPosition, sourceEnd - startPosition + 1);
1808        return instanceOfExpression;
1809    }
1810
1811    public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteral expression) {
1812        int length = expression.sourceEnd - expression.sourceStart + 1;
1813        int sourceStart = expression.sourceStart;
1814        final NumberLiteral literal = new NumberLiteral(this.ast);
1815        literal.internalSetToken(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1816        if (this.resolveBindings) {
1817            this.recordNodes(literal, expression);
1818        }
1819        literal.setSourceRange(sourceStart, length);
1820        removeLeadingAndTrailingCommentsFromLiteral(literal);
1821        return literal;
1822    }
1823
1824    public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue expression) {
1825        int length = expression.sourceEnd - expression.sourceStart + 1;
1826        int sourceStart = expression.sourceStart;
1827        NumberLiteral literal = new NumberLiteral(this.ast);
1828        literal.internalSetToken(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1829        if (this.resolveBindings) {
1830            this.recordNodes(literal, expression);
1831        }
1832        literal.setSourceRange(sourceStart, length);
1833        removeLeadingAndTrailingCommentsFromLiteral(literal);
1834        return literal;
1835    }
1836
1837    public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, BodyDeclaration bodyDeclaration) {
1838        if (bodyDeclaration.getJavadoc() == null) {
1839            if (javadoc != null) {
1840                if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
1841                    this.commentMapper = new DefaultCommentMapper(this.commentsTable);
1842                }
1843                Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
1844                if (comment != null && comment.isDocComment() && comment.getParent() == null) {
1845                    Javadoc docComment = (Javadoc) comment;
1846                    if (this.resolveBindings) {
1847                        recordNodes(docComment, javadoc);
1848                        // resolve member and method references binding
1849
Iterator JavaDoc tags = docComment.tags().listIterator();
1850                        while (tags.hasNext()) {
1851                            recordNodes(javadoc, (TagElement) tags.next());
1852                        }
1853                    }
1854                    bodyDeclaration.setJavadoc(docComment);
1855                }
1856            }
1857        }
1858    }
1859
1860    public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, PackageDeclaration packageDeclaration) {
1861        if (ast.apiLevel == AST.JLS3 && packageDeclaration.getJavadoc() == null) {
1862            if (javadoc != null) {
1863                if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
1864                    this.commentMapper = new DefaultCommentMapper(this.commentsTable);
1865                }
1866                Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
1867                if (comment != null && comment.isDocComment() && comment.getParent() == null) {
1868                    Javadoc docComment = (Javadoc) comment;
1869                    if (this.resolveBindings) {
1870                        recordNodes(docComment, javadoc);
1871                        // resolve member and method references binding
1872
Iterator JavaDoc tags = docComment.tags().listIterator();
1873                        while (tags.hasNext()) {
1874                            recordNodes(javadoc, (TagElement) tags.next());
1875                        }
1876                    }
1877                    packageDeclaration.setJavadoc(docComment);
1878                }
1879            }
1880        }
1881    }
1882    
1883    public LabeledStatement convert(org.eclipse.jdt.internal.compiler.ast.LabeledStatement statement) {
1884        LabeledStatement labeledStatement = new LabeledStatement(this.ast);
1885        final int sourceStart = statement.sourceStart;
1886        labeledStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
1887        Statement body = convert(statement.statement);
1888        if (body == null) return null;
1889        labeledStatement.setBody(body);
1890        final SimpleName name = new SimpleName(this.ast);
1891        name.internalSetIdentifier(new String JavaDoc(statement.label));
1892        name.setSourceRange(sourceStart, statement.labelEnd - sourceStart + 1);
1893        labeledStatement.setLabel(name);
1894        return labeledStatement;
1895    }
1896
1897    public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteral expression) {
1898        int length = expression.sourceEnd - expression.sourceStart + 1;
1899        int sourceStart = expression.sourceStart;
1900        final NumberLiteral literal = new NumberLiteral(this.ast);
1901        literal.internalSetToken(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1902        if (this.resolveBindings) {
1903            this.recordNodes(literal, expression);
1904        }
1905        literal.setSourceRange(sourceStart, length);
1906        removeLeadingAndTrailingCommentsFromLiteral(literal);
1907        return literal;
1908    }
1909
1910    public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue expression) {
1911        int length = expression.sourceEnd - expression.sourceStart + 1;
1912        int sourceStart = expression.sourceStart;
1913        final NumberLiteral literal = new NumberLiteral(this.ast);
1914        literal.internalSetToken(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
1915        if (this.resolveBindings) {
1916            this.recordNodes(literal, expression);
1917        }
1918        literal.setSourceRange(sourceStart, length);
1919        removeLeadingAndTrailingCommentsFromLiteral(literal);
1920        return literal;
1921    }
1922
1923    public Expression convert(MessageSend expression) {
1924        // will return a MethodInvocation or a SuperMethodInvocation or
1925
Expression expr;
1926        int sourceStart = expression.sourceStart;
1927        if (expression.isSuperAccess()) {
1928            // returns a SuperMethodInvocation
1929
final SuperMethodInvocation superMethodInvocation = new SuperMethodInvocation(this.ast);
1930            if (this.resolveBindings) {
1931                recordNodes(superMethodInvocation, expression);
1932            }
1933            final SimpleName name = new SimpleName(this.ast);
1934            name.internalSetIdentifier(new String JavaDoc(expression.selector));
1935            int nameSourceStart = (int) (expression.nameSourcePosition >>> 32);
1936            int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
1937            name.setSourceRange(nameSourceStart, nameSourceLength);
1938            if (this.resolveBindings) {
1939                recordNodes(name, expression);
1940            }
1941            superMethodInvocation.setName(name);
1942            // expression.receiver is either a QualifiedSuperReference or a SuperReference
1943
// so the casting cannot fail
1944
if (expression.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
1945                Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) expression.receiver);
1946                superMethodInvocation.setQualifier(qualifier);
1947                if (this.resolveBindings) {
1948                    recordNodes(qualifier, expression.receiver);
1949                }
1950                if (qualifier != null) {
1951                    sourceStart = qualifier.getStartPosition();
1952                }
1953            }
1954            org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
1955            if (arguments != null) {
1956                int argumentsLength = arguments.length;
1957                for (int i = 0; i < argumentsLength; i++) {
1958                    Expression expri = convert(arguments[i]);
1959                    if (this.resolveBindings) {
1960                        recordNodes(expri, arguments[i]);
1961                    }
1962                    superMethodInvocation.arguments().add(expri);
1963                }
1964            }
1965            final TypeReference[] typeArguments = expression.typeArguments;
1966            if (typeArguments != null) {
1967                switch(this.ast.apiLevel) {
1968                    case AST.JLS2_INTERNAL :
1969                        superMethodInvocation.setFlags(superMethodInvocation.getFlags() | ASTNode.MALFORMED);
1970                        break;
1971                    case AST.JLS3 :
1972                        for (int i = 0, max = typeArguments.length; i < max; i++) {
1973                            superMethodInvocation.typeArguments().add(convertType(typeArguments[i]));
1974                        }
1975                        break;
1976                }
1977            }
1978            expr = superMethodInvocation;
1979        } else {
1980            // returns a MethodInvocation
1981
final MethodInvocation methodInvocation = new MethodInvocation(this.ast);
1982            if (this.resolveBindings) {
1983                recordNodes(methodInvocation, expression);
1984            }
1985            final SimpleName name = new SimpleName(this.ast);
1986            name.internalSetIdentifier(new String JavaDoc(expression.selector));
1987            int nameSourceStart = (int) (expression.nameSourcePosition >>> 32);
1988            int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
1989            name.setSourceRange(nameSourceStart, nameSourceLength);
1990            methodInvocation.setName(name);
1991            if (this.resolveBindings) {
1992                recordNodes(name, expression);
1993            }
1994            org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
1995            if (arguments != null) {
1996                int argumentsLength = arguments.length;
1997                for (int i = 0; i < argumentsLength; i++) {
1998                    Expression expri = convert(arguments[i]);
1999                    if (this.resolveBindings) {
2000                        recordNodes(expri, arguments[i]);
2001                    }
2002                    methodInvocation.arguments().add(expri);
2003                }
2004            }
2005            Expression qualifier = null;
2006            org.eclipse.jdt.internal.compiler.ast.Expression receiver = expression.receiver;
2007            if (receiver instanceof MessageSend) {
2008                if ((receiver.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
2009                    qualifier = convertToParenthesizedExpression(receiver);
2010                } else {
2011                    qualifier = convert((MessageSend) receiver);
2012                }
2013            } else {
2014                qualifier = convert(receiver);
2015            }
2016            if (qualifier instanceof Name && this.resolveBindings) {
2017                recordNodes(qualifier, receiver);
2018            }
2019            methodInvocation.setExpression(qualifier);
2020            if (qualifier != null) {
2021                sourceStart = qualifier.getStartPosition();
2022            }
2023            final TypeReference[] typeArguments = expression.typeArguments;
2024            if (typeArguments != null) {
2025                switch(this.ast.apiLevel) {
2026                    case AST.JLS2_INTERNAL :
2027                        methodInvocation.setFlags(methodInvocation.getFlags() | ASTNode.MALFORMED);
2028                        break;
2029                    case AST.JLS3 :
2030                        for (int i = 0, max = typeArguments.length; i < max; i++) {
2031                            methodInvocation.typeArguments().add(convertType(typeArguments[i]));
2032                        }
2033                        break;
2034                }
2035            }
2036            expr = methodInvocation;
2037        }
2038        expr.setSourceRange(sourceStart, expression.sourceEnd - sourceStart + 1);
2039        removeTrailingCommentFromExpressionEndingWithAParen(expr);
2040        return expr;
2041    }
2042
2043    public MarkerAnnotation convert(org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation annotation) {
2044        final MarkerAnnotation markerAnnotation = new MarkerAnnotation(this.ast);
2045        setTypeNameForAnnotation(annotation, markerAnnotation);
2046        int start = annotation.sourceStart;
2047        int end = annotation.declarationSourceEnd;
2048        markerAnnotation.setSourceRange(start, end - start + 1);
2049        if (this.resolveBindings) {
2050            recordNodes(markerAnnotation, annotation);
2051            markerAnnotation.resolveAnnotationBinding();
2052        }
2053        return markerAnnotation;
2054    }
2055
2056    public MemberValuePair convert(org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair) {
2057        final MemberValuePair pair = new MemberValuePair(this.ast);
2058        final SimpleName simpleName = new SimpleName(this.ast);
2059        simpleName.internalSetIdentifier(new String JavaDoc(memberValuePair.name));
2060        int start = memberValuePair.sourceStart;
2061        int end = memberValuePair.sourceEnd;
2062        simpleName.setSourceRange(start, end - start + 1);
2063        pair.setName(simpleName);
2064        final Expression value = convert(memberValuePair.value);
2065        pair.setValue(value);
2066        start = memberValuePair.sourceStart;
2067        end = value.getStartPosition() + value.getLength() - 1;
2068        pair.setSourceRange(start, end - start + 1);
2069        if (this.resolveBindings) {
2070            recordNodes(simpleName, memberValuePair);
2071            recordNodes(pair, memberValuePair);
2072        }
2073        return pair;
2074    }
2075
2076    public Name convert(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
2077        if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) {
2078            return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) reference);
2079        } else {
2080            return convert((org.eclipse.jdt.internal.compiler.ast.SingleNameReference) reference);
2081        }
2082    }
2083
2084    public InfixExpression convert(StringLiteralConcatenation expression) {
2085        expression.computeConstant();
2086        final InfixExpression infixExpression = new InfixExpression(this.ast);
2087        infixExpression.setOperator(InfixExpression.Operator.PLUS);
2088        org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = expression.literals;
2089        infixExpression.setLeftOperand(convert(stringLiterals[0]));
2090        infixExpression.setRightOperand(convert(stringLiterals[1]));
2091        for (int i = 2; i < expression.counter; i++) {
2092            infixExpression.extendedOperands().add(convert(stringLiterals[i]));
2093        }
2094        if (this.resolveBindings) {
2095            this.recordNodes(infixExpression, expression);
2096        }
2097        infixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2098        return infixExpression;
2099    }
2100    
2101    public NormalAnnotation convert(org.eclipse.jdt.internal.compiler.ast.NormalAnnotation annotation) {
2102        final NormalAnnotation normalAnnotation = new NormalAnnotation(this.ast);
2103        setTypeNameForAnnotation(annotation, normalAnnotation);
2104        org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] memberValuePairs = annotation.memberValuePairs;
2105        if (memberValuePairs != null) {
2106            for (int i = 0, max = memberValuePairs.length; i < max; i++) {
2107                normalAnnotation.values().add(convert(memberValuePairs[i]));
2108            }
2109        }
2110        int start = annotation.sourceStart;
2111        int end = annotation.declarationSourceEnd;
2112        normalAnnotation.setSourceRange(start, end - start + 1);
2113        if (this.resolveBindings) {
2114            recordNodes(normalAnnotation, annotation);
2115            normalAnnotation.resolveAnnotationBinding();
2116        }
2117        return normalAnnotation;
2118    }
2119
2120    public NullLiteral convert(org.eclipse.jdt.internal.compiler.ast.NullLiteral expression) {
2121        final NullLiteral literal = new NullLiteral(this.ast);
2122        if (this.resolveBindings) {
2123            this.recordNodes(literal, expression);
2124        }
2125        literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2126        return literal;
2127    }
2128
2129    public Expression convert(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression expression) {
2130        InfixExpression infixExpression = new InfixExpression(this.ast);
2131        infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
2132        if (this.resolveBindings) {
2133            this.recordNodes(infixExpression, expression);
2134        }
2135        final int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
2136        if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
2137                && ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
2138            // create an extended string literal equivalent => use the extended operands list
2139
infixExpression.extendedOperands().add(convert(expression.right));
2140            org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
2141            org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
2142            do {
2143                rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
2144                if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
2145                            && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
2146                     || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
2147                            && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
2148                            && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
2149                    List JavaDoc extendedOperands = infixExpression.extendedOperands();
2150                    InfixExpression temp = new InfixExpression(this.ast);
2151                    if (this.resolveBindings) {
2152                        this.recordNodes(temp, expression);
2153                    }
2154                    temp.setOperator(getOperatorFor(expressionOperatorID));
2155                    Expression leftSide = convert(leftOperand);
2156                    temp.setLeftOperand(leftSide);
2157                    temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
2158                    int size = extendedOperands.size();
2159                    for (int i = 0; i < size - 1; i++) {
2160                        Expression expr = temp;
2161                        temp = new InfixExpression(this.ast);
2162                        
2163                        if (this.resolveBindings) {
2164                            this.recordNodes(temp, expression);
2165                        }
2166                        temp.setLeftOperand(expr);
2167                        temp.setOperator(getOperatorFor(expressionOperatorID));
2168                        temp.setSourceRange(expr.getStartPosition(), expr.getLength());
2169                    }
2170                    infixExpression = temp;
2171                    for (int i = 0; i < size; i++) {
2172                        Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
2173                        temp.setRightOperand(extendedOperand);
2174                        int startPosition = temp.getLeftOperand().getStartPosition();
2175                        temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
2176                        if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
2177                            temp = (InfixExpression) temp.getLeftOperand();
2178                        }
2179                    }
2180                    int startPosition = infixExpression.getLeftOperand().getStartPosition();
2181                    infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
2182                    if (this.resolveBindings) {
2183                        this.recordNodes(infixExpression, expression);
2184                    }
2185                    return infixExpression;
2186                }
2187                infixExpression.extendedOperands().add(0, convert(rightOperand));
2188                leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
2189            } while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
2190            Expression leftExpression = convert(leftOperand);
2191            infixExpression.setLeftOperand(leftExpression);
2192            infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
2193            int startPosition = leftExpression.getStartPosition();
2194            infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
2195            return infixExpression;
2196        }
2197        Expression leftExpression = convert(expression.left);
2198        infixExpression.setLeftOperand(leftExpression);
2199        infixExpression.setRightOperand(convert(expression.right));
2200        infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
2201        int startPosition = leftExpression.getStartPosition();
2202        infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
2203        return infixExpression;
2204    }
2205
2206    public PostfixExpression convert(org.eclipse.jdt.internal.compiler.ast.PostfixExpression expression) {
2207        final PostfixExpression postfixExpression = new PostfixExpression(this.ast);
2208        if (this.resolveBindings) {
2209            recordNodes(postfixExpression, expression);
2210        }
2211        postfixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2212        postfixExpression.setOperand(convert(expression.lhs));
2213        switch (expression.operator) {
2214            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
2215                postfixExpression.setOperator(PostfixExpression.Operator.INCREMENT);
2216                break;
2217            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
2218                postfixExpression.setOperator(PostfixExpression.Operator.DECREMENT);
2219                break;
2220        }
2221        return postfixExpression;
2222    }
2223
2224    public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.PrefixExpression expression) {
2225        final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
2226        if (this.resolveBindings) {
2227            recordNodes(prefixExpression, expression);
2228        }
2229        prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2230        prefixExpression.setOperand(convert(expression.lhs));
2231        switch (expression.operator) {
2232            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
2233                prefixExpression.setOperator(PrefixExpression.Operator.INCREMENT);
2234                break;
2235            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
2236                prefixExpression.setOperator(PrefixExpression.Operator.DECREMENT);
2237                break;
2238        }
2239        return prefixExpression;
2240    }
2241
2242    public Expression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression allocation) {
2243        final ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
2244        if (allocation.enclosingInstance != null) {
2245            classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
2246        }
2247        switch(this.ast.apiLevel) {
2248            case AST.JLS2_INTERNAL :
2249                classInstanceCreation.internalSetName(convert(allocation.type));
2250                break;
2251            case AST.JLS3 :
2252                classInstanceCreation.setType(convertType(allocation.type));
2253        }
2254        org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = allocation.arguments;
2255        if (arguments != null) {
2256            int length = arguments.length;
2257            for (int i = 0; i < length; i++) {
2258                Expression argument = convert(arguments[i]);
2259                if (this.resolveBindings) {
2260                    recordNodes(argument, arguments[i]);
2261                }
2262                classInstanceCreation.arguments().add(argument);
2263            }
2264        }
2265        if (allocation.typeArguments != null) {
2266            switch(this.ast.apiLevel) {
2267                case AST.JLS2_INTERNAL :
2268                    classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
2269                    break;
2270                case AST.JLS3 :
2271                    for (int i = 0, max = allocation.typeArguments.length; i < max; i++) {
2272                        classInstanceCreation.typeArguments().add(convertType(allocation.typeArguments[i]));
2273                    }
2274            }
2275        }
2276        if (allocation.anonymousType != null) {
2277            int declarationSourceStart = allocation.sourceStart;
2278            classInstanceCreation.setSourceRange(declarationSourceStart, allocation.anonymousType.bodyEnd - declarationSourceStart + 1);
2279            final AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
2280            int start = retrieveStartBlockPosition(allocation.anonymousType.sourceEnd, allocation.anonymousType.bodyEnd);
2281            anonymousClassDeclaration.setSourceRange(start, allocation.anonymousType.bodyEnd - start + 1);
2282            classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
2283            buildBodyDeclarations(allocation.anonymousType, anonymousClassDeclaration);
2284            if (this.resolveBindings) {
2285                recordNodes(classInstanceCreation, allocation.anonymousType);
2286                recordNodes(anonymousClassDeclaration, allocation.anonymousType);
2287                anonymousClassDeclaration.resolveBinding();
2288            }
2289            return classInstanceCreation;
2290        } else {
2291            final int start = allocation.sourceStart;
2292            classInstanceCreation.setSourceRange(start, allocation.sourceEnd - start + 1);
2293            if (this.resolveBindings) {
2294                recordNodes(classInstanceCreation, allocation);
2295            }
2296            removeTrailingCommentFromExpressionEndingWithAParen(classInstanceCreation);
2297            return classInstanceCreation;
2298        }
2299    }
2300
2301    public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference nameReference) {
2302        return setQualifiedNameNameAndSourceRanges(nameReference.tokens, nameReference.sourcePositions, nameReference);
2303    }
2304
2305    public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference reference) {
2306        return convert(reference.qualification);
2307    }
2308
2309    public ThisExpression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference reference) {
2310        final ThisExpression thisExpression = new ThisExpression(this.ast);
2311        thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
2312        thisExpression.setQualifier(convert(reference.qualification));
2313        if (this.resolveBindings) {
2314            recordNodes(thisExpression, reference);
2315            recordPendingThisExpressionScopeResolution(thisExpression);
2316        }
2317        return thisExpression;
2318    }
2319    
2320    public Expression convert(org.eclipse.jdt.internal.compiler.ast.Reference reference) {
2321        if (reference instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
2322            return convert((org.eclipse.jdt.internal.compiler.ast.NameReference) reference);
2323        }
2324        if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ThisReference) {
2325            return convert((org.eclipse.jdt.internal.compiler.ast.ThisReference) reference);
2326        }
2327        if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ArrayReference) {
2328            return convert((org.eclipse.jdt.internal.compiler.ast.ArrayReference) reference);
2329        }
2330        if (reference instanceof org.eclipse.jdt.internal.compiler.ast.FieldReference) {
2331            return convert((org.eclipse.jdt.internal.compiler.ast.FieldReference) reference);
2332        }
2333        return null; // cannot be reached
2334
}
2335    
2336    public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
2337        final ReturnStatement returnStatement = new ReturnStatement(this.ast);
2338        returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2339        if (statement.expression != null) {
2340            returnStatement.setExpression(convert(statement.expression));
2341        }
2342        return returnStatement;
2343    }
2344    
2345    public SingleMemberAnnotation convert(org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation annotation) {
2346        final SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(this.ast);
2347        setTypeNameForAnnotation(annotation, singleMemberAnnotation);
2348        singleMemberAnnotation.setValue(convert(annotation.memberValue));
2349        int start = annotation.sourceStart;
2350        int end = annotation.declarationSourceEnd;
2351        singleMemberAnnotation.setSourceRange(start, end - start + 1);
2352        if (this.resolveBindings) {
2353            recordNodes(singleMemberAnnotation, annotation);
2354            singleMemberAnnotation.resolveAnnotationBinding();
2355        }
2356        return singleMemberAnnotation;
2357    }
2358
2359    public SimpleName convert(org.eclipse.jdt.internal.compiler.ast.SingleNameReference nameReference) {
2360        final SimpleName name = new SimpleName(this.ast);
2361        name.internalSetIdentifier(new String JavaDoc(nameReference.token));
2362        if (this.resolveBindings) {
2363            recordNodes(name, nameReference);
2364        }
2365        name.setSourceRange(nameReference.sourceStart, nameReference.sourceEnd - nameReference.sourceStart + 1);
2366        return name;
2367    }
2368
2369    public Statement convert(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
2370        if (statement instanceof ForeachStatement) {
2371            return convert((ForeachStatement) statement);
2372        }
2373        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
2374            return convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)statement);
2375        }
2376        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.AssertStatement) {
2377            return convert((org.eclipse.jdt.internal.compiler.ast.AssertStatement) statement);
2378        }
2379        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Block) {
2380            return convert((org.eclipse.jdt.internal.compiler.ast.Block) statement);
2381        }
2382        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.BreakStatement) {
2383            return convert((org.eclipse.jdt.internal.compiler.ast.BreakStatement) statement);
2384        }
2385        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ContinueStatement) {
2386            return convert((org.eclipse.jdt.internal.compiler.ast.ContinueStatement) statement);
2387        }
2388        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.CaseStatement) {
2389            return convert((org.eclipse.jdt.internal.compiler.ast.CaseStatement) statement);
2390        }
2391        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.DoStatement) {
2392            return convert((org.eclipse.jdt.internal.compiler.ast.DoStatement) statement);
2393        }
2394        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.EmptyStatement) {
2395            return convert((org.eclipse.jdt.internal.compiler.ast.EmptyStatement) statement);
2396        }
2397        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) {
2398            return convert((org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) statement);
2399        }
2400        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ForStatement) {
2401            return convert((org.eclipse.jdt.internal.compiler.ast.ForStatement) statement);
2402        }
2403        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.IfStatement) {
2404            return convert((org.eclipse.jdt.internal.compiler.ast.IfStatement) statement);
2405        }
2406        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LabeledStatement) {
2407            return convert((org.eclipse.jdt.internal.compiler.ast.LabeledStatement) statement);
2408        }
2409        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ReturnStatement) {
2410            return convert((org.eclipse.jdt.internal.compiler.ast.ReturnStatement) statement);
2411        }
2412        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SwitchStatement) {
2413            return convert((org.eclipse.jdt.internal.compiler.ast.SwitchStatement) statement);
2414        }
2415        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) {
2416            return convert((org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) statement);
2417        }
2418        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ThrowStatement) {
2419            return convert((org.eclipse.jdt.internal.compiler.ast.ThrowStatement) statement);
2420        }
2421        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TryStatement) {
2422            return convert((org.eclipse.jdt.internal.compiler.ast.TryStatement) statement);
2423        }
2424        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
2425            ASTNode result = convert((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) statement);
2426            if (result == null) {
2427                return createFakeEmptyStatement(statement);
2428            }
2429            switch(result.getNodeType()) {
2430                case ASTNode.ENUM_DECLARATION:
2431                    switch(this.ast.apiLevel) {
2432                        case AST.JLS2_INTERNAL :
2433                            return createFakeEmptyStatement(statement);
2434                        case AST.JLS3 :
2435                            final TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
2436                            typeDeclarationStatement.setDeclaration((EnumDeclaration) result);
2437                            AbstractTypeDeclaration typeDecl = typeDeclarationStatement.getDeclaration();
2438                            typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
2439                            return typeDeclarationStatement;
2440                    }
2441                    break;
2442                case ASTNode.ANNOTATION_TYPE_DECLARATION :
2443                    switch(this.ast.apiLevel) {
2444                        case AST.JLS2_INTERNAL :
2445                            return createFakeEmptyStatement(statement);
2446                        case AST.JLS3 :
2447                            TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
2448                            typeDeclarationStatement.setDeclaration((AnnotationTypeDeclaration) result);
2449                            AbstractTypeDeclaration typeDecl = typeDeclarationStatement.getDeclaration();
2450                            typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
2451                            return typeDeclarationStatement;
2452                    }
2453                    break;
2454                default:
2455                    TypeDeclaration typeDeclaration = (TypeDeclaration) result;
2456                    TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
2457                    typeDeclarationStatement.setDeclaration(typeDeclaration);
2458                    switch(this.ast.apiLevel) {
2459                        case AST.JLS2_INTERNAL :
2460                            TypeDeclaration typeDecl = typeDeclarationStatement.internalGetTypeDeclaration();
2461                            typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
2462                            break;
2463                        case AST.JLS3 :
2464                            AbstractTypeDeclaration typeDeclAST3 = typeDeclarationStatement.getDeclaration();
2465                            typeDeclarationStatement.setSourceRange(typeDeclAST3.getStartPosition(), typeDeclAST3.getLength());
2466                            break;
2467                    }
2468                    return typeDeclarationStatement;
2469            }
2470        }
2471        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.WhileStatement) {
2472            return convert((org.eclipse.jdt.internal.compiler.ast.WhileStatement) statement);
2473        }
2474        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
2475            org.eclipse.jdt.internal.compiler.ast.Expression statement2 = (org.eclipse.jdt.internal.compiler.ast.Expression) statement;
2476            final Expression expr = convert(statement2);
2477            final ExpressionStatement stmt = new ExpressionStatement(this.ast);
2478            stmt.setExpression(expr);
2479            int sourceStart = expr.getStartPosition();
2480            int sourceEnd = statement2.statementEnd;
2481            stmt.setSourceRange(sourceStart, sourceEnd - sourceStart + 1);
2482            return stmt;
2483        }
2484        return createFakeEmptyStatement(statement);
2485    }
2486
2487    public Expression convert(org.eclipse.jdt.internal.compiler.ast.StringLiteral expression) {
2488        if (expression instanceof StringLiteralConcatenation) {
2489            return convert((StringLiteralConcatenation) expression);
2490        }
2491        int length = expression.sourceEnd - expression.sourceStart + 1;
2492        int sourceStart = expression.sourceStart;
2493        StringLiteral literal = new StringLiteral(this.ast);
2494        if (this.resolveBindings) {
2495            this.recordNodes(literal, expression);
2496        }
2497        literal.internalSetEscapedValue(new String JavaDoc(this.compilationUnitSource, sourceStart, length));
2498        literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2499        return literal;
2500    }
2501    
2502    public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) {
2503        SwitchStatement switchStatement = new SwitchStatement(this.ast);
2504        switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2505        switchStatement.setExpression(convert(statement.expression));
2506        org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
2507        if (statements != null) {
2508            int statementsLength = statements.length;
2509            for (int i = 0; i < statementsLength; i++) {
2510                if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
2511                    checkAndAddMultipleLocalDeclaration(statements, i, switchStatement.statements());
2512                } else {
2513                    final Statement currentStatement = convert(statements[i]);
2514                    if (currentStatement != null) {
2515                        switchStatement.statements().add(currentStatement);
2516                    }
2517                }
2518            }
2519        }
2520        return switchStatement;
2521    }
2522    
2523    public SynchronizedStatement convert(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement statement) {
2524        SynchronizedStatement synchronizedStatement = new SynchronizedStatement(this.ast);
2525        synchronizedStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2526        synchronizedStatement.setBody(convert(statement.block));
2527        synchronizedStatement.setExpression(convert(statement.expression));
2528        return synchronizedStatement;
2529    }
2530    
2531    public Expression convert(org.eclipse.jdt.internal.compiler.ast.ThisReference reference) {
2532        if (reference.isImplicitThis()) {
2533            // There is no source associated with an implicit this
2534
return null;
2535        } else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
2536            return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference);
2537        } else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) {
2538            return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) reference);
2539        } else {
2540            ThisExpression thisExpression = new ThisExpression(this.ast);
2541            thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
2542            if (this.resolveBindings) {
2543                recordNodes(thisExpression, reference);
2544                recordPendingThisExpressionScopeResolution(thisExpression);
2545            }
2546            return thisExpression;
2547        }
2548    }
2549    
2550    public ThrowStatement convert(org.eclipse.jdt.internal.compiler.ast.ThrowStatement statement) {
2551        final ThrowStatement throwStatement = new ThrowStatement(this.ast);
2552        throwStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2553        throwStatement.setExpression(convert(statement.exception));
2554        return throwStatement;
2555    }
2556        
2557    public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.TrueLiteral expression) {
2558        final BooleanLiteral literal = new BooleanLiteral(this.ast);
2559        literal.setBooleanValue(true);
2560        if (this.resolveBindings) {
2561            this.recordNodes(literal, expression);
2562        }
2563        literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2564        return literal;
2565    }
2566    
2567    public TryStatement convert(org.eclipse.jdt.internal.compiler.ast.TryStatement statement) {
2568        final TryStatement tryStatement = new TryStatement(this.ast);
2569        tryStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2570
2571        tryStatement.setBody(convert(statement.tryBlock));
2572        org.eclipse.jdt.internal.compiler.ast.Argument[] catchArguments = statement.catchArguments;
2573        if (catchArguments != null) {
2574            int catchArgumentsLength = catchArguments.length;
2575            org.eclipse.jdt.internal.compiler.ast.Block[] catchBlocks = statement.catchBlocks;
2576            int start = statement.tryBlock.sourceEnd;
2577            for (int i = 0; i < catchArgumentsLength; i++) {
2578                CatchClause catchClause = new CatchClause(this.ast);
2579                int catchClauseSourceStart = retrieveStartingCatchPosition(start, catchArguments[i].sourceStart);
2580                catchClause.setSourceRange(catchClauseSourceStart, catchBlocks[i].sourceEnd - catchClauseSourceStart + 1);
2581                catchClause.setBody(convert(catchBlocks[i]));
2582                catchClause.setException(convert(catchArguments[i]));
2583                tryStatement.catchClauses().add(catchClause);
2584                start = catchBlocks[i].sourceEnd;
2585            }
2586        }
2587        if (statement.finallyBlock != null) {
2588            tryStatement.setFinally(convert(statement.finallyBlock));
2589        }
2590        return tryStatement;
2591    }
2592
2593    public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
2594        int kind = org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.kind(typeDeclaration.modifiers);
2595        switch (kind) {
2596            case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.ENUM_DECL :
2597                if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
2598                    return null;
2599                } else {
2600                    return convertToEnumDeclaration(typeDeclaration);
2601                }
2602            case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.ANNOTATION_TYPE_DECL :
2603                if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
2604                    return null;
2605                } else {
2606                    return convertToAnnotationDeclaration(typeDeclaration);
2607                }
2608        }
2609
2610        checkCanceled();
2611        TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
2612        if (typeDeclaration.modifiersSourceStart != -1) {
2613            setModifiers(typeDecl, typeDeclaration);
2614        }
2615        typeDecl.setInterface(kind == org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.INTERFACE_DECL);
2616        final SimpleName typeName = new SimpleName(this.ast);
2617        typeName.internalSetIdentifier(new String JavaDoc(typeDeclaration.name));
2618        typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
2619        typeDecl.setName(typeName);
2620        typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
2621        
2622        // need to set the superclass and super interfaces here since we cannot distinguish them at
2623
// the type references level.
2624
if (typeDeclaration.superclass != null) {
2625            switch(this.ast.apiLevel) {
2626                case AST.JLS2_INTERNAL :
2627                    typeDecl.internalSetSuperclass(convert(typeDeclaration.superclass));
2628                    break;
2629                case AST.JLS3 :
2630                    typeDecl.setSuperclassType(convertType(typeDeclaration.superclass));
2631                    break;
2632            }
2633        }
2634        
2635        org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
2636        if (superInterfaces != null) {
2637            switch(this.ast.apiLevel) {
2638                case AST.JLS2_INTERNAL :
2639                    for (int index = 0, length = superInterfaces.length; index < length; index++) {
2640                        typeDecl.internalSuperInterfaces().add(convert(superInterfaces[index]));
2641                    }
2642                    break;
2643                case AST.JLS3 :
2644                    for (int index = 0, length = superInterfaces.length; index < length; index++) {
2645                        typeDecl.superInterfaceTypes().add(convertType(superInterfaces[index]));
2646                    }
2647            }
2648        }
2649        org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = typeDeclaration.typeParameters;
2650        if (typeParameters != null) {
2651            switch(this.ast.apiLevel) {
2652                case AST.JLS2_INTERNAL :
2653                    typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
2654                    break;
2655                case AST.JLS3 :
2656                    for (int index = 0, length = typeParameters.length; index < length; index++) {
2657                        typeDecl.typeParameters().add(convert(typeParameters[index]));
2658                    }
2659            }
2660        }
2661        buildBodyDeclarations(typeDeclaration, typeDecl);
2662        if (this.resolveBindings) {
2663            recordNodes(typeDecl, typeDeclaration);
2664            recordNodes(typeName, typeDeclaration);
2665            typeDecl.resolveBinding();
2666        }
2667        return typeDecl;
2668    }
2669
2670    public TypeParameter convert(org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter) {
2671        final TypeParameter typeParameter2 = new TypeParameter(this.ast);
2672        final SimpleName simpleName = new SimpleName(this.ast);
2673        simpleName.internalSetIdentifier(new String JavaDoc(typeParameter.name));
2674        int start = typeParameter.sourceStart;
2675        int end = typeParameter.sourceEnd;
2676        simpleName.setSourceRange(start, end - start + 1);
2677        typeParameter2.setName(simpleName);
2678        final TypeReference superType = typeParameter.type;
2679        end = typeParameter.declarationSourceEnd;
2680        if (superType != null) {
2681            Type type = convertType(superType);
2682            typeParameter2.typeBounds().add(type);
2683            end = type.getStartPosition() + type.getLength() - 1;
2684        }
2685        TypeReference[] bounds = typeParameter.bounds;
2686        if (bounds != null) {
2687            Type type = null;
2688            for (int index = 0, length = bounds.length; index < length; index++) {
2689                type = convertType(bounds[index]);
2690                typeParameter2.typeBounds().add(type);
2691                end = type.getStartPosition() + type.getLength() - 1;
2692            }
2693        }
2694        start = typeParameter.declarationSourceStart;
2695        end = retrieveClosingAngleBracketPosition(end);
2696        typeParameter2.setSourceRange(start, end - start + 1);
2697        if (this.resolveBindings) {
2698            recordName(simpleName, typeParameter);
2699            recordNodes(typeParameter2, typeParameter);
2700            typeParameter2.resolveBinding();
2701        }
2702        return typeParameter2;
2703    }
2704    
2705    public Name convert(org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference) {
2706        char[][] typeName = typeReference.getTypeName();
2707        int length = typeName.length;
2708        if (length > 1) {
2709            // QualifiedName
2710
org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference;
2711            final long[] positions = qualifiedTypeReference.sourcePositions;
2712            return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
2713        } else {
2714            final SimpleName name = new SimpleName(this.ast);
2715            name.internalSetIdentifier(new String JavaDoc(typeName[0]));
2716            name.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);
2717            name.index = 1;
2718            if (this.resolveBindings) {
2719                recordNodes(name, typeReference);
2720            }
2721            return name;
2722        }
2723    }
2724            
2725    public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.UnaryExpression expression) {
2726        final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
2727        if (this.resolveBindings) {
2728            this.recordNodes(prefixExpression, expression);
2729        }
2730        prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2731        prefixExpression.setOperand(convert(expression.expression));
2732        switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
2733            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
2734                prefixExpression.setOperator(PrefixExpression.Operator.PLUS);
2735                break;
2736            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
2737                prefixExpression.setOperator(PrefixExpression.Operator.MINUS);
2738                break;
2739            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT :
2740                prefixExpression.setOperator(PrefixExpression.Operator.NOT);
2741                break;
2742            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.TWIDDLE :
2743                prefixExpression.setOperator(PrefixExpression.Operator.COMPLEMENT);
2744        }
2745        return prefixExpression;
2746    }
2747    
2748    public WhileStatement convert(org.eclipse.jdt.internal.compiler.ast.WhileStatement statement) {
2749        final WhileStatement whileStatement = new WhileStatement(this.ast);
2750        whileStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2751        whileStatement.setExpression(convert(statement.condition));
2752        final Statement action = convert(statement.action);
2753        if (action == null) return null;
2754        whileStatement.setBody(action);
2755        return whileStatement;
2756    }
2757    
2758    public ImportDeclaration convertImport(org.eclipse.jdt.internal.compiler.ast.ImportReference importReference) {
2759        final ImportDeclaration importDeclaration = new ImportDeclaration(this.ast);
2760        final boolean onDemand = (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0;
2761        final char[][] tokens = importReference.tokens;
2762        int length = importReference.tokens.length;
2763        final long[] positions = importReference.sourcePositions;
2764        if (length > 1) {
2765            importDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
2766        } else {
2767            final SimpleName name = new SimpleName(this.ast);
2768            name.internalSetIdentifier(new String JavaDoc(tokens[0]));
2769            final int start = (int)(positions[0]>>>32);
2770            final int end = (int)(positions[0] & 0xFFFFFFFF);
2771            name.setSourceRange(start, end - start + 1);
2772            name.index = 1;
2773            importDeclaration.setName(name);
2774            if (this.resolveBindings) {
2775                recordNodes(name, importReference);
2776            }
2777        }
2778        importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
2779        importDeclaration.setOnDemand(onDemand);
2780        int modifiers = importReference.modifiers;
2781        if (modifiers != ClassFileConstants.AccDefault) {
2782            switch(this.ast.apiLevel) {
2783                case AST.JLS2_INTERNAL :
2784                    importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
2785                    break;
2786                case AST.JLS3 :
2787                    if (modifiers == ClassFileConstants.AccStatic) {
2788                        importDeclaration.setStatic(true);
2789                    } else {
2790                        importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
2791                    }
2792            }
2793        }
2794        if (this.resolveBindings) {
2795            recordNodes(importDeclaration, importReference);
2796        }
2797        return importDeclaration;
2798    }
2799
2800    public PackageDeclaration convertPackage(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration) {
2801        org.eclipse.jdt.internal.compiler.ast.ImportReference importReference = compilationUnitDeclaration.currentPackage;
2802        final PackageDeclaration packageDeclaration = new PackageDeclaration(this.ast);
2803        final char[][] tokens = importReference.tokens;
2804        final int length = importReference.tokens.length;
2805        long[] positions = importReference.sourcePositions;
2806        if (length > 1) {
2807            packageDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
2808        } else {
2809            final SimpleName name = new SimpleName(this.ast);
2810            name.internalSetIdentifier(new String JavaDoc(tokens[0]));
2811            int start = (int)(positions[0]>>>32);
2812            int end = (int)(positions[length - 1] & 0xFFFFFFFF);
2813            name.setSourceRange(start, end - start + 1);
2814            name.index = 1;
2815            packageDeclaration.setName(name);
2816            if (this.resolveBindings) {
2817                recordNodes(name, compilationUnitDeclaration);
2818            }
2819        }
2820        packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
2821        org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = importReference.annotations;
2822        if (annotations != null) {
2823            switch(this.ast.apiLevel) {
2824                case AST.JLS2_INTERNAL :
2825                    packageDeclaration.setFlags(packageDeclaration.getFlags() & ASTNode.MALFORMED);
2826                    break;
2827                case AST.JLS3 :
2828                    for (int i = 0, max = annotations.length; i < max; i++) {
2829                        packageDeclaration.annotations().add(convert(annotations[i]));
2830                    }
2831            }
2832        }
2833        if (this.resolveBindings) {
2834            recordNodes(packageDeclaration, importReference);
2835        }
2836        // Set javadoc
2837
convert(compilationUnitDeclaration.javadoc, packageDeclaration);
2838        return packageDeclaration;
2839    }
2840    
2841    private EnumDeclaration convertToEnumDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
2842        checkCanceled();
2843        final EnumDeclaration enumDeclaration2 = new EnumDeclaration(this.ast);
2844        setModifiers(enumDeclaration2, typeDeclaration);
2845        final SimpleName typeName = new SimpleName(this.ast);
2846        typeName.internalSetIdentifier(new String JavaDoc(typeDeclaration.name));
2847        typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
2848        enumDeclaration2.setName(typeName);
2849        enumDeclaration2.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
2850        
2851        org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
2852        if (superInterfaces != null) {
2853            for (int index = 0, length = superInterfaces.length; index < length; index++) {
2854                enumDeclaration2.superInterfaceTypes().add(convertType(superInterfaces[index]));
2855            }
2856        }
2857        buildBodyDeclarations(typeDeclaration, enumDeclaration2);
2858        if (this.resolveBindings) {
2859            recordNodes(enumDeclaration2, typeDeclaration);
2860            recordNodes(typeName, typeDeclaration);
2861            enumDeclaration2.resolveBinding();
2862        }
2863        return enumDeclaration2;
2864    }
2865    public Expression convertToExpression(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
2866        if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
2867            return convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
2868        } else {
2869            return null;
2870        }
2871    }
2872
2873    protected FieldDeclaration convertToFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
2874        VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
2875        final FieldDeclaration fieldDeclaration = new FieldDeclaration(this.ast);
2876        fieldDeclaration.fragments().add(variableDeclarationFragment);
2877        if (this.resolveBindings) {
2878            recordNodes(variableDeclarationFragment, fieldDecl);
2879            variableDeclarationFragment.resolveBinding();
2880        }
2881        fieldDeclaration.setSourceRange(fieldDecl.declarationSourceStart, fieldDecl.declarationEnd - fieldDecl.declarationSourceStart + 1);
2882        Type type = convertType(fieldDecl.type);
2883        setTypeForField(fieldDeclaration, type, variableDeclarationFragment.getExtraDimensions());
2884        setModifiers(fieldDeclaration, fieldDecl);
2885        convert(fieldDecl.javadoc, fieldDeclaration);
2886        return fieldDeclaration;
2887    }
2888
2889    public ParenthesizedExpression convertToParenthesizedExpression(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
2890        final ParenthesizedExpression parenthesizedExpression = new ParenthesizedExpression(this.ast);
2891        if (this.resolveBindings) {
2892            recordNodes(parenthesizedExpression, expression);
2893        }
2894        parenthesizedExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2895        adjustSourcePositionsForParent(expression);
2896        trimWhiteSpacesAndComments(expression);
2897        // decrement the number of parenthesis
2898
int numberOfParenthesis = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
2899        expression.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK;
2900        expression.bits |= (numberOfParenthesis - 1) << org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
2901        parenthesizedExpression.setExpression(convert(expression));
2902        return parenthesizedExpression;
2903    }
2904        
2905    public Type convertToType(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
2906        Name name = convert(reference);
2907        final SimpleType type = new SimpleType(this.ast);
2908        type.setName(name);
2909        type.setSourceRange(name.getStartPosition(), name.getLength());
2910        if (this.resolveBindings) {
2911            this.recordNodes(type, reference);
2912        }
2913        return type;
2914    }
2915    
2916    protected VariableDeclarationExpression convertToVariableDeclarationExpression(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
2917        final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
2918        final VariableDeclarationExpression variableDeclarationExpression = new VariableDeclarationExpression(this.ast);
2919        variableDeclarationExpression.fragments().add(variableDeclarationFragment);
2920        if (this.resolveBindings) {
2921            recordNodes(variableDeclarationFragment, localDeclaration);
2922        }
2923        variableDeclarationExpression.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
2924        Type type = convertType(localDeclaration.type);
2925        setTypeForVariableDeclarationExpression(variableDeclarationExpression, type, variableDeclarationFragment.getExtraDimensions());
2926        if (localDeclaration.modifiersSourceStart != -1) {
2927            setModifiers(variableDeclarationExpression, localDeclaration);
2928        }
2929        return variableDeclarationExpression;
2930    }
2931
2932    protected SingleVariableDeclaration convertToSingleVariableDeclaration(LocalDeclaration localDeclaration) {
2933        final SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
2934        setModifiers(variableDecl, localDeclaration);
2935        final SimpleName name = new SimpleName(this.ast);
2936        name.internalSetIdentifier(new String JavaDoc(localDeclaration.name));
2937        int start = localDeclaration.sourceStart;
2938        int nameEnd = localDeclaration.sourceEnd;
2939        name.setSourceRange(start, nameEnd - start + 1);
2940        variableDecl.setName(name);
2941        final int extraDimensions = retrieveExtraDimension(nameEnd + 1, localDeclaration.type.sourceEnd);
2942        variableDecl.setExtraDimensions(extraDimensions);
2943        Type type = convertType(localDeclaration.type);
2944        int typeEnd = type.getStartPosition() + type.getLength() - 1;
2945        int rightEnd = Math.max(typeEnd, localDeclaration.declarationSourceEnd);
2946        /*
2947         * There is extra work to do to set the proper type positions
2948         * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
2949         */

2950        setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
2951        variableDecl.setSourceRange(localDeclaration.declarationSourceStart, rightEnd - localDeclaration.declarationSourceStart + 1);
2952        if (this.resolveBindings) {
2953            recordNodes(name, localDeclaration);
2954            recordNodes(variableDecl, localDeclaration);
2955            variableDecl.resolveBinding();
2956        }
2957        return variableDecl;
2958    }
2959    
2960    protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
2961        final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
2962        final SimpleName name = new SimpleName(this.ast);
2963        name.internalSetIdentifier(new String JavaDoc(fieldDeclaration.name));
2964        name.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.sourceEnd - fieldDeclaration.sourceStart + 1);
2965        variableDeclarationFragment.setName(name);
2966        int start = fieldDeclaration.sourceEnd;
2967        if (fieldDeclaration.initialization != null) {
2968            final Expression expression = convert(fieldDeclaration.initialization);
2969            variableDeclarationFragment.setInitializer(expression);
2970            start = expression.getStartPosition() + expression.getLength();
2971        }
2972        int end = retrievePositionBeforeNextCommaOrSemiColon(start, fieldDeclaration.declarationSourceEnd);
2973        if (end == -1) {
2974            variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.declarationSourceEnd - fieldDeclaration.sourceStart + 1);
2975            variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
2976        } else {
2977            variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, end - fieldDeclaration.sourceStart + 1);
2978        }
2979        variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd ));
2980        if (this.resolveBindings) {
2981            recordNodes(name, fieldDeclaration);
2982            recordNodes(variableDeclarationFragment, fieldDeclaration);
2983            variableDeclarationFragment.resolveBinding();
2984        }
2985        return variableDeclarationFragment;
2986    }
2987
2988    protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
2989        final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
2990        final SimpleName name = new SimpleName(this.ast);
2991        name.internalSetIdentifier(new String JavaDoc(localDeclaration.name));
2992        name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
2993        variableDeclarationFragment.setName(name);
2994        int start = localDeclaration.sourceEnd;
2995        if (localDeclaration.name == RecoveryScanner.FAKE_IDENTIFIER) {
2996            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=199668
2997
// sourceEnd is equals to sourceStart - 1 when the token is empty (token created by the statements recovery).
2998
// sourceStart must be used instead otherwise retrievePositionBeforeNextCommaOrSemiColon() could find the
2999
// previous comma or semicolon.
3000
start = localDeclaration.sourceStart;
3001        }
3002        org.eclipse.jdt.internal.compiler.ast.Expression initialization = localDeclaration.initialization;
3003        boolean hasInitialization = initialization != null;
3004        if (hasInitialization) {
3005            final Expression expression = convert(initialization);
3006            variableDeclarationFragment.setInitializer(expression);
3007            start = expression.getStartPosition() + expression.getLength();
3008        }
3009        int end = retrievePositionBeforeNextCommaOrSemiColon(start, localDeclaration.declarationSourceEnd);
3010        if (end == -1) {
3011            if (hasInitialization) {
3012                // the initiazation sourceEnd is modified during convert(initialization)
3013
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=128961
3014
end = start - 1;
3015            } else {
3016                end = localDeclaration.sourceEnd;
3017            }
3018        }
3019        variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, end - localDeclaration.sourceStart + 1);
3020        variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSourceLength));
3021        if (this.resolveBindings) {
3022            recordNodes(variableDeclarationFragment, localDeclaration);
3023            recordNodes(name, localDeclaration);
3024            variableDeclarationFragment.resolveBinding();
3025        }
3026        return variableDeclarationFragment;
3027    }
3028
3029    protected VariableDeclarationStatement convertToVariableDeclarationStatement(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
3030        final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
3031        final VariableDeclarationStatement variableDeclarationStatement = new VariableDeclarationStatement(this.ast);
3032        variableDeclarationStatement.fragments().add(variableDeclarationFragment);
3033        if (this.resolveBindings) {
3034            recordNodes(variableDeclarationFragment, localDeclaration);
3035        }
3036        variableDeclarationStatement.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
3037        Type type = convertType(localDeclaration.type);
3038        setTypeForVariableDeclarationStatement(variableDeclarationStatement, type, variableDeclarationFragment.getExtraDimensions());
3039        if (localDeclaration.modifiersSourceStart != -1) {
3040            setModifiers(variableDeclarationStatement, localDeclaration);
3041        }
3042        return variableDeclarationStatement;
3043    }
3044
3045    public Type convertType(TypeReference typeReference) {
3046        if (typeReference instanceof Wildcard) {
3047            final Wildcard wildcard = (Wildcard) typeReference;
3048            final WildcardType wildcardType = new WildcardType(this.ast);
3049            if (wildcard.bound != null) {
3050                final Type bound = convertType(wildcard.bound);
3051                wildcardType.setBound(bound, wildcard.kind == Wildcard.EXTENDS);
3052                int start = wildcard.sourceStart;
3053                wildcardType.setSourceRange(start, bound.getStartPosition() + bound.getLength() - start);
3054            } else {
3055                final int start = wildcard.sourceStart;
3056                final int end = wildcard.sourceEnd;
3057                wildcardType.setSourceRange(start, end - start + 1);
3058            }
3059            if (this.resolveBindings) {
3060                recordNodes(wildcardType, typeReference);
3061            }
3062            return wildcardType;
3063        }
3064        Type type = null;
3065        int sourceStart = -1;
3066        int length = 0;
3067        int dimensions = typeReference.dimensions();
3068        if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) {
3069            // this is either an ArrayTypeReference or a SingleTypeReference
3070
char[] name = ((org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) typeReference).getTypeName()[0];
3071            sourceStart = typeReference.sourceStart;
3072            length = typeReference.sourceEnd - typeReference.sourceStart + 1;
3073            // need to find out if this is an array type of primitive types or not
3074
if (isPrimitiveType(name)) {
3075                int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
3076                if (end == -1) {
3077                    end = sourceStart + length - 1;
3078                }
3079                final PrimitiveType primitiveType = new PrimitiveType(this.ast);
3080                primitiveType.setPrimitiveTypeCode(getPrimitiveTypeCode(name));
3081                primitiveType.setSourceRange(sourceStart, end - sourceStart + 1);
3082                type = primitiveType;
3083            } else if (typeReference instanceof ParameterizedSingleTypeReference) {
3084                ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) typeReference;
3085                final SimpleName simpleName = new SimpleName(this.ast);
3086                simpleName.internalSetIdentifier(new String JavaDoc(name));
3087                int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
3088                if (end == -1) {
3089                    end = sourceStart + length - 1;
3090                }
3091                simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
3092                switch(this.ast.apiLevel) {
3093                    case AST.JLS2_INTERNAL :
3094                        SimpleType simpleType = new SimpleType(this.ast);
3095                        simpleType.setName(simpleName);
3096                        simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
3097                        simpleType.setSourceRange(sourceStart, end - sourceStart + 1);
3098                        type = simpleType;
3099                        if (this.resolveBindings) {
3100                            this.recordNodes(simpleName, typeReference);
3101                        }
3102                        break;
3103                    case AST.JLS3 :
3104                        simpleType = new SimpleType(this.ast);
3105                        simpleType.setName(simpleName);
3106                        simpleType.setSourceRange(simpleName.getStartPosition(), simpleName.getLength());
3107                        final ParameterizedType parameterizedType = new ParameterizedType(this.ast);
3108                        parameterizedType.setType(simpleType);
3109                        type = parameterizedType;
3110                        TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
3111                        if (typeArguments != null) {
3112                            Type type2 = null;
3113                            for (int i = 0, max = typeArguments.length; i < max; i++) {
3114                                type2 = convertType(typeArguments[i]);
3115                                ((ParameterizedType) type).typeArguments().add(type2);
3116                                end = type2.getStartPosition() + type2.getLength() - 1;
3117                            }
3118                            end = retrieveClosingAngleBracketPosition(end + 1);
3119                            type.setSourceRange(sourceStart, end - sourceStart + 1);
3120                        } else {
3121                            type.setSourceRange(sourceStart, end - sourceStart + 1);
3122                        }
3123                        if (this.resolveBindings) {
3124                            this.recordNodes(simpleName, typeReference);
3125                            this.recordNodes(simpleType, typeReference);
3126                        }
3127                }
3128            } else {
3129                final SimpleName simpleName = new SimpleName(this.ast);
3130                simpleName.internalSetIdentifier(new String JavaDoc(name));
3131                // we need to search for the starting position of the first brace in order to set the proper length
3132
// PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759
3133
int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
3134                if (end == -1) {
3135                    end = sourceStart + length - 1;
3136                }
3137                simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
3138                final SimpleType simpleType = new SimpleType(this.ast);
3139                simpleType.setName(simpleName);
3140                type = simpleType;
3141                type.setSourceRange(sourceStart, end - sourceStart + 1);
3142                type = simpleType;
3143                if (this.resolveBindings) {
3144                    this.recordNodes(simpleName, typeReference);
3145                }
3146            }
3147            if (dimensions != 0) {
3148                type = this.ast.newArrayType(type, dimensions);
3149                type.setSourceRange(sourceStart, length);
3150                ArrayType subarrayType = (ArrayType) type;
3151                int index = dimensions - 1;
3152                while (index > 0) {
3153                    subarrayType = (ArrayType) subarrayType.getComponentType();
3154                    int end = retrieveProperRightBracketPosition(index, sourceStart);
3155                    subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
3156                    index--;
3157                }
3158                if (this.resolveBindings) {
3159                    // store keys for inner types
3160
completeRecord((ArrayType) type, typeReference);
3161                }
3162            }
3163        } else {
3164            if (typeReference instanceof ParameterizedQualifiedTypeReference) {
3165                ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) typeReference;
3166                char[][] tokens = parameterizedQualifiedTypeReference.tokens;
3167                TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
3168                long[] positions = parameterizedQualifiedTypeReference.sourcePositions;
3169                sourceStart = (int)(positions[0]>>>32);
3170                switch(this.ast.apiLevel) {
3171                    case AST.JLS2_INTERNAL : {
3172                            char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
3173                            int nameLength = name.length;
3174                            sourceStart = (int)(positions[0]>>>32);
3175                            length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
3176                            Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
3177                            final SimpleType simpleType = new SimpleType(this.ast);
3178                            simpleType.setName(qualifiedName);
3179                            simpleType.setSourceRange(sourceStart, length);
3180                            type = simpleType;
3181                        }
3182                        break;
3183                    case AST.JLS3 :
3184                        if (typeArguments != null) {
3185                            int numberOfEnclosingType = 0;
3186                            int startingIndex = 0;
3187                            int endingIndex = 0;
3188                            for (int i = 0, max = typeArguments.length; i < max; i++) {
3189                                if (typeArguments[i] != null) {
3190                                    numberOfEnclosingType++;
3191                                } else if (numberOfEnclosingType == 0) {
3192                                    endingIndex++;
3193                                }
3194                            }
3195                            Name name = null;
3196                            if (endingIndex - startingIndex == 0) {
3197                                final SimpleName simpleName = new SimpleName(this.ast);
3198                                simpleName.internalSetIdentifier(new String JavaDoc(tokens[startingIndex]));
3199                                recordPendingNameScopeResolution(simpleName);
3200                                int start = (int)(positions[startingIndex]>>>32);
3201                                int end = (int) positions[startingIndex];
3202                                simpleName.setSourceRange(start, end - start + 1);
3203                                simpleName.index = 1;
3204                                name = simpleName;
3205                                if (this.resolveBindings) {
3206                                    recordNodes(simpleName, typeReference);
3207                                }
3208                            } else {
3209                                name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, endingIndex, typeReference);
3210                            }
3211                            SimpleType simpleType = new SimpleType(this.ast);
3212                            simpleType.setName(name);
3213                            int start = (int)(positions[startingIndex]>>>32);
3214                            int end = (int) positions[endingIndex];
3215                            simpleType.setSourceRange(start, end - start + 1);
3216                            ParameterizedType parameterizedType = new ParameterizedType(this.ast);
3217                            parameterizedType.setType(simpleType);
3218                            if (this.resolveBindings) {
3219                                recordNodes(simpleType, typeReference);
3220                                recordNodes(parameterizedType, typeReference);
3221                            }
3222                            start = simpleType.getStartPosition();
3223                            end = start + simpleType.getLength() - 1;
3224                            for (int i = 0, max = typeArguments[endingIndex].length; i < max; i++) {
3225                                final Type type2 = convertType(typeArguments[endingIndex][i]);
3226                                parameterizedType.typeArguments().add(type2);
3227                                end = type2.getStartPosition() + type2.getLength() - 1;
3228                            }
3229                            int indexOfEnclosingType = 1;
3230                            parameterizedType.index = indexOfEnclosingType;
3231                            end = retrieveClosingAngleBracketPosition(end + 1);
3232                            length = end + 1;
3233                            parameterizedType.setSourceRange(start, end - start + 1);
3234                            startingIndex = endingIndex + 1;
3235                            Type currentType = parameterizedType;
3236                            while(startingIndex < typeArguments.length) {
3237                                SimpleName simpleName = new SimpleName(this.ast);
3238                                simpleName.internalSetIdentifier(new String JavaDoc(tokens[startingIndex]));
3239                                simpleName.index = startingIndex + 1;
3240                                start = (int)(positions[startingIndex]>>>32);
3241                                end = (int) positions[startingIndex];
3242                                simpleName.setSourceRange(start, end - start + 1);
3243                                recordPendingNameScopeResolution(simpleName);
3244                                QualifiedType qualifiedType = new QualifiedType(this.ast);
3245                                qualifiedType.setQualifier(currentType);
3246                                qualifiedType.setName(simpleName);
3247                                if (this.resolveBindings) {
3248                                    recordNodes(simpleName, typeReference);
3249                                    recordNodes(qualifiedType, typeReference);
3250                                }
3251                                start = currentType.getStartPosition();
3252                                end = simpleName.getStartPosition() + simpleName.getLength() - 1;
3253                                qualifiedType.setSourceRange(start, end - start + 1);
3254                                indexOfEnclosingType++;
3255                                if (typeArguments[startingIndex] != null) {
3256                                    qualifiedType.index = indexOfEnclosingType;
3257                                    ParameterizedType parameterizedType2 = new ParameterizedType(this.ast);
3258                                    parameterizedType2.setType(qualifiedType);
3259                                    parameterizedType2.index = indexOfEnclosingType;
3260                                   if (this.resolveBindings) {
3261                                        recordNodes(parameterizedType2, typeReference);
3262                                    }
3263                                    for (int i = 0, max = typeArguments[startingIndex].length; i < max; i++) {
3264                                        final Type type2 = convertType(typeArguments[startingIndex][i]);
3265                                        parameterizedType2.typeArguments().add(type2);
3266                                        end = type2.getStartPosition() + type2.getLength() - 1;
3267                                    }
3268                                    end = retrieveClosingAngleBracketPosition(end + 1);
3269                                    length = end + 1;
3270                                    parameterizedType2.setSourceRange(start, end - start + 1);
3271                                    currentType = parameterizedType2;
3272                                } else {
3273                                    currentType = qualifiedType;
3274                                    qualifiedType.index = indexOfEnclosingType;
3275                                }
3276                                startingIndex++;
3277                            }
3278                            if (this.resolveBindings) {
3279                                this.recordNodes(currentType, typeReference);
3280                            }
3281                            type = currentType;
3282                            length -= sourceStart;
3283                        }
3284                }
3285            } else {
3286                char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
3287                int nameLength = name.length;
3288                long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
3289                sourceStart = (int)(positions[0]>>>32);
3290                length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
3291                final Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
3292                final SimpleType simpleType = new SimpleType(this.ast);
3293                simpleType.setName(qualifiedName);
3294                type = simpleType;
3295                type.setSourceRange(sourceStart, length);
3296            }
3297
3298            length = typeReference.sourceEnd - sourceStart + 1;
3299            if (dimensions != 0) {
3300                type = this.ast.newArrayType(type, dimensions);
3301                if (this.resolveBindings) {
3302                    completeRecord((ArrayType) type, typeReference);
3303                }
3304                int end = retrieveEndOfDimensionsPosition(sourceStart+length, this.compilationUnitSourceLength);
3305                if (end != -1) {
3306                    type.setSourceRange(sourceStart, end - sourceStart + 1);
3307                } else {
3308                    type.setSourceRange(sourceStart, length);
3309                }
3310                ArrayType subarrayType = (ArrayType) type;
3311                int index = dimensions - 1;
3312                while (index > 0) {
3313                    subarrayType = (ArrayType) subarrayType.getComponentType();
3314                    end = retrieveProperRightBracketPosition(index, sourceStart);
3315                    subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
3316                    index--;
3317                }
3318            }
3319        }
3320        if (this.resolveBindings) {
3321            this.recordNodes(type, typeReference);
3322        }
3323        return type;
3324    }
3325
3326    protected Comment createComment(int[] positions) {
3327        // Create comment node
3328
Comment comment = null;
3329        int start = positions[0];
3330        int end = positions[1];
3331        if (positions[1]>0) { // Javadoc comments have positive end position
3332
Javadoc docComment = this.docParser.parse(positions);
3333            if (docComment == null) return null;
3334            comment = docComment;
3335        } else {
3336            end = -end;
3337            if (positions[0] == 0) { // we cannot know without testing chars again
3338
if (this.docParser.scanner.source[1] == '/') {
3339                    comment = new LineComment(this.ast);
3340                } else {
3341                    comment = new BlockComment(this.ast);
3342                }
3343            }
3344            else if (positions[0]>0) { // Block comment have positive start position
3345
comment = new BlockComment(this.ast);
3346            } else { // Line comment have negative start and end position
3347
start = -start;
3348                comment = new LineComment(this.ast);
3349            }
3350            comment.setSourceRange(start, end - start);
3351        }
3352        return comment;
3353    }
3354    
3355    protected Statement createFakeEmptyStatement(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
3356        if (statement == null) return null;
3357        EmptyStatement emptyStatement = new EmptyStatement(this.ast);
3358        emptyStatement.setFlags(emptyStatement.getFlags() | ASTNode.MALFORMED);
3359        int start = statement.sourceStart;
3360        int end = statement.sourceEnd;
3361        emptyStatement.setSourceRange(start, end - start + 1);
3362        return emptyStatement;
3363    }
3364    /**
3365     * @return a new modifier
3366     */

3367    private Modifier createModifier(ModifierKeyword keyword) {
3368        final Modifier modifier = new Modifier(this.ast);
3369        modifier.setKeyword(keyword);
3370        int start = this.scanner.getCurrentTokenStartPosition();
3371        int end = this.scanner.getCurrentTokenEndPosition();
3372        modifier.setSourceRange(start, end - start + 1);
3373        return modifier;
3374    }
3375    
3376    protected InfixExpression.Operator getOperatorFor(int operatorID) {
3377        switch (operatorID) {
3378            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
3379                return InfixExpression.Operator.EQUALS;
3380            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
3381                return InfixExpression.Operator.LESS_EQUALS;
3382            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
3383                return InfixExpression.Operator.GREATER_EQUALS;
3384            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
3385                return InfixExpression.Operator.NOT_EQUALS;
3386            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
3387                return InfixExpression.Operator.LEFT_SHIFT;
3388            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
3389                return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
3390            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
3391                return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
3392            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR_OR :
3393                return InfixExpression.Operator.CONDITIONAL_OR;
3394            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND_AND :
3395                return InfixExpression.Operator.CONDITIONAL_AND;
3396            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
3397                return InfixExpression.Operator.PLUS;
3398            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
3399                return InfixExpression.Operator.MINUS;
3400            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
3401                return InfixExpression.Operator.REMAINDER;
3402            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
3403                return InfixExpression.Operator.XOR;
3404            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
3405                return InfixExpression.Operator.AND;
3406            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
3407                return InfixExpression.Operator.TIMES;
3408            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
3409                return InfixExpression.Operator.OR;
3410            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
3411                return InfixExpression.Operator.DIVIDE;
3412            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER :
3413                return InfixExpression.Operator.GREATER;
3414            case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS :
3415                return InfixExpression.Operator.LESS;
3416        }
3417        return null;
3418    }
3419    
3420    protected PrimitiveType.Code getPrimitiveTypeCode(char[] name) {
3421        switch(name[0]) {
3422            case 'i' :
3423                if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
3424                    return PrimitiveType.INT;
3425                }
3426                break;
3427            case 'l' :
3428                if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
3429                    return PrimitiveType.LONG;
3430                }
3431                break;
3432            case 'd' :
3433                if (name.length == 6
3434                     && name[1] == 'o'
3435                     && name[2] == 'u'
3436                     && name[3] == 'b'
3437                     && name[4] == 'l'
3438                     && name[5] == 'e') {
3439                    return PrimitiveType.DOUBLE;
3440                }
3441                break;
3442            case 'f' :
3443                if (name.length == 5
3444                     && name[1] == 'l'
3445                     && name[2] == 'o'
3446                     && name[3] == 'a'
3447                     && name[4] == 't') {
3448                    return PrimitiveType.FLOAT;
3449                }
3450                break;
3451            case 'b' :
3452                if (name.length == 4
3453                     && name[1] == 'y'
3454                     && name[2] == 't'
3455                     && name[3] == 'e') {
3456                    return PrimitiveType.BYTE;
3457                } else
3458                    if (name.length == 7
3459                         && name[1] == 'o'
3460                         && name[2] == 'o'
3461                         && name[3] == 'l'
3462                         && name[4] == 'e'
3463                         && name[5] == 'a'
3464                         && name[6] == 'n') {
3465                    return PrimitiveType.BOOLEAN;
3466                }
3467                break;
3468            case 'c' :
3469                if (name.length == 4
3470                     && name[1] == 'h'
3471                     && name[2] == 'a'
3472                     && name[3] == 'r') {
3473                    return PrimitiveType.CHAR;
3474                }
3475                break;
3476            case 's' :
3477                if (name.length == 5
3478                     && name[1] == 'h'
3479                     && name[2] == 'o'
3480                     && name[3] == 'r'
3481                     && name[4] == 't') {
3482                    return PrimitiveType.SHORT;
3483                }
3484                break;
3485            case 'v' :
3486                if (name.length == 4
3487                     && name[1] == 'o'
3488                     && name[2] == 'i'
3489                     && name[3] == 'd') {
3490                    return PrimitiveType.VOID;
3491                }
3492        }
3493        return null; // cannot be reached
3494
}
3495    
3496    protected boolean isPrimitiveType(char[] name) {
3497        switch(name[0]) {
3498            case 'i' :
3499                if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
3500                    return true;
3501                }
3502                return false;
3503            case 'l' :
3504                if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
3505                    return true;
3506                }
3507                return false;
3508            case 'd' :
3509                if (name.length == 6
3510                     && name[1] == 'o'
3511                     && name[2] == 'u'
3512                     && name[3] == 'b'
3513                     && name[4] == 'l'
3514                     && name[5] == 'e') {
3515                    return true;
3516                }
3517                return false;
3518            case 'f' :
3519                if (name.length == 5
3520                     && name[1] == 'l'
3521                     && name[2] == 'o'
3522                     && name[3] == 'a'
3523                     && name[4] == 't') {
3524                    return true;
3525                }
3526                return false;
3527            case 'b' :
3528                if (name.length == 4
3529                     && name[1] == 'y'
3530                     && name[2] == 't'
3531                     && name[3] == 'e') {
3532                    return true;
3533                } else
3534                    if (name.length == 7
3535                         && name[1] == 'o'
3536                         && name[2] == 'o'
3537                         && name[3] == 'l'
3538                         && name[4] == 'e'
3539                         && name[5] == 'a'
3540                         && name[6] == 'n') {
3541                    return true;
3542                }
3543                return false;
3544            case 'c' :
3545                if (name.length == 4
3546                     && name[1] == 'h'
3547                     && name[2] == 'a'
3548                     && name[3] == 'r') {
3549                    return true;
3550                }
3551                return false;
3552            case 's' :
3553                if (name.length == 5
3554                     && name[1] == 'h'
3555                     && name[2] == 'o'
3556                     && name[3] == 'r'
3557                     && name[4] == 't') {
3558                    return true;
3559                }
3560                return false;
3561            case 'v' :
3562                if (name.length == 4
3563                     && name[1] == 'o'
3564                     && name[2] == 'i'
3565                     && name[3] == 'd') {
3566                    return true;
3567                }
3568                return false;
3569        }
3570        return false;
3571    }
3572    
3573    private void lookupForScopes() {
3574        if (this.pendingNameScopeResolution != null) {
3575            for (Iterator JavaDoc iterator = this.pendingNameScopeResolution.iterator(); iterator.hasNext(); ) {
3576                Name name = (Name) iterator.next();
3577                this.ast.getBindingResolver().recordScope(name, lookupScope(name));
3578            }
3579        }
3580        if (this.pendingThisExpressionScopeResolution != null) {
3581            for (Iterator JavaDoc iterator = this.pendingThisExpressionScopeResolution.iterator(); iterator.hasNext(); ) {
3582                ThisExpression thisExpression = (ThisExpression) iterator.next();
3583                this.ast.getBindingResolver().recordScope(thisExpression, lookupScope(thisExpression));
3584            }
3585        }
3586        
3587    }
3588    
3589    private BlockScope lookupScope(ASTNode node) {
3590        ASTNode currentNode = node;
3591        while(currentNode != null
3592            &&!(currentNode instanceof MethodDeclaration)
3593            && !(currentNode instanceof Initializer)
3594            && !(currentNode instanceof FieldDeclaration)
3595            && !(currentNode instanceof AbstractTypeDeclaration)) {
3596            currentNode = currentNode.getParent();
3597        }
3598        if (currentNode == null) {
3599            return null;
3600        }
3601        if (currentNode instanceof Initializer) {
3602            Initializer initializer = (Initializer) currentNode;
3603            while(!(currentNode instanceof AbstractTypeDeclaration)) {
3604                currentNode = currentNode.getParent();
3605            }
3606            if (currentNode instanceof TypeDeclaration
3607                || currentNode instanceof EnumDeclaration
3608                || currentNode instanceof AnnotationTypeDeclaration) {
3609                org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3610                if ((initializer.getModifiers() & Modifier.STATIC) != 0) {
3611                    return typeDecl.staticInitializerScope;
3612                } else {
3613                    return typeDecl.initializerScope;
3614                }
3615            }
3616        } else if (currentNode instanceof FieldDeclaration) {
3617            FieldDeclaration fieldDeclaration = (FieldDeclaration) currentNode;
3618            while(!(currentNode instanceof AbstractTypeDeclaration)) {
3619                currentNode = currentNode.getParent();
3620            }
3621            if (currentNode instanceof AbstractTypeDeclaration) {
3622                org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3623                if ((fieldDeclaration.getModifiers() & Modifier.STATIC) != 0) {
3624                    return typeDecl.staticInitializerScope;
3625                } else {
3626                    return typeDecl.initializerScope;
3627                }
3628            }
3629        } else if (currentNode instanceof AbstractTypeDeclaration) {
3630            org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3631            return typeDecl.initializerScope;
3632        }
3633        AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3634        return abstractMethodDeclaration.scope;
3635    }
3636
3637    protected void recordName(Name name, org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode) {
3638        if (compilerNode != null) {
3639            recordNodes(name, compilerNode);
3640            if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3641                org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) compilerNode;
3642                if (name.isQualifiedName()) {
3643                    SimpleName simpleName = null;
3644                    while (name.isQualifiedName()) {
3645                        simpleName = ((QualifiedName) name).getName();
3646                        recordNodes(simpleName, typeRef);
3647                        name = ((QualifiedName) name).getQualifier();
3648                        recordNodes(name, typeRef);
3649                    }
3650                }
3651            }
3652        }
3653    }
3654    
3655    protected void recordNodes(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
3656        this.ast.getBindingResolver().store(node, oldASTNode);
3657    }
3658    
3659    protected void recordNodes(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, TagElement tagElement) {
3660        Iterator JavaDoc fragments = tagElement.fragments().listIterator();
3661        while (fragments.hasNext()) {
3662            ASTNode node = (ASTNode) fragments.next();
3663            if (node.getNodeType() == ASTNode.MEMBER_REF) {
3664                MemberRef memberRef = (MemberRef) node;
3665                Name name = memberRef.getName();
3666                // get compiler node and record nodes
3667
int start = name.getStartPosition();
3668                org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
3669                if (compilerNode!= null) {
3670                    recordNodes(name, compilerNode);
3671                    recordNodes(node, compilerNode);
3672                }
3673                // Replace qualifier to have all nodes recorded
3674
if (memberRef.getQualifier() != null) {
3675                    org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
3676                    if (compilerNode instanceof JavadocFieldReference) {
3677                        org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocFieldReference)compilerNode).receiver;
3678                        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3679                            typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
3680                        }
3681                    }
3682                    else if (compilerNode instanceof JavadocMessageSend) {
3683                        org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocMessageSend)compilerNode).receiver;
3684                        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3685                            typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
3686                        }
3687                    }
3688                    if (typeRef != null) {
3689                        recordName(memberRef.getQualifier(), typeRef);
3690                    }
3691                }
3692            } else if (node.getNodeType() == ASTNode.METHOD_REF) {
3693                MethodRef methodRef = (MethodRef) node;
3694                Name name = methodRef.getName();
3695                // get method name start position
3696
int start = methodRef.getStartPosition();
3697                this.scanner.resetTo(start, start + name.getStartPosition()+name.getLength());
3698                int token;
3699                try {
3700                    nextToken: while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF && token != TerminalTokens.TokenNameLPAREN) {
3701                        if (token == TerminalTokens.TokenNameERROR && this.scanner.currentCharacter == '#') {
3702                            start = this.scanner.getCurrentTokenEndPosition()+1;
3703                            break nextToken;
3704                        }
3705                    }
3706                }
3707                catch(InvalidInputException e) {
3708                    // ignore
3709
}
3710                // get compiler node and record nodes
3711
org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
3712                // record nodes
3713
if (compilerNode != null) {
3714                    recordNodes(methodRef, compilerNode);
3715                    // get type ref
3716
org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
3717                    if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression) {
3718                        typeRef = ((org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression)compilerNode).type;
3719                        if (typeRef != null) recordNodes(name, compilerNode);
3720                    }
3721                    else if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend) {
3722                        org.eclipse.jdt.internal.compiler.ast.Expression expression = ((org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend)compilerNode).receiver;
3723                        if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3724                            typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
3725                        }
3726                        // TODO (frederic) remove following line to fix bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=62650
3727
recordNodes(name, compilerNode);
3728                    }
3729                    // record name and qualifier
3730
if (typeRef != null && methodRef.getQualifier() != null) {
3731                        recordName(methodRef.getQualifier(), typeRef);
3732                    }
3733                }
3734                // Resolve parameters
3735
Iterator JavaDoc parameters = methodRef.parameters().listIterator();
3736                while (parameters.hasNext()) {
3737                    MethodRefParameter param = (MethodRefParameter) parameters.next();
3738                    org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) javadoc.getNodeStartingAt(param.getStartPosition());
3739                    if (expression != null) {
3740                        recordNodes(param, expression);
3741                        if (expression instanceof JavadocArgumentExpression) {
3742                            JavadocArgumentExpression argExpr = (JavadocArgumentExpression) expression;
3743                            org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = argExpr.argument.type;
3744                            if (this.ast.apiLevel >= AST.JLS3) param.setVarargs(argExpr.argument.isVarArgs());
3745                            recordNodes(param.getType(), typeRef);
3746                            if (param.getType().isSimpleType()) {
3747                                recordName(((SimpleType)param.getType()).getName(), typeRef);
3748                            } else if (param.getType().isArrayType()) {
3749                                Type type = ((ArrayType) param.getType()).getElementType();
3750                                recordNodes(type, typeRef);
3751                                if (type.isSimpleType()) {
3752                                    recordName(((SimpleType)type).getName(), typeRef);
3753                                }
3754                            }
3755                        }
3756                    }
3757                }
3758            } else if (node.getNodeType() == ASTNode.SIMPLE_NAME ||
3759                    node.getNodeType() == ASTNode.QUALIFIED_NAME) {
3760                org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(node.getStartPosition());
3761                recordName((Name) node, compilerNode);
3762            } else if (node.getNodeType() == ASTNode.TAG_ELEMENT) {
3763                // resolve member and method references binding
3764
recordNodes(javadoc, (TagElement) node);
3765            }
3766        }
3767    }
3768    
3769    protected void recordPendingNameScopeResolution(Name name) {
3770        if (this.pendingNameScopeResolution == null) {
3771            this.pendingNameScopeResolution = new HashSet JavaDoc();
3772        }
3773        this.pendingNameScopeResolution.add(name);
3774    }
3775    
3776    protected void recordPendingThisExpressionScopeResolution(ThisExpression thisExpression) {
3777        if (this.pendingThisExpressionScopeResolution == null) {
3778            this.pendingThisExpressionScopeResolution = new HashSet JavaDoc();
3779        }
3780        this.pendingThisExpressionScopeResolution.add(thisExpression);
3781    }
3782    
3783    /**
3784     * Remove whitespaces and comments before and after the expression.
3785     */

3786    private void trimWhiteSpacesAndComments(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
3787        int start = expression.sourceStart;
3788        int end = expression.sourceEnd;
3789        int token;
3790        int trimLeftPosition = expression.sourceStart;
3791        int trimRightPosition = expression.sourceEnd;
3792        boolean first = true;
3793        Scanner removeBlankScanner = this.ast.scanner;
3794        try {
3795            removeBlankScanner.setSource(this.compilationUnitSource);
3796            removeBlankScanner.resetTo(start, end);
3797            while (true) {
3798                token = removeBlankScanner.getNextToken();
3799                switch (token) {
3800                    case TerminalTokens.TokenNameCOMMENT_JAVADOC :
3801                    case TerminalTokens.TokenNameCOMMENT_LINE :
3802                    case TerminalTokens.TokenNameCOMMENT_BLOCK :
3803                        if (first) {
3804                            trimLeftPosition = removeBlankScanner.currentPosition;
3805                        }
3806                        break;
3807                    case TerminalTokens.TokenNameWHITESPACE :
3808                        if (first) {
3809                            trimLeftPosition = removeBlankScanner.currentPosition;
3810                        }
3811                        break;
3812                    case TerminalTokens.TokenNameEOF :
3813                        expression.sourceStart = trimLeftPosition;
3814                        expression.sourceEnd = trimRightPosition;
3815                        return;
3816                    default :
3817                        /*
3818                         * if we find something else than a whitespace or a comment,
3819                         * then we reset the trimRigthPosition to the expression
3820                         * source end.
3821                         */

3822                        trimRightPosition = removeBlankScanner.currentPosition - 1;
3823                        first = false;
3824                }
3825            }
3826        } catch (InvalidInputException e){
3827            // ignore
3828
}
3829    }
3830
3831    /**
3832     * Remove potential trailing comment by settings the source end on the closing parenthesis
3833     */

3834    protected void removeLeadingAndTrailingCommentsFromLiteral(ASTNode node) {
3835        int start = node.getStartPosition();
3836        this.scanner.resetTo(start, start + node.getLength());
3837        int token;
3838        int startPosition = -1;
3839        try {
3840            while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3841                switch(token) {
3842                    case TerminalTokens.TokenNameIntegerLiteral :
3843                    case TerminalTokens.TokenNameFloatingPointLiteral :
3844                    case TerminalTokens.TokenNameLongLiteral :
3845                    case TerminalTokens.TokenNameDoubleLiteral :
3846                    case TerminalTokens.TokenNameCharacterLiteral :
3847                        if (startPosition == -1) {
3848                            startPosition = this.scanner.startPosition;
3849                        }
3850                        int end = this.scanner.currentPosition;
3851                        node.setSourceRange(startPosition, end - startPosition);
3852                        return;
3853                    case TerminalTokens.TokenNameMINUS :
3854                        startPosition = this.scanner.startPosition;
3855                        break;
3856                }
3857            }
3858        } catch(InvalidInputException e) {
3859            // ignore
3860
}
3861    }
3862    
3863    /**
3864     * Remove potential trailing comment by settings the source end on the closing parenthesis
3865     */

3866    protected void removeTrailingCommentFromExpressionEndingWithAParen(ASTNode node) {
3867        int start = node.getStartPosition();
3868        this.scanner.resetTo(start, start + node.getLength());
3869        int token;
3870        int parenCounter = 0;
3871        try {
3872            while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3873                switch(token) {
3874                    case TerminalTokens.TokenNameLPAREN :
3875                        parenCounter++;
3876                        break;
3877                    case TerminalTokens.TokenNameRPAREN :
3878                        parenCounter--;
3879                        if (parenCounter == 0) {
3880                            int end = this.scanner.currentPosition - 1;
3881                            node.setSourceRange(start, end - start + 1);
3882                        }
3883                }
3884            }
3885        } catch(InvalidInputException e) {
3886            // ignore
3887
}
3888    }
3889
3890    /**
3891     * This method is used to retrieve the end position of the block.
3892     * @return int the dimension found, -1 if none
3893     */

3894    protected int retrieveClosingAngleBracketPosition(int start) {
3895        this.scanner.resetTo(start, this.compilationUnitSourceLength);
3896        this.scanner.returnOnlyGreater = true;
3897        try {
3898            int token;
3899            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3900                switch(token) {
3901                    case TerminalTokens.TokenNameGREATER:
3902                        return this.scanner.currentPosition - 1;
3903                    default:
3904                        return start;
3905                }
3906            }
3907        } catch(InvalidInputException e) {
3908            // ignore
3909
}
3910        this.scanner.returnOnlyGreater = false;
3911        return start;
3912    }
3913
3914    /**
3915     * This method is used to set the right end position for expression
3916     * statement. The actual AST nodes don't include the trailing semicolon.
3917     * This method fixes the length of the corresponding node.
3918     */

3919    protected void retrieveColonPosition(ASTNode node) {
3920        int start = node.getStartPosition();
3921        int length = node.getLength();
3922        int end = start + length;
3923        this.scanner.resetTo(end, this.compilationUnitSourceLength);
3924        try {
3925            int token;
3926            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3927                switch(token) {
3928                    case TerminalTokens.TokenNameCOLON:
3929                        node.setSourceRange(start, this.scanner.currentPosition - start);
3930                        return;
3931                }
3932            }
3933        } catch(InvalidInputException e) {
3934            // ignore
3935
}
3936    }
3937    /**
3938     * This method is used to retrieve the start position of the Ellipsis
3939     */

3940    protected int retrieveEllipsisStartPosition(int start, int end) {
3941        this.scanner.resetTo(start, end);
3942        try {
3943            int token;
3944            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3945                switch(token) {
3946                    case TerminalTokens.TokenNameELLIPSIS:
3947                        return this.scanner.startPosition - 1;
3948                }
3949            }
3950        } catch(InvalidInputException e) {
3951            // ignore
3952
}
3953        return -1;
3954    
3955    }
3956    /**
3957     * This method is used to retrieve the end position of the block.
3958     * @return int the dimension found, -1 if none
3959     */

3960    protected int retrieveEndBlockPosition(int start, int end) {
3961        this.scanner.resetTo(start, end);
3962        int count = 0;
3963        try {
3964            int token;
3965            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3966                switch(token) {
3967                    case TerminalTokens.TokenNameLBRACE://110
3968
count++;
3969                        break;
3970                    case TerminalTokens.TokenNameRBRACE://95
3971
count--;
3972                        if (count == 0) {
3973                            return this.scanner.currentPosition - 1;
3974                        }
3975                }
3976            }
3977        } catch(InvalidInputException e) {
3978            // ignore
3979
}
3980        return -1;
3981    }
3982
3983    protected int retrieveSemiColonPosition(Expression node) {
3984        int start = node.getStartPosition();
3985        int length = node.getLength();
3986        int end = start + length;
3987        this.scanner.resetTo(end, this.compilationUnitSourceLength);
3988        try {
3989            int token;
3990            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3991                switch(token) {
3992                    case TerminalTokens.TokenNameSEMICOLON:
3993                        return this.scanner.currentPosition - 1;
3994                }
3995            }
3996        } catch(InvalidInputException e) {
3997            // ignore
3998
}
3999        return -1;
4000    }
4001
4002    /**
4003     * This method is used to retrieve the ending position for a type declaration when the dimension is right after the type
4004     * name.
4005     * For example:
4006     * int[] i; => return 5, but int i[] => return -1;
4007     * @return int the dimension found
4008     */

4009    protected int retrieveEndOfDimensionsPosition(int start, int end) {
4010        this.scanner.resetTo(start, end);
4011        int foundPosition = -1;
4012        try {
4013            int token;
4014            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4015                switch(token) {
4016                    case TerminalTokens.TokenNameLBRACKET:
4017                    case TerminalTokens.TokenNameCOMMENT_BLOCK:
4018                    case TerminalTokens.TokenNameCOMMENT_JAVADOC:
4019                    case TerminalTokens.TokenNameCOMMENT_LINE:
4020                        break;
4021                    case TerminalTokens.TokenNameRBRACKET://166
4022
foundPosition = this.scanner.currentPosition - 1;
4023                        break;
4024                    default:
4025                        return foundPosition;
4026                }
4027            }
4028        } catch(InvalidInputException e) {
4029            // ignore
4030
}
4031        return foundPosition;
4032    }
4033
4034    /**
4035     * This method is used to retrieve the position just before the left bracket.
4036     * @return int the dimension found, -1 if none
4037     */

4038    protected int retrieveEndOfElementTypeNamePosition(int start, int end) {
4039        this.scanner.resetTo(start, end);
4040        try {
4041            int token;
4042            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4043                switch(token) {
4044                    case TerminalTokens.TokenNameIdentifier:
4045                    case TerminalTokens.TokenNamebyte:
4046                    case TerminalTokens.TokenNamechar:
4047                    case TerminalTokens.TokenNamedouble:
4048                    case TerminalTokens.TokenNamefloat:
4049                    case TerminalTokens.TokenNameint:
4050                    case TerminalTokens.TokenNamelong:
4051                    case TerminalTokens.TokenNameshort:
4052                    case TerminalTokens.TokenNameboolean:
4053                        return this.scanner.currentPosition - 1;
4054                }
4055            }
4056        } catch(InvalidInputException e) {
4057            // ignore
4058
}
4059        return -1;
4060    }
4061
4062    /**
4063     * This method is used to retrieve the position after the right parenthesis.
4064     * @return int the position found
4065     */

4066    protected int retrieveEndOfRightParenthesisPosition(int start, int end) {
4067        this.scanner.resetTo(start, end);
4068        try {
4069            int token;
4070            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4071                switch(token) {
4072                    case TerminalTokens.TokenNameRPAREN:
4073                        return this.scanner.currentPosition;
4074                }
4075            }
4076        } catch(InvalidInputException e) {
4077            // ignore
4078
}
4079        return -1;
4080    }
4081
4082    /**
4083     * This method is used to retrieve the array dimension declared after the
4084     * name of a local or a field declaration.
4085     * For example:
4086     * int i, j[] = null, k[][] = {{}};
4087     * It should return 0 for i, 1 for j and 2 for k.
4088     * @return int the dimension found
4089     */

4090    protected int retrieveExtraDimension(int start, int end) {
4091        this.scanner.resetTo(start, end);
4092        int dimensions = 0;
4093        try {
4094            int token;
4095            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4096                switch(token) {
4097                    case TerminalTokens.TokenNameLBRACKET:
4098                    case TerminalTokens.TokenNameCOMMENT_BLOCK:
4099                    case TerminalTokens.TokenNameCOMMENT_JAVADOC:
4100                    case TerminalTokens.TokenNameCOMMENT_LINE:
4101                        break;
4102                    case TerminalTokens.TokenNameRBRACKET://166
4103
dimensions++;
4104                        break;
4105                    default:
4106                        return dimensions;
4107                }
4108            }
4109        } catch(InvalidInputException e) {
4110            // ignore
4111
}
4112        return dimensions;
4113    }
4114
4115    protected void retrieveIdentifierAndSetPositions(int start, int end, Name name) {
4116        this.scanner.resetTo(start, end);
4117        int token;
4118        try {
4119            while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4120                if (token == TerminalTokens.TokenNameIdentifier) {
4121                    int startName = this.scanner.startPosition;
4122                    int endName = this.scanner.currentPosition - 1;
4123                    name.setSourceRange(startName, endName - startName + 1);
4124                    return;
4125                }
4126            }
4127        } catch(InvalidInputException e) {
4128            // ignore
4129
}
4130    }
4131    
4132    /**
4133     * This method is used to retrieve the start position of the block.
4134     * @return int the dimension found, -1 if none
4135     */

4136    protected int retrieveIdentifierEndPosition(int start, int end) {
4137        this.scanner.resetTo(start, end);
4138        try {
4139            int token;
4140            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4141                switch(token) {
4142                    case TerminalTokens.TokenNameIdentifier://110
4143
return this.scanner.getCurrentTokenEndPosition();
4144                }
4145            }
4146        } catch(InvalidInputException e) {
4147            // ignore
4148
}
4149        return -1;
4150    }
4151
4152    /**
4153     * This method is used to retrieve position before the next comma or semi-colon.
4154     * @return int the position found.
4155     */

4156    protected int retrievePositionBeforeNextCommaOrSemiColon(int start, int end) {
4157        this.scanner.resetTo(start, end);
4158        try {
4159            int token;
4160            int balance = 0;
4161            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4162                switch(token) {
4163                    case TerminalTokens.TokenNameLBRACE :
4164                        balance++;
4165                        break;
4166                    case TerminalTokens.TokenNameRBRACE :
4167                        balance --;
4168                        break;
4169                    case TerminalTokens.TokenNameCOMMA :
4170                        if (balance == 0) return this.scanner.startPosition - 1;
4171                        break;
4172                    case TerminalTokens.TokenNameSEMICOLON :
4173                        return this.scanner.startPosition - 1;
4174                }
4175            }
4176        } catch(InvalidInputException e) {
4177            // ignore
4178
}
4179        return -1;
4180    }
4181
4182    protected int retrieveProperRightBracketPosition(int bracketNumber, int start) {
4183        this.scanner.resetTo(start, this.compilationUnitSourceLength);
4184        try {
4185            int token, count = 0;
4186            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4187                switch(token) {
4188                    case TerminalTokens.TokenNameRBRACKET:
4189                        count++;
4190                        if (count == bracketNumber) {
4191                            return this.scanner.currentPosition - 1;
4192                        }
4193                }
4194            }
4195        } catch(InvalidInputException e) {
4196            // ignore
4197
}
4198        return -1;
4199    }
4200
4201    /**
4202     * This method is used to retrieve position before the next right brace or semi-colon.
4203     * @return int the position found.
4204     */

4205    protected int retrieveRightBraceOrSemiColonPosition(int start, int end) {
4206        this.scanner.resetTo(start, end);
4207        try {
4208            int token;
4209            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4210                switch(token) {
4211                    case TerminalTokens.TokenNameRBRACE :
4212                        return this.scanner.currentPosition - 1;
4213                    case TerminalTokens.TokenNameSEMICOLON :
4214                        return this.scanner.currentPosition - 1;
4215                }
4216            }
4217        } catch(InvalidInputException e) {
4218            // ignore
4219
}
4220        return -1;
4221    }
4222
4223    /**
4224     * This method is used to retrieve position before the next right brace or semi-colon.
4225     * @return int the position found.
4226     */

4227    protected int retrieveRightBrace(int start, int end) {
4228        this.scanner.resetTo(start, end);
4229        try {
4230            int token;
4231            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4232                switch(token) {
4233                    case TerminalTokens.TokenNameRBRACE :
4234                        return this.scanner.currentPosition - 1;
4235                }
4236            }
4237        } catch(InvalidInputException e) {
4238            // ignore
4239
}
4240        return -1;
4241    }
4242    
4243    /**
4244     * This method is used to retrieve the position of the right bracket.
4245     * @return int the dimension found, -1 if none
4246     */

4247    protected int retrieveRightBracketPosition(int start, int end) {
4248        this.scanner.resetTo(start, end);
4249        try {
4250            int token;
4251            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4252                switch(token) {
4253                    case TerminalTokens.TokenNameRBRACKET:
4254                        return this.scanner.currentPosition - 1;
4255                }
4256            }
4257        } catch(InvalidInputException e) {
4258            // ignore
4259
}
4260        return -1;
4261    }
4262
4263    /**
4264     * This method is used to retrieve the start position of the block.
4265     * @return int the dimension found, -1 if none
4266     */

4267    protected int retrieveStartBlockPosition(int start, int end) {
4268        this.scanner.resetTo(start, end);
4269        try {
4270            int token;
4271            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4272                switch(token) {
4273                    case TerminalTokens.TokenNameLBRACE://110
4274
return this.scanner.startPosition;
4275                }
4276            }
4277        } catch(InvalidInputException e) {
4278            // ignore
4279
}
4280        return -1;
4281    }
4282
4283    /**
4284     * This method is used to retrieve the starting position of the catch keyword.
4285     * @return int the dimension found, -1 if none
4286     */

4287    protected int retrieveStartingCatchPosition(int start, int end) {
4288        this.scanner.resetTo(start, end);
4289        try {
4290            int token;
4291            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4292                switch(token) {
4293                    case TerminalTokens.TokenNamecatch://225
4294
return this.scanner.startPosition;
4295                }
4296            }
4297        } catch(InvalidInputException e) {
4298            // ignore
4299
}
4300        return -1;
4301    }
4302    
4303    public void setAST(AST ast) {
4304        this.ast = ast;
4305        this.docParser = new DocCommentParser(this.ast, this.scanner, this.insideComments);
4306    }
4307
4308    protected void setModifiers(AnnotationTypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
4309        this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
4310        this.setModifiers(typeDecl, typeDeclaration.annotations);
4311    }
4312    
4313    protected void setModifiers(AnnotationTypeMemberDeclaration annotationTypeMemberDecl, org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
4314        this.scanner.resetTo(annotationTypeMemberDeclaration.declarationSourceStart, annotationTypeMemberDeclaration.sourceStart);
4315        this.setModifiers(annotationTypeMemberDecl, annotationTypeMemberDeclaration.annotations);
4316    }
4317
4318    /**
4319     * @param bodyDeclaration
4320     */

4321    protected void setModifiers(BodyDeclaration bodyDeclaration, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) {
4322        try {
4323            int token;
4324            int indexInAnnotations = 0;
4325            while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4326                IExtendedModifier modifier = null;
4327                switch(token) {
4328                    case TerminalTokens.TokenNameabstract:
4329                        modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4330                        break;
4331                    case TerminalTokens.TokenNamepublic:
4332                        modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4333                        break;
4334                    case TerminalTokens.TokenNamestatic:
4335                        modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4336                        break;
4337                    case TerminalTokens.TokenNameprotected:
4338                        modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4339                        break;
4340                    case TerminalTokens.TokenNameprivate:
4341                        modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4342                        break;
4343                    case TerminalTokens.TokenNamefinal:
4344                        modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4345                        break;
4346                    case TerminalTokens.TokenNamenative:
4347                        modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4348                        break;
4349                    case TerminalTokens.TokenNamesynchronized:
4350                        modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4351                        break;
4352                    case TerminalTokens.TokenNametransient:
4353                        modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4354                        break;
4355                    case TerminalTokens.TokenNamevolatile:
4356                        modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4357                        break;
4358                    case TerminalTokens.TokenNamestrictfp:
4359                        modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4360                        break;
4361                    case TerminalTokens.TokenNameAT :
4362                        // we have an annotation
4363
if (annotations != null && indexInAnnotations < annotations.length) {
4364                            org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4365                            modifier = convert(annotation);
4366                            this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4367                        }
4368                        break;
4369                    case TerminalTokens.TokenNameCOMMENT_BLOCK :
4370                    case TerminalTokens.TokenNameCOMMENT_LINE :
4371                    case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4372                        break;
4373                    default :
4374                        return;
4375                }
4376                if (modifier != null) {
4377                    bodyDeclaration.modifiers().add(modifier);
4378                }
4379            }
4380        } catch(InvalidInputException e) {
4381            // ignore
4382
}
4383    }
4384    
4385    
4386    protected void setModifiers(EnumDeclaration enumDeclaration, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enumDeclaration2) {
4387        this.scanner.resetTo(enumDeclaration2.declarationSourceStart, enumDeclaration2.sourceStart);
4388        this.setModifiers(enumDeclaration, enumDeclaration2.annotations);
4389    }
4390    
4391    protected void setModifiers(EnumConstantDeclaration enumConstantDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
4392        switch(this.ast.apiLevel) {
4393            case AST.JLS2_INTERNAL :
4394                enumConstantDeclaration.internalSetModifiers(fieldDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
4395                if (fieldDeclaration.annotations != null) {
4396                    enumConstantDeclaration.setFlags(enumConstantDeclaration.getFlags() | ASTNode.MALFORMED);
4397                }
4398                break;
4399            case AST.JLS3 :
4400                this.scanner.resetTo(fieldDeclaration.declarationSourceStart, fieldDeclaration.sourceStart);
4401                this.setModifiers(enumConstantDeclaration, fieldDeclaration.annotations);
4402        }
4403    }
4404    
4405    /**
4406     * @param fieldDeclaration
4407     * @param fieldDecl
4408     */

4409    protected void setModifiers(FieldDeclaration fieldDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
4410        switch(this.ast.apiLevel) {
4411            case AST.JLS2_INTERNAL :
4412                fieldDeclaration.internalSetModifiers(fieldDecl.modifiers & ExtraCompilerModifiers.AccJustFlag);
4413                if (fieldDecl.annotations != null) {
4414                    fieldDeclaration.setFlags(fieldDeclaration.getFlags() | ASTNode.MALFORMED);
4415                }
4416                break;
4417            case AST.JLS3 :
4418                this.scanner.resetTo(fieldDecl.declarationSourceStart, fieldDecl.sourceStart);
4419                this.setModifiers(fieldDeclaration, fieldDecl.annotations);
4420        }
4421    }
4422    
4423    /**
4424     * @param initializer
4425     * @param oldInitializer
4426     */

4427    protected void setModifiers(Initializer initializer, org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer) {
4428        switch(this.ast.apiLevel) {
4429            case AST.JLS2_INTERNAL:
4430                initializer.internalSetModifiers(oldInitializer.modifiers & ExtraCompilerModifiers.AccJustFlag);
4431                if (oldInitializer.annotations != null) {
4432                    initializer.setFlags(initializer.getFlags() | ASTNode.MALFORMED);
4433                }
4434                break;
4435            case AST.JLS3 :
4436                this.scanner.resetTo(oldInitializer.declarationSourceStart, oldInitializer.bodyStart);
4437                this.setModifiers(initializer, oldInitializer.annotations);
4438        }
4439    }
4440    /**
4441     * @param methodDecl
4442     * @param methodDeclaration
4443     */

4444    protected void setModifiers(MethodDeclaration methodDecl, AbstractMethodDeclaration methodDeclaration) {
4445        switch(this.ast.apiLevel) {
4446            case AST.JLS2_INTERNAL :
4447                methodDecl.internalSetModifiers(methodDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
4448                if (methodDeclaration.annotations != null) {
4449                    methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
4450                }
4451                break;
4452            case AST.JLS3 :
4453                this.scanner.resetTo(methodDeclaration.declarationSourceStart, methodDeclaration.sourceStart);
4454                this.setModifiers(methodDecl, methodDeclaration.annotations);
4455        }
4456    }
4457
4458    /**
4459     * @param variableDecl
4460     * @param argument
4461     */

4462    protected void setModifiers(SingleVariableDeclaration variableDecl, Argument argument) {
4463        switch(this.ast.apiLevel) {
4464            case AST.JLS2_INTERNAL :
4465                variableDecl.internalSetModifiers(argument.modifiers & ExtraCompilerModifiers.AccJustFlag);
4466                if (argument.annotations != null) {
4467                    variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
4468                }
4469                break;
4470            case AST.JLS3 :
4471                this.scanner.resetTo(argument.declarationSourceStart, argument.sourceStart);
4472                org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = argument.annotations;
4473                int indexInAnnotations = 0;
4474                try {
4475                    int token;
4476                    while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4477                        IExtendedModifier modifier = null;
4478                        switch(token) {
4479                            case TerminalTokens.TokenNameabstract:
4480                                modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4481                                break;
4482                            case TerminalTokens.TokenNamepublic:
4483                                modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4484                                break;
4485                            case TerminalTokens.TokenNamestatic:
4486                                modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4487                                break;
4488                            case TerminalTokens.TokenNameprotected:
4489                                modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4490                                break;
4491                            case TerminalTokens.TokenNameprivate:
4492                                modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4493                                break;
4494                            case TerminalTokens.TokenNamefinal:
4495                                modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4496                                break;
4497                            case TerminalTokens.TokenNamenative:
4498                                modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4499                                break;
4500                            case TerminalTokens.TokenNamesynchronized:
4501                                modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4502                                break;
4503                            case TerminalTokens.TokenNametransient:
4504                                modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4505                                break;
4506                            case TerminalTokens.TokenNamevolatile:
4507                                modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4508                                break;
4509                            case TerminalTokens.TokenNamestrictfp:
4510                                modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4511                                break;
4512                            case TerminalTokens.TokenNameAT :
4513                                // we have an annotation
4514
if (annotations != null && indexInAnnotations < annotations.length) {
4515                                    org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4516                                    modifier = convert(annotation);
4517                                    this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4518                                }
4519                                break;
4520                            case TerminalTokens.TokenNameCOMMENT_BLOCK :
4521                            case TerminalTokens.TokenNameCOMMENT_LINE :
4522                            case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4523                                break;
4524                            default :
4525                                return;
4526                        }
4527                        if (modifier != null) {
4528                            variableDecl.modifiers().add(modifier);
4529                        }
4530                    }
4531                } catch(InvalidInputException e) {
4532                    // ignore
4533
}
4534        }
4535    }
4536    
4537    protected void setModifiers(SingleVariableDeclaration variableDecl, LocalDeclaration localDeclaration) {
4538        switch(this.ast.apiLevel) {
4539        case AST.JLS2_INTERNAL :
4540            variableDecl.internalSetModifiers(localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
4541            if (localDeclaration.annotations != null) {
4542                variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
4543            }
4544            break;
4545        case AST.JLS3 :
4546            this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
4547            org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
4548            int indexInAnnotations = 0;
4549            try {
4550                int token;
4551                while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4552                    IExtendedModifier modifier = null;
4553                    switch(token) {
4554                        case TerminalTokens.TokenNameabstract:
4555                            modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4556                            break;
4557                        case TerminalTokens.TokenNamepublic:
4558                            modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4559                            break;
4560                        case TerminalTokens.TokenNamestatic:
4561                            modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4562                            break;
4563                        case TerminalTokens.TokenNameprotected:
4564                            modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4565                            break;
4566                        case TerminalTokens.TokenNameprivate:
4567                            modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4568                            break;
4569                        case TerminalTokens.TokenNamefinal:
4570                            modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4571                            break;
4572                        case TerminalTokens.TokenNamenative:
4573                            modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4574                            break;
4575                        case TerminalTokens.TokenNamesynchronized:
4576                            modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4577                            break;
4578                        case TerminalTokens.TokenNametransient:
4579                            modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4580                            break;
4581                        case TerminalTokens.TokenNamevolatile:
4582                            modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4583                            break;
4584                        case TerminalTokens.TokenNamestrictfp:
4585                            modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4586                            break;
4587                        case TerminalTokens.TokenNameAT :
4588                            // we have an annotation
4589
if (annotations != null && indexInAnnotations < annotations.length) {
4590                                org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4591                                modifier = convert(annotation);
4592                                this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4593                            }
4594                            break;
4595                        case TerminalTokens.TokenNameCOMMENT_BLOCK :
4596                        case TerminalTokens.TokenNameCOMMENT_LINE :
4597                        case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4598                            break;
4599                        default :
4600                            return;
4601                    }
4602                    if (modifier != null) {
4603                        variableDecl.modifiers().add(modifier);
4604                    }
4605                }
4606            } catch(InvalidInputException e) {
4607                // ignore
4608
}
4609        }
4610    }
4611
4612    /**
4613     * @param typeDecl
4614     * @param typeDeclaration
4615     */

4616    protected void setModifiers(TypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
4617        switch(this.ast.apiLevel) {
4618            case AST.JLS2_INTERNAL :
4619                int modifiers = typeDeclaration.modifiers;
4620                modifiers &= ~ClassFileConstants.AccInterface; // remove AccInterface flags
4621
modifiers &= ExtraCompilerModifiers.AccJustFlag;
4622                typeDecl.internalSetModifiers(modifiers);
4623                if (typeDeclaration.annotations != null) {
4624                    typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
4625                }
4626                break;
4627            case AST.JLS3 :
4628                this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
4629                this.setModifiers(typeDecl, typeDeclaration.annotations);
4630        }
4631    }
4632    
4633    /**
4634     * @param variableDeclarationExpression
4635     * @param localDeclaration
4636     */

4637    protected void setModifiers(VariableDeclarationExpression variableDeclarationExpression, LocalDeclaration localDeclaration) {
4638        switch(this.ast.apiLevel) {
4639            case AST.JLS2_INTERNAL :
4640                int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
4641                modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
4642                variableDeclarationExpression.internalSetModifiers(modifiers);
4643                if (localDeclaration.annotations != null) {
4644                    variableDeclarationExpression.setFlags(variableDeclarationExpression.getFlags() | ASTNode.MALFORMED);
4645                }
4646                break;
4647            case AST.JLS3 :
4648                this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
4649                org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
4650                int indexInAnnotations = 0;
4651                try {
4652                    int token;
4653                    while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4654                        IExtendedModifier modifier = null;
4655                        switch(token) {
4656                            case TerminalTokens.TokenNameabstract:
4657                                modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4658                                break;
4659                            case TerminalTokens.TokenNamepublic:
4660                                modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4661                                break;
4662                            case TerminalTokens.TokenNamestatic:
4663                                modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4664                                break;
4665                            case TerminalTokens.TokenNameprotected:
4666                                modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4667                                break;
4668                            case TerminalTokens.TokenNameprivate:
4669                                modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4670                                break;
4671                            case TerminalTokens.TokenNamefinal:
4672                                modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4673                                break;
4674                            case TerminalTokens.TokenNamenative:
4675                                modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4676                                break;
4677                            case TerminalTokens.TokenNamesynchronized:
4678                                modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4679                                break;
4680                            case TerminalTokens.TokenNametransient:
4681                                modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4682                                break;
4683                            case TerminalTokens.TokenNamevolatile:
4684                                modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4685                                break;
4686                            case TerminalTokens.TokenNamestrictfp:
4687                                modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4688                                break;
4689                            case TerminalTokens.TokenNameAT :
4690                                // we have an annotation
4691
if (annotations != null && indexInAnnotations < annotations.length) {
4692                                    org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4693                                    modifier = convert(annotation);
4694                                    this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4695                                }
4696                                break;
4697                            case TerminalTokens.TokenNameCOMMENT_BLOCK :
4698                            case TerminalTokens.TokenNameCOMMENT_LINE :
4699                            case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4700                                break;
4701                            default :
4702                                return;
4703                        }
4704                        if (modifier != null) {
4705                            variableDeclarationExpression.modifiers().add(modifier);
4706                        }
4707                    }
4708                } catch(InvalidInputException e) {
4709                    // ignore
4710
}
4711        }
4712    }
4713
4714    /**
4715     * @param variableDeclarationStatement
4716     * @param localDeclaration
4717     */

4718    protected void setModifiers(VariableDeclarationStatement variableDeclarationStatement, LocalDeclaration localDeclaration) {
4719        switch(this.ast.apiLevel) {
4720            case AST.JLS2_INTERNAL :
4721                int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
4722                modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
4723                variableDeclarationStatement.internalSetModifiers(modifiers);
4724                if (localDeclaration.annotations != null) {
4725                    variableDeclarationStatement.setFlags(variableDeclarationStatement.getFlags() | ASTNode.MALFORMED);
4726                }
4727                break;
4728            case AST.JLS3 :
4729                this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
4730                org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
4731                int indexInAnnotations = 0;
4732                try {
4733                    int token;
4734                    while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4735                        IExtendedModifier modifier = null;
4736                        switch(token) {
4737                            case TerminalTokens.TokenNameabstract:
4738                                modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4739                                break;
4740                            case TerminalTokens.TokenNamepublic:
4741                                modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4742                                break;
4743                            case TerminalTokens.TokenNamestatic:
4744                                modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4745                                break;
4746                            case TerminalTokens.TokenNameprotected:
4747                                modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4748                                break;
4749                            case TerminalTokens.TokenNameprivate:
4750                                modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4751                                break;
4752                            case TerminalTokens.TokenNamefinal:
4753                                modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4754                                break;
4755                            case TerminalTokens.TokenNamenative:
4756                                modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4757                                break;
4758                            case TerminalTokens.TokenNamesynchronized:
4759                                modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4760                                break;
4761                            case TerminalTokens.TokenNametransient:
4762                                modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4763                                break;
4764                            case TerminalTokens.TokenNamevolatile:
4765                                modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4766                                break;
4767                            case TerminalTokens.TokenNamestrictfp:
4768                                modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4769                                break;
4770                            case TerminalTokens.TokenNameAT :
4771                                // we have an annotation
4772
if (annotations != null && indexInAnnotations < annotations.length) {
4773                                    org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4774                                    modifier = convert(annotation);
4775                                    this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4776                                }
4777                                break;
4778                            case TerminalTokens.TokenNameCOMMENT_BLOCK :
4779                            case TerminalTokens.TokenNameCOMMENT_LINE :
4780                            case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4781                                break;
4782                            default :
4783                                return;
4784                        }
4785                        if (modifier != null) {
4786                            variableDeclarationStatement.modifiers().add(modifier);
4787                        }
4788                    }
4789                } catch(InvalidInputException e) {
4790                    // ignore
4791
}
4792        }
4793    }
4794
4795    protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
4796        int length = typeName.length;
4797        final SimpleName firstToken = new SimpleName(this.ast);
4798        firstToken.internalSetIdentifier(new String JavaDoc(typeName[0]));
4799        firstToken.index = 1;
4800        int start0 = (int)(positions[0]>>>32);
4801        int start = start0;
4802        int end = (int)(positions[0] & 0xFFFFFFFF);
4803        firstToken.setSourceRange(start, end - start + 1);
4804        final SimpleName secondToken = new SimpleName(this.ast);
4805        secondToken.internalSetIdentifier(new String JavaDoc(typeName[1]));
4806        secondToken.index = 2;
4807        start = (int)(positions[1]>>>32);
4808        end = (int)(positions[1] & 0xFFFFFFFF);
4809        secondToken.setSourceRange(start, end - start + 1);
4810        QualifiedName qualifiedName = new QualifiedName(this.ast);
4811        qualifiedName.setQualifier(firstToken);
4812        qualifiedName.setName(secondToken);
4813        if (this.resolveBindings) {
4814            recordNodes(qualifiedName, node);
4815            recordPendingNameScopeResolution(qualifiedName);
4816            recordNodes(firstToken, node);
4817            recordNodes(secondToken, node);
4818            recordPendingNameScopeResolution(firstToken);
4819            recordPendingNameScopeResolution(secondToken);
4820        }
4821        qualifiedName.index = 2;
4822        qualifiedName.setSourceRange(start0, end - start0 + 1);
4823        SimpleName newPart = null;
4824        for (int i = 2; i < length; i++) {
4825            newPart = new SimpleName(this.ast);
4826            newPart.internalSetIdentifier(new String JavaDoc(typeName[i]));
4827            newPart.index = i + 1;
4828            start = (int)(positions[i]>>>32);
4829            end = (int)(positions[i] & 0xFFFFFFFF);
4830            newPart.setSourceRange(start, end - start + 1);
4831            QualifiedName qualifiedName2 = new QualifiedName(this.ast);
4832            qualifiedName2.setQualifier(qualifiedName);
4833            qualifiedName2.setName(newPart);
4834            qualifiedName = qualifiedName2;
4835            qualifiedName.index = newPart.index;
4836            qualifiedName.setSourceRange(start0, end - start0 + 1);
4837            if (this.resolveBindings) {
4838                recordNodes(qualifiedName, node);
4839                recordNodes(newPart, node);
4840                recordPendingNameScopeResolution(qualifiedName);
4841                recordPendingNameScopeResolution(newPart);
4842            }
4843        }
4844        QualifiedName name = qualifiedName;
4845        if (this.resolveBindings) {
4846            recordNodes(name, node);
4847            recordPendingNameScopeResolution(name);
4848        }
4849        return name;
4850    }
4851    
4852    protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int endingIndex, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
4853        int length = endingIndex + 1;
4854        final SimpleName firstToken = new SimpleName(this.ast);
4855        firstToken.internalSetIdentifier(new String JavaDoc(typeName[0]));
4856        firstToken.index = 1;
4857        int start0 = (int)(positions[0]>>>32);
4858        int start = start0;
4859        int end = (int) positions[0];
4860        firstToken.setSourceRange(start, end - start + 1);
4861        final SimpleName secondToken = new SimpleName(this.ast);
4862        secondToken.internalSetIdentifier(new String JavaDoc(typeName[1]));
4863        secondToken.index = 2;
4864        start = (int)(positions[1]>>>32);
4865        end = (int) positions[1];
4866        secondToken.setSourceRange(start, end - start + 1);
4867        QualifiedName qualifiedName = new QualifiedName(this.ast);
4868        qualifiedName.setQualifier(firstToken);
4869        qualifiedName.setName(secondToken);
4870        if (this.resolveBindings) {
4871            recordNodes(qualifiedName, node);
4872            recordPendingNameScopeResolution(qualifiedName);
4873            recordNodes(firstToken, node);
4874            recordNodes(secondToken, node);
4875            recordPendingNameScopeResolution(firstToken);
4876            recordPendingNameScopeResolution(secondToken);
4877        }
4878        qualifiedName.index = 2;
4879        qualifiedName.setSourceRange(start0, end - start0 + 1);
4880        SimpleName newPart = null;
4881        for (int i = 2; i < length; i++) {
4882            newPart = new SimpleName(this.ast);
4883            newPart.internalSetIdentifier(new String JavaDoc(typeName[i]));
4884            newPart.index = i + 1;
4885            start = (int)(positions[i]>>>32);
4886            end = (int) positions[i];
4887            newPart.setSourceRange(start, end - start + 1);
4888            QualifiedName qualifiedName2 = new QualifiedName(this.ast);
4889            qualifiedName2.setQualifier(qualifiedName);
4890            qualifiedName2.setName(newPart);
4891            qualifiedName = qualifiedName2;
4892            qualifiedName.index = newPart.index;
4893            qualifiedName.setSourceRange(start0, end - start0 + 1);
4894            if (this.resolveBindings) {
4895                recordNodes(qualifiedName, node);
4896                recordNodes(newPart, node);
4897                recordPendingNameScopeResolution(qualifiedName);
4898                recordPendingNameScopeResolution(newPart);
4899            }
4900        }
4901        if (newPart == null && this.resolveBindings) {
4902            recordNodes(qualifiedName, node);
4903            recordPendingNameScopeResolution(qualifiedName);
4904        }
4905        return qualifiedName;
4906    }
4907    
4908    protected void setTypeNameForAnnotation(org.eclipse.jdt.internal.compiler.ast.Annotation compilerAnnotation, Annotation annotation) {
4909        TypeReference typeReference = compilerAnnotation.type;
4910        if (typeReference instanceof QualifiedTypeReference) {
4911            QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
4912            char[][] tokens = qualifiedTypeReference.tokens;
4913            long[] positions = qualifiedTypeReference.sourcePositions;
4914            // QualifiedName
4915
annotation.setTypeName(setQualifiedNameNameAndSourceRanges(tokens, positions, typeReference));
4916        } else {
4917            SingleTypeReference singleTypeReference = (SingleTypeReference) typeReference;
4918            final SimpleName name = new SimpleName(this.ast);
4919            name.internalSetIdentifier(new String JavaDoc(singleTypeReference.token));
4920            int start = singleTypeReference.sourceStart;
4921            int end = singleTypeReference.sourceEnd;
4922            name.setSourceRange(start, end - start + 1);
4923            name.index = 1;
4924            annotation.setTypeName(name);
4925            if (this.resolveBindings) {
4926                recordNodes(name, typeReference);
4927            }
4928        }
4929    }
4930    
4931    protected void setTypeForField(FieldDeclaration fieldDeclaration, Type type, int extraDimension) {
4932        if (extraDimension != 0) {
4933            if (type.isArrayType()) {
4934                ArrayType arrayType = (ArrayType) type;
4935                int remainingDimensions = arrayType.getDimensions() - extraDimension;
4936                if (remainingDimensions == 0) {
4937                    // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
4938
Type elementType = arrayType.getElementType();
4939                    // cut the child loose from its parent (without creating garbage)
4940
elementType.setParent(null, null);
4941                    this.ast.getBindingResolver().updateKey(type, elementType);
4942                    fieldDeclaration.setType(elementType);
4943                } else {
4944                    int start = type.getStartPosition();
4945                    ArrayType subarrayType = arrayType;
4946                    int index = extraDimension;
4947                    while (index > 0) {
4948                        subarrayType = (ArrayType) subarrayType.getComponentType();
4949                        index--;
4950                    }
4951                    int end = retrieveProperRightBracketPosition(remainingDimensions, start);
4952                    subarrayType.setSourceRange(start, end - start + 1);
4953                    // cut the child loose from its parent (without creating garbage)
4954
subarrayType.setParent(null, null);
4955                    fieldDeclaration.setType(subarrayType);
4956                    updateInnerPositions(subarrayType, remainingDimensions);
4957                    this.ast.getBindingResolver().updateKey(type, subarrayType);
4958                }
4959            } else {
4960                fieldDeclaration.setType(type);
4961            }
4962        } else {
4963            if (type.isArrayType()) {
4964                // update positions of the component types of the array type
4965
int dimensions = ((ArrayType) type).getDimensions();
4966                updateInnerPositions(type, dimensions);
4967            }
4968            fieldDeclaration.setType(type);
4969        }
4970    }
4971    
4972    protected void setTypeForMethodDeclaration(MethodDeclaration methodDeclaration, Type type, int extraDimension) {
4973        if (extraDimension != 0) {
4974            if (type.isArrayType()) {
4975                ArrayType arrayType = (ArrayType) type;
4976                int remainingDimensions = arrayType.getDimensions() - extraDimension;
4977                if (remainingDimensions == 0) {
4978                    // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
4979
Type elementType = arrayType.getElementType();
4980                    // cut the child loose from its parent (without creating garbage)
4981
elementType.setParent(null, null);
4982                    this.ast.getBindingResolver().updateKey(type, elementType);
4983                    switch(this.ast.apiLevel) {
4984                        case AST.JLS2_INTERNAL :
4985                            methodDeclaration.internalSetReturnType(elementType);
4986                            break;
4987                        case AST.JLS3 :
4988                            methodDeclaration.setReturnType2(elementType);
4989                        break;
4990                    }
4991                } else {
4992                    int start = type.getStartPosition();
4993                    ArrayType subarrayType = arrayType;
4994                    int index = extraDimension;
4995                    while (index > 0) {
4996                        subarrayType = (ArrayType) subarrayType.getComponentType();
4997                        index--;
4998                    }
4999                    int