1 11 package org.eclipse.jdt.internal.core.util; 12 13 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 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; 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 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 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 } 117 } 118 block.statements = statements; 119 } 120 121 return initializer; 122 } 123 124 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 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 } 164 } 165 } 166 } 167 168 return field; 169 } 170 171 174 private AbstractMethodDeclaration convert(SourceMethodElementInfo sourceMethod, CompilationResult compilationResult) { 175 176 AbstractMethodDeclaration method; 177 178 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 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 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 } 215 216 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 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 } 248 } 249 method.statements = statements; 250 } 251 } 252 253 return method; 254 } 255 256 259 private TypeDeclaration convert(SourceTypeElementInfo sourceType, CompilationResult compilationResult) { 260 261 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 } 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; 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 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 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 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 333 ISourceMethod[] sourceMethods = sourceType.getMethods(); 334 int sourceMethodCount = sourceMethods == null ? 0 : sourceMethods.length; 335 336 337 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 break; 346 } 347 } 348 } 349 type.methods = new AbstractMethodDeclaration[sourceMethodCount + neededCount]; 350 if (neededCount != 0) { 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()) { method.modifiers |= AccSemicolonBody; 358 } 359 type.methods[neededCount + i] = method; 360 } 361 362 return type; 363 } 364 365 370 private CompilationUnitDeclaration convert(SourceTypeElementInfo[] sourceTypes, CompilationResult compilationResult) { 371 372 SourceTypeElementInfo sourceType = sourceTypes[0]; 373 if (sourceType.getName() == null) 374 return null; 376 this.unit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0); 377 379 380 int start = sourceType.getNameSourceStart(); 381 int end = sourceType.getNameSourceEnd(); 382 383 384 if (sourceType.getPackageName() != null 385 && sourceType.getPackageName().length > 0) 386 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 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 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; } 426 return new ImportReference( 427 qImportName, 428 positions, 429 onDemand, 430 modifiers); 431 } 432 433 436 private TypeReference createTypeReference( 437 char[] typeSignature, 438 int start, 439 int end) { 440 441 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 459 if (identCount == 1) { 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 { 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 |