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.ConstructorDeclaration;
24 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
25 import net.sourceforge.phpdt.internal.compiler.ast.MemberTypeDeclaration;
26 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
27 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference;
28 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
29 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
30 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
31 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
32 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
35 * Converter from a type to an AST type declaration.
37 public class TypeConverter {
40 * Convert a type into an AST type declaration and put it in the given compilation unit.
42 // public static TypeDeclaration buildTypeDeclaration(IType type, CompilationUnitDeclaration compilationUnit, CompilationResult compilationResult, ProblemReporter problemReporter) throws JavaModelException {
43 // char[] packageName = type.getPackageFragment().getElementName().toCharArray();
45 // if (packageName != null && packageName.length > 0) {
46 // compilationUnit.currentPackage = new ImportReference(CharOperation.splitOn('.', packageName), new long[]{0}, false);
50 // TypeDeclaration typeDeclaration = convert(type, null, null, compilationResult);
52 // IType alreadyComputedMember = type;
53 // IType parent = type.getDeclaringType();
54 // TypeDeclaration previousDeclaration = typeDeclaration;
55 // while(parent != null) {
56 // TypeDeclaration declaration = convert(parent, alreadyComputedMember, (MemberTypeDeclaration)previousDeclaration, compilationResult);
58 // alreadyComputedMember = parent;
59 // previousDeclaration = declaration;
60 // parent = parent.getDeclaringType();
63 // compilationUnit.types = new TypeDeclaration[]{previousDeclaration};
65 // return typeDeclaration;
68 private static FieldDeclaration convert(IField field, IType type) throws JavaModelException {
70 FieldDeclaration fieldDeclaration = new FieldDeclaration();
72 fieldDeclaration.name = field.getElementName().toCharArray();
73 fieldDeclaration.type = createTypeReference(Signature.toString(field.getTypeSignature()).toCharArray(), type);
74 fieldDeclaration.modifiers = field.getFlags();
76 return fieldDeclaration;
79 private static AbstractMethodDeclaration convert(IMethod method, IType type, CompilationResult compilationResult) throws JavaModelException {
81 AbstractMethodDeclaration methodDeclaration;
83 if (method.isConstructor()) {
84 ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
85 decl.isDefaultConstructor = false;
86 methodDeclaration = decl;
88 MethodDeclaration decl = new MethodDeclaration(compilationResult);
89 /* convert return type */
90 decl.returnType = createTypeReference(Signature.toString(method.getReturnType()).toCharArray(), type);
91 methodDeclaration = decl;
93 methodDeclaration.selector = method.getElementName().toCharArray();
94 methodDeclaration.modifiers = method.getFlags();
96 /* convert arguments */
97 String[] argumentTypeNames = method.getParameterTypes();
98 String[] argumentNames = method.getParameterNames();
99 int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
100 methodDeclaration.arguments = new Argument[argumentCount];
101 for (int i = 0; i < argumentCount; i++) {
102 methodDeclaration.arguments[i] = new Argument(
103 argumentNames[i].toCharArray(),
105 createTypeReference(Signature.toString(argumentTypeNames[i]).toCharArray(), type),
106 CompilerModifiers.AccDefault);
107 // do not care whether was final or not
110 /* convert thrown exceptions */
111 String[] exceptionTypeNames = method.getExceptionTypes();
112 int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
113 if(exceptionCount > 0) {
114 methodDeclaration.thrownExceptions = new TypeReference[exceptionCount];
115 for (int i = 0; i < exceptionCount; i++) {
116 methodDeclaration.thrownExceptions[i] =
117 createTypeReference(Signature.toString(exceptionTypeNames[i]).toCharArray(), type);
120 return methodDeclaration;
123 private static TypeDeclaration convert(IType type, IType alreadyComputedMember,MemberTypeDeclaration alreadyComputedMemberDeclaration, CompilationResult compilationResult) throws JavaModelException {
124 /* create type declaration - can be member type */
125 TypeDeclaration typeDeclaration;
126 if (type.getDeclaringType() == null) {
127 typeDeclaration = new TypeDeclaration(compilationResult);
129 typeDeclaration = new MemberTypeDeclaration(compilationResult);
131 typeDeclaration.name = type.getElementName().toCharArray();
132 typeDeclaration.modifiers = type.getFlags();
135 /* set superclass and superinterfaces */
136 if (type.getSuperclassName() != null) {
137 typeDeclaration.superclass = createTypeReference(type.getSuperclassName().toCharArray(), type);
139 String[] interfaceNames = type.getSuperInterfaceNames();
140 int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length;
141 typeDeclaration.superInterfaces = new TypeReference[interfaceCount];
142 for (int i = 0; i < interfaceCount; i++) {
143 typeDeclaration.superInterfaces[i] = createTypeReference(interfaceNames[i].toCharArray(), type);
146 /* convert member types */
147 IType[] memberTypes = type.getTypes();
148 int memberTypeCount = memberTypes == null ? 0 : memberTypes.length;
149 typeDeclaration.memberTypes = new MemberTypeDeclaration[memberTypeCount];
150 for (int i = 0; i < memberTypeCount; i++) {
151 if(alreadyComputedMember != null && alreadyComputedMember.getFullyQualifiedName().equals(memberTypes[i].getFullyQualifiedName())) {
152 typeDeclaration.memberTypes[i] = alreadyComputedMemberDeclaration;
154 typeDeclaration.memberTypes[i] =
155 (MemberTypeDeclaration) convert(memberTypes[i], null, null, compilationResult);
160 IField[] fields = type.getFields();
161 int fieldCount = fields == null ? 0 : fields.length;
162 typeDeclaration.fields = new FieldDeclaration[fieldCount];
163 for (int i = 0; i < fieldCount; i++) {
164 typeDeclaration.fields[i] = convert(fields[i], type);
167 /* convert methods - need to add default constructor if necessary */
168 IMethod[] methods = type.getMethods();
169 int methodCount = methods == null ? 0 : methods.length;
171 /* source type has a constructor ? */
172 /* by default, we assume that one is needed. */
174 for (int i = 0; i < methodCount; i++) {
175 if (methods[i].isConstructor()) {
177 // Does not need the extra constructor since one constructor already exists.
181 typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount];
182 if (neededCount != 0) { // add default constructor in first position
183 typeDeclaration.methods[0] = typeDeclaration.createsInternalConstructor(false, false);
185 boolean isInterface = type.isInterface();
186 for (int i = 0; i < methodCount; i++) {
187 AbstractMethodDeclaration method =convert(methods[i], type, compilationResult);
188 if (isInterface || method.isAbstract()) { // fix-up flag
189 method.modifiers |= CompilerModifiers.AccSemicolonBody;
191 typeDeclaration.methods[neededCount + i] = method;
193 return typeDeclaration;
196 private static TypeReference createTypeReference(char[] type, IType contextType) {
198 String[][] resolvedName = contextType.resolveType(new String(type));
199 char[] superClassName = null;
200 if(resolvedName != null && resolvedName.length == 1) {
201 type= CharOperation.concat(resolvedName[0][0].toCharArray(), resolvedName[0][1].toCharArray(), '.');
203 } catch (JavaModelException e) {
207 /* count identifiers and dimensions */
208 int max = type.length;
212 for (int i = 0; i < max; i++) {
224 /* rebuild identifiers and dimensions */
225 if (identCount == 1) { // simple type reference
227 return new SingleTypeReference(type, 0);
229 char[] identifier = new char[dimStart];
230 System.arraycopy(type, 0, identifier, 0, dimStart);
231 return new ArrayTypeReference(identifier, dim, 0);
233 } else { // qualified type reference
234 char[][] identifiers = CharOperation.splitOn('.', type, 0, dimStart - 1);
236 return new QualifiedTypeReference(identifiers, new long[]{0});
238 return new ArrayQualifiedTypeReference(identifiers, dim, new long[]{0});