KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > BinaryTypeConverter


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 package org.eclipse.jdt.internal.core;
12
13 import org.eclipse.jdt.core.Flags;
14 import org.eclipse.jdt.core.IField;
15 import org.eclipse.jdt.core.IMethod;
16 import org.eclipse.jdt.core.IType;
17 import org.eclipse.jdt.core.JavaModelException;
18 import org.eclipse.jdt.core.Signature;
19 import org.eclipse.jdt.core.compiler.CharOperation;
20 import org.eclipse.jdt.internal.compiler.CompilationResult;
21 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
22 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
23 import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
24 import org.eclipse.jdt.internal.compiler.ast.Argument;
25 import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
26 import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
27 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
28 import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
29 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
30 import org.eclipse.jdt.internal.compiler.ast.ImportReference;
31 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
32 import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
33 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
34 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
35 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
36 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
37 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
38 import org.eclipse.jdt.internal.core.util.Util;
39
40 /**
41  * Converter from a binary type to an AST type declaration.
42  */

43 public class BinaryTypeConverter {
44     
45     /**
46      * Convert a binary type into an AST type declaration and put it in the given compilation unit.
47      */

48     public static TypeDeclaration buildTypeDeclaration(IType type, CompilationUnitDeclaration compilationUnit, CompilationResult compilationResult) throws JavaModelException {
49         PackageFragment pkg = (PackageFragment) type.getPackageFragment();
50         char[][] packageName = Util.toCharArrays(pkg.names);
51         
52         if (packageName.length > 0) {
53             compilationUnit.currentPackage = new ImportReference(packageName, new long[]{0}, false, ClassFileConstants.AccDefault);
54         }
55     
56         /* convert type */
57         TypeDeclaration typeDeclaration = convert(type, null, null, compilationResult);
58         
59         IType alreadyComputedMember = type;
60         IType parent = type.getDeclaringType();
61         TypeDeclaration previousDeclaration = typeDeclaration;
62         while(parent != null) {
63             TypeDeclaration declaration = convert(parent, alreadyComputedMember, previousDeclaration, compilationResult);
64             
65             alreadyComputedMember = parent;
66             previousDeclaration = declaration;
67             parent = parent.getDeclaringType();
68         }
69         
70         compilationUnit.types = new TypeDeclaration[]{previousDeclaration};
71
72         return typeDeclaration;
73     }
74     
75     private static FieldDeclaration convert(IField field, IType type) throws JavaModelException {
76
77         FieldDeclaration fieldDeclaration = new FieldDeclaration();
78
79         fieldDeclaration.name = field.getElementName().toCharArray();
80         fieldDeclaration.type = createTypeReference(Signature.toString(field.getTypeSignature()).toCharArray());
81         fieldDeclaration.modifiers = field.getFlags();
82
83         return fieldDeclaration;
84     }
85     
86     private static AbstractMethodDeclaration convert(IMethod method, IType type, CompilationResult compilationResult) throws JavaModelException {
87
88         AbstractMethodDeclaration methodDeclaration;
89
90         if (method.isConstructor()) {
91             ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
92             decl.bits &= ~ASTNode.IsDefaultConstructor;
93             methodDeclaration = decl;
94         } else {
95             MethodDeclaration decl = type.isAnnotation() ? new AnnotationMethodDeclaration(compilationResult) : new MethodDeclaration(compilationResult);
96             /* convert return type */
97             decl.returnType = createTypeReference(Signature.toString(method.getReturnType()).toCharArray());
98             methodDeclaration = decl;
99         }
100         methodDeclaration.selector = method.getElementName().toCharArray();
101         int flags = method.getFlags();
102         boolean isVarargs = Flags.isVarargs(flags);
103         methodDeclaration.modifiers = flags & ~Flags.AccVarargs;
104
105         /* convert arguments */
106         String JavaDoc[] argumentTypeNames = method.getParameterTypes();
107         String JavaDoc[] argumentNames = method.getParameterNames();
108         int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
109         methodDeclaration.arguments = new Argument[argumentCount];
110         for (int i = 0; i < argumentCount; i++) {
111             String JavaDoc argumentTypeName = argumentTypeNames[i];
112             TypeReference typeReference = createTypeReference(Signature.toString(argumentTypeName).toCharArray());
113             if (isVarargs && i == argumentCount-1) {
114                 typeReference.bits |= ASTNode.IsVarArgs;
115             }
116             methodDeclaration.arguments[i] = new Argument(
117                 argumentNames[i].toCharArray(),
118                 0,
119                 typeReference,
120                 ClassFileConstants.AccDefault);
121             // do not care whether was final or not
122
}
123
124         /* convert thrown exceptions */
125         String JavaDoc[] exceptionTypeNames = method.getExceptionTypes();
126         int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
127         if(exceptionCount > 0) {
128             methodDeclaration.thrownExceptions = new TypeReference[exceptionCount];
129             for (int i = 0; i < exceptionCount; i++) {
130                 methodDeclaration.thrownExceptions[i] =
131                     createTypeReference(Signature.toString(exceptionTypeNames[i]).toCharArray());
132             }
133         }
134         return methodDeclaration;
135     }
136     
137     private static TypeDeclaration convert(IType type, IType alreadyComputedMember,TypeDeclaration alreadyComputedMemberDeclaration, CompilationResult compilationResult) throws JavaModelException {
138         /* create type declaration - can be member type */
139         TypeDeclaration typeDeclaration = new TypeDeclaration(compilationResult);
140
141         if (type.getDeclaringType() != null) {
142             typeDeclaration.bits |= ASTNode.IsMemberType;
143         }
144         typeDeclaration.name = type.getElementName().toCharArray();
145         typeDeclaration.modifiers = type.getFlags();
146
147
148         /* set superclass and superinterfaces */
149         if (type.getSuperclassName() != null) {
150             typeDeclaration.superclass = createTypeReference(type.getSuperclassName().toCharArray());
151             typeDeclaration.superclass.bits |= ASTNode.IsSuperType;
152         }
153         String JavaDoc[] interfaceNames = type.getSuperInterfaceNames();
154         int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length;
155         typeDeclaration.superInterfaces = new TypeReference[interfaceCount];
156         for (int i = 0; i < interfaceCount; i++) {
157             typeDeclaration.superInterfaces[i] = createTypeReference(interfaceNames[i].toCharArray());
158             typeDeclaration.superInterfaces[i].bits |= ASTNode.IsSuperType;
159         }
160         
161         /* convert member types */
162         IType[] memberTypes = type.getTypes();
163         int memberTypeCount = memberTypes == null ? 0 : memberTypes.length;
164         typeDeclaration.memberTypes = new TypeDeclaration[memberTypeCount];
165         for (int i = 0; i < memberTypeCount; i++) {
166             if(alreadyComputedMember != null && alreadyComputedMember.getFullyQualifiedName().equals(memberTypes[i].getFullyQualifiedName())) {
167                 typeDeclaration.memberTypes[i] = alreadyComputedMemberDeclaration;
168             } else {
169                 typeDeclaration.memberTypes[i] = convert(memberTypes[i], null, null, compilationResult);
170             }
171         }
172
173         /* convert fields */
174         IField[] fields = type.getFields();
175         int fieldCount = fields == null ? 0 : fields.length;
176         typeDeclaration.fields = new FieldDeclaration[fieldCount];
177         for (int i = 0; i < fieldCount; i++) {
178             typeDeclaration.fields[i] = convert(fields[i], type);
179         }
180
181         /* convert methods - need to add default constructor if necessary */
182         IMethod[] methods = type.getMethods();
183         int methodCount = methods == null ? 0 : methods.length;
184
185         /* source type has a constructor ? */
186         /* by default, we assume that one is needed. */
187         int neededCount = 1;
188         for (int i = 0; i < methodCount; i++) {
189             if (methods[i].isConstructor()) {
190                 neededCount = 0;
191                 // Does not need the extra constructor since one constructor already exists.
192
break;
193             }
194         }
195         boolean isInterface = type.isInterface();
196         neededCount = isInterface ? 0 : neededCount;
197         typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount];
198         if (neededCount != 0) { // add default constructor in first position
199
typeDeclaration.methods[0] = typeDeclaration.createDefaultConstructor(false, false);
200         }
201         boolean hasAbstractMethods = false;
202         for (int i = 0; i < methodCount; i++) {
203             AbstractMethodDeclaration method =convert(methods[i], type, compilationResult);
204             boolean isAbstract;
205             if ((isAbstract = method.isAbstract()) || isInterface) { // fix-up flag
206
method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
207             }
208             if (isAbstract) {
209                 hasAbstractMethods = true;
210             }
211             typeDeclaration.methods[neededCount + i] = method;
212         }
213         if (hasAbstractMethods) {
214             typeDeclaration.bits |= ASTNode.HasAbstractMethods;
215         }
216         return typeDeclaration;
217     }
218     
219     private static TypeReference createTypeReference(char[] type) {
220         /* count identifiers and dimensions */
221         int max = type.length;
222         int dimStart = max;
223         int dim = 0;
224         int identCount = 1;
225         for (int i = 0; i < max; i++) {
226             switch (type[i]) {
227                 case '[' :
228                     if (dim == 0)
229                         dimStart = i;
230                     dim++;
231                     break;
232                 case '.' :
233                     identCount++;
234                     break;
235             }
236         }
237         /* rebuild identifiers and dimensions */
238         if (identCount == 1) { // simple type reference
239
if (dim == 0) {
240                 return new SingleTypeReference(type, 0);
241             } else {
242                 char[] identifier = new char[dimStart];
243                 System.arraycopy(type, 0, identifier, 0, dimStart);
244                 return new ArrayTypeReference(identifier, dim, 0);
245             }
246         } else { // qualified type reference
247
char[][] identifiers = CharOperation.splitOn('.', type, 0, dimStart);
248             if (dim == 0) {
249                 return new QualifiedTypeReference(identifiers, new long[identifiers.length]);
250             } else {
251                 return new ArrayQualifiedTypeReference(identifiers, dim, new long[identifiers.length]);
252             }
253         }
254     }
255 }
256
Popular Tags