@Override
    public void process(CompilationUnitDeclaration cud, int i) {
      super.process(cud, i);
      ClassFile[] classFiles = cud.compilationResult().getClassFiles();
      Map<ClassFile, CompiledClass> results = new LinkedHashMap<ClassFile, CompiledClass>();
      for (ClassFile classFile : classFiles) {
        createCompiledClass(classFile, results);
      }
      List<CompiledClass> compiledClasses = new ArrayList<CompiledClass>(results.values());
      addBinaryTypes(compiledClasses);

      ICompilationUnit icu = cud.compilationResult().compilationUnit;
      Adapter adapter = (Adapter) icu;
      CompilationUnitBuilder builder = adapter.getBuilder();

      // TODO this code was added for the arquillian gwt extension
      if (cud.types != null) {
        for (TypeDeclaration type : cud.types) {
          if (type.methods != null) {
            if (isAnnotationPresent(RunWith.class.getSimpleName(), type.annotations)) {
              Set<AbstractMethodDeclaration> filteredMethods =
                  new HashSet<AbstractMethodDeclaration>();
              boolean match = false;
              for (AbstractMethodDeclaration decl : type.methods) {
                if (decl.annotations != null) {
                  // TODO make this configurable
                  if ((isAnnotationPresent(RunAsGwtClient.class.getSimpleName(), decl.annotations)
                          || isAnnotationPresent(
                              RunAsGwtClient.class.getSimpleName(), type.annotations))
                      && !isAnnotationPresent(Deployment.class.getSimpleName(), decl.annotations)) {
                    filteredMethods.add(decl);
                  } else {
                    match = true;
                    System.out.println("Ignoring non-translatable method:\n" + decl.toString());
                  }
                }
              }
              if (match) {
                type.methods =
                    filteredMethods.toArray(new AbstractMethodDeclaration[filteredMethods.size()]);
              }
            }
          }
        }
      }

      processor.process(builder, cud, compiledClasses);
    }
