예제 #1
0
  private static boolean canSeeFocus(
      IJavaElement focus, JavaProject javaProject, char[][][] focusQualifiedNames) {
    try {
      if (focus == null) return false;
      if (focus.equals(javaProject)) return true;

      if (focus instanceof JarPackageFragmentRoot) {
        // focus is part of a jar
        IPath focusPath = focus.getPath();
        IClasspathEntry[] entries = javaProject.getExpandedClasspath();
        for (int i = 0, length = entries.length; i < length; i++) {
          IClasspathEntry entry = entries[i];
          if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
              && entry.getPath().equals(focusPath)) return true;
        }
        return false;
      }
      // look for dependent projects
      IPath focusPath = ((JavaProject) focus).getProject().getFullPath();
      IClasspathEntry[] entries = javaProject.getExpandedClasspath();
      for (int i = 0, length = entries.length; i < length; i++) {
        IClasspathEntry entry = entries[i];
        if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
            && entry.getPath().equals(focusPath)) {
          if (focusQualifiedNames
              != null) { // builder state is usable, hence use it to try to reduce project which can
                         // see the focus...
            State projectState =
                (State)
                    JavaModelManager.getJavaModelManager()
                        .getLastBuiltState(javaProject.getProject(), null);
            if (projectState != null) {
              Object[] values = projectState.getReferences().valueTable;
              int vLength = values.length;
              for (int j = 0; j < vLength; j++) {
                if (values[j] == null) continue;
                ReferenceCollection references = (ReferenceCollection) values[j];
                if (references.includes(focusQualifiedNames, null, null)) {
                  return true;
                }
              }
              return false;
            }
          }
          return true;
        }
      }
      return false;
    } catch (JavaModelException e) {
      return false;
    }
  }
예제 #2
0
 private boolean isClasspathBroken(JavaProject jProj, boolean tryRepair) throws CoreException {
   IMarker[] markers =
       jProj
           .getProject()
           .findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
   for (int i = 0, l = markers.length; i < l; i++) {
     if (markers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) {
       if (tryRepair) {
         Object code = markers[i].getAttribute(IJavaModelMarker.ID);
         if (code instanceof Integer
             && ((Integer) code)
                 == IJavaModelStatusConstants.CP_INVALID_EXTERNAL_ANNOTATION_PATH) {
           new ClasspathValidation(jProj).validate();
           return isClasspathBroken(jProj, false);
         }
       }
       return true;
     }
   }
   return false;
 }
