KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > util > ElementInfoConverter


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

11 package org.eclipse.jdt.internal.core.util;
12
13 /**
14  * Converter from element info to parsed compilation unit.
15  *
16  */

17
18 import org.eclipse.jdt.core.IJavaElement;
19 import org.eclipse.jdt.core.IType;
20 import org.eclipse.jdt.core.JavaModelException;
21 import org.eclipse.jdt.core.compiler.CharOperation;
22 import org.eclipse.jdt.internal.compiler.CompilationResult;
23 import org.eclipse.jdt.internal.compiler.ast.*;
24 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
25 import org.eclipse.jdt.internal.compiler.ast.Argument;
26 import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
27 import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
28 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
29 import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
30 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
31 import org.eclipse.jdt.internal.compiler.ast.ImportReference;
32 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
33 import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
34 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
35 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
36 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
37 import org.eclipse.jdt.internal.compiler.env.*;
38 import org.eclipse.jdt.internal.compiler.env.ISourceField;
39 import org.eclipse.jdt.internal.compiler.env.ISourceImport;
40 import org.eclipse.jdt.internal.compiler.env.ISourceMethod;
41 import org.eclipse.jdt.internal.compiler.env.ISourceType;
42
43 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
44 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
45 import org.eclipse.jdt.internal.core.*;
46 import org.eclipse.jdt.internal.core.JavaElement;
47 import org.eclipse.jdt.internal.core.SourceFieldElementInfo;
48 import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
49
50 public class ElementInfoConverter implements CompilerModifiers {
51
52     /*
53      * Convert a set of source type infos into a parsed compilation unit declaration
54      * The argument types are then all grouped in the same unit. The argument types must
55      * at least contain one type.
56      * Can optionally add local and anonymous types
57      */

58     public static CompilationUnitDeclaration buildCompilationUnit(
59         SourceTypeElementInfo[] sourceTypes,
60         boolean needLocalTypes,
61         ProblemReporter problemReporter,
62         CompilationResult compilationResult) {
63
64         return
65             new ElementInfoConverter(needLocalTypes, problemReporter).convert(
66                 sourceTypes,
67                 compilationResult);
68     }
69     
70     private boolean needLocalTypes; // local and anoymous types
71
private ProblemReporter problemReporter;
72     private CompilationUnitDeclaration unit;
73     
74     private ElementInfoConverter(boolean needLocalTypes, ProblemReporter problemReporter) {
75         this.needLocalTypes = needLocalTypes;
76         this.problemReporter = problemReporter;
77     }
78     
79     /*
80      * Convert an initializerinfo into a parsed initializer declaration
81      */

82     private Initializer convert(InitializerElementInfo initializerInfo, CompilationResult compilationResult) {
83
84         Block block = new Block(0);
85         Initializer initializer = new Initializer(block, IConstants.AccDefault);
86
87         int start = initializerInfo.getDeclarationSourceStart();
88         int end = initializerInfo.getDeclarationSourceEnd();
89
90         initializer.name = initializerInfo.getName();
91         initializer.sourceStart = initializer.declarationSourceStart = start;
92         initializer.sourceEnd = initializer.declarationSourceEnd = end;
93         initializer.modifiers = initializerInfo.getModifiers();
94
95         /* convert local and anonymous types */
96         IJavaElement[] children = initializerInfo.getChildren();
97         int typesLength = children.length;
98         if (typesLength > 0) {
99             Statement[] statements = new Statement[typesLength];
100             for (int i = 0; i < typesLength; i++) {
101                 JavaElement type = (JavaElement)children[i];
102                 try {
103                     TypeDeclaration localType = convert((SourceTypeElementInfo)type.getElementInfo(), compilationResult);
104                     if ((localType.bits & ASTNode.IsAnonymousTypeMASK) != 0) {
105                         QualifiedAllocationExpression expression = new QualifiedAllocationExpression(localType);
106                         expression.type = localType.superclass;
107                         localType.superclass = null;
108                         localType.superInterfaces = null;
109                         localType.allocation = expression;
110                         statements[i] = expression;
111                     } else {
112                         statements[i] = localType;
113                     }
114                 } catch (JavaModelException e) {
115                     // ignore
116
}
117             }
118             block.statements = statements;
119         }
120         
121         return initializer;
122     }
123
124     /*
125      * Convert a source field info into a parsed field declaration
126      */

127     private FieldDeclaration convert(SourceFieldElementInfo sourceField, CompilationResult compilationResult) {
128
129         FieldDeclaration field = new FieldDeclaration();
130
131         int start = sourceField.getNameSourceStart();
132         int end = sourceField.getNameSourceEnd();
133
134         field.name = sourceField.getName();
135         field.sourceStart = start;
136         field.sourceEnd = end;
137         field.type = createTypeReference(sourceField.getTypeName(), start, end);
138         field.declarationSourceStart = sourceField.getDeclarationSourceStart();
139         field.declarationSourceEnd = sourceField.getDeclarationSourceEnd();
140         field.modifiers = sourceField.getModifiers();
141
142         /* convert local and anonymous types */
143         if (this.needLocalTypes) {
144             IJavaElement[] children = sourceField.getChildren();
145             int typesLength = children.length;
146             if (typesLength > 0) {
147                 ArrayInitializer initializer = new ArrayInitializer();
148                 field.initialization = initializer;
149                 Expression[] expressions = new Expression[typesLength];
150                 initializer.expressions = expressions;
151                 for (int i = 0; i < typesLength; i++) {
152                     IJavaElement localType = children[i];
153                     try {
154                         TypeDeclaration anonymousLocalTypeDeclaration = convert((SourceTypeElementInfo)((JavaElement)localType).getElementInfo(),compilationResult);
155                         QualifiedAllocationExpression expression = new QualifiedAllocationExpression(anonymousLocalTypeDeclaration);
156                         expression.type = anonymousLocalTypeDeclaration.superclass;
157                         anonymousLocalTypeDeclaration.superclass = null;
158                         anonymousLocalTypeDeclaration.superInterfaces = null;
159                         anonymousLocalTypeDeclaration.allocation = expression;
160                         expressions[i] = expression;
161                     } catch (JavaModelException e) {
162                         // ignore
163
}
164                 }
165             }
166         }
167         
168         return field;
169     }
170
171     /*
172      * Convert a source method info into a parsed method/constructor declaration
173      */

174     private AbstractMethodDeclaration convert(SourceMethodElementInfo sourceMethod, CompilationResult compilationResult) {
175
176         AbstractMethodDeclaration method;
177
178         /* only source positions available */
179         int start = sourceMethod.getNameSourceStart();
180         int end = sourceMethod.getNameSourceEnd();
181
182         if (sourceMethod.isConstructor()) {
183             ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
184             decl.isDefaultConstructor = false;
185             method = decl;
186         } else {
187             MethodDeclaration decl = new MethodDeclaration(compilationResult);
188             /* convert return type */
189             decl.returnType =
190                 createTypeReference(sourceMethod.getReturnTypeName(), start, end);
191             method = decl;
192         }
193         method.selector = sourceMethod.getSelector();
194         method.modifiers = sourceMethod.getModifiers();
195         method.sourceStart = start;
196         method.sourceEnd = end;
197         method.declarationSourceStart = sourceMethod.getDeclarationSourceStart();
198         method.declarationSourceEnd = sourceMethod.getDeclarationSourceEnd();
199
200         /* convert arguments */
201         char[][] argumentTypeNames = sourceMethod.getArgumentTypeNames();
202         char[][] argumentNames = sourceMethod.getArgumentNames();
203         int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
204         long position = (long) start << 32 + end;
205         method.arguments = new Argument[argumentCount];
206         for (int i = 0; i < argumentCount; i++) {
207             method.arguments[i] =
208                 new Argument(
209                     argumentNames[i],
210                     position,
211                     createTypeReference(argumentTypeNames[i], start, end),
212                     AccDefault);
213             // do not care whether was final or not
214
}
215
216         /* convert thrown exceptions */
217         char[][] exceptionTypeNames = sourceMethod.getExceptionTypeNames();
218         int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
219         method.thrownExceptions = new TypeReference[exceptionCount];
220         for (int i = 0; i < exceptionCount; i++) {
221             method.thrownExceptions[i] =
222                 createTypeReference(exceptionTypeNames[i], start, end);
223         }
224         
225         /* convert local and anonymous types */
226         if (this.needLocalTypes) {
227             IJavaElement[] children = sourceMethod.getChildren();
228             int typesLength = children.length;
229             if (typesLength != 0) {
230                 Statement[] statements = new Statement[typesLength];
231                 for (int i = 0; i < typesLength; i++) {
232                     JavaElement type = (JavaElement)children[i];
233                     try {
234                         TypeDeclaration localType = convert((SourceTypeElementInfo)type.getElementInfo(), compilationResult);
235                         if ((localType.bits & ASTNode.IsAnonymousTypeMASK) != 0) {
236                             QualifiedAllocationExpression expression = new QualifiedAllocationExpression(localType);
237                             expression.type = localType.superclass;
238                             localType.superclass = null;
239                             localType.superInterfaces = null;
240                             localType.allocation = expression;
241                             statements[i] = expression;
242                         } else {
243                             statements[i] = localType;
244                         }
245                     } catch (JavaModelException e) {
246                         // ignore
247
}
248                 }
249                 method.statements = statements;
250             }
251         }
252         
253         return method;
254     }
255
256     /*
257      * Convert a source type info into a parsed type declaration
258      */

259     private TypeDeclaration convert(SourceTypeElementInfo sourceType, CompilationResult compilationResult) {
260         
261         /* create type declaration - can be member type, local type or anonymous type */
262         TypeDeclaration type = new TypeDeclaration(compilationResult);
263         if (sourceType.getEnclosingType() == null) {
264             IType typeHandle = sourceType.getHandle();
265             try {
266                 if (typeHandle.isAnonymous()) {
267                     type.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
268                     type.bits |= ASTNode.AnonymousAndLocalMask;
269                 } else {
270                     if (typeHandle.isLocal()) {
271                         type.bits |= ASTNode.IsLocalTypeMASK;
272                     }
273                 }
274             } catch (JavaModelException e) {
275                 // could not figure, assume toplevel
276
}
277         } else {
278             type.bits |= ASTNode.IsMemberTypeMASK;
279         }
280         if ((type.bits & ASTNode.IsAnonymousTypeMASK) == 0) {
281             type.name = sourceType.getName();
282         }
283         int start, end; // only positions available
284
type.sourceStart = start = sourceType.getNameSourceStart();
285         type.sourceEnd = end = sourceType.getNameSourceEnd();
286         type.modifiers = sourceType.getModifiers();
287         type.declarationSourceStart = sourceType.getDeclarationSourceStart();
288         type.declarationSourceEnd = sourceType.getDeclarationSourceEnd();
289         type.bodyEnd = type.declarationSourceEnd;
290
291         /* set superclass and superinterfaces */
292         if (sourceType.getSuperclassName() != null)
293             type.superclass =
294                 createTypeReference(sourceType.getSuperclassName(), start, end);
295         char[][] interfaceNames = sourceType.getInterfaceNames();
296         int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length;
297         type.superInterfaces = new TypeReference[interfaceCount];
298         for (int i = 0; i < interfaceCount; i++) {
299             type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end);
300         }
301         
302         /* convert member types */
303         ISourceType[] sourceMemberTypes = sourceType.getMemberTypes();
304         int sourceMemberTypeCount =
305             sourceMemberTypes == null ? 0 : sourceMemberTypes.length;
306         type.memberTypes = new TypeDeclaration[sourceMemberTypeCount];
307         for (int i = 0; i < sourceMemberTypeCount; i++) {
308             type.memberTypes[i] = convert((SourceTypeElementInfo)sourceMemberTypes[i], compilationResult);
309         }
310         
311         /* convert fields and initializers */
312         ISourceField[] sourceFields = sourceType.getFields();
313         int sourceFieldCount = sourceFields == null ? 0 : sourceFields.length;
314         InitializerElementInfo[] initializers = null;
315         int initializerCount = 0;
316         if (this.needLocalTypes) {
317             initializers = sourceType.getInitializers();
318             initializerCount = initializers.length;
319             type.fields = new FieldDeclaration[initializerCount + sourceFieldCount];
320             for (int i = 0; i < initializerCount; i++) {
321                 type.fields[i] = convert(initializers[i], compilationResult);
322             }
323         } else {
324             type.fields = new FieldDeclaration[sourceFieldCount];
325         }
326         int length = initializerCount + sourceFieldCount;
327         int index = 0;
328         for (int i = initializerCount; i < length; i++) {
329             type.fields[i] = convert((SourceFieldElementInfo)sourceFields[index++], compilationResult);
330         }
331
332         /* convert methods - need to add default constructor if necessary */
333         ISourceMethod[] sourceMethods = sourceType.getMethods();
334         int sourceMethodCount = sourceMethods == null ? 0 : sourceMethods.length;
335
336         /* source type has a constructor ? */
337         /* by default, we assume that one is needed. */
338         int neededCount = 0;
339         if (!type.isInterface()) {
340             neededCount = 1;
341             for (int i = 0; i < sourceMethodCount; i++) {
342                 if (sourceMethods[i].isConstructor()) {
343                     neededCount = 0;
344                     // Does not need the extra constructor since one constructor already exists.
345
break;
346                 }
347             }
348         }
349         type.methods = new AbstractMethodDeclaration[sourceMethodCount + neededCount];
350         if (neededCount != 0) { // add default constructor in first position
351
type.methods[0] = type.createsInternalConstructor(false, false);
352         }
353         boolean isInterface = type.isInterface();
354         for (int i = 0; i < sourceMethodCount; i++) {
355             AbstractMethodDeclaration method =convert((SourceMethodElementInfo)sourceMethods[i], compilationResult);
356             if (isInterface || method.isAbstract()) { // fix-up flag
357
method.modifiers |= AccSemicolonBody;
358             }
359             type.methods[neededCount + i] = method;
360         }
361
362         return type;
363     }
364
365     /*
366      * Convert a set of source element types into a parsed compilation unit declaration
367      * The argument types are then all grouped in the same unit. The argument types must
368      * at least contain one type.
369      */

