Beispiel #1
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;
  }
Beispiel #2
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
      }
    }
  }
Beispiel #3
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();
    }
  }
Beispiel #4
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)));
      }
    }
  }