Example #2
0
  /** Process a compilation unit already parsed and build. */
  public void process(CompilationUnitDeclaration unit, int i) {
    this.lookupEnvironment.unitBeingCompleted = unit;
    long parseStart = System.currentTimeMillis();

    this.parser.getMethodBodies(unit);

    long resolveStart = System.currentTimeMillis();
    this.stats.parseTime += resolveStart - parseStart;

    // fault in fields & methods
    if (unit.scope != null) unit.scope.faultInTypes();

    // verify inherited methods
    if (unit.scope != null) unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());

    // type checking
    unit.resolve();

    long analyzeStart = System.currentTimeMillis();
    this.stats.resolveTime += analyzeStart - resolveStart;

    // No need of analysis or generation of code if statements are not required
    if (!this.options.ignoreMethodBodies) unit.analyseCode(); // flow analysis

    long generateStart = System.currentTimeMillis();
    this.stats.analyzeTime += generateStart - analyzeStart;

    if (!this.options.ignoreMethodBodies) unit.generateCode(); // code generation

    // reference info
    if (this.options.produceReferenceInfo && unit.scope != null) unit.scope.storeDependencyInfo();

    // finalize problems (suppressWarnings)
    unit.finalizeProblems();

    this.stats.generateTime += System.currentTimeMillis() - generateStart;

    // refresh the total number of units known at this stage
    unit.compilationResult.totalUnitsKnown = this.totalUnits;

    this.lookupEnvironment.unitBeingCompleted = null;
  }
  /*
   * Parse the given compiation unit and build its type bindings.
   */
  protected CompilationUnitDeclaration buildBindings(
      ICompilationUnit compilationUnit, boolean isTopLevelOrMember) throws JavaModelException {
    // source unit
    org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit =
        (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnit;

    CompilationResult compilationResult = new CompilationResult(sourceUnit, 1, 1, 0);
    CompilationUnitDeclaration unit =
        isTopLevelOrMember
            ? this.locator.basicParser().dietParse(sourceUnit, compilationResult)
            : this.locator.basicParser().parse(sourceUnit, compilationResult);
    if (unit != null) {
      this.locator.lookupEnvironment.buildTypeBindings(unit, null /*no access restriction*/);
      this.locator.lookupEnvironment.completeTypeBindings(unit, !isTopLevelOrMember);
      if (!isTopLevelOrMember) {
        if (unit.scope != null) unit.scope.faultInTypes(); // fault in fields & methods
        unit.resolve();
      }
    }
    return unit;
  }
Example #4
0
  /**
   * Add an additional compilation unit into the loop -> build compilation unit declarations, their
   * bindings and record their results.
   */
  public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
    // Switch the current policy and compilation result for this unit to the requested one.
    CompilationResult unitResult =
        new CompilationResult(
            sourceUnit, this.totalUnits, this.totalUnits, this.options.maxProblemsPerUnit);
    unitResult.checkSecondaryTypes = true;
    try {
      if (this.options.verbose) {
        String count = String.valueOf(this.totalUnits + 1);
        this.out.println(
            Messages.bind(
                Messages.compilation_request,
                new String[] {count, count, new String(sourceUnit.getFileName())}));
      }
      // diet parsing for large collection of unit
      CompilationUnitDeclaration parsedUnit;
      if (this.totalUnits < this.parseThreshold) {
        parsedUnit = this.parser.parse(sourceUnit, unitResult);
      } else {
        parsedUnit = this.parser.dietParse(sourceUnit, unitResult);
      }
      parsedUnit.bits |= ASTNode.IsImplicitUnit;
      // initial type binding creation
      this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
      addCompilationUnit(sourceUnit, parsedUnit);

      // binding resolution
      this.lookupEnvironment.completeTypeBindings(parsedUnit);
    } catch (AbortCompilationUnit e) {
      // at this point, currentCompilationUnitResult may not be sourceUnit, but some other
      // one requested further along to resolve sourceUnit.
      if (unitResult.compilationUnit == sourceUnit) { // only report once
        this.requestor.acceptResult(unitResult.tagAsAccepted());
      } else {
        throw e; // want to abort enclosing request to compile
      }
    }
  }
 @Override
 public void process(
     CompilationUnitBuilder builder,
     CompilationUnitDeclaration cud,
     List<CompiledClass> compiledClasses) {
   builder
       .setClasses(compiledClasses)
       .setTypes(Collections.<JDeclaredType>emptyList())
       .setDependencies(new Dependencies())
       .setJsniMethods(Collections.<JsniMethod>emptyList())
       .setMethodArgs(new MethodArgNamesLookup())
       .setProblems(cud.compilationResult().getProblems());
   results.add(builder.build());
 }
Example #6
0
  /**
   * Internal API used to resolve a given compilation unit. Can run a subset of the compilation
   * process
   */
  public CompilationUnitDeclaration resolve(
      CompilationUnitDeclaration unit,
      ICompilationUnit sourceUnit,
      boolean verifyMethods,
      boolean analyzeCode,
      boolean generateCode) {

    try {
      if (unit == null) {
        // build and record parsed units
        this.parseThreshold = 0; // will request a full parse
        beginToCompile(new ICompilationUnit[] {sourceUnit});
        // process all units (some more could be injected in the loop by the lookup environment)
        unit = this.unitsToProcess[0];
      } else {
        // initial type binding creation
        this.lookupEnvironment.buildTypeBindings(unit, null /*no access restriction*/);

        // binding resolution
        this.lookupEnvironment.completeTypeBindings();
      }
      this.lookupEnvironment.unitBeingCompleted = unit;
      this.parser.getMethodBodies(unit);
      if (unit.scope != null) {
        // fault in fields & methods
        unit.scope.faultInTypes();
        if (unit.scope != null && verifyMethods) {
          // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
          // verify inherited methods
          unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());
        }
        // type checking
        unit.resolve();

        // flow analysis
        if (analyzeCode) unit.analyseCode();

        // code generation
        if (generateCode) unit.generateCode();

        // finalize problems (suppressWarnings)
        unit.finalizeProblems();
      }
      if (this.unitsToProcess != null)
        this.unitsToProcess[0] = null; // release reference to processed unit declaration
      this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
      return unit;
    } catch (AbortCompilation e) {
      this.handleInternalException(e, unit);
      return unit == null ? this.unitsToProcess[0] : unit;
    } catch (Error e) {
      this.handleInternalException(e, unit, null);
      throw e; // rethrow
    } catch (RuntimeException e) {
      this.handleInternalException(e, unit, null);
      throw e; // rethrow
    } finally {
      // leave this.lookupEnvironment.unitBeingCompleted set to the unit, until another unit is
      // resolved
      // other calls to dom can cause classpath errors to be detected, resulting in AbortCompilation
      // exceptions

      // No reset is performed there anymore since,
      // within the CodeAssist (or related tools),
      // the compiler may be called *after* a call
      // to this resolve(...) method. And such a call
      // needs to have a compiler with a non-empty
      // environment.
      // this.reset();
    }
  }
