1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
13 import net.sourceforge.phpdt.core.IField;
14 import net.sourceforge.phpdt.core.IMethod;
15 import net.sourceforge.phpdt.core.IType;
16 import net.sourceforge.phpdt.core.JavaModelException;
17 import net.sourceforge.phpdt.core.Signature;
18 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
19 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
20 import net.sourceforge.phpdt.internal.compiler.ast.Argument;
21 import net.sourceforge.phpdt.internal.compiler.ast.ArrayQualifiedTypeReference;
22 import net.sourceforge.phpdt.internal.compiler.ast.ArrayTypeReference;
23 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
24 import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration;
25 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
26 import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
27 import net.sourceforge.phpdt.internal.compiler.ast.MemberTypeDeclaration;
28 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
29 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference;
30 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
31 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
32 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
33 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
34 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
35 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
38 * Converter from a type to an AST type declaration.
40 public class TypeConverter {
43 * Convert a type into an AST type declaration and put it in the given compilation unit.
45 // public static TypeDeclaration buildTypeDeclaration(IType type, CompilationUnitDeclaration compilationUnit, CompilationResult compilationResult, ProblemReporter problemReporter) throws JavaModelException {
46 // char[] packageName = type.getPackageFragment().getElementName().toCharArray();
48 // if (packageName != null && packageName.length > 0) {
49 // compilationUnit.currentPackage = new ImportReference(CharOperation.splitOn('.', packageName), new long[]{0}, false);
53 // TypeDeclaration typeDeclaration = convert(type, null, null, compilationResult);
55 // IType alreadyComputedMember = type;
56 // IType parent = type.getDeclaringType();
57 // TypeDeclaration previousDeclaration = typeDeclaration;
58 // while(parent != null) {
59 // TypeDeclaration declaration = convert(parent, alreadyComputedMember, (MemberTypeDeclaration)previousDeclaration, compilationResult);
61 // alreadyComputedMember = parent;
62 // previousDeclaration = declaration;
63 // parent = parent.getDeclaringType();
66 // compilationUnit.types = new TypeDeclaration[]{previousDeclaration};
68 // return typeDeclaration;
71 private static FieldDeclaration convert(IField field, IType type) throws JavaModelException {
73 FieldDeclaration fieldDeclaration = new FieldDeclaration();
75 fieldDeclaration.name = field.getElementName().toCharArray();
76 fieldDeclaration.type = createTypeReference(Signature.toString(field.getTypeSignature()).toCharArray(), type);
77 fieldDeclaration.modifiers = field.getFlags();
79 return fieldDeclaration;
82 private static AbstractMethodDeclaration convert(IMethod method, IType type, CompilationResult compilationResult) throws JavaModelException {
84 AbstractMethodDeclaration methodDeclaration;
86 if (method.isConstructor()) {
87 ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
88 decl.isDefaultConstructor = false;
89 methodDeclaration = decl;
91 MethodDeclaration decl = new MethodDeclaration(compilationResult);
92 /* convert return type */
93 decl.returnType = createTypeReference(Signature.toString(method.getReturnType()).toCharArray(), type);
94 methodDeclaration = decl;
96 methodDeclaration.selector = method.getElementName().toCharArray();
97 methodDeclaration.modifiers = method.getFlags();
99 /* convert arguments */
100 String[] argumentTypeNames = method.getParameterTypes();
101 String[] argumentNames = method.getParameterNames();
102 int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
103 methodDeclaration.arguments = new Argument[argumentCount];
104 for (int i = 0; i < argumentCount; i++) {
105 methodDeclaration.arguments[i] = new Argument(
106 argumentNames[i].toCharArray(),
108 createTypeReference(Signature.toString(argumentTypeNames[i]).toCharArray(), type),
109 CompilerModifiers.AccDefault);
110 // do not care whether was final or not
113 /* convert thrown exceptions */
114 String[] exceptionTypeNames = method.getExceptionTypes();
115 int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
116 if(exceptionCount > 0) {
117 methodDeclaration.thrownExceptions = new TypeReference[exceptionCount];
118 for (int i = 0; i < exceptionCount; i++) {
119 methodDeclaration.thrownExceptions[i] =
120 createTypeReference(Signature.toString(exceptionTypeNames[i]).toCharArray(), type);
123 return methodDeclaration;
126 private static TypeDeclaration convert(IType type, IType alreadyComputedMember,MemberTypeDeclaration alreadyComputedMemberDeclaration, CompilationResult compilationResult) throws JavaModelException {
127 /* create type declaration - can be member type */
128 TypeDeclaration typeDeclaration;
129 if (type.getDeclaringType() == null) {
130 typeDeclaration = new TypeDeclaration(compilationResult);
132 typeDeclaration = new MemberTypeDeclaration(compilationResult);
134 typeDeclaration.name = type.getElementName().toCharArray();
135 typeDeclaration.modifiers = type.getFlags();
138 /* set superclass and superinterfaces */
139 if (type.getSuperclassName() != null) {
140 typeDeclaration.superclass = createTypeReference(type.getSuperclassName().toCharArray(), type);
142 String[] interfaceNames = type.getSuperInterfaceNames();
143 int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length;
144 typeDeclaration.superInterfaces = new TypeReference[interfaceCount];
145 for (int i = 0; i < interfaceCount; i++) {
146 typeDeclaration.superInterfaces[i] = createTypeReference(interfaceNames[i].toCharArray(), type);
149 /* convert member types */
150 IType[] memberTypes = type.getTypes();
151 int memberTypeCount = memberTypes == null ? 0 : memberTypes.length;
152 typeDeclaration.memberTypes = new MemberTypeDeclaration[memberTypeCount];
153 for (int i = 0; i < memberTypeCount; i++) {
154 if(alreadyComputedMember != null && alreadyComputedMember.getFullyQualifiedName().equals(memberTypes[i].getFullyQualifiedName())) {
155 typeDeclaration.memberTypes[i] = alreadyComputedMemberDeclaration;
157 typeDeclaration.memberTypes[i] =
158 (MemberTypeDeclaration) convert(memberTypes[i], null, null, compilationResult);
163 IField[] fields = type.getFields();
164 int fieldCount = fields == null ? 0 : fields.length;
165 typeDeclaration.fields = new FieldDeclaration[fieldCount];
166 for (int i = 0; i < fieldCount; i++) {
167 typeDeclaration.fields[i] = convert(fields[i], type);
170 /* convert methods - need to add default constructor if necessary */
171 IMethod[] methods = type.getMethods();
172 int methodCount = methods == null ? 0 : methods.length;
174 /* source type has a constructor ? */
175 /* by default, we assume that one is needed. */
177 for (int i = 0; i < methodCount; i++) {
178 if (methods[i].isConstructor()) {
180 // Does not need the extra constructor since one constructor already exists.
184 typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount];
185 if (neededCount != 0) { // add default constructor in first position
186 typeDeclaration.methods[0] = typeDeclaration.createsInternalConstructor(false, false);
188 boolean isInterface = type.isInterface();
189 for (int i = 0; i < methodCount; i++) {
190 AbstractMethodDeclaration method =convert(methods[i], type, compilationResult);
191 if (isInterface || method.isAbstract()) { // fix-up flag
192 method.modifiers |= CompilerModifiers.AccSemicolonBody;
194 typeDeclaration.methods[neededCount + i] = method;
196 return typeDeclaration;
199 private static TypeReference createTypeReference(char[] type, IType contextType) {
201 String[][] resolvedName = contextType.resolveType(new String(type));
202 char[] superClassName = null;
203 if(resolvedName != null && resolvedName.length == 1) {
204 type= CharOperation.concat(resolvedName[0][0].toCharArray(), resolvedName[0][1].toCharArray(), '.');
206 } catch (JavaModelException e) {
210 /* count identifiers and dimensions */
211 int max = type.length;
215 for (int i = 0; i < max; i++) {
227 /* rebuild identifiers and dimensions */
228 if (identCount == 1) { // simple type reference
230 return new SingleTypeReference(type, 0);
232 char[] identifier = new char[dimStart];
233 System.arraycopy(type, 0, identifier, 0, dimStart);
234 return new ArrayTypeReference(identifier, dim, 0);
236 } else { // qualified type reference
237 char[][] identifiers = CharOperation.splitOn('.', type, 0, dimStart - 1);
239 return new QualifiedTypeReference(identifiers, new long[]{0});
241 return new ArrayQualifiedTypeReference(identifiers, dim, new long[]{0});