/** 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();
    }
  }
Ejemplo n.º 2
0
  public char[][][] collect() throws JavaModelException {
    if (this.type != null) {
      // Collect the paths of the cus that are in the hierarchy of the given type
      this.result = new char[1][][];
      this.resultIndex = 0;
      JavaProject javaProject = (JavaProject) this.type.getJavaProject();
      this.locator.initialize(javaProject, 0);
      try {
        if (this.type.isBinary()) {
          BinaryTypeBinding binding = this.locator.cacheBinaryType(this.type, null);
          if (binding != null) collectSuperTypeNames(binding);
        } else {
          ICompilationUnit unit = this.type.getCompilationUnit();
          SourceType sourceType = (SourceType) this.type;
          boolean isTopLevelOrMember = sourceType.getOuterMostLocalContext() == null;
          CompilationUnitDeclaration parsedUnit = buildBindings(unit, isTopLevelOrMember);
          if (parsedUnit != null) {
            TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(this.type);
            if (typeDecl != null && typeDecl.binding != null)
              collectSuperTypeNames(typeDecl.binding);
          }
        }
      } catch (AbortCompilation e) {
        // problem with classpath: report inacurrate matches
        return null;
      }
      if (this.result.length > this.resultIndex)
        System.arraycopy(
            this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex);
      return this.result;
    }

    // Collect the paths of the cus that declare a type which matches declaringQualification +
    // declaringSimpleName
    String[] paths = this.getPathsOfDeclaringType();
    if (paths == null) return null;

    // Create bindings from source types and binary types and collect super type names of the type
    // declaration
    // that match the given declaring type
    Util.sort(paths); // sort by projects
    JavaProject previousProject = null;
    this.result = new char[1][][];
    this.resultIndex = 0;
    for (int i = 0, length = paths.length; i < length; i++) {
      try {
        Openable openable = this.locator.handleFactory.createOpenable(paths[i], this.locator.scope);
        if (openable == null) continue; // outside classpath

        IJavaProject project = openable.getJavaProject();
        if (!project.equals(previousProject)) {
          previousProject = (JavaProject) project;
          this.locator.initialize(previousProject, 0);
        }
        if (openable instanceof ICompilationUnit) {
          ICompilationUnit unit = (ICompilationUnit) openable;
          CompilationUnitDeclaration parsedUnit =
              buildBindings(
                  unit, true /*only toplevel and member types are visible to the focus type*/);
          if (parsedUnit != null)
            parsedUnit.traverse(new TypeDeclarationVisitor(), parsedUnit.scope);
        } else if (openable instanceof IClassFile) {
          IClassFile classFile = (IClassFile) openable;
          BinaryTypeBinding binding = this.locator.cacheBinaryType(classFile.getType(), null);
          if (matches(binding)) collectSuperTypeNames(binding);
        }
      } catch (AbortCompilation e) {
        // ignore: continue with next element
      } catch (JavaModelException e) {
        // ignore: continue with next element
      }
    }
    if (this.result.length > this.resultIndex)
      System.arraycopy(
          this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex);
    return this.result;
  }