370     private CompilationUnitDeclaration convert(SourceTypeElementInfo[] sourceTypes, CompilationResult compilationResult) {
371         
372         SourceTypeElementInfo sourceType = sourceTypes[0];
373         if (sourceType.getName() == null)
374             return null; // do a basic test that the sourceType is valid
375

376         this.unit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
377         // not filled at this point
378

379         /* only positions available */
380         int start = sourceType.getNameSourceStart();
381         int end = sourceType.getNameSourceEnd();
382
383         /* convert package and imports */
384         if (sourceType.getPackageName() != null
385             && sourceType.getPackageName().length > 0)
386             // if its null then it is defined in the default package
387
this.unit.currentPackage =
388                 createImportReference(sourceType.getPackageName(), start, end, false, AccDefault);
389         ISourceImport[] sourceImports = sourceType.getImports();
390         int importCount = sourceImports == null ? 0 : sourceImports.length;
391         this.unit.imports = new ImportReference[importCount];
392         for (int i = 0; i < importCount; i++) {
393             ISourceImport sourceImport = sourceImports[i];
394             this.unit.imports[i] = createImportReference(
395                 sourceImport.getName(),
396                 sourceImport.getDeclarationSourceStart(),
397                 sourceImport.getDeclarationSourceEnd(),
398                 sourceImport.onDemand(),
399                 sourceImport.getModifiers());
400         }
401         /* convert type(s) */
402         int typeCount = sourceTypes.length;
403         this.unit.types = new TypeDeclaration[typeCount];
404         for (int i = 0; i < typeCount; i++) {
405             this.unit.types[i] = convert(sourceTypes[i], compilationResult);
406         }
407         return this.unit;
408     }
409
410     /*
411      * Build an import reference from an import name, e.g. java.lang.*
412      */