Example #7
0
  /**
   * General API -> compile each of supplied files -> recompile any required types for which we have
   * an incomplete principle structure
   */
  public void compile(ICompilationUnit[] sourceUnits) {
    this.stats.startTime = System.currentTimeMillis();
    // GROOVY start
    // sort the sourceUnits - java first! might be temporary, hmmm
    if (this.options.buildGroovyFiles == 2) {
      int groovyFileIndex = -1;
      //			System.out.println("before");
      //			for (int u=0,max=sourceUnits.length;u<max;u++) {
      //				System.out.println(sourceUnits[u].getFileName());
      //			}
      for (int u = 0, max = sourceUnits.length; u < max; u++) {
        char[] fn = sourceUnits[u].getFileName();
        boolean isDotJava = fn[fn.length - 1] == 'a'; // a means .java
        if (isDotJava) {
          if (groovyFileIndex != -1) {
            // swap them!
            ICompilationUnit swap = sourceUnits[groovyFileIndex];
            sourceUnits[groovyFileIndex] = sourceUnits[u];
            sourceUnits[u] = swap;
            // find the next .groovy file after the groovyFileIndex (worst case it will be 'u')
            int newGroovyFileIndex = -1;
            for (int g = groovyFileIndex; g <= u; g++) {
              char[] fn2 = sourceUnits[g].getFileName();
              boolean isDotGroovy = fn2[fn2.length - 1] == 'm'; // ZALUUM
              if (isDotGroovy) {
                newGroovyFileIndex = g;
                break;
              }
            }
            groovyFileIndex = newGroovyFileIndex;
          }
        } else {
          if (groovyFileIndex == -1) {
            groovyFileIndex = u;
          }
        }
      }
      //			System.out.println("after");
      //			for (int u=0,max=sourceUnits.length;u<max;u++) {
      //				System.out.println(sourceUnits[u].getFileName());
      //			}
    }
    // GROOVY end
    CompilationUnitDeclaration unit = null;
    ProcessTaskManager processingTask = null;
    try {
      // build and record parsed units
      reportProgress(Messages.compilation_beginningToCompile);

      if (this.annotationProcessorManager == null) {
        beginToCompile(sourceUnits);
      } else {
        ICompilationUnit[] originalUnits =
            (ICompilationUnit[])
                sourceUnits.clone(); // remember source units in case a source type collision occurs
        try {
          beginToCompile(sourceUnits);

          processAnnotations();
          if (!this.options.generateClassFiles) {
            // -proc:only was set on the command line
            return;
          }
        } catch (SourceTypeCollisionException e) {
          reset();
          // a generated type was referenced before it was created
          // the compiler either created a MissingType or found a BinaryType for it
          // so add the processor's generated files & start over,
          // but remember to only pass the generated files to the annotation processor
          int originalLength = originalUnits.length;
          int newProcessedLength = e.newAnnotationProcessorUnits.length;
          ICompilationUnit[] combinedUnits =
              new ICompilationUnit[originalLength + newProcessedLength];
          System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength);
          System.arraycopy(
              e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength);
          this.annotationProcessorStartIndex = originalLength;
          compile(combinedUnits);
          return;
        }
      }

      if (this.useSingleThread) {
        // process all units (some more could be injected in the loop by the lookup environment)
        for (int i = 0; i < this.totalUnits; i++) {
          unit = this.unitsToProcess[i];
          reportProgress(
              Messages.bind(Messages.compilation_processing, new String(unit.getFileName())));
          try {
            if (this.options.verbose)
              this.out.println(
                  Messages.bind(
                      Messages.compilation_process,
                      new String[] {
                        String.valueOf(i + 1),
                        String.valueOf(this.totalUnits),
                        new String(this.unitsToProcess[i].getFileName())
                      }));
            process(unit, i);
          } finally {
            // cleanup compilation unit result
            unit.cleanUp();
          }
          this.unitsToProcess[i] = null; // release reference to processed unit declaration

          reportWorked(1, i);
          this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
          long acceptStart = System.currentTimeMillis();
          this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
          this.stats.generateTime +=
              System.currentTimeMillis() - acceptStart; // record accept time as part of generation
          if (this.options.verbose)
            this.out.println(
                Messages.bind(
                    Messages.compilation_done,
                    new String[] {
                      String.valueOf(i + 1),
                      String.valueOf(this.totalUnits),
                      new String(unit.getFileName())
                    }));
        }
      } else {
        processingTask = new ProcessTaskManager(this);
        int acceptedCount = 0;
        // process all units (some more could be injected in the loop by the lookup environment)
        // the processTask can continue to process units until its fixed sized cache is full then it
        // must wait
        // for this this thread to accept the units as they appear (it only waits if no units are
        // available)
        while (true) {
          try {
            unit = processingTask.removeNextUnit(); // waits if no units are in the processed queue
          } catch (Error e) {
            unit = processingTask.unitToProcess;
            throw e;
          } catch (RuntimeException e) {
            unit = processingTask.unitToProcess;
            throw e;
          }
          if (unit == null) break;
          reportWorked(1, acceptedCount++);
          this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
          this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
          if (this.options.verbose)
            this.out.println(
                Messages.bind(
                    Messages.compilation_done,
                    new String[] {
                      String.valueOf(acceptedCount),
                      String.valueOf(this.totalUnits),
                      new String(unit.getFileName())
                    }));
        }
      }
    } catch (AbortCompilation e) {
      this.handleInternalException(e, unit);
    } catch (Error e) {
      this.handleInternalException(e, unit, null);
      throw e; // rethrow
    } catch (RuntimeException e) {
      this.handleInternalException(e, unit, null);
      throw e; // rethrow
    } finally {
      if (processingTask != null) {
        processingTask.shutdown();
        processingTask = null;
      }
      reset();
      this.annotationProcessorStartIndex = 0;
      this.stats.endTime = System.currentTimeMillis();
    }
    if (this.options.verbose) {
      if (this.totalUnits > 1) {
        this.out.println(
            Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits)));
      } else {
        this.out.println(Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits)));
      }
    }
  }
  public ArrayList<String> collectApiRefs(final CompilationUnitDeclaration cud) {
    final Set<String> apiRefs = new HashSet<String>();
    class DependencyVisitor extends TypeRefVisitor {
      public DependencyVisitor() {
        super(cud);
      }

      @Override
      public boolean visit(Argument arg, BlockScope scope) {
        // Adapted from {@link Argument#traverse}.
        // Don't visit annotations.
        if (arg.type != null) {
          arg.type.traverse(this, scope);
        }
        return false;
      }

      @Override
      public boolean visit(Argument arg, ClassScope scope) {
        // Adapted from {@link Argument#traverse}.
        // Don't visit annotations.
        if (arg.type != null) {
          arg.type.traverse(this, scope);
        }
        return false;
      }

      @Override
      public boolean visit(Block block, BlockScope scope) {
        assert false : "Error in DepedencyVisitor; should never visit a block";
        return false;
      }

      @Override
      public boolean visit(Clinit clinit, ClassScope scope) {
        return false;
      }

      @Override
      public boolean visit(ConstructorDeclaration ctor, ClassScope scope) {
        if (ctor.typeParameters != null) {
          int typeParametersLength = ctor.typeParameters.length;
          for (int i = 0; i < typeParametersLength; i++) {
            ctor.typeParameters[i].traverse(this, ctor.scope);
          }
        }
        traverse(ctor);
        return false;
      }

      @Override
      public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
        // Don't visit javadoc.
        // Don't visit annotations.
        if (fieldDeclaration.type != null) {
          fieldDeclaration.type.traverse(this, scope);
        }
        // Don't visit initialization.
        return false;
      }

      @Override
      public boolean visit(Initializer initializer, MethodScope scope) {
        return false;
      }

      @Override
      public boolean visit(MethodDeclaration meth, ClassScope scope) {
        if (meth.typeParameters != null) {
          int typeParametersLength = meth.typeParameters.length;
          for (int i = 0; i < typeParametersLength; i++) {
            meth.typeParameters[i].traverse(this, meth.scope);
          }
        }
        if (meth.returnType != null) {
          meth.returnType.traverse(this, meth.scope);
        }
        traverse(meth);
        return false;
      }

      @Override
      public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
        traverse(typeDeclaration);
        return false;
      }

      @Override
      public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
        traverse(typeDeclaration);
        return false;
      }

      @Override
      protected void onBinaryTypeRef(
          BinaryTypeBinding referencedType,
          CompilationUnitDeclaration unitOfReferrer,
          Expression expression) {
        if (!String.valueOf(referencedType.getFileName()).endsWith(".java")) {
          // ignore binary-only annotations
          return;
        }
        addReference(referencedType);
      }

      @Override
      protected void onTypeRef(
          SourceTypeBinding referencedType, CompilationUnitDeclaration unitOfReferrer) {
        addReference(referencedType);
      }

      private void addReference(ReferenceBinding referencedType) {
        String binaryName = CharOperation.toString(referencedType.compoundName);
        apiRefs.add(BinaryName.toSourceName(binaryName));
      }

      /** Adapted from {@link MethodDeclaration#traverse}. */
      private void traverse(AbstractMethodDeclaration meth) {
        // Don't visit javadoc.
        // Don't visit annotations.
        if (meth.arguments != null) {
          int argumentLength = meth.arguments.length;
          for (int i = 0; i < argumentLength; i++) {
            meth.arguments[i].traverse(this, meth.scope);
          }
        }
        if (meth.thrownExceptions != null) {
          int thrownExceptionsLength = meth.thrownExceptions.length;
          for (int i = 0; i < thrownExceptionsLength; i++) {
            meth.thrownExceptions[i].traverse(this, meth.scope);
          }
        }
        // Don't visit method bodies.
      }

      /** Adapted from {@link TypeDeclaration#traverse}. */
      private void traverse(TypeDeclaration type) {
        // Don't visit javadoc.
        // Don't visit annotations.
        if (type.superclass != null) {
          type.superclass.traverse(this, type.scope);
        }
        if (type.superInterfaces != null) {
          int length = type.superInterfaces.length;
          for (int i = 0; i < length; i++) {
            type.superInterfaces[i].traverse(this, type.scope);
          }
        }
        if (type.typeParameters != null) {
          int length = type.typeParameters.length;
          for (int i = 0; i < length; i++) {
            type.typeParameters[i].traverse(this, type.scope);
          }
        }
        if (type.memberTypes != null) {
          int length = type.memberTypes.length;
          for (int i = 0; i < length; i++) {
            type.memberTypes[i].traverse(this, type.scope);
          }
        }
        if (type.fields != null) {
          int length = type.fields.length;
          for (int i = 0; i < length; i++) {
            FieldDeclaration field;
            if ((field = type.fields[i]).isStatic()) {
              field.traverse(this, type.staticInitializerScope);
            } else {
              field.traverse(this, type.initializerScope);
            }
          }
        }
        if (type.methods != null) {
          int length = type.methods.length;
          for (int i = 0; i < length; i++) {
            type.methods[i].traverse(this, type.scope);
          }
        }
      }
    }
    DependencyVisitor visitor = new DependencyVisitor();
    cud.traverse(visitor, cud.scope);
    ArrayList<String> result = new ArrayList<String>(apiRefs);
    Collections.sort(result);
    return result;
  }
  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;
  }