1 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 43 public class BinaryTypeConverter { 44 45 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 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 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 106 String [] argumentTypeNames = method.getParameterTypes(); 107 String [] 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 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 } 123 124 125 String [] 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 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 149 if (type.getSuperclassName() != null) { 150 typeDeclaration.superclass = createTypeReference(type.getSuperclassName().toCharArray()); 151 typeDeclaration.superclass.bits |= ASTNode.IsSuperType; 152 } 153 String [] 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 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 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 182 IMethod[] methods = type.getMethods(); 183 int methodCount = methods == null ? 0 : methods.length; 184 185 186 187 int neededCount = 1; 188 for (int i = 0; i < methodCount; i++) { 189 if (methods[i].isConstructor()) { 190 neededCount = 0; 191 break; 193 } 194 } 195 boolean isInterface = type.isInterface(); 196 neededCount = isInterface ? 0 : neededCount; 197 typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount]; 198 if (neededCount != 0) { 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) { 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 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 238 if (identCount == 1) { 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 { 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 |