<s> package org . eclipse . jdt . internal . compiler ; import org . codehaus . jdt . groovy . integration . LanguageSupportFactory ; import org . eclipse . jdt . core . compiler . * ; import org . eclipse . jdt . internal . compiler . env . * ; import org . eclipse . jdt . internal . compiler . impl . * ; import org . eclipse . jdt . internal . compiler . ast . * ; import org . eclipse . jdt . internal . compiler . lookup . * ; import org . eclipse . jdt . internal . compiler . parser . * ; import org . eclipse . jdt . internal . compiler . problem . * ; import org . eclipse . jdt . internal . compiler . util . * ; import java . io . * ; import java . util . * ; public class Compiler implements ITypeRequestor , ProblemSeverities { public Parser parser ; public ICompilerRequestor requestor ; public CompilerOptions options ; public ProblemReporter problemReporter ; protected PrintWriter out ; public CompilerStats stats ; public CompilationProgress progress ; public int remainingIterations = 1 ; public CompilationUnitDeclaration [ ] unitsToProcess ; public int totalUnits ; public LookupEnvironment lookupEnvironment ; public static boolean DEBUG = false ; public int parseThreshold = - 1 ; public AbstractAnnotationProcessorManager annotationProcessorManager ; public int annotationProcessorStartIndex = 0 ; public ReferenceBinding [ ] referenceBindings ; public boolean useSingleThread = true ; public static IDebugRequestor DebugRequestor = null ; public Compiler ( INameEnvironment environment , IErrorHandlingPolicy policy , Map settings , final ICompilerRequestor requestor , IProblemFactory problemFactory ) { this ( environment , policy , new CompilerOptions ( settings ) , requestor , problemFactory , null , null ) ; } public Compiler ( INameEnvironment environment , IErrorHandlingPolicy policy , Map settings , final ICompilerRequestor requestor , IProblemFactory problemFactory , boolean parseLiteralExpressionsAsConstants ) { this ( environment , policy , new CompilerOptions ( settings , parseLiteralExpressionsAsConstants ) , requestor , problemFactory , null , null ) ; } public Compiler ( INameEnvironment environment , IErrorHandlingPolicy policy , CompilerOptions options , final ICompilerRequestor requestor , IProblemFactory problemFactory ) { this ( environment , policy , options , requestor , problemFactory , null , null ) ; } public Compiler ( INameEnvironment environment , IErrorHandlingPolicy policy , CompilerOptions options , final ICompilerRequestor requestor , IProblemFactory problemFactory , PrintWriter out ) { this ( environment , policy , options , requestor , problemFactory , out , null ) ; } public Compiler ( INameEnvironment environment , IErrorHandlingPolicy policy , CompilerOptions options , final ICompilerRequestor requestor , IProblemFactory problemFactory , PrintWriter out , CompilationProgress progress ) { this . options = options ; this . progress = progress ; if ( this . options . buildGroovyFiles == 0 ) { this . options . buildGroovyFiles = 1 ; this . options . groovyFlags = 0 ; } if ( DebugRequestor == null ) { this . requestor = requestor ; } else { this . requestor = new ICompilerRequestor ( ) { public void acceptResult ( CompilationResult result ) { if ( DebugRequestor . isActive ( ) ) { DebugRequestor . acceptDebugResult ( result ) ; } requestor . acceptResult ( result ) ; } } ; } this . problemReporter = new ProblemReporter ( policy , this . options , problemFactory ) ; this . lookupEnvironment = new LookupEnvironment ( this , this . options , this . problemReporter , environment ) ; this . out = out == null ? new PrintWriter ( System . out , true ) : out ; this . stats = new CompilerStats ( ) ; initializeParser ( ) ; } public void accept ( IBinaryType binaryType , PackageBinding packageBinding , AccessRestriction accessRestriction ) { if ( this . options . verbose ) { this . out . println ( Messages . bind ( Messages . compilation_loadBinary , new String ( binaryType . getName ( ) ) ) ) ; } this . lookupEnvironment . createBinaryTypeFrom ( binaryType , packageBinding , accessRestriction ) ; } public void accept ( ICompilationUnit sourceUnit , AccessRestriction accessRestriction ) { 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 ( ) ) } ) ) ; } CompilationUnitDeclaration parsedUnit ; if ( this . totalUnits < this . parseThreshold ) { parsedUnit = this . parser . parse ( sourceUnit , unitResult ) ; } else { parsedUnit = this . parser . dietParse ( sourceUnit , unitResult ) ; } parsedUnit . bits |= ASTNode . IsImplicitUnit ; this . lookupEnvironment . buildTypeBindings ( parsedUnit , accessRestriction ) ; addCompilationUnit ( sourceUnit , parsedUnit ) ; this . lookupEnvironment . completeTypeBindings ( parsedUnit ) ; } catch ( AbortCompilationUnit e ) { if ( unitResult . compilationUnit == sourceUnit ) { this . requestor . acceptResult ( unitResult . tagAsAccepted ( ) ) ; } else { throw e ; } } } public void accept ( ISourceType [ ] sourceTypes , PackageBinding packageBinding , AccessRestriction accessRestriction ) { this . problemReporter . abortDueToInternalError ( Messages . bind ( Messages . abort_againstSourceModel , new String [ ] { String . valueOf ( sourceTypes [ 0 ] . getName ( ) ) , String . valueOf ( sourceTypes [ 0 ] . getFileName ( ) ) } ) ) ; } protected synchronized void addCompilationUnit ( ICompilationUnit sourceUnit , CompilationUnitDeclaration parsedUnit ) { if ( this . unitsToProcess == null ) return ; int size = this . unitsToProcess . length ; if ( this . totalUnits == size ) System . arraycopy ( this . unitsToProcess , 0 , ( this . unitsToProcess = new CompilationUnitDeclaration [ size * 2 ] ) , 0 , this . totalUnits ) ; this . unitsToProcess [ this . totalUnits ++ ] = parsedUnit ; } protected void beginToCompile ( ICompilationUnit [ ] sourceUnits ) { int maxUnits = sourceUnits . length ; this . totalUnits = 0 ; this . unitsToProcess = new CompilationUnitDeclaration [ maxUnits ] ; internalBeginToCompile ( sourceUnits , maxUnits ) ; } protected void reportProgress ( String taskDecription ) { if ( this . progress != null ) { if ( this . progress . isCanceled ( ) ) { throw new AbortCompilation ( true , null ) ; } this . progress . setTaskName ( taskDecription ) ; } } protected void reportWorked ( int workIncrement , int currentUnitIndex ) { if ( this . progress != null ) { if ( this . progress . isCanceled ( ) ) { throw new AbortCompilation ( true , null ) ; } this . progress . worked ( workIncrement , ( this . totalUnits * this . remainingIterations ) - currentUnitIndex - 1 ) ; } } public void compile ( ICompilationUnit [ ] sourceUnits ) { this . stats . startTime = System . currentTimeMillis ( ) ; if ( this . options . buildGroovyFiles == 2 ) { int groovyFileIndex = - 1 ; for ( int u = 0 , max = sourceUnits . length ; u < max ; u ++ ) { char [ ] fn = sourceUnits [ u ] . getFileName ( ) ; boolean isDotJava = fn [ fn . length - 1 ] == 'a' ; if ( isDotJava ) { if ( groovyFileIndex != - 1 ) { ICompilationUnit swap = sourceUnits [ groovyFileIndex ] ; sourceUnits [ groovyFileIndex ] = sourceUnits [ u ] ; sourceUnits [ u ] = swap ; int newGroovyFileIndex = - 1 ; for ( int g = groovyFileIndex ; g <= u ; g ++ ) { char [ ] fn2 = sourceUnits [ g ] . getFileName ( ) ; boolean isDotGroovy = fn2 [ fn2 . length - 1 ] == 'y' ; if ( isDotGroovy ) { newGroovyFileIndex = g ; break ; } } groovyFileIndex = newGroovyFileIndex ; } } else { if ( groovyFileIndex == - 1 ) { groovyFileIndex = u ; } } } } CompilationUnitDeclaration unit = null ; ProcessTaskManager processingTask = null ; try { reportProgress ( Messages . compilation_beginningToCompile ) ; if ( this . annotationProcessorManager == null ) { beginToCompile ( sourceUnits ) ; } else { ICompilationUnit [ ] originalUnits = ( ICompilationUnit [ ] ) sourceUnits . clone ( ) ; try { beginToCompile ( sourceUnits ) ; processAnnotations ( ) ; if ( ! this . options . generateClassFiles ) { return ; } } catch ( SourceTypeCollisionException e ) { reset ( ) ; 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 ) { 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 { unit . cleanUp ( ) ; } this . unitsToProcess [ i ] = null ; 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 ; 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 ; while ( true ) { try { unit = processingTask . removeNextUnit ( ) ; } 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 ; } catch ( RuntimeException e ) { this . handleInternalException ( e , unit , null ) ; throw e ; } 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 synchronized CompilationUnitDeclaration getUnitToProcess ( int next ) { if ( next < this . totalUnits ) { CompilationUnitDeclaration unit = this . unitsToProcess [ next ] ; this . unitsToProcess [ next ] = null ; return unit ; } return null ; } public void setBinaryTypes ( ReferenceBinding [ ] binaryTypes ) { this . referenceBindings = binaryTypes ; } protected void handleInternalException ( Throwable internalException , CompilationUnitDeclaration unit , CompilationResult result ) { if ( result == null && unit != null ) { result = unit . compilationResult ; } 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 ; } } boolean needToPrint = true ; if ( result != null ) { String [ ] pbArguments = new String [ ] { Messages . bind ( Messages . compilation_internalError , Util . getExceptionSummary ( internalException ) ) , } ; result . record ( this . problemReporter . createProblem ( result . getFileName ( ) , IProblem . Unclassified , pbArguments , pbArguments , Error , 0 , 0 , 0 , 0 ) , unit , true ) ; if ( ! result . hasBeenAccepted ) { this . requestor . acceptResult ( result . tagAsAccepted ( ) ) ; needToPrint = false ; } } if ( needToPrint ) { internalException . printStackTrace ( ) ; } } protected void handleInternalException ( AbortCompilation abortException , CompilationUnitDeclaration unit ) { if ( abortException . isSilent ) { if ( abortException . silentException == null ) { return ; } throw abortException . silentException ; } CompilationResult result = abortException . compilationResult ; if ( result == null && unit != null ) { result = unit . compilationResult ; } 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 ; } } if ( result != null && ! result . hasBeenAccepted ) { 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 ) { break recordDistantProblem ; } } if ( distantProblem instanceof DefaultProblem ) { ( ( DefaultProblem ) distantProblem ) . setOriginatingFileName ( result . getFileName ( ) ) ; } result . record ( distantProblem , unit , true ) ; } } else { if ( abortException . exception != null ) { this . handleInternalException ( abortException . exception , null , result ) ; return ; } } if ( ! result . hasBeenAccepted ) { this . requestor . acceptResult ( result . tagAsAccepted ( ) ) ; } } else { abortException . printStackTrace ( ) ; } } public void initializeParser ( ) { this . parser = LanguageSupportFactory . getParser ( this , this . lookupEnvironment == null ? null : this . lookupEnvironment . globalOptions , this . problemReporter , this . options . parseLiteralExpressionsAsConstants , 1 ) ; } protected void internalBeginToCompile ( ICompilationUnit [ ] sourceUnits , int maxUnits ) { if ( ! this . useSingleThread && maxUnits >= ReadManager . THRESHOLD ) this . parser . readManager = new ReadManager ( sourceUnits , maxUnits ) ; 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 ( ) ) } ) ) ; } 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 ; this . lookupEnvironment . buildTypeBindings ( parsedUnit , null ) ; this . stats . resolveTime += System . currentTimeMillis ( ) - resolveStart ; addCompilationUnit ( sourceUnits [ i ] , parsedUnit ) ; ImportReference currentPackage = parsedUnit . currentPackage ; if ( currentPackage != null ) { unitResult . recordPackageName ( currentPackage . tokens ) ; } } catch ( AbortCompilation a ) { if ( a . compilationResult == null ) a . compilationResult = unitResult ; throw a ; } finally { sourceUnits [ i ] = null ; } } if ( this . parser . readManager != null ) { this . parser . readManager . shutdown ( ) ; this . parser . readManager = null ; } this . lookupEnvironment . completeTypeBindings ( ) ; } 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 ; if ( unit . scope != null ) unit . scope . faultInTypes ( ) ; if ( unit . scope != null ) unit . scope . verifyMethods ( this . lookupEnvironment . methodVerifier ( ) ) ; unit . resolve ( ) ; long analyzeStart = System . currentTimeMillis ( ) ; this . stats . resolveTime += analyzeStart - resolveStart ; if ( ! this . options . ignoreMethodBodies ) unit . analyseCode ( ) ; long generateStart = System . currentTimeMillis ( ) ; this . stats . analyzeTime += generateStart - analyzeStart ; if ( ! this . options . ignoreMethodBodies ) unit . generateCode ( ) ; if ( this . options . produceReferenceInfo && unit . scope != null ) unit . scope . storeDependencyInfo ( ) ; unit . finalizeProblems ( ) ; this . stats . generateTime += System . currentTimeMillis ( ) - generateStart ; unit . compilationResult . totalUnitsKnown = this . totalUnits ; this . lookupEnvironment . unitBeingCompleted = null ; } protected void processAnnotations ( ) { int newUnitSize = 0 ; int newClassFilesSize = 0 ; int bottom = this . annotationProcessorStartIndex ; int top = this . totalUnits ; ReferenceBinding [ ] binaryTypeBindingsTemp = this . referenceBindings ; if ( top == 0 && binaryTypeBindingsTemp == null ) return ; this . referenceBindings = null ; do { int length = top - bottom ; CompilationUnitDeclaration [ ] currentUnits = new CompilationUnitDeclaration [ length ] ; int index = 0 ; for ( int i = bottom ; i < top ; i ++ ) { CompilationUnitDeclaration currentUnit = this . unitsToProcess [ i ] ; if ( ( currentUnit . bits & ASTNode . IsImplicitUnit ) == 0 ) { currentUnits [ index ++ ] = currentUnit ; } } if ( index != length ) { System . arraycopy ( currentUnits , 0 , ( currentUnits = new CompilationUnitDeclaration [ index ] ) , 0 , index ) ; } this . annotationProcessorManager . processAnnotations ( currentUnits , binaryTypeBindingsTemp , false ) ; ICompilationUnit [ ] newUnits = this . annotationProcessorManager . getNewUnits ( ) ; newUnitSize = newUnits . length ; ReferenceBinding [ ] newClassFiles = this . annotationProcessorManager . getNewClassFiles ( ) ; binaryTypeBindingsTemp = newClassFiles ; newClassFilesSize = newClassFiles . length ; if ( newUnitSize != 0 ) { ICompilationUnit [ ] newProcessedUnits = ( ICompilationUnit [ ] ) newUnits . clone ( ) ; try { this . lookupEnvironment . isProcessingAnnotations = true ; internalBeginToCompile ( newUnits , newUnitSize ) ; } catch ( SourceTypeCollisionException e ) { e . newAnnotationProcessorUnits = newProcessedUnits ; throw e ; } finally { this . lookupEnvironment . isProcessingAnnotations = false ; this . annotationProcessorManager . reset ( ) ; } bottom = top ; top = this . totalUnits ; } else { bottom = top ; this . annotationProcessorManager . reset ( ) ; } } while ( newUnitSize != 0 || newClassFilesSize != 0 ) ; this . annotationProcessorManager . processAnnotations ( null , null , true ) ; ICompilationUnit [ ] newUnits = this . annotationProcessorManager . getNewUnits ( ) ; newUnitSize = newUnits . length ; if ( newUnitSize != 0 ) { ICompilationUnit [ ] newProcessedUnits = ( ICompilationUnit [ ] ) newUnits . clone ( ) ; try { this . lookupEnvironment . isProcessingAnnotations = true ; internalBeginToCompile ( newUnits , newUnitSize ) ; } catch ( SourceTypeCollisionException e ) { e . newAnnotationProcessorUnits = newProcessedUnits ; throw e ; } finally { this . lookupEnvironment . isProcessingAnnotations = false ; this . annotationProcessorManager . reset ( ) ; } } else { this . annotationProcessorManager . reset ( ) ; } } public void reset ( ) { this . lookupEnvironment . reset ( ) ; this . parser . reset ( ) ; this . parser . scanner . source = null ; this . unitsToProcess = null ; if ( DebugRequestor != null ) DebugRequestor . reset ( ) ; this . problemReporter . reset ( ) ; } public CompilationUnitDeclaration resolve ( CompilationUnitDeclaration unit , ICompilationUnit sourceUnit , boolean verifyMethods , boolean analyzeCode , boolean generateCode ) { try { if ( unit == null ) { this . parseThreshold = 0 ; beginToCompile ( new ICompilationUnit [ ] { sourceUnit } ) ; for ( int i = 0 ; i < this . totalUnits ; i ++ ) { if ( this . unitsToProcess [ i ] != null && this . unitsToProcess [ i ] . compilationResult . compilationUnit == sourceUnit ) { unit = this . unitsToProcess [ i ] ; break ; } } if ( unit == null ) unit = this . unitsToProcess [ 0 ] ; } else { this . lookupEnvironment . buildTypeBindings ( unit , null ) ; this . lookupEnvironment . completeTypeBindings ( ) ; } this . lookupEnvironment . unitBeingCompleted = unit ; this . parser . getMethodBodies ( unit ) ; if ( unit . scope != null ) { unit . scope . faultInTypes ( ) ; if ( unit . scope != null && verifyMethods ) { unit . scope . verifyMethods ( this . lookupEnvironment . methodVerifier ( ) ) ; } unit . resolve ( ) ; if ( analyzeCode ) unit . analyseCode ( ) ; if ( generateCode ) unit . generateCode ( ) ; unit . finalizeProblems ( ) ; } if ( this . unitsToProcess != null ) this . unitsToProcess [ 0 ] = null ; 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 ; } catch ( RuntimeException e ) { this . handleInternalException ( e , unit , null ) ; throw e ; } finally { } } public CompilationUnitDeclaration resolve ( ICompilationUnit sourceUnit , boolean verifyMethods , boolean analyzeCode , boolean generateCode ) { return resolve ( null , sourceUnit , verifyMethods , analyzeCode , generateCode ) ; } } </s>