예제 #1
0
  /**
   * Add the initial set of compilation units into the loop -> build compilation unit declarations,
   * their bindings and record their results.
   */
  protected void internalBeginToCompile(ICompilationUnit[] sourceUnits, int maxUnits) {
    if (!this.useSingleThread && maxUnits >= ReadManager.THRESHOLD)
      this.parser.readManager = new ReadManager(sourceUnits, maxUnits);

    // Switch the current policy and compilation result for this unit to the requested one.
    for (int i = 0; i < maxUnits; i++) {
      CompilationResult unitResult = null;
      try {
        if (this.options.verbose) {
          this.out.println(
              Messages.bind(
                  Messages.compilation_request,
                  new String[] {
                    String.valueOf(i + 1),
                    String.valueOf(maxUnits),
                    new String(sourceUnits[i].getFileName())
                  }));
        }
        // diet parsing for large collection of units
        CompilationUnitDeclaration parsedUnit;
        unitResult =
            new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit);
        long parseStart = System.currentTimeMillis();
        if (this.totalUnits < this.parseThreshold) {
          parsedUnit = this.parser.parse(sourceUnits[i], unitResult);
        } else {
          parsedUnit = this.parser.dietParse(sourceUnits[i], unitResult);
        }
        long resolveStart = System.currentTimeMillis();
        this.stats.parseTime += resolveStart - parseStart;
        // initial type binding creation
        this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
        this.stats.resolveTime += System.currentTimeMillis() - resolveStart;
        addCompilationUnit(sourceUnits[i], parsedUnit);
        ImportReference currentPackage = parsedUnit.currentPackage;
        if (currentPackage != null) {
          unitResult.recordPackageName(currentPackage.tokens);
        }
        // } catch (AbortCompilationUnit e) {
        //	requestor.acceptResult(unitResult.tagAsAccepted());
      } catch (AbortCompilation a) {
        // best effort to find a way for reporting this problem:
        if (a.compilationResult == null) a.compilationResult = unitResult;
        throw a;
      } finally {
        sourceUnits[i] = null; // no longer hold onto the unit
      }
    }
    if (this.parser.readManager != null) {
      this.parser.readManager.shutdown();
      this.parser.readManager = null;
    }
    // binding resolution
    this.lookupEnvironment.completeTypeBindings();
  }
예제 #2
0
  /*
   * Compiler crash recovery in case of unexpected runtime exceptions
   */
  protected void handleInternalException(
      Throwable internalException, CompilationUnitDeclaration unit, CompilationResult result) {

    if (result == null && unit != null) {
      result = unit.compilationResult; // current unit being processed ?
    }
    // Lookup environment may be in middle of connecting types
    if (result == null && this.lookupEnvironment.unitBeingCompleted != null) {
      result = this.lookupEnvironment.unitBeingCompleted.compilationResult;
    }
    if (result == null) {
      synchronized (this) {
        if (this.unitsToProcess != null && this.totalUnits > 0)
          result = this.unitsToProcess[this.totalUnits - 1].compilationResult;
      }
    }
    // last unit in beginToCompile ?

    boolean needToPrint = true;
    if (result != null) {
      /* create and record a compilation problem */
      // only keep leading portion of the trace
      String[] pbArguments =
          new String[] {
            Messages.bind(
                Messages.compilation_internalError, Util.getExceptionSummary(internalException)),
          };

      result.record(
          this.problemReporter.createProblem(
              result.getFileName(),
              IProblem.Unclassified,
              pbArguments,
              pbArguments,
              Error, // severity
              0, // source start
              0, // source end
              0, // line number
              0), // column number
          unit);

      /* hand back the compilation result */
      if (!result.hasBeenAccepted) {
        this.requestor.acceptResult(result.tagAsAccepted());
        needToPrint = false;
      }
    }
    if (needToPrint) {
      /* dump a stack trace to the console */
      internalException.printStackTrace();
    }
  }
  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 updateTasksFor(SourceFile sourceFile, CompilationResult result)
      throws CoreException {
    IMarker[] markers = JavaBuilder.getTasksFor(sourceFile.resource);
    CategorizedProblem[] tasks = result.getTasks();
    if (tasks == null && markers.length == 0) return;

    JavaBuilder.removeTasksFor(sourceFile.resource);
    storeTasksFor(sourceFile, tasks);
  }
  protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result)
      throws CoreException {
    IMarker[] markers = JavaBuilder.getProblemsFor(sourceFile.resource);
    CategorizedProblem[] problems = result.getProblems();
    if (problems == null && markers.length == 0) return;

    this.notifier.updateProblemCounts(markers, problems);
    JavaBuilder.removeProblemsFor(sourceFile.resource);
    storeProblemsFor(sourceFile, problems);
  }
  public CompilationUnitDeclaration parseCompilationUnit(
      ICompilationUnit unit, boolean fullParse, IProgressMonitor pm) {

    boolean old = this.diet;
    CompilationUnitDeclaration parsedUnit = null;
    try {
      this.diet = true;
      this.reportReferenceInfo = fullParse;
      CompilationResult compilationUnitResult =
          new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
      parsedUnit = parse(unit, compilationUnitResult);
      if (pm != null && pm.isCanceled())
        throw new OperationCanceledException(Messages.operation_cancelled);
      if (this.scanner.recordLineSeparator) {
        this.requestor.acceptLineSeparatorPositions(
            compilationUnitResult.getLineSeparatorPositions());
      }
      int initialStart = this.scanner.initialPosition;
      int initialEnd = this.scanner.eofPosition;
      if (this.reportLocalDeclarations || fullParse) {
        this.diet = false;
        getMethodBodies(parsedUnit);
      }
      this.scanner.resetTo(initialStart, initialEnd);
      this.notifier.notifySourceElementRequestor(
          parsedUnit,
          this.scanner.initialPosition,
          this.scanner.eofPosition,
          this.reportReferenceInfo,
          this.sourceEnds,
          this.nodesToCategories);
      return parsedUnit;
    } catch (AbortCompilation e) {
      // ignore this exception
    } finally {
      this.diet = old;
      reset();
    }
    return parsedUnit;
  }
