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