예제 #3
0
  /**
   * Add a path to current java search scope or all project fragment roots if null. Use project
   * resolved classpath to retrieve and store access restriction on each classpath entry. Recurse if
   * dependent projects are found.
   *
   * @param javaProject Project used to get resolved classpath entries
   * @param pathToAdd Path to add in case of single element or null if user want to add all project
   *     package fragment roots
   * @param includeMask Mask to apply on classpath entries
   * @param projectsToBeAdded Set to avoid infinite recursion
   * @param visitedProjects Set to avoid adding twice the same project
   * @param referringEntry Project raw entry in referring project classpath
   * @throws JavaModelException May happen while getting java model info
   */
  void add(
      JavaProject javaProject,
      IPath pathToAdd,
      int includeMask,
      HashSet projectsToBeAdded,
      HashSet visitedProjects,
      IClasspathEntry referringEntry)
      throws JavaModelException {
    IProject project = javaProject.getProject();
    if (!project.isAccessible() || !visitedProjects.add(project)) return;

    IPath projectPath = project.getFullPath();
    String projectPathString = projectPath.toString();
    addEnclosingProjectOrJar(projectPath);

    IClasspathEntry[] entries = javaProject.getResolvedClasspath();
    IJavaModel model = javaProject.getJavaModel();
    JavaModelManager.PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo();
    for (int i = 0, length = entries.length; i < length; i++) {
      IClasspathEntry entry = entries[i];
      AccessRuleSet access = null;
      ClasspathEntry cpEntry = (ClasspathEntry) entry;
      if (referringEntry != null) {
        // Add only exported entries.
        // Source folder are implicitly exported.
        if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
          continue;
        }
        cpEntry = cpEntry.combineWith((ClasspathEntry) referringEntry);
        //				cpEntry = ((ClasspathEntry)referringEntry).combineWith(cpEntry);
      }
      access = cpEntry.getAccessRuleSet();
      switch (entry.getEntryKind()) {
        case IClasspathEntry.CPE_LIBRARY:
          IClasspathEntry rawEntry = null;
          Map rootPathToRawEntries = perProjectInfo.rootPathToRawEntries;
          if (rootPathToRawEntries != null) {
            rawEntry = (IClasspathEntry) rootPathToRawEntries.get(entry.getPath());
          }
          if (rawEntry == null) break;
          rawKind:
          switch (rawEntry.getEntryKind()) {
            case IClasspathEntry.CPE_LIBRARY:
            case IClasspathEntry.CPE_VARIABLE:
              if ((includeMask & APPLICATION_LIBRARIES) != 0) {
                IPath path = entry.getPath();
                if (pathToAdd == null || pathToAdd.equals(path)) {
                  Object target = JavaModel.getTarget(path, false /*don't check existence*/);
                  if (target instanceof IFolder) // case of an external folder
                  path = ((IFolder) target).getFullPath();
                  String pathToString =
                      path.getDevice() == null ? path.toString() : path.toOSString();
                  add(
                      projectPath.toString(),
                      "",
                      pathToString,
                      false /*not a package*/,
                      access); //$NON-NLS-1$
                  addEnclosingProjectOrJar(entry.getPath());
                }
              }
              break;
            case IClasspathEntry.CPE_CONTAINER:
              IClasspathContainer container =
                  JavaCore.getClasspathContainer(rawEntry.getPath(), javaProject);
              if (container == null) break;
              switch (container.getKind()) {
                case IClasspathContainer.K_APPLICATION:
                  if ((includeMask & APPLICATION_LIBRARIES) == 0) break rawKind;
                  break;
                case IClasspathContainer.K_SYSTEM:
                case IClasspathContainer.K_DEFAULT_SYSTEM:
                  if ((includeMask & SYSTEM_LIBRARIES) == 0) break rawKind;
                  break;
                default:
                  break rawKind;
              }
              IPath path = entry.getPath();
              if (pathToAdd == null || pathToAdd.equals(path)) {
                Object target = JavaModel.getTarget(path, false /*don't check existence*/);
                if (target instanceof IFolder) // case of an external folder
                path = ((IFolder) target).getFullPath();
                String pathToString =
                    path.getDevice() == null ? path.toString() : path.toOSString();
                add(
                    projectPath.toString(),
                    "",
                    pathToString,
                    false /*not a package*/,
                    access); //$NON-NLS-1$
                addEnclosingProjectOrJar(entry.getPath());
              }
              break;
          }
          break;
        case IClasspathEntry.CPE_PROJECT:
          if ((includeMask & REFERENCED_PROJECTS) != 0) {
            IPath path = entry.getPath();
            if (pathToAdd == null || pathToAdd.equals(path)) {
              JavaProject referencedProject = (JavaProject) model.getJavaProject(path.toOSString());
              if (!projectsToBeAdded.contains(
                  referencedProject)) { // do not recurse if depending project was used to create
                                        // the scope
                add(
                    referencedProject,
                    null,
                    includeMask,
                    projectsToBeAdded,
                    visitedProjects,
                    cpEntry);
              }
            }
          }
          break;
        case IClasspathEntry.CPE_SOURCE:
          if ((includeMask & SOURCES) != 0) {
            IPath path = entry.getPath();
            if (pathToAdd == null || pathToAdd.equals(path)) {
              add(
                  projectPath.toString(),
                  Util.relativePath(path, projectPath.segmentCount() /*remove project segment*/),
                  projectPathString,
                  false /*not a package*/,
                  access);
            }
          }
          break;
      }
    }
  }
  @SuppressWarnings({"unchecked", "rawtypes", "nls", "restriction"})
  @Override
  protected boolean buildStructure(
      OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)
      throws JavaModelException {
    try {
      depth.set(depth.get() + 1);

      // if (!isOnBuildPath()) {
      // return false;
      // }

      if (GroovyLogManager.manager.hasLoggers()) {
        GroovyLogManager.manager.log(
            TraceCategory.COMPILER, "Build Structure starting for " + this.name);
        GroovyLogManager.manager.logStart(
            "Build structure: " + name + " : " + Thread.currentThread().getName());
      }

      CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;

      // ensure buffer is opened
      IBuffer buffer = getBufferManager().getBuffer(this);
      if (buffer == null) {
        openBuffer(pm, unitInfo); // open buffer independently from the
        // info, since we are building the info
      }

      // generate structure and compute syntax problems if needed
      GroovyCompilationUnitStructureRequestor requestor =
          new GroovyCompilationUnitStructureRequestor(this, unitInfo, newElements);
      JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
      JavaProject project = (JavaProject) getJavaProject();

      // determine what kind of buildStructure we are doing
      boolean createAST;
      int reconcileFlags;
      boolean resolveBindings;
      HashMap problems;
      if (info instanceof ASTHolderCUInfo) {
        ASTHolderCUInfo astHolder = (ASTHolderCUInfo) info;
        createAST =
            ((Integer)
                        ReflectionUtils.getPrivateField(
                            ASTHolderCUInfo.class, "astLevel", astHolder))
                    .intValue()
                != NO_AST; //$NON-NLS-1$
        resolveBindings =
            ((Boolean)
                    ReflectionUtils.getPrivateField(
                        ASTHolderCUInfo.class, "resolveBindings", astHolder))
                .booleanValue();
        reconcileFlags =
            ((Integer)
                    ReflectionUtils.getPrivateField(
                        ASTHolderCUInfo.class, "reconcileFlags", astHolder)) // $NON-NLS-1$
                .intValue();
        problems =
            (HashMap) ReflectionUtils.getPrivateField(ASTHolderCUInfo.class, "problems", astHolder);
      } else {
        createAST = false;
        resolveBindings = false;
        reconcileFlags = 0;
        problems = null;
      }

      boolean computeProblems =
          perWorkingCopyInfo != null
              && perWorkingCopyInfo.isActive()
              && project != null
              && JavaProject.hasJavaNature(project.getProject());
      IProblemFactory problemFactory = new DefaultProblemFactory();

      // compiler options
      Map<String, String> options =
          (project == null ? JavaCore.getOptions() : project.getOptions(true));
      if (!computeProblems) {
        // disable task tags checking to speed up parsing
        options.put(JavaCore.COMPILER_TASK_TAGS, ""); // $NON-NLS-1$
      }

      // FIXASC deal with the case of project==null to reduce duplication in this next line and call
      // to setGroovyClasspath
      // Required for Groovy, but not for Java
      options.put(CompilerOptions.OPTIONG_BuildGroovyFiles, CompilerOptions.ENABLED);

      CompilerOptions compilerOptions = new CompilerOptions(options);

      if (project != null) {
        CompilerUtils.setGroovyClasspath(compilerOptions, project);
      }

      // Required for Groovy, but not for Java
      ProblemReporter reporter =
          new ProblemReporter(
              new GroovyErrorHandlingPolicy(!computeProblems),
              compilerOptions,
              new DefaultProblemFactory());

      SourceElementParser parser =
          new MultiplexingSourceElementRequestorParser(
              reporter,
              requestor, /*
                          * not needed if
                          * computing groovy only
                          */
              problemFactory,
              compilerOptions,
              true /* report local declarations */,
              !createAST /*
                          * optimize string literals only if not
                          * creating a DOM AST
                          */);
      parser.reportOnlyOneSyntaxError = !computeProblems;
      // maybe not needed for groovy, but I don't want to find out.
      parser.setMethodsFullRecovery(true);
      parser.setStatementsRecovery(
          (reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);

      if (!computeProblems
          && !resolveBindings
          && !createAST) // disable javadoc parsing if not computing problems, not
        // resolving
        // and not creating ast
        parser.javadocParser.checkDocComment = false;
      requestor.setParser(parser);

      // update timestamp (might be IResource.NULL_STAMP if original does not
      // exist)
      if (underlyingResource == null) {
        underlyingResource = getResource();
      }
      // underlying resource is null in the case of a working copy on a class
      // file in a jar
      if (underlyingResource != null) {
        ReflectionUtils.setPrivateField(
            CompilationUnitElementInfo.class,
            "timestamp",
            unitInfo,
            underlyingResource //$NON-NLS-1$
                .getModificationStamp());
      }

      GroovyCompilationUnitDeclaration compilationUnitDeclaration = null;
      CompilationUnit source = cloneCachingContents();
      try {
        // GROOVY
        // note that this is a slightly different approach than taken by super.buildStructure
        // in super.buildStructure, there is a test here to see if computeProblems is true.
        // if false, then parser.parserCompilationUnit is called.
        // this will not work for Groovy because we need to ensure bindings are resolved
        // for many operations (content assist and code select) to work.
        // So, for groovy, always use CompilationUnitProblemFinder.process and then process problems
        // separately only if necessary
        // addendum (GRECLIPSE-942). The testcase for that bug includes a package with 200
        // types in that refer to each other in a chain, through field references. If a reconcile
        // references the top of the chain we can go through a massive number of recursive calls
        // into
        // this buildStructure for each one. The 'full' parse (with bindings) is only required for
        // the top most (regardless of the computeProblems setting) and so we track how many
        // recursive
        // calls we have made - if we are at depth 2 we do what JDT was going to do (the quick
        // thing).
        if (computeProblems || depth.get() < 2) {
          if (problems == null) {
            // report problems to the problem requestor
            problems = new HashMap();
            compilationUnitDeclaration =
                (GroovyCompilationUnitDeclaration)
                    CompilationUnitProblemFinder.process(
                        source, parser, this.owner, problems, createAST, reconcileFlags, pm);
            if (computeProblems) {
              try {
                perWorkingCopyInfo.beginReporting();
                for (Iterator iteraror = problems.values().iterator(); iteraror.hasNext(); ) {
                  CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror.next();
                  if (categorizedProblems == null) continue;
                  for (int i = 0, length = categorizedProblems.length; i < length; i++) {
                    perWorkingCopyInfo.acceptProblem(categorizedProblems[i]);
                  }
                }
              } finally {
                perWorkingCopyInfo.endReporting();
              }
            }
          } else {
            // collect problems
            compilationUnitDeclaration =
                (GroovyCompilationUnitDeclaration)
                    CompilationUnitProblemFinder.process(
                        source, parser, this.owner, problems, createAST, reconcileFlags, pm);
          }
        } else {
          compilationUnitDeclaration =
              (GroovyCompilationUnitDeclaration)
                  parser.parseCompilationUnit(
                      source, true /* full parse to find local elements */, pm);
        }

        // GROOVY
        // if this is a working copy, then we have more work to do
        maybeCacheModuleNode(perWorkingCopyInfo, compilationUnitDeclaration);

        // create the DOM AST from the compiler AST
        if (createAST) {
          org.eclipse.jdt.core.dom.CompilationUnit ast;
          try {
            ast =
                AST.convertCompilationUnit(
                    AST.JLS3,
                    compilationUnitDeclaration,
                    options,
                    computeProblems,
                    source,
                    reconcileFlags,
                    pm);
            ReflectionUtils.setPrivateField(ASTHolderCUInfo.class, "ast", info, ast); // $NON-NLS-1$
          } catch (OperationCanceledException e) {
            // catch this exception so as to not enter the catch(RuntimeException e) below
            // might need to do the same for AbortCompilation
            throw e;
          } catch (IllegalArgumentException e) {
            // if necessary, we can do some better reporting here.
            Util.log(
                e,
                "Problem with build structure: Offset for AST node is incorrect in " //$NON-NLS-1$
                    + this.getParent().getElementName()
                    + "."
                    + getElementName()); //$NON-NLS-1$
          } catch (Exception e) {
            Util.log(e, "Problem with build structure for " + this.getElementName()); // $NON-NLS-1$
          }
        }
      } catch (OperationCanceledException e) {
        // catch this exception so as to not enter the catch(RuntimeException e) below
        // might need to do the same for AbortCompilation
        throw e;
      } catch (JavaModelException e) {
        // GRECLIPSE-1480 don't log element does not exist exceptions. since this could occur when
        // element is in a non-java
        // project
        if (e.getStatus().getCode() != IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST
            || this.getJavaProject().exists()) {
          Util.log(e, "Problem with build structure for " + this.getElementName()); // $NON-NLS-1$
        }
      } catch (Exception e) {
        // GROOVY: The groovy compiler does not handle broken code well in many situations
        // use this general catch clause so that exceptions thrown by broken code
        // do not bubble up the stack.
        Util.log(e, "Problem with build structure for " + this.getElementName()); // $NON-NLS-1$
      } finally {
        if (compilationUnitDeclaration != null) {
          compilationUnitDeclaration.cleanUp();
        }
      }
      return unitInfo.isStructureKnown();
    } finally {
      depth.set(depth.get() - 1);
      if (GroovyLogManager.manager.hasLoggers()) {
        GroovyLogManager.manager.logEnd(
            "Build structure: " + name + " : " + Thread.currentThread().getName(),
            TraceCategory.COMPILER);
      }
    }
  }