1 16 package com.google.gwt.dev.jdt; 17 18 import com.google.gwt.core.ext.TreeLogger; 19 import com.google.gwt.core.ext.UnableToCompleteException; 20 import com.google.gwt.core.ext.typeinfo.CompilationUnitProvider; 21 import com.google.gwt.core.ext.typeinfo.HasMetaData; 22 import com.google.gwt.core.ext.typeinfo.JAbstractMethod; 23 import com.google.gwt.core.ext.typeinfo.JClassType; 24 import com.google.gwt.core.ext.typeinfo.JConstructor; 25 import com.google.gwt.core.ext.typeinfo.JField; 26 import com.google.gwt.core.ext.typeinfo.JMethod; 27 import com.google.gwt.core.ext.typeinfo.JPackage; 28 import com.google.gwt.core.ext.typeinfo.JParameter; 29 import com.google.gwt.core.ext.typeinfo.JPrimitiveType; 30 import com.google.gwt.core.ext.typeinfo.JType; 31 import com.google.gwt.core.ext.typeinfo.TypeOracle; 32 import com.google.gwt.dev.util.Empty; 33 import com.google.gwt.dev.util.Util; 34 35 import org.eclipse.jdt.core.compiler.CharOperation; 36 import org.eclipse.jdt.core.compiler.IProblem; 37 import org.eclipse.jdt.internal.compiler.ASTVisitor; 38 import org.eclipse.jdt.internal.compiler.CompilationResult; 39 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 40 import org.eclipse.jdt.internal.compiler.ast.Argument; 41 import org.eclipse.jdt.internal.compiler.ast.Clinit; 42 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; 43 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 44 import org.eclipse.jdt.internal.compiler.ast.Initializer; 45 import org.eclipse.jdt.internal.compiler.ast.Javadoc; 46 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; 47 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 48 import org.eclipse.jdt.internal.compiler.ast.TypeReference; 49 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; 50 import org.eclipse.jdt.internal.compiler.env.IGenericType; 51 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 52 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; 53 import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding; 54 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 55 import org.eclipse.jdt.internal.compiler.lookup.ClassScope; 56 import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; 57 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding; 58 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 59 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; 60 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 61 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 62 63 import java.io.BufferedReader ; 64 import java.io.CharArrayReader ; 65 import java.io.File ; 66 import java.io.IOException ; 67 import java.util.ArrayList ; 68 import java.util.Arrays ; 69 import java.util.HashMap ; 70 import java.util.HashSet ; 71 import java.util.Iterator ; 72 import java.util.List ; 73 import java.util.Map ; 74 import java.util.Set ; 75 import java.util.regex.Pattern ; 76 77 93 public class TypeOracleBuilder { 94 95 private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s"); 96 97 static boolean parseMetaDataTags(char[] unitSource, HasMetaData hasMetaData, 98 Javadoc javadoc) { 99 100 int start = javadoc.sourceStart; 101 int end = javadoc.sourceEnd; 102 char[] comment = CharOperation.subarray(unitSource, start, end + 1); 103 if (comment == null) { 104 comment = new char[0]; 105 } 106 BufferedReader reader = new BufferedReader (new CharArrayReader (comment)); 107 String activeTag = null; 108 final List tagValues = new ArrayList (); 109 try { 110 String line = reader.readLine(); 111 boolean firstLine = true; 112 while (line != null) { 113 if (firstLine) { 114 firstLine = false; 115 int commentStart = line.indexOf("/**"); 116 if (commentStart == -1) { 117 return false; 119 } 120 line = line.substring(commentStart + 3); 121 } 122 123 String [] tokens = PATTERN_WHITESPACE.split(line); 124 boolean canIgnoreStar = true; 125 for (int i = 0; i < tokens.length; i++) { 126 String token = tokens[i]; 127 128 if (token.endsWith("*/")) { 131 token = token.substring(0, token.length() - 2); 132 } 133 134 if (canIgnoreStar && token.startsWith("*")) { 137 token = token.substring(1); 138 canIgnoreStar = false; 139 } 140 141 if (token.length() > 0) { 144 canIgnoreStar = false; 145 if (token.startsWith("@")) { 146 if (activeTag != null) { 151 finishTag(hasMetaData, activeTag, tagValues); 152 } 153 activeTag = token.substring(1); 154 } else if (activeTag != null) { 155 tagValues.add(token); 158 } else { 159 } 162 } 163 } 164 165 line = reader.readLine(); 166 } 167 } catch (IOException e) { 168 return false; 169 } 170 171 finishTag(hasMetaData, activeTag, tagValues); 174 return true; 175 } 176 177 private static void finishTag(HasMetaData hasMetaData, String tagName, 178 List tagValues) { 179 String [] values = (String []) tagValues.toArray(Empty.STRINGS); 183 hasMetaData.addMetaData(tagName, values); 184 tagValues.clear(); 185 } 186 187 private static void removeInfectedUnits(final TreeLogger logger, 188 final Map cudsByFileName) { 189 190 final Set pendingRemovals = new HashSet (); 191 TypeRefVisitor trv = new TypeRefVisitor() { 192 protected void onTypeRef(SourceTypeBinding referencedType, 193 CompilationUnitDeclaration unitOfReferrer) { 194 String referencedFn = String.valueOf(referencedType.getFileName()); 199 CompilationUnitDeclaration referencedCud = (CompilationUnitDeclaration) cudsByFileName.get(referencedFn); 200 if (referencedCud == null) { 201 String referrerFn = String.valueOf(unitOfReferrer.getFileName()); 205 if (cudsByFileName.containsKey(referrerFn) 206 && !pendingRemovals.contains(referrerFn)) { 207 TreeLogger branch = logger.branch(TreeLogger.TRACE, 208 "Cascaded removal of compilation unit '" + referrerFn + "'", 209 null); 210 final String badTypeName = CharOperation.toString(referencedType.compoundName); 211 branch.branch(TreeLogger.TRACE, 212 "Due to reference to unavailable type: " + badTypeName, null); 213 pendingRemovals.add(referrerFn); 214 } 215 } 216 } 217 }; 218 219 do { 220 for (Iterator iter = pendingRemovals.iterator(); iter.hasNext();) { 223 String fnToRemove = (String ) iter.next(); 224 Object removed = cudsByFileName.remove(fnToRemove); 225 assert (removed != null); 226 } 227 228 pendingRemovals.clear(); 231 232 for (Iterator iter = cudsByFileName.values().iterator(); iter.hasNext();) { 235 CompilationUnitDeclaration cud = (CompilationUnitDeclaration) iter.next(); 236 cud.traverse(trv, cud.scope); 237 } 238 } while (!pendingRemovals.isEmpty()); 239 } 240 241 private static void removeUnitsWithErrors(TreeLogger logger, 242 Map cudsByFileName) { 243 boolean anyRemoved = false; 246 for (Iterator iter = cudsByFileName.values().iterator(); iter.hasNext();) { 247 CompilationUnitDeclaration cud = (CompilationUnitDeclaration) iter.next(); 248 CompilationResult result = cud.compilationResult; 249 IProblem[] errors = result.getErrors(); 250 if (errors != null && errors.length > 0) { 251 anyRemoved = true; 252 iter.remove(); 253 254 String fileName = CharOperation.charToString(cud.getFileName()); 255 char[] source = cud.compilationResult.compilationUnit.getContents(); 256 Util.maybeDumpSource(logger, fileName, source, null); 257 logger.log(TreeLogger.TRACE, "Removing problematic compilation unit '" 258 + fileName + "'", null); 259 } 260 } 261 262 if (anyRemoved) { 263 removeInfectedUnits(logger, cudsByFileName); 266 } 267 } 268 269 private final CacheManager cacheManager; 270 271 275 public TypeOracleBuilder() { 276 cacheManager = new CacheManager(); 277 } 278 279 285 public TypeOracleBuilder(CacheManager cacheManager) { 286 this.cacheManager = cacheManager; 287 } 288 289 294 public TypeOracleBuilder(TypeOracle typeOracle) { 295 cacheManager = new CacheManager(typeOracle); 296 } 297 298 303 public void addCompilationUnit(CompilationUnitProvider cup) 304 throws UnableToCompleteException { 305 cacheManager.addCompilationUnit(cup); 306 } 307 308 public TypeOracle build(final TreeLogger logger) 309 throws UnableToCompleteException { 310 Set addedCups = cacheManager.getAddedCups(); 311 TypeOracle oracle = cacheManager.getTypeOracle(); 312 for (Iterator iter = addedCups.iterator(); iter.hasNext();) { 315 CompilationUnitProvider cup = (CompilationUnitProvider) iter.next(); 316 String location = cup.getLocation(); 317 if (!((location.indexOf("http://") != -1) || (location.indexOf("ftp://") != -1))) { 318 location = Util.findFileName(location); 319 if (!(new File (location).exists() || cup.isTransient())) { 320 iter.remove(); 321 logger.log( 322 TreeLogger.TRACE, 323 "The file " 324 + location 325 + " was removed by the user. All types therein are now unavailable.", 326 null); 327 } 328 } 329 } 330 CompilationUnitProvider[] cups = (CompilationUnitProvider[]) Util.toArray( 331 CompilationUnitProvider.class, addedCups); 332 Arrays.sort(cups, CompilationUnitProvider.LOCATION_COMPARATOR); 333 334 boolean foundJavaLangPackage = oracle.findPackage("java.lang") != null; 337 338 ICompilationUnit[] units = new ICompilationUnit[cups.length]; 341 for (int i = 0; i < cups.length; i++) { 342 if (!foundJavaLangPackage && cups[i].getPackageName().equals("java.lang")) { 343 foundJavaLangPackage = true; 344 } 345 units[i] = cacheManager.findUnitForCup(cups[i]); 346 } 347 348 if (!foundJavaLangPackage) { 350 Util.logMissingTypeErrorWithHints(logger, "java.lang.Object"); 351 throw new UnableToCompleteException(); 352 } 353 cacheManager.invalidateOnRefresh(oracle); 354 CompilationUnitDeclaration[] cuds = cacheManager.getAstCompiler().getCompilationUnitDeclarations( 355 logger, units); 356 357 final Map cudsByFileName = new HashMap (); 360 for (int i = 0; i < cuds.length; i++) { 361 CompilationUnitDeclaration cud = cuds[i]; 362 char[] location = cud.getFileName(); 363 cudsByFileName.put(String.valueOf(location), cud); 364 } 365 cacheManager.getCudsByFileName().putAll(cudsByFileName); 366 367 removeUnitsWithErrors(logger, cudsByFileName); 370 371 for (Iterator iter = cudsByFileName.values().iterator(); iter.hasNext();) { 374 CompilationUnitDeclaration cud = (CompilationUnitDeclaration) iter.next(); 375 ICompilationUnit unit = cud.compilationResult.compilationUnit; 379 ICompilationUnitAdapter adapter = ((ICompilationUnitAdapter) unit); 380 CompilationUnitProvider cup = adapter.getCompilationUnitProvider(); 381 JClassType[] seen = oracle.getTypesInCompilationUnit(cup); 382 if (seen.length > 0) { 383 iter.remove(); 386 } 387 } 388 389 final CacheManager.Mapper identityMapper = cacheManager.getIdentityMapper(); 392 for (Iterator iter = cudsByFileName.values().iterator(); iter.hasNext();) { 393 CompilationUnitDeclaration cud = (CompilationUnitDeclaration) iter.next(); 394 395 cud.traverse(new ASTVisitor() { 396 public boolean visit(TypeDeclaration typeDecl, BlockScope scope) { 397 JClassType enclosingType = identityMapper.get((SourceTypeBinding) typeDecl.binding.enclosingType()); 398 processType(typeDecl, enclosingType, true); 399 return true; 400 } 401 402 public boolean visit(TypeDeclaration typeDecl, ClassScope scope) { 403 JClassType enclosingType = identityMapper.get((SourceTypeBinding) typeDecl.binding.enclosingType()); 404 processType(typeDecl, enclosingType, false); 405 return true; 406 } 407 408 public boolean visit(TypeDeclaration typeDecl, 409 CompilationUnitScope scope) { 410 processType(typeDecl, null, false); 411 return true; 412 } 413 }, cud.scope); 414 } 415 416 for (Iterator iter = cudsByFileName.values().iterator(); iter.hasNext();) { 419 CompilationUnitDeclaration cud = (CompilationUnitDeclaration) iter.next(); 420 String loc = String.valueOf(cud.getFileName()); 421 String processing = "Processing types in compilation unit: " + loc; 422 final TreeLogger cudLogger = logger.branch(TreeLogger.SPAM, processing, 423 null); 424 final char[] source = cud.compilationResult.compilationUnit.getContents(); 425 426 cud.traverse(new ASTVisitor() { 427 public boolean visit(TypeDeclaration typeDecl, BlockScope scope) { 428 if (!resolveTypeDeclaration(cudLogger, source, typeDecl)) { 429 String name = String.valueOf(typeDecl.binding.readableName()); 430 String msg = "Unexpectedly unable to fully resolve type " + name; 431 logger.log(TreeLogger.WARN, msg, null); 432 } 433 return true; 434 } 435 436 public boolean visit(TypeDeclaration typeDecl, ClassScope scope) { 437 if (!resolveTypeDeclaration(cudLogger, source, typeDecl)) { 438 String name = String.valueOf(typeDecl.binding.readableName()); 439 String msg = "Unexpectedly unable to fully resolve type " + name; 440 logger.log(TreeLogger.WARN, msg, null); 441 } 442 return true; 443 } 444 445 public boolean visit(TypeDeclaration typeDecl, 446 CompilationUnitScope scope) { 447 if (!resolveTypeDeclaration(cudLogger, source, typeDecl)) { 448 String name = String.valueOf(typeDecl.binding.readableName()); 449 String msg = "Unexpectedly unable to fully resolve type " + name; 450 logger.log(TreeLogger.WARN, msg, null); 451 } 452 return true; 453 } 454 }, cud.scope); 455 } 456 Util.invokeInaccessableMethod(TypeOracle.class, "refresh", 457 new Class [] {TreeLogger.class}, oracle, new Object [] {logger}); 458 return oracle; 459 } 460 461 private CompilationUnitProvider getCup(TypeDeclaration typeDecl) { 462 ICompilationUnit icu = typeDecl.compilationResult.compilationUnit; 463 ICompilationUnitAdapter icua = (ICompilationUnitAdapter) icu; 464 return icua.getCompilationUnitProvider(); 465 } 466 467 private String getPackage(TypeDeclaration typeDecl) { 468 final char[][] pkgParts = typeDecl.compilationResult.compilationUnit.getPackageName(); 469 return String.valueOf(CharOperation.concatWith(pkgParts, '.')); 470 } 471 472 private String getQualifiedName(ReferenceBinding binding) { 473 return CharOperation.toString(binding.compoundName); 474 } 475 476 private String getSimpleName(TypeDeclaration typeDecl) { 477 return String.valueOf(typeDecl.name); 478 } 479 480 private boolean isInterface(TypeDeclaration typeDecl) { 481 if (typeDecl.kind() == IGenericType.INTERFACE_DECL) { 482 return true; 483 } else { 484 return false; 485 } 486 } 487 488 491 private void processType(TypeDeclaration typeDecl, JClassType enclosingType, 492 boolean isLocalType) { 493 TypeOracle oracle = cacheManager.getTypeOracle(); 494 495 SourceTypeBinding binding = typeDecl.binding; 499 if (binding.constantPoolName() == null) { 500 504 return; 505 } 506 507 String qname; 508 String jclassName; 509 if (binding instanceof LocalTypeBinding) { 510 char[] localName = binding.constantPoolName(); 511 for (int i = 0, c = localName.length; i < c; ++i) { 512 if (localName[i] == '/' || localName[i] == '$') { 513 localName[i] = '.'; 514 } 515 } 516 qname = String.valueOf(localName); 517 jclassName = qname.substring(qname.lastIndexOf('.') + 1); 518 } else { 519 qname = getQualifiedName(binding); 520 jclassName = getSimpleName(typeDecl); 521 } 522 if (oracle.findType(qname) != null) { 523 return; 527 } 528 529 String jpkgName = getPackage(typeDecl); 530 JPackage pkg = oracle.getOrCreatePackage(jpkgName); 531 final boolean jclassIsIntf = isInterface(typeDecl); 532 CompilationUnitProvider cup = getCup(typeDecl); 533 534 int declStart = typeDecl.declarationSourceStart; 535 int declEnd = typeDecl.declarationSourceEnd; 536 int bodyStart = typeDecl.bodyStart; 537 int bodyEnd = typeDecl.bodyEnd; 538 539 JClassType type = new JClassType(oracle, cup, pkg, enclosingType, 540 isLocalType, jclassName, declStart, declEnd, bodyStart, bodyEnd, 541 jclassIsIntf); 542 543 cacheManager.setTypeForBinding(binding, type); 544 } 545 546 private boolean resolveField(TreeLogger logger, char[] unitSource, 547 JClassType enclosingType, FieldDeclaration jfield) { 548 549 if (jfield instanceof Initializer) { 550 return true; 553 } 554 555 String name = String.valueOf(jfield.name); 556 JField field = new JField(enclosingType, name); 557 558 field.addModifierBits(Shared.bindingToModifierBits(jfield.binding)); 561 562 TypeBinding jfieldType = jfield.binding.type; 565 566 JType fieldType = resolveType(logger, jfieldType); 567 if (fieldType == null) { 568 return false; 571 } 572 field.setType(fieldType); 573 574 if (jfield.javadoc != null) { 577 if (!parseMetaDataTags(unitSource, field, jfield.javadoc)) { 578 return false; 579 } 580 } 581 582 return true; 583 } 584 585 private boolean resolveFields(TreeLogger logger, char[] unitSource, 586 JClassType type, FieldDeclaration[] jfields) { 587 if (jfields != null) { 588 for (int i = 0; i < jfields.length; i++) { 589 FieldDeclaration jfield = jfields[i]; 590 if (!resolveField(logger, unitSource, type, jfield)) { 591 return false; 592 } 593 } 594 } 595 return true; 596 } 597 598 private boolean resolveMethod(TreeLogger logger, char[] unitSource, 599 JClassType enclosingType, AbstractMethodDeclaration jmethod) { 600 JAbstractMethod method; 601 602 if (jmethod instanceof Clinit) { 603 return true; 606 } 607 608 String name = null; 609 int declStart = jmethod.declarationSourceStart; 610 int declEnd = jmethod.declarationSourceEnd; 611 int bodyStart = jmethod.bodyStart; 612 int bodyEnd = jmethod.bodyEnd; 613 614 if (jmethod.isConstructor()) { 615 name = String.valueOf(enclosingType.getSimpleSourceName()); 616 method = new JConstructor(enclosingType, name, declStart, declEnd, 617 bodyStart, bodyEnd); 618 } else { 619 name = String.valueOf(jmethod.binding.selector); 620 method = new JMethod(enclosingType, name, declStart, declEnd, bodyStart, 621 bodyEnd); 622 623 TypeBinding jreturnType = ((MethodDeclaration) jmethod).returnType.resolvedType; 626 JType returnType = resolveType(logger, jreturnType); 627 if (returnType == null) { 628 return false; 631 } 632 ((JMethod) method).setReturnType(returnType); 633 } 634 635 method.addModifierBits(Shared.bindingToModifierBits(jmethod.binding)); 638 if (enclosingType.isInterface() != null) { 639 method.addModifierBits(Shared.MOD_PUBLIC | Shared.MOD_ABSTRACT); 642 } 643 644 Argument[] jparams = jmethod.arguments; 647 if (!resolveParameters(logger, method, jparams)) { 648 return false; 649 } 650 651 TypeReference[] jthrows = jmethod.thrownExceptions; 654 if (!resolveThrownTypes(logger, method, jthrows)) { 655 return false; 656 } 657 658 if (jmethod.javadoc != null) { 661 if (!parseMetaDataTags(unitSource, method, jmethod.javadoc)) { 662 return false; 663 } 664 } 665 666 return true; 667 } 668 669 private boolean resolveMethods(TreeLogger logger, char[] unitSource, 670 JClassType type, AbstractMethodDeclaration[] jmethods) { 671 if (jmethods != null) { 672 for (int i = 0; i < jmethods.length; i++) { 673 AbstractMethodDeclaration jmethod = jmethods[i]; 674 if (!resolveMethod(logger, unitSource, type, jmethod)) { 675 return false; 676 } 677 } 678 } 679 return true; 680 } 681 682 private boolean resolveParameter(TreeLogger logger, JAbstractMethod method, 683 Argument jparam) { 684 TypeBinding jtype = jparam.binding.type; 685 JType type = resolveType(logger, jtype); 686 if (type == null) { 687 return false; 690 } 691 692 String name = String.valueOf(jparam.name); 693 new JParameter(method, type, name); 694 return true; 695 } 696 697 private boolean resolveParameters(TreeLogger logger, JAbstractMethod method, 698 Argument[] jparams) { 699 if (jparams != null) { 700 for (int i = 0; i < jparams.length; i++) { 701 Argument jparam = jparams[i]; 702 if (!resolveParameter(logger, method, jparam)) { 703 return false; 704 } 705 } 706 } 707 return true; 708 } 709 710 private boolean resolveThrownType(TreeLogger logger, JAbstractMethod method, 711 TypeReference jthrown) { 712 713 JType type = resolveType(logger, jthrown.resolvedType); 714 if (type == null) { 715 return false; 718 } 719 720 method.addThrows(type); 721 722 return true; 723 } 724 725 private boolean resolveThrownTypes(TreeLogger logger, JAbstractMethod method, 726 TypeReference[] jthrows) { 727 if (jthrows != null) { 728 for (int i = 0; i < jthrows.length; i++) { 729 TypeReference jthrown = jthrows[i]; 730 if (!resolveThrownType(logger, method, jthrown)) { 731 return false; 732 } 733 } 734 } 735 return true; 736 } 737 738 private JType resolveType(TreeLogger logger, TypeBinding binding) { 739 TypeOracle oracle = cacheManager.getTypeOracle(); 740 if (binding instanceof BaseTypeBinding) { 743 switch (binding.id) { 744 case TypeIds.T_boolean: 745 return JPrimitiveType.BOOLEAN; 746 case TypeIds.T_byte: 747 return JPrimitiveType.BYTE; 748 case TypeIds.T_char: 749 return JPrimitiveType.CHAR; 750 case TypeIds.T_short: 751 return JPrimitiveType.SHORT; 752 case TypeIds.T_int: 753 return JPrimitiveType.INT; 754 case TypeIds.T_long: 755 return JPrimitiveType.LONG; 756 case TypeIds.T_float: 757 return JPrimitiveType.FLOAT; 758 case TypeIds.T_double: 759 return JPrimitiveType.DOUBLE; 760 case TypeIds.T_void: 761 return JPrimitiveType.VOID; 762 default: 763 assert false : "Unexpected base type id " + binding.id; 764 } 765 } 766 767 if (binding instanceof SourceTypeBinding) { 770 SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) binding; 771 772 String typeName = String.valueOf(sourceTypeBinding.readableName()); 776 JType resolvedType = oracle.findType(typeName); 777 if (resolvedType != null) { 778 return resolvedType; 779 } 780 781 resolvedType = cacheManager.getTypeForBinding(sourceTypeBinding); 784 if (resolvedType != null) { 785 return resolvedType; 786 } 787 } 788 789 if (binding instanceof ArrayBinding) { 792 ArrayBinding arrayBinding = (ArrayBinding) binding; 793 794 TypeBinding leafBinding = arrayBinding.leafComponentType; 797 JType resolvedType = resolveType(logger, leafBinding); 798 if (resolvedType != null) { 799 int dims = arrayBinding.dimensions; 800 for (int i = 0; i < dims; ++i) { 801 resolvedType = oracle.getArrayType(resolvedType); 805 } 806 return resolvedType; 807 } else { 808 } 811 } 812 813 if (binding instanceof BinaryTypeBinding) { 816 logger.log(TreeLogger.WARN, 817 "Source not available for this type, so it cannot be resolved", null); 818 } 819 820 String name = String.valueOf(binding.readableName()); 821 logger.log(TreeLogger.WARN, "Unable to resolve type: " + name, null); 822 return null; 823 } 824 825 private boolean resolveTypeDeclaration(TreeLogger logger, char[] unitSource, 826 TypeDeclaration jclass) { 827 SourceTypeBinding binding = jclass.binding; 828 if (binding.constantPoolName() == null) { 829 833 return true; 834 } 835 836 String qname = String.valueOf(binding.qualifiedSourceName()); 837 logger.log(TreeLogger.SPAM, "Found type '" + qname + "'", null); 838 839 JClassType type = (JClassType) resolveType(logger, binding); 840 if (type == null) { 841 return false; 844 } 845 846 type.addModifierBits(Shared.bindingToModifierBits(jclass.binding)); 849 850 if (type.isInterface() == null) { 853 ReferenceBinding superclassRef = binding.superclass; 854 if (superclassRef != null) { 855 JClassType superclass = (JClassType) resolveType(logger, superclassRef); 856 if (superclass == null) { 857 return false; 858 } 859 type.setSuperclass(superclass); 860 } 861 } 862 863 ReferenceBinding[] superintfRefs = binding.superInterfaces; 866 for (int i = 0; i < superintfRefs.length; i++) { 867 ReferenceBinding superintfRef = superintfRefs[i]; 868 JClassType intf = (JClassType) resolveType(logger, superintfRef); 869 if (intf == null) { 870 return false; 873 } 874 type.addImplementedInterface(intf); 875 } 876 877 FieldDeclaration[] jfields = jclass.fields; 880 if (!resolveFields(logger, unitSource, type, jfields)) { 881 return false; 882 } 883 884 AbstractMethodDeclaration[] jmethods = jclass.methods; 887 if (!resolveMethods(logger, unitSource, type, jmethods)) { 888 return false; 889 } 890 891 if (jclass.javadoc != null) { 894 if (!parseMetaDataTags(unitSource, type, jclass.javadoc)) { 895 return false; 896 } 897 } 898 899 return true; 900 } 901 902 } 903 | Popular Tags |