413     private ImportReference createImportReference(
414         char[] importName,
415         int start,
416         int end,
417         boolean onDemand,
418         int modifiers) {
419     
420         char[][] qImportName = CharOperation.splitOn('.', importName);
421         long[] positions = new long[qImportName.length];
422         long position = (long) start << 32 + end;
423         for (int i = 0; i < qImportName.length; i++) {
424             positions[i] = position; // dummy positions
425
}
426         return new ImportReference(
427             qImportName,
428             positions,
429             onDemand,
430             modifiers);
431     }
432
433     /*
434      * Build a type reference from a readable name, e.g. java.lang.Object[][]
435      */

436     private TypeReference createTypeReference(
437         char[] typeSignature,
438         int start,
439         int end) {
440
441         /* count identifiers and dimensions */
442         int max = typeSignature.length;
443         int dimStart = max;
444         int dim = 0;
445         int identCount = 1;
446         for (int i = 0; i < max; i++) {
447             switch (typeSignature[i]) {
448                 case '[' :
449                     if (dim == 0)
450                         dimStart = i;
451                     dim++;
452                     break;
453                 case '.' :
454                     identCount++;
455                     break;
456             }
457         }
458         /* rebuild identifiers and dimensions */
459         if (identCount == 1) { // simple type reference
460
if (dim == 0) {
461                 return new SingleTypeReference(typeSignature, (((long) start )<< 32) + end);
462             } else {
463                 char[] identifier = new char[dimStart];
464                 System.arraycopy(typeSignature, 0, identifier, 0, dimStart);
465                 return new ArrayTypeReference(identifier, dim, (((long) start) << 32) + end);
466             }
467         } else { // qualified type reference
468
long[] positions = new long[identCount];
469             long pos = (((long) start) << 32) + end;
470             for (int i = 0; i < identCount; i++) {
471                 positions[i] = pos;
472             }
473             char[][] identifiers =
474                 CharOperation.splitOn('.', typeSignature, 0, dimStart);
475             if (dim == 0) {
476                 return new QualifiedTypeReference(identifiers, positions);
477             } else {
478                 return new ArrayQualifiedTypeReference(identifiers, dim, positions);
479             }
480         }
481     }
482 }
483
Popular Tags