Ejemplo n.º 1
0
 public boolean existsUsingJarTypeCache() {
   if (getPackageFragmentRoot().isArchive()) {
     JavaModelManager manager = JavaModelManager.getJavaModelManager();
     IType type = getType();
     Object info = manager.getInfo(type);
     if (info == JavaModelCache.NON_EXISTING_JAR_TYPE_INFO) return false;
     else if (info != null) return true;
     // info is null
     JavaElementInfo parentInfo = (JavaElementInfo) manager.getInfo(getParent());
     if (parentInfo != null) {
       // if parent is open, this class file must be in its children
       IJavaElement[] children = parentInfo.getChildren();
       for (int i = 0, length = children.length; i < length; i++) {
         if (this.name.equals(((ClassFile) children[i]).name)) return true;
       }
       return false;
     }
     try {
       info =
           getJarBinaryTypeInfo(
               (PackageFragment) getParent(),
               true /*fully initialize so as to not keep a reference to the byte array*/);
     } catch (CoreException e) {
       // leave info null
     } catch (IOException e) {
       // leave info null
     } catch (ClassFormatException e) {
       // leave info null
     }
     manager.putJarTypeInfo(type, info == null ? JavaModelCache.NON_EXISTING_JAR_TYPE_INFO : info);
     return info != null;
   } else return exists();
 }
Ejemplo n.º 2
0
  private int initializeBuilder(int kind, boolean forBuild) throws CoreException {
    // some calls just need the nameEnvironment initialized so skip the rest
    this.javaProject = (JavaProject) JavaCore.create(this.currentProject);
    this.workspaceRoot = this.currentProject.getWorkspace().getRoot();

    if (forBuild) {
      // cache the known participants for this project
      this.participants =
          JavaModelManager.getJavaModelManager()
              .compilationParticipants
              .getCompilationParticipants(this.javaProject);
      if (this.participants != null)
        for (int i = 0, l = this.participants.length; i < l; i++)
          if (this.participants[i].aboutToBuild(this.javaProject)
              == CompilationParticipant.NEEDS_FULL_BUILD) kind = FULL_BUILD;

      // Flush the existing external files cache if this is the beginning of a build cycle
      String projectName = this.currentProject.getName();
      if (builtProjects == null || builtProjects.contains(projectName)) {
        builtProjects = new ArrayList();
      }
      builtProjects.add(projectName);
    }

    this.binaryLocationsPerProject = new SimpleLookupTable(3);
    this.nameEnvironment =
        new NameEnvironment(
            this.workspaceRoot, this.javaProject, this.binaryLocationsPerProject, this.notifier);

    if (forBuild) {
      String filterSequence =
          this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, true);
      char[][] filters =
          filterSequence != null && filterSequence.length() > 0
              ? CharOperation.splitAndTrimOn(',', filterSequence.toCharArray())
              : null;
      if (filters == null) {
        this.extraResourceFileFilters = null;
        this.extraResourceFolderFilters = null;
      } else {
        int fileCount = 0, folderCount = 0;
        for (int i = 0, l = filters.length; i < l; i++) {
          char[] f = filters[i];
          if (f.length == 0) continue;
          if (f[f.length - 1] == '/') folderCount++;
          else fileCount++;
        }
        this.extraResourceFileFilters = new char[fileCount][];
        this.extraResourceFolderFilters = new String[folderCount];
        for (int i = 0, l = filters.length; i < l; i++) {
          char[] f = filters[i];
          if (f.length == 0) continue;
          if (f[f.length - 1] == '/')
            this.extraResourceFolderFilters[--folderCount] = new String(f, 0, f.length - 1);
          else this.extraResourceFileFilters[--fileCount] = f;
        }
      }
    }
    return kind;
  }