예제 #7
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
      }
    }
  }
예제 #8
0
  /*
   * Compiler recovery in case of internal AbortCompilation event
   */
  protected void handleInternalException(
      AbortCompilation abortException, CompilationUnitDeclaration unit) {

    /* special treatment for SilentAbort: silently cancelling the compilation process */
    if (abortException.isSilent) {
      if (abortException.silentException == null) {
        return;
      }
      throw abortException.silentException;
    }

    /* uncomment following line to see where the abort came from */
    // abortException.printStackTrace();

    // Exception may tell which compilation result it is related, and which problem caused it
    CompilationResult result = abortException.compilationResult;
    if (result == null && unit != null) {
      result = unit.compilationResult; // current unit being processed ?
    }
    // Lookup environment may be in middle of connecting types
    if (result == null && this.lookupEnvironment.unitBeingCompleted != null) {
      result = this.lookupEnvironment.unitBeingCompleted.compilationResult;
    }
    if (result == null) {
      synchronized (this) {
        if (this.unitsToProcess != null && this.totalUnits > 0)
          result = this.unitsToProcess[this.totalUnits - 1].compilationResult;
      }
    }
    // last unit in beginToCompile ?
    if (result != null && !result.hasBeenAccepted) {
      /* distant problem which could not be reported back there? */
      if (abortException.problem != null) {
        recordDistantProblem:
        {
          CategorizedProblem distantProblem = abortException.problem;
          CategorizedProblem[] knownProblems = result.problems;
          for (int i = 0; i < result.problemCount; i++) {
            if (knownProblems[i] == distantProblem) { // already recorded
              break recordDistantProblem;
            }
          }
          if (distantProblem
              instanceof
              DefaultProblem) { // fixup filename TODO (philippe) should improve API to make this
                                // official
            ((DefaultProblem) distantProblem).setOriginatingFileName(result.getFileName());
          }
          result.record(distantProblem, unit);
        }
      } else {
        /* distant internal exception which could not be reported back there */
        if (abortException.exception != null) {
          this.handleInternalException(abortException.exception, null, result);
          return;
        }
      }
      /* hand back the compilation result */
      if (!result.hasBeenAccepted) {
        this.requestor.acceptResult(result.tagAsAccepted());
      }
    } else {
      abortException.printStackTrace();
    }
  }
  /**
   * Bytecode generation for a method
   *
   * @param classScope
   * @param classFile
   */
  public void generateCode(ClassScope classScope, ClassFile classFile) {

    classFile.codeStream.wideMode = false; // reset wideMode to false
    if (this.ignoreFurtherInvestigation) {
      // method is known to have errors, dump a problem method
      if (this.binding == null) return; // handle methods with invalid signature or duplicates
      int problemsLength;
      CategorizedProblem[] problems =
          this.scope.referenceCompilationUnit().compilationResult.getProblems();
      CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
      System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
      classFile.addProblemMethod(this, this.binding, problemsCopy);
      return;
    }
    int problemResetPC = 0;
    CompilationResult unitResult = null;
    int problemCount = 0;
    if (classScope != null) {
      TypeDeclaration referenceContext = classScope.referenceContext;
      if (referenceContext != null) {
        unitResult = referenceContext.compilationResult();
        problemCount = unitResult.problemCount;
      }
    }
    boolean restart = false;
    boolean abort = false;
    // regular code generation
    do {
      try {
        problemResetPC = classFile.contentsOffset;
        this.generateCode(classFile);
        restart = false;
      } catch (AbortMethod e) {
        // a fatal error was detected during code generation, need to restart code gen if possible
        if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
          // a branch target required a goto_w, restart code gen in wide mode.
          classFile.contentsOffset = problemResetPC;
          classFile.methodCount--;
          classFile.codeStream.resetInWideMode(); // request wide mode
          // reset the problem count to prevent reporting the same warning twice
          if (unitResult != null) {
            unitResult.problemCount = problemCount;
          }
          restart = true;
        } else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
          classFile.contentsOffset = problemResetPC;
          classFile.methodCount--;
          classFile.codeStream.resetForCodeGenUnusedLocals();
          // reset the problem count to prevent reporting the same warning twice
          if (unitResult != null) {
            unitResult.problemCount = problemCount;
          }
          restart = true;
        } else {
          restart = false;
          abort = true;
        }
      }
    } while (restart);
    // produce a problem method accounting for this fatal error
    if (abort) {
      int problemsLength;
      CategorizedProblem[] problems =
          this.scope.referenceCompilationUnit().compilationResult.getAllProblems();
      CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
      System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
      classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC);
    }
  }