/* * 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(); } }
/** * 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 } } }
/* * 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(); } }