Ejemplo n.º 3
0
 public static IMarker[] getProblemsFor(IResource resource) {
   try {
     if (resource != null && resource.exists()) {
       IMarker[] markers =
           resource.findMarkers(
               IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
       Set markerTypes =
           JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
       if (markerTypes.isEmpty()) return markers;
       ArrayList markerList = new ArrayList(5);
       for (int i = 0, length = markers.length; i < length; i++) {
         markerList.add(markers[i]);
       }
       Iterator iterator = markerTypes.iterator();
       while (iterator.hasNext()) {
         markers = resource.findMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
         for (int i = 0, length = markers.length; i < length; i++) {
           markerList.add(markers[i]);
         }
       }
       IMarker[] result;
       markerList.toArray(result = new IMarker[markerList.size()]);
       return result;
     }
   } catch (CoreException e) {
     // assume there are no problems
   }
   return new IMarker[0];
 }
Ejemplo n.º 4
0
 public byte[] getBytes() throws JavaModelException {
   JavaElement pkg = (JavaElement) getParent();
   if (pkg instanceof JarPackageFragment) {
     JarPackageFragmentRoot root = (JarPackageFragmentRoot) pkg.getParent();
     ZipFile zip = null;
     try {
       zip = root.getJar();
       String entryName = Util.concatWith(((PackageFragment) pkg).names, getElementName(), '/');
       ZipEntry ze = zip.getEntry(entryName);
       if (ze != null) {
         return org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
       }
       throw new JavaModelException(
           new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
     } catch (IOException ioe) {
       throw new JavaModelException(ioe, IJavaModelStatusConstants.IO_EXCEPTION);
     } catch (CoreException e) {
       if (e instanceof JavaModelException) {
         throw (JavaModelException) e;
       } else {
         throw new JavaModelException(e);
       }
     } finally {
       JavaModelManager.getJavaModelManager().closeZipFile(zip);
     }
   } else {
     IFile file = (IFile) resource();
     return Util.getResourceContentsAsByteArray(file);
   }
 }
  public void build(boolean computeSubtypes) {
    JavaModelManager manager = JavaModelManager.getJavaModelManager();
    try {
      // optimize access to zip files while building hierarchy
      manager.cacheZipFiles(this);

      if (computeSubtypes) {
        // Note by construction there always is a focus type here
        IType focusType = getType();
        boolean focusIsObject =
            focusType.getElementName().equals(new String(IIndexConstants.OBJECT));
        int amountOfWorkForSubtypes =
            focusIsObject ? 5 : 80; // percentage of work needed to get possible subtypes
        IProgressMonitor possibleSubtypesMonitor =
            this.hierarchy.progressMonitor == null
                ? null
                : new SubProgressMonitor(this.hierarchy.progressMonitor, amountOfWorkForSubtypes);
        HashSet localTypes =
            new HashSet(
                10); // contains the paths that have potential subtypes that are local/anonymous
                     // types
        String[] allPossibleSubtypes;
        if (((Member) focusType).getOuterMostLocalContext() == null) {
          // top level or member type
          allPossibleSubtypes = determinePossibleSubTypes(localTypes, possibleSubtypesMonitor);
        } else {
          // local or anonymous type
          allPossibleSubtypes = CharOperation.NO_STRINGS;
        }
        if (allPossibleSubtypes != null) {
          IProgressMonitor buildMonitor =
              this.hierarchy.progressMonitor == null
                  ? null
                  : new SubProgressMonitor(
                      this.hierarchy.progressMonitor, 100 - amountOfWorkForSubtypes);
          this.hierarchy.initialize(allPossibleSubtypes.length);
          buildFromPotentialSubtypes(allPossibleSubtypes, localTypes, buildMonitor);
        }
      } else {
        this.hierarchy.initialize(1);
        buildSupertypes();
      }
    } finally {
      manager.flushZipFiles(this);
    }
  }
 /** @private Debugging purposes */
 protected void toString(int tab, StringBuffer buffer) {
   Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this);
   if (info == null || !(info instanceof JavaElementInfo)) return;
   IJavaScriptElement[] children = ((JavaElementInfo) info).getChildren();
   for (int i = 0; i < children.length; i++) {
     if (i > 0) buffer.append("\n"); // $NON-NLS-1$
     ((JavaElement) children[i]).toString(tab, buffer);
   }
 }
Ejemplo n.º 7
0
 /*
  * @see IClassFile
  */
 public ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProgressMonitor monitor)
     throws JavaModelException {
   CompilationUnit workingCopy =
       new ClassFileWorkingCopy(this, owner == null ? DefaultWorkingCopyOwner.PRIMARY : owner);
   JavaModelManager manager = JavaModelManager.getJavaModelManager();
   JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo =
       manager.getPerWorkingCopyInfo(
           workingCopy,
           false /*don't create*/,
           true /*record usage*/,
           null /*not used since don't create*/);
   if (perWorkingCopyInfo != null) {
     return perWorkingCopyInfo
         .getWorkingCopy(); // return existing handle instead of the one created above
   }
   BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, null);
   op.runOperation(monitor);
   return workingCopy;
 }
Ejemplo n.º 8
0
  private void recordNewState(State state) {
    Object[] keyTable = this.binaryLocationsPerProject.keyTable;
    for (int i = 0, l = keyTable.length; i < l; i++) {
      IProject prereqProject = (IProject) keyTable[i];
      if (prereqProject != null && prereqProject != this.currentProject)
        state.recordStructuralDependency(prereqProject, getLastState(prereqProject));
    }

    if (DEBUG) System.out.println("JavaBuilder: Recording new state : " + state); // $NON-NLS-1$
    // state.dump();
    JavaModelManager.getJavaModelManager().setLastBuiltState(this.currentProject, state);
  }
  ProjectCache getProjectCache(JavaProject project) {
    ProjectCache cache = this.projectCache;
    if (cache == null) {
      IPackageFragmentRoot[] roots;
      Map reverseMap = new HashMap(3);
      try {
        roots = project.getAllPackageFragmentRoots(reverseMap);
      } catch (JavaModelException e) {
        // project does not exist: cannot happen since this is the info of the project
        roots = new IPackageFragmentRoot[0];
        reverseMap.clear();
      }

      //			HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
      HashMap pkgFragmentsCaches = new HashMap();
      int length = roots.length;
      JavaModelManager manager = project.manager; // JavaModelManager.getJavaModelManager();
      for (int i = 0; i < length; i++) {
        IPackageFragmentRoot root = roots[i];
        DeltaProcessor.RootInfo rootInfo =
            null; // (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
        if (rootInfo == null || rootInfo.project.equals(project)) {
          // ensure that an identical root is used (see
          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=217059 )
          roots[i] = root = (IPackageFragmentRoot) manager.getExistingElement(root);
          // compute fragment cache
          HashSetOfArray fragmentsCache = new HashSetOfArray();
          initializePackageNames(root, fragmentsCache);
          pkgFragmentsCaches.put(root, fragmentsCache);
        }
      }

      cache = new ProjectCache(roots, reverseMap, pkgFragmentsCaches);
      this.projectCache = cache;
    }
    return cache;
  }
Ejemplo n.º 10
0
  /*
   * @see IClassFile#becomeWorkingCopy(IProblemRequestor, WorkingCopyOwner, IProgressMonitor)
   */
  public ICompilationUnit becomeWorkingCopy(
      IProblemRequestor problemRequestor, WorkingCopyOwner owner, IProgressMonitor monitor)
      throws JavaModelException {
    JavaModelManager manager = JavaModelManager.getJavaModelManager();
    CompilationUnit workingCopy =
        new ClassFileWorkingCopy(this, owner == null ? DefaultWorkingCopyOwner.PRIMARY : owner);
    JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo =
        manager.getPerWorkingCopyInfo(
            workingCopy,
            false /*don't create*/,
            true /*record usage*/,
            null /*no problem requestor needed*/);
    if (perWorkingCopyInfo == null) {
      // close cu and its children
      close();

      BecomeWorkingCopyOperation operation =
          new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
      operation.runOperation(monitor);

      return workingCopy;
    }
    return perWorkingCopyInfo.workingCopy;
  }
Ejemplo n.º 11
0
  public static void removeProblemsFor(IResource resource) {
    try {
      if (resource != null && resource.exists()) {
        resource.deleteMarkers(
            IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);

        // delete managed markers
        Set markerTypes =
            JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
        if (markerTypes.size() == 0) return;
        Iterator iterator = markerTypes.iterator();
        while (iterator.hasNext())
          resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
      }
    } catch (CoreException e) {
      // assume there were no problems
    }
  }
Ejemplo n.º 12
0
  /* Return the list of projects for which it requires a resource delta. This builder's project
   * is implicitly included and need not be specified. Builders must re-specify the list
   * of interesting projects every time they are run as this is not carried forward
   * beyond the next build. Missing projects should be specified but will be ignored until
   * they are added to the workspace.
   */
  private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) {
    if (this.javaProject == null || this.workspaceRoot == null) return new IProject[0];

    ArrayList projects = new ArrayList();
    ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
    try {
      IClasspathEntry[] entries = this.javaProject.getExpandedClasspath();
      for (int i = 0, l = entries.length; i < l; i++) {
        IClasspathEntry entry = entries[i];
        IPath path = entry.getPath();
        IProject p = null;
        switch (entry.getEntryKind()) {
          case IClasspathEntry.CPE_PROJECT:
            p =
                this.workspaceRoot.getProject(
                    path.lastSegment()); // missing projects are considered too
            if (((ClasspathEntry) entry).isOptional()
                && !JavaProject.hasJavaNature(p)) // except if entry is optional
            p = null;
            break;
          case IClasspathEntry.CPE_LIBRARY:
            if (includeBinaryPrerequisites && path.segmentCount() > 0) {
              // some binary resources on the class path can come from projects that are not
              // included in the project references
              IResource resource = this.workspaceRoot.findMember(path.segment(0));
              if (resource instanceof IProject) {
                p = (IProject) resource;
              } else {
                resource = externalFoldersManager.getFolder(path);
                if (resource != null) p = resource.getProject();
              }
            }
        }
        if (p != null && !projects.contains(p)) projects.add(p);
      }
    } catch (JavaModelException e) {
      return new IProject[0];
    }
    IProject[] result = new IProject[projects.size()];
    projects.toArray(result);
    return result;
  }
Ejemplo n.º 13
0
 private IBinaryType getJarBinaryTypeInfo(PackageFragment pkg, boolean fullyInitialize)
     throws CoreException, IOException, ClassFormatException {
   JarPackageFragmentRoot root = (JarPackageFragmentRoot) pkg.getParent();
   ZipFile zip = null;
   try {
     zip = root.getJar();
     String entryName = Util.concatWith(pkg.names, getElementName(), '/');
     ZipEntry ze = zip.getEntry(entryName);
     if (ze != null) {
       byte contents[] =
           org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
       String fileName =
           root.getHandleIdentifier() + IDependent.JAR_FILE_ENTRY_SEPARATOR + entryName;
       return new ClassFileReader(contents, fileName.toCharArray(), fullyInitialize);
     }
   } finally {
     JavaModelManager.getJavaModelManager().closeZipFile(zip);
   }
   return null;
 }
Ejemplo n.º 14
0
  protected String[] getPathsOfDeclaringType() {
    if (this.typeQualification == null && this.typeSimpleName == null) return null;

    final PathCollector pathCollector = new PathCollector();
    IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
    IndexManager indexManager = JavaModelManager.getIndexManager();
    SearchPattern searchPattern =
        new TypeDeclarationPattern(
            this.typeSimpleName != null
                ? null
                : this.typeQualification, // use the qualification only if no simple name
            null, // do find member types
            this.typeSimpleName,
            IIndexConstants.TYPE_SUFFIX,
            this.pattern.getMatchRule());
    IndexQueryRequestor searchRequestor =
        new IndexQueryRequestor() {
          public boolean acceptIndexMatch(
              String documentPath,
              SearchPattern indexRecord,
              SearchParticipant participant,
              AccessRuleSet access) {
            TypeDeclarationPattern record = (TypeDeclarationPattern) indexRecord;
            if (record.enclosingTypeNames
                != IIndexConstants.ONE_ZERO_CHAR) { // filter out local and anonymous classes
              pathCollector.acceptIndexMatch(documentPath, indexRecord, participant, access);
            }
            return true;
          }
        };

    indexManager.performConcurrentJob(
        new PatternSearchJob(searchPattern, new JavaSearchParticipant(), scope, searchRequestor),
        IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
        progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));
    return pathCollector.getPaths();
  }
  /**
   * Find the set of candidate subtypes of a given type.
   *
   * <p>The requestor is notified of super type references (with actual path of its occurrence) for
   * all types which are potentially involved inside a particular hierarchy. The match locator is
   * not used here to narrow down the results, the type hierarchy resolver is rather used to compute
   * the whole hierarchy at once.
   *
   * @param type
   * @param scope
   * @param binariesFromIndexMatches
   * @param pathRequestor
   * @param waitingPolicy
   * @param progressMonitor
   */
  public static void searchAllPossibleSubTypes(
      IType type,
      IJavaSearchScope scope,
      final Map binariesFromIndexMatches,
      final IPathRequestor pathRequestor,
      int waitingPolicy, // WaitUntilReadyToSearch | ForceImmediateSearch | CancelIfNotReadyToSearch
      final IProgressMonitor progressMonitor) {

    /* embed constructs inside arrays so as to pass them to (inner) collector */
    final Queue queue = new Queue();
    final HashtableOfObject foundSuperNames = new HashtableOfObject(5);

    IndexManager indexManager = JavaModelManager.getIndexManager();

    /* use a special collector to collect paths and queue new subtype names */
    IndexQueryRequestor searchRequestor =
        new IndexQueryRequestor() {
          public boolean acceptIndexMatch(
              String documentPath,
              SearchPattern indexRecord,
              SearchParticipant participant,
              AccessRuleSet access) {
            SuperTypeReferencePattern record = (SuperTypeReferencePattern) indexRecord;
            boolean isLocalOrAnonymous = record.enclosingTypeName == IIndexConstants.ONE_ZERO;
            pathRequestor.acceptPath(documentPath, isLocalOrAnonymous);
            char[] typeName = record.simpleName;
            if (documentPath.toLowerCase().endsWith(SUFFIX_STRING_class)) {
              int suffix = documentPath.length() - SUFFIX_STRING_class.length();
              HierarchyBinaryType binaryType =
                  (HierarchyBinaryType) binariesFromIndexMatches.get(documentPath);
              if (binaryType == null) {
                char[] enclosingTypeName = record.enclosingTypeName;
                if (isLocalOrAnonymous) {
                  int lastSlash = documentPath.lastIndexOf('/');
                  int lastDollar = documentPath.lastIndexOf('$');
                  if (lastDollar == -1) {
                    // malformed local or anonymous type: it doesn't contain a $ in its name
                    // treat it as a top level type
                    enclosingTypeName = null;
                    typeName = documentPath.substring(lastSlash + 1, suffix).toCharArray();
                  } else {
                    enclosingTypeName =
                        documentPath.substring(lastSlash + 1, lastDollar).toCharArray();
                    typeName = documentPath.substring(lastDollar + 1, suffix).toCharArray();
                  }
                }
                binaryType =
                    new HierarchyBinaryType(
                        record.modifiers,
                        record.pkgName,
                        typeName,
                        enclosingTypeName,
                        record.typeParameterSignatures,
                        record.classOrInterface);
                binariesFromIndexMatches.put(documentPath, binaryType);
              }
              binaryType.recordSuperType(
                  record.superSimpleName, record.superQualification, record.superClassOrInterface);
            }
            if (!isLocalOrAnonymous // local or anonymous types cannot have subtypes outside the cu
                                    // that define them
                && !foundSuperNames.containsKey(typeName)) {
              foundSuperNames.put(typeName, typeName);
              queue.add(typeName);
            }
            return true;
          }
        };

    int superRefKind;
    try {
      superRefKind =
          type.isClass()
              ? SuperTypeReferencePattern.ONLY_SUPER_CLASSES
              : SuperTypeReferencePattern.ALL_SUPER_TYPES;
    } catch (JavaModelException e) {
      superRefKind = SuperTypeReferencePattern.ALL_SUPER_TYPES;
    }
    SuperTypeReferencePattern pattern =
        new SuperTypeReferencePattern(
            null, null, superRefKind, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
    MatchLocator.setFocus(pattern, type);
    SubTypeSearchJob job =
        new SubTypeSearchJob(
            pattern,
            new JavaSearchParticipant(), // java search only
            scope,
            searchRequestor);

    int ticks = 0;
    queue.add(type.getElementName().toCharArray());
    try {
      while (queue.start <= queue.end) {
        if (progressMonitor != null && progressMonitor.isCanceled()) return;

        // all subclasses of OBJECT are actually all types
        char[] currentTypeName = queue.retrieve();
        if (CharOperation.equals(currentTypeName, IIndexConstants.OBJECT)) currentTypeName = null;

        // search all index references to a given supertype
        pattern.superSimpleName = currentTypeName;
        indexManager.performConcurrentJob(
            job,
            waitingPolicy,
            progressMonitor == null
                ? null
                : new NullProgressMonitor() {
                  // don't report progress since this is too costly for deep hierarchies (see
                  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=34078 )
                  // just handle isCanceled() (see
                  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=179511 )
                  public void setCanceled(boolean value) {
                    progressMonitor.setCanceled(value);
                  }

                  public boolean isCanceled() {
                    return progressMonitor.isCanceled();
                  }
                  // and handle subTask(...) (see
                  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=34078 )
                  public void subTask(String name) {
                    progressMonitor.subTask(name);
                  }
                });
        if (progressMonitor != null && ++ticks <= MAXTICKS) progressMonitor.worked(1);

        // in case, we search all subtypes, no need to search further
        if (currentTypeName == null) break;
      }
    } finally {
      job.finished();
    }
  }
Ejemplo n.º 16
0
 private void clearLastState() {
   JavaModelManager.getJavaModelManager().setLastBuiltState(this.currentProject, null);
 }
Ejemplo n.º 17
0
 public State getLastState(IProject project) {
   return (State)
       JavaModelManager.getJavaModelManager().getLastBuiltState(project, this.notifier.monitor);
 }
  /**
   * Resolve the supertypes for the types contained in the given openables (ICompilationUnits and/or
   * IClassFiles). Inform the requestor of the resolved supertypes for each supplied source type
   * using: connect(ISourceType suppliedType, IGenericType superclass, IGenericType[]
   * superinterfaces)
   *
   * <p>Also inform the requestor of the supertypes of each additional requested super type which is
   * also a source type instead of a binary type.
   *
   * @param openables
   * @param localTypes
   * @param monitor
   */
  public void resolve(Openable[] openables, HashSet localTypes, IProgressMonitor monitor) {
    try {
      int openablesLength = openables.length;
      CompilationUnitDeclaration[] parsedUnits = new CompilationUnitDeclaration[openablesLength];
      boolean[] hasLocalType = new boolean[openablesLength];
      org.aspectj.org.eclipse.jdt.core.ICompilationUnit[] cus =
          new org.aspectj.org.eclipse.jdt.core.ICompilationUnit[openablesLength];
      int unitsIndex = 0;

      CompilationUnitDeclaration focusUnit = null;
      ReferenceBinding focusBinaryBinding = null;
      IType focus = this.builder.getType();
      Openable focusOpenable = null;
      if (focus != null) {
        if (focus.isBinary()) {
          focusOpenable = (Openable) focus.getClassFile();
        } else {
          focusOpenable = (Openable) focus.getCompilationUnit();
        }
      }

      // build type bindings
      Parser parser = new Parser(this.lookupEnvironment.problemReporter, true);
      final boolean isJava8 = this.options.sourceLevel >= ClassFileConstants.JDK1_8;
      for (int i = 0; i < openablesLength; i++) {
        Openable openable = openables[i];
        if (openable instanceof org.aspectj.org.eclipse.jdt.core.ICompilationUnit) {
          org.aspectj.org.eclipse.jdt.core.ICompilationUnit cu =
              (org.aspectj.org.eclipse.jdt.core.ICompilationUnit) openable;

          // contains a potential subtype as a local or anonymous type?
          boolean containsLocalType = false;
          if (localTypes == null) { // case of hierarchy on region
            containsLocalType = true;
          } else {
            IPath path = cu.getPath();
            containsLocalType =
                cu.isWorkingCopy()
                    ? true /* presume conservatively */
                    : localTypes.contains(path.toString());
          }

          // build parsed unit
          CompilationUnitDeclaration parsedUnit = null;
          if (cu.isOpen()) {
            // create parsed unit from source element infos
            CompilationResult result =
                new CompilationResult(
                    (ICompilationUnit) cu, i, openablesLength, this.options.maxProblemsPerUnit);
            SourceTypeElementInfo[] typeInfos = null;
            try {
              IType[] topLevelTypes = cu.getTypes();
              int topLevelLength = topLevelTypes.length;
              if (topLevelLength == 0)
                continue; // empty cu: no need to parse (see
                          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=65677)
              typeInfos = new SourceTypeElementInfo[topLevelLength];
              for (int j = 0; j < topLevelLength; j++) {
                IType topLevelType = topLevelTypes[j];
                typeInfos[j] =
                    (SourceTypeElementInfo) ((JavaElement) topLevelType).getElementInfo();
              }
            } catch (JavaModelException e) {
              // types/cu exist since cu is opened
            }
            int flags =
                !containsLocalType
                    ? SourceTypeConverter.MEMBER_TYPE | (isJava8 ? SourceTypeConverter.METHOD : 0)
                    : SourceTypeConverter.FIELD_AND_METHOD
                        | SourceTypeConverter.MEMBER_TYPE
                        | SourceTypeConverter.LOCAL_TYPE;
            parsedUnit =
                SourceTypeConverter.buildCompilationUnit(
                    typeInfos, flags, this.lookupEnvironment.problemReporter, result);

            // We would have got all the necessary local types by now and hence there is no further
            // need
            // to parse the method bodies. Parser.getMethodBodies, which is called latter in this
            // function,
            // will not parse the method statements if ASTNode.HasAllMethodBodies is set.
            if (containsLocalType) parsedUnit.bits |= ASTNode.HasAllMethodBodies;
          } else {
            // create parsed unit from file
            IFile file = (IFile) cu.getResource();
            ICompilationUnit sourceUnit =
                this.builder.createCompilationUnitFromPath(openable, file);
            CompilationResult unitResult =
                new CompilationResult(
                    sourceUnit, i, openablesLength, this.options.maxProblemsPerUnit);
            parsedUnit = parser.dietParse(sourceUnit, unitResult);
          }

          if (parsedUnit != null) {
            hasLocalType[unitsIndex] = containsLocalType;
            cus[unitsIndex] = cu;
            parsedUnits[unitsIndex++] = parsedUnit;
            try {
              this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
              if (openable.equals(focusOpenable)) {
                focusUnit = parsedUnit;
              }
            } catch (AbortCompilation e) {
              // classpath problem for this type: ignore
            }
          }
        } else {
          // cache binary type binding
          ClassFile classFile = (ClassFile) openable;
          IBinaryType binaryType =
              (IBinaryType) JavaModelManager.getJavaModelManager().getInfo(classFile.getType());
          if (binaryType == null) {
            // create binary type from file
            if (classFile.getPackageFragmentRoot().isArchive()) {
              binaryType = this.builder.createInfoFromClassFileInJar(classFile);
            } else {
              IResource file = classFile.resource();
              binaryType = this.builder.createInfoFromClassFile(classFile, file);
            }
          }
          if (binaryType != null) {
            try {
              BinaryTypeBinding binaryTypeBinding =
                  this.lookupEnvironment.cacheBinaryType(
                      binaryType,
                      false /*don't need field and method (bug 125067)*/,
                      null /*no access restriction*/);
              remember(binaryType, binaryTypeBinding);
              if (openable.equals(focusOpenable)) {
                focusBinaryBinding = binaryTypeBinding;
              }
            } catch (AbortCompilation e) {
              // classpath problem for this type: ignore
            }
          }
        }
      }

      // remember type declaration of focus if local/anonymous early (see
      // https://bugs.eclipse.org/bugs/show_bug.cgi?id=210498)
      TypeDeclaration focusLocalType = null;
      if (focus != null
          && focusBinaryBinding == null
          && focusUnit != null
          && ((Member) focus).getOuterMostLocalContext() != null) {
        focusLocalType = new ASTNodeFinder(focusUnit).findType(focus);
      }

      for (int i = 0; i <= this.typeIndex; i++) {
        IGenericType suppliedType = this.typeModels[i];
        if (suppliedType != null && suppliedType.isBinaryType()) {
          CompilationUnitDeclaration previousUnitBeingCompleted =
              this.lookupEnvironment.unitBeingCompleted;
          // fault in its hierarchy...
          try {
            // ensure that unitBeingCompleted is set so that we don't get an AbortCompilation for a
            // missing type
            // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=213249 )
            if (previousUnitBeingCompleted == null) {
              this.lookupEnvironment.unitBeingCompleted = FakeUnit;
            }
            ReferenceBinding typeBinding = this.typeBindings[i];
            typeBinding.superclass();
            typeBinding.superInterfaces();
          } catch (AbortCompilation e) {
            // classpath problem for this type: ignore
          } finally {
            this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
          }
        }
      }

      // complete type bindings (i.e. connect super types)
      for (int i = 0; i < unitsIndex; i++) {
        CompilationUnitDeclaration parsedUnit = parsedUnits[i];
        if (parsedUnit != null) {
          try {
            if (hasLocalType[i]) { // NB: no-op if method bodies have been already parsed
              if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
              parser.getMethodBodies(parsedUnit);
            }
          } catch (AbortCompilation e) {
            // classpath problem for this type: don't try to resolve (see
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=49809)
            hasLocalType[i] = false;
          }
        }
      }
      // complete type bindings and build fields and methods only for local types
      // (in this case the constructor is needed when resolving local types)
      // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=145333)
      try {
        this.lookupEnvironment.completeTypeBindings(parsedUnits, hasLocalType, unitsIndex);
        // remember type bindings
        for (int i = 0; i < unitsIndex; i++) {
          CompilationUnitDeclaration parsedUnit = parsedUnits[i];
          if (parsedUnit != null && !parsedUnit.hasErrors()) {
            boolean containsLocalType = hasLocalType[i];
            if (containsLocalType) {
              if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
              parsedUnit.scope.faultInTypes();
              parsedUnit.resolve();
            }

            rememberAllTypes(parsedUnit, cus[i], containsLocalType);
          }
        }
      } catch (AbortCompilation e) {
        // skip it silently
      }
      worked(monitor, 1);

      // if no potential subtype was a real subtype of the binary focus type, no need to go further
      // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=54043)
      if (focusBinaryBinding == null && focus != null && focus.isBinary()) {
        char[] fullyQualifiedName = focus.getFullyQualifiedName().toCharArray();
        focusBinaryBinding =
            this.lookupEnvironment.getCachedType(CharOperation.splitOn('.', fullyQualifiedName));
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=436155
        // When local types are requested, it's likely a type is found from cache without
        // the hierarchy being resolved completely, so consider that factor too
        if (focusBinaryBinding == null
            || (focusBinaryBinding.tagBits & TagBits.HasUnresolvedSuperclass) != 0) return;
      }

      reportHierarchy(focus, focusLocalType, focusBinaryBinding);

    } catch (
        ClassCastException
            e) { // work-around for 1GF5W1S - can happen in case duplicates are fed to the hierarchy
                 // with binaries hiding sources
    } catch (
        AbortCompilation
            e) { // ignore this exception for now since it typically means we cannot find
                 // java.lang.Object
      if (TypeHierarchy.DEBUG) e.printStackTrace();
    } finally {
      reset();
    }
  }