protected void finishedWith(
      String sourceLocator,
      CompilationResult result,
      char[] mainTypeName,
      ArrayList definedTypeNames,
      ArrayList duplicateTypeNames) {
    char[][] previousTypeNames = this.newState.getDefinedTypeNamesFor(sourceLocator);
    if (previousTypeNames == null) previousTypeNames = new char[][] {mainTypeName};
    IPath packagePath = null;
    next:
    for (int i = 0, l = previousTypeNames.length; i < l; i++) {
      char[] previous = previousTypeNames[i];
      for (int j = 0, m = definedTypeNames.size(); j < m; j++)
        if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j))) continue next;

      SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
      if (packagePath == null) {
        int count = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount();
        packagePath =
            sourceFile.resource.getFullPath().removeFirstSegments(count).removeLastSegments(1);
      }
      if (this.secondaryTypesToRemove == null)
        this.secondaryTypesToRemove = new SimpleLookupTable();
      ArrayList types =
          (ArrayList) this.secondaryTypesToRemove.get(sourceFile.sourceLocation.binaryFolder);
      if (types == null) types = new ArrayList(definedTypeNames.size());
      types.add(packagePath.append(new String(previous)));
      this.secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
    }
    super.finishedWith(sourceLocator, result, mainTypeName, definedTypeNames, duplicateTypeNames);
  }
 protected void compile(
     SourceFile[] units, SourceFile[] additionalUnits, boolean compilingFirstGroup) {
   if (compilingFirstGroup && additionalUnits != null) {
     // add any source file from additionalUnits to units if it defines secondary types
     // otherwise its possible during testing with MAX_AT_ONCE == 1 that a secondary type
     // can cause an infinite loop as it alternates between not found and defined, see bug 146324
     ArrayList extras = null;
     for (int i = 0, l = additionalUnits.length; i < l; i++) {
       SourceFile unit = additionalUnits[i];
       if (unit != null && this.newState.getDefinedTypeNamesFor(unit.typeLocator()) != null) {
         if (JavaBuilder.DEBUG)
           System.out.println(
               "About to compile file with secondary types " + unit.typeLocator()); // $NON-NLS-1$
         if (extras == null) extras = new ArrayList(3);
         extras.add(unit);
       }
     }
     if (extras != null) {
       int oldLength = units.length;
       int toAdd = extras.size();
       System.arraycopy(units, 0, units = new SourceFile[oldLength + toAdd], 0, oldLength);
       for (int i = 0; i < toAdd; i++) units[oldLength++] = (SourceFile) extras.get(i);
     }
   }
   super.compile(units, additionalUnits, compilingFirstGroup);
 }
  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;
  }
  ISourceContainer[] getSourceContainers(String location, String id) throws CoreException {

    ISourceContainer[] containers = (ISourceContainer[]) fSourceContainerMap.get(location);
    if (containers != null) {
      return containers;
    }

    ArrayList result = new ArrayList();
    ModelEntry entry = MonitorRegistry.findEntry(id);

    boolean match = false;

    IMonitorModelBase[] models = entry.getWorkspaceModels();
    for (int i = 0; i < models.length; i++) {
      if (isPerfectMatch(models[i], new Path(location))) {
        IResource resource = models[i].getUnderlyingResource();
        // if the plug-in matches a workspace model,
        // add the project and any libraries not coming via a container
        // to the list of source containers, in that order
        if (resource != null) {
          addProjectSourceContainers(resource.getProject(), result);
        }
        match = true;
        break;
      }
    }

    if (!match) {
      File file = new File(location);
      if (file.isFile()) {
        // in case of linked plug-in projects that map to an external JARd plug-in,
        // use source container that maps to the library in the linked project.
        ISourceContainer container = getArchiveSourceContainer(location);
        if (container != null) {
          containers = new ISourceContainer[] {container};
          fSourceContainerMap.put(location, containers);
          return containers;
        }
      }

      models = entry.getExternalModels();
      for (int i = 0; i < models.length; i++) {
        if (isPerfectMatch(models[i], new Path(location))) {
          // try all source zips found in the source code locations
          IClasspathEntry[] entries = MDEClasspathContainer.getExternalEntries(models[i]);
          for (int j = 0; j < entries.length; j++) {
            IRuntimeClasspathEntry rte = convertClasspathEntry(entries[j]);
            if (rte != null) result.add(rte);
          }
          break;
        }
      }
    }

    IRuntimeClasspathEntry[] entries =
        (IRuntimeClasspathEntry[]) result.toArray(new IRuntimeClasspathEntry[result.size()]);
    containers = JavaRuntime.getSourceContainers(entries);
    fSourceContainerMap.put(location, containers);
    return containers;
  }
 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];
 }
 protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
   ArrayList visited =
       this.makeOutputFolderConsistent ? new ArrayList(this.sourceLocations.length) : null;
   for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
     ClasspathMultiDirectory md = this.sourceLocations[i];
     if (this.makeOutputFolderConsistent
         && md.hasIndependentOutputFolder
         && !visited.contains(md.binaryFolder)) {
       // even a project which acts as its own source folder can have an independent/nested output
       // folder
       visited.add(md.binaryFolder);
       IResourceDelta binaryDelta = delta.findMember(md.binaryFolder.getProjectRelativePath());
       if (binaryDelta != null) {
         int segmentCount = binaryDelta.getFullPath().segmentCount();
         IResourceDelta[] children = binaryDelta.getAffectedChildren();
         for (int j = 0, m = children.length; j < m; j++)
           if (!checkForClassFileChanges(children[j], md, segmentCount)) return false;
       }
     }
     if (md.sourceFolder.equals(this.javaBuilder.currentProject)) {
       // skip nested source & output folders when the project is a source folder
       int segmentCount = delta.getFullPath().segmentCount();
       IResourceDelta[] children = delta.getAffectedChildren();
       for (int j = 0, m = children.length; j < m; j++)
         if (!isExcludedFromProject(children[j].getFullPath()))
           if (!findSourceFiles(children[j], md, segmentCount)) return false;
     } else {
       IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath());
       if (sourceDelta != null) {
         if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
           if (JavaBuilder.DEBUG)
             System.out.println(
                 "ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
           return false; // removed source folder should not make it here, but handle anyways
           // (ADDED is supported)
         }
         int segmentCount = sourceDelta.getFullPath().segmentCount();
         IResourceDelta[] children = sourceDelta.getAffectedChildren();
         try {
           for (int j = 0, m = children.length; j < m; j++)
             if (!findSourceFiles(children[j], md, segmentCount)) return false;
         } catch (CoreException e) {
           // catch the case that a package has been renamed and collides on disk with an
           // as-yet-to-be-deleted package
           if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
             if (JavaBuilder.DEBUG)
               System.out.println(
                   "ABORTING incremental build... found renamed package"); //$NON-NLS-1$
             return false;
           }
           throw e; // rethrow
         }
       }
     }
     this.notifier.checkCancel();
   }
   return true;
 }
  private void addProjectSourceContainers(IProject project, ArrayList result) throws CoreException {
    if (project == null || !project.hasNature(JavaCore.NATURE_ID)) return;

    IJavaProject jProject = JavaCore.create(project);
    result.add(JavaRuntime.newProjectRuntimeClasspathEntry(jProject));

    IClasspathEntry[] entries = jProject.getRawClasspath();
    for (int i = 0; i < entries.length; i++) {
      IClasspathEntry entry = entries[i];
      if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
        IRuntimeClasspathEntry rte = convertClasspathEntry(entry);
        if (rte != null) result.add(rte);
      }
    }
  }
 protected void removeSecondaryTypes() throws CoreException {
   if (this.secondaryTypesToRemove
       != null) { // delayed deleting secondary types until the end of the compile loop
     Object[] keyTable = this.secondaryTypesToRemove.keyTable;
     Object[] valueTable = this.secondaryTypesToRemove.valueTable;
     for (int i = 0, l = keyTable.length; i < l; i++) {
       IContainer outputFolder = (IContainer) keyTable[i];
       if (outputFolder != null) {
         ArrayList paths = (ArrayList) valueTable[i];
         for (int j = 0, m = paths.size(); j < m; j++)
           removeClassFile((IPath) paths.get(j), outputFolder);
       }
     }
     this.secondaryTypesToRemove = null;
     if (this.previousSourceFiles != null)
       this.previousSourceFiles =
           null; // cannot optimize recompile case when a secondary type is deleted, see 181269
   }
 }
  /* 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;
  }
Beispiel #10
0
  private ArrayList convertPkgList(ArrayList pkgList) {
    ArrayList conList = new ArrayList();
    Iterator it = pkgList.iterator();
    while (it.hasNext()) {
      CallData cd = (CallData) it.next();
      TestNode tn = null;
      if (alreadyDone.containsKey(cd)) {
        tn = (TestNode) alreadyDone.get(cd);
      } else {
        tn = new TestNode();
        tn.setData(cd.getData());
        alreadyDone.put(cd, tn);
        if (cd.getChildren().size() != 0) {
          tn.setChildren(convertPkgList(cd.getChildren()));
        }
        if (cd.getOutputs().size() != 0) {
          tn.setOutputs(convertPkgList(cd.getOutputs()));
        }
      }
      conList.add(tn);
    }

    return conList;
  }
  /**
   * Returns the children of <code>source</code> which are affected by this operation. If <code>
   * source</code> is a <code>K_SOURCE</code>, these are the <code>.java</code> files, if it is a
   * <code>K_BINARY</code>, they are the <code>.class</code> files.
   */
  private IResource[] collectResourcesOfInterest(IPackageFragment source)
      throws JavaModelException {
    IJavaElement[] children = source.getChildren();
    int childOfInterest = IJavaElement.COMPILATION_UNIT;
    if (source.getKind() == IPackageFragmentRoot.K_BINARY) {
      childOfInterest = IJavaElement.CLASS_FILE;
    }
    ArrayList correctKindChildren = new ArrayList(children.length);
    for (int i = 0; i < children.length; i++) {
      IJavaElement child = children[i];
      if (child.getElementType() == childOfInterest) {
        correctKindChildren.add(((JavaElement) child).resource());
      }
    }
    // Gather non-java resources
    Object[] nonJavaResources = source.getNonJavaResources();
    int actualNonJavaResourceCount = 0;
    for (int i = 0, max = nonJavaResources.length; i < max; i++) {
      if (nonJavaResources[i] instanceof IResource) actualNonJavaResourceCount++;
    }
    IResource[] actualNonJavaResources = new IResource[actualNonJavaResourceCount];
    for (int i = 0, max = nonJavaResources.length, index = 0; i < max; i++) {
      if (nonJavaResources[i] instanceof IResource)
        actualNonJavaResources[index++] = (IResource) nonJavaResources[i];
    }

    if (actualNonJavaResourceCount != 0) {
      int correctKindChildrenSize = correctKindChildren.size();
      IResource[] result = new IResource[correctKindChildrenSize + actualNonJavaResourceCount];
      correctKindChildren.toArray(result);
      System.arraycopy(
          actualNonJavaResources, 0, result, correctKindChildrenSize, actualNonJavaResourceCount);
      return result;
    } else {
      IResource[] result = new IResource[correctKindChildren.size()];
      correctKindChildren.toArray(result);
      return result;
    }
  }
  /** Configure this type hierarchy based on the given potential subtypes. */
  private void buildFromPotentialSubtypes(
      String[] allPotentialSubTypes, HashSet localTypes, IProgressMonitor monitor) {
    IType focusType = getType();

    // substitute compilation units with working copies
    HashMap wcPaths = new HashMap(); // a map from path to working copies
    int wcLength;
    org.eclipse.jdt.core.ICompilationUnit[] workingCopies = this.hierarchy.workingCopies;
    if (workingCopies != null && (wcLength = workingCopies.length) > 0) {
      String[] newPaths = new String[wcLength];
      for (int i = 0; i < wcLength; i++) {
        org.eclipse.jdt.core.ICompilationUnit workingCopy = workingCopies[i];
        String path = workingCopy.getPath().toString();
        wcPaths.put(path, workingCopy);
        newPaths[i] = path;
      }
      int potentialSubtypesLength = allPotentialSubTypes.length;
      System.arraycopy(
          allPotentialSubTypes,
          0,
          allPotentialSubTypes = new String[potentialSubtypesLength + wcLength],
          0,
          potentialSubtypesLength);
      System.arraycopy(newPaths, 0, allPotentialSubTypes, potentialSubtypesLength, wcLength);
    }

    int length = allPotentialSubTypes.length;

    // inject the compilation unit of the focus type (so that types in
    // this cu have special visibility permission (this is also usefull
    // when the cu is a working copy)
    Openable focusCU = (Openable) focusType.getCompilationUnit();
    String focusPath = null;
    if (focusCU != null) {
      focusPath = focusCU.getPath().toString();
      if (length > 0) {
        System.arraycopy(
            allPotentialSubTypes, 0, allPotentialSubTypes = new String[length + 1], 0, length);
        allPotentialSubTypes[length] = focusPath;
      } else {
        allPotentialSubTypes = new String[] {focusPath};
      }
      length++;
    }

    /*
     * Sort in alphabetical order so that potential subtypes are grouped per project
     */
    Arrays.sort(allPotentialSubTypes);

    ArrayList potentialSubtypes = new ArrayList();
    try {
      // create element infos for subtypes
      HandleFactory factory = new HandleFactory();
      IJavaProject currentProject = null;
      if (monitor != null)
        monitor.beginTask(
            "", length * 2 /* 1 for build binding, 1 for connect hierarchy*/); // $NON-NLS-1$
      for (int i = 0; i < length; i++) {
        try {
          String resourcePath = allPotentialSubTypes[i];

          // skip duplicate paths (e.g. if focus path was injected when it was already a potential
          // subtype)
          if (i > 0 && resourcePath.equals(allPotentialSubTypes[i - 1])) continue;

          Openable handle;
          org.eclipse.jdt.core.ICompilationUnit workingCopy =
              (org.eclipse.jdt.core.ICompilationUnit) wcPaths.get(resourcePath);
          if (workingCopy != null) {
            handle = (Openable) workingCopy;
          } else {
            handle =
                resourcePath.equals(focusPath)
                    ? focusCU
                    : factory.createOpenable(resourcePath, this.scope);
            if (handle == null) continue; // match is outside classpath
          }

          IJavaProject project = handle.getJavaProject();
          if (currentProject == null) {
            currentProject = project;
            potentialSubtypes = new ArrayList(5);
          } else if (!currentProject.equals(project)) {
            // build current project
            buildForProject(
                (JavaProject) currentProject,
                potentialSubtypes,
                workingCopies,
                localTypes,
                monitor);
            currentProject = project;
            potentialSubtypes = new ArrayList(5);
          }

          potentialSubtypes.add(handle);
        } catch (JavaModelException e) {
          continue;
        }
      }

      // build last project
      try {
        if (currentProject == null) {
          // case of no potential subtypes
          currentProject = focusType.getJavaProject();
          if (focusType.isBinary()) {
            potentialSubtypes.add(focusType.getClassFile());
          } else {
            potentialSubtypes.add(focusType.getCompilationUnit());
          }
        }
        buildForProject(
            (JavaProject) currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
      } catch (JavaModelException e) {
        // ignore
      }

      // Compute hierarchy of focus type if not already done (case of a type with potential subtypes
      // that are not real subtypes)
      if (!this.hierarchy.contains(focusType)) {
        try {
          currentProject = focusType.getJavaProject();
          potentialSubtypes = new ArrayList();
          if (focusType.isBinary()) {
            potentialSubtypes.add(focusType.getClassFile());
          } else {
            potentialSubtypes.add(focusType.getCompilationUnit());
          }
          buildForProject(
              (JavaProject) currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
        } catch (JavaModelException e) {
          // ignore
        }
      }

      // Add focus if not already in (case of a type with no explicit super type)
      if (!this.hierarchy.contains(focusType)) {
        this.hierarchy.addRootClass(focusType);
      }
    } finally {
      if (monitor != null) monitor.done();
    }
  }
  private void buildForProject(
      JavaProject project,
      ArrayList potentialSubtypes,
      org.eclipse.jdt.core.ICompilationUnit[] workingCopies,
      HashSet localTypes,
      IProgressMonitor monitor)
      throws JavaModelException {
    // resolve
    int openablesLength = potentialSubtypes.size();
    if (openablesLength > 0) {
      // copy vectors into arrays
      Openable[] openables = new Openable[openablesLength];
      potentialSubtypes.toArray(openables);

      // sort in the order of roots and in reverse alphabetical order for .class file
      // since requesting top level types in the process of caching an enclosing type is
      // not supported by the lookup environment
      IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
      int rootsLength = roots.length;
      final HashtableOfObjectToInt indexes = new HashtableOfObjectToInt(openablesLength);
      for (int i = 0; i < openablesLength; i++) {
        IJavaElement root = openables[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
        int index;
        for (index = 0; index < rootsLength; index++) {
          if (roots[index].equals(root)) break;
        }
        indexes.put(openables[i], index);
      }
      Arrays.sort(
          openables,
          new Comparator() {
            public int compare(Object a, Object b) {
              int aIndex = indexes.get(a);
              int bIndex = indexes.get(b);
              if (aIndex != bIndex) return aIndex - bIndex;
              return ((Openable) b).getElementName().compareTo(((Openable) a).getElementName());
            }
          });

      IType focusType = getType();
      boolean inProjectOfFocusType =
          focusType != null && focusType.getJavaProject().equals(project);
      org.eclipse.jdt.core.ICompilationUnit[] unitsToLookInside = null;
      if (inProjectOfFocusType) {
        org.eclipse.jdt.core.ICompilationUnit unitToLookInside = focusType.getCompilationUnit();
        if (unitToLookInside != null) {
          int wcLength = workingCopies == null ? 0 : workingCopies.length;
          if (wcLength == 0) {
            unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[] {unitToLookInside};
          } else {
            unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[wcLength + 1];
            unitsToLookInside[0] = unitToLookInside;
            System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength);
          }
        } else {
          unitsToLookInside = workingCopies;
        }
      }

      SearchableEnvironment searchableEnvironment =
          project.newSearchableNameEnvironment(unitsToLookInside);
      this.nameLookup = searchableEnvironment.nameLookup;
      Map options = project.getOptions(true);
      // disable task tags to speed up parsing
      options.put(JavaCore.COMPILER_TASK_TAGS, ""); // $NON-NLS-1$
      this.hierarchyResolver =
          new HierarchyResolver(searchableEnvironment, options, this, new DefaultProblemFactory());
      if (focusType != null) {
        Member declaringMember = ((Member) focusType).getOuterMostLocalContext();
        if (declaringMember == null) {
          // top level or member type
          if (!inProjectOfFocusType) {
            char[] typeQualifiedName = focusType.getTypeQualifiedName('.').toCharArray();
            String[] packageName = ((PackageFragment) focusType.getPackageFragment()).names;
            if (searchableEnvironment.findType(typeQualifiedName, Util.toCharArrays(packageName))
                == null) {
              // focus type is not visible in this project: no need to go further
              return;
            }
          }
        } else {
          // local or anonymous type
          Openable openable;
          if (declaringMember.isBinary()) {
            openable = (Openable) declaringMember.getClassFile();
          } else {
            openable = (Openable) declaringMember.getCompilationUnit();
          }
          localTypes = new HashSet();
          localTypes.add(openable.getPath().toString());
          this.hierarchyResolver.resolve(new Openable[] {openable}, localTypes, monitor);
          return;
        }
      }
      this.hierarchyResolver.resolve(openables, localTypes, monitor);
    }
  }