edu.rice.cs.drjava.model.compiler
Class DefaultCompilerModel

java.lang.Object
  extended by edu.rice.cs.drjava.model.compiler.DefaultCompilerModel
All Implemented Interfaces:
CompilerModel

public class DefaultCompilerModel
extends java.lang.Object
implements CompilerModel

Default implementation of the CompilerModel interface. This implementation is used for normal DrJava execution (as opposed to testing DrJava). TO DO: convert edu.rice.cs.util.Pair to edu.rice.cs.plt.tuple.Pair; requires making the same conversion in javalanglevels.

Version:
$Id: DefaultCompilerModel.java 5443 2011-08-17 04:58:50Z rcartwright $

Field Summary
private  CompilerInterface _active
          Current compiler -- one of _compilers, or a NoCompilerAvailable
private  CompilerErrorModel _compilerErrorModel
          The error model containing all current compiler errors.
private  java.lang.Object _compilerLock
          The lock providing mutual exclustion between compilation and unit testing
private  java.util.List<CompilerInterface> _compilers
          The available compilers
 LanguageLevelStackTraceMapper _LLSTM
          The LanguageLevelStackTraceMapper that helps translate .java line numbers to .dj* line numbers when an error is thrown
private static Log _log
          for logging debug info
private  GlobalModel _model
          The global model to which this compiler model belongs.
private  CompilerEventNotifier _notifier
          Manages listeners to this model.
 
Constructor Summary
DefaultCompilerModel(GlobalModel m, java.lang.Iterable<? extends CompilerInterface> compilers)
          Main constructor.
 
Method Summary
private  void _compileFiles(java.util.List<java.io.File> files, java.io.File buildDir)
          Compile the given files and update the model with any errors that result.
private  java.util.List<java.io.File> _compileLanguageLevelsFiles(java.util.List<java.io.File> files, java.util.List<DJError> errors, java.lang.Iterable<java.io.File> classPath, java.lang.Iterable<java.io.File> bootClassPath)
          Compiles the language levels files in the list.
private  void _distributeErrors(java.util.List<? extends DJError> errors)
          Sorts the given array of CompilerErrors and divides it into groups based on the file, giving each group to the appropriate OpenDefinitionsDocument, opening files if necessary.
private  void _doCompile(java.util.List<OpenDefinitionsDocument> docs)
          Compile the given documents.
private  java.util.LinkedList<DJError> _parseExceptions2CompilerErrors(java.util.LinkedList<JExprParseException> pes)
          Converts JExprParseExceptions thrown by the JExprParser in language levels to CompilerErrors.
private  boolean _prepareForCompile()
          Check that there are no unsaved or untitled files currently open.
private static java.util.List<java.io.File> _testFileSort(java.util.List<java.io.File> files)
          Reorders files so that all file names containing "Test" are at the end.
private  java.util.LinkedList<DJError> _visitorErrors2CompilerErrors(java.util.LinkedList<Pair<java.lang.String,JExpressionIF>> visitorErrors)
          Converts errors thrown by the language level visitors to CompilerErrors.
 void addCompiler(CompilerInterface compiler)
          Add a compiler to the active list
 void addListener(CompilerListener listener)
          Adds a CompilerListener to the model.
 void compile(java.util.List<OpenDefinitionsDocument> defDocs)
          Compiles all of the given files.
 void compile(OpenDefinitionsDocument doc)
          Compiles the given file.
 void compileAll()
          Compile all open documents.
 void compileProject()
          Compiles all documents in the project source tree.
 CompilerInterface getActiveCompiler()
          Gets the compiler that is the "active" compiler.
 java.lang.Iterable<CompilerInterface> getAvailableCompilers()
          Returns all registered compilers that are actually available.
 CompilerErrorModel getCompilerErrorModel()
          Gets the CompilerErrorModel representing the last compile.
 java.lang.Object getCompilerLock()
          Returns the lock used to prevent simultaneous compilation and JUnit testing
 LanguageLevelStackTraceMapper getLLSTM()
          returns the LanguageLevelStackTraceMapper
 int getNumCompErrors()
          Gets the total number of current compiler errors.
 int getNumErrors()
          Gets the total number of errors in this compiler model.
 int getNumWarnings()
          Gets the total number of current warnings.
 void removeAllListeners()
          Removes all CompilerListeners from this model.
 void removeListener(CompilerListener listener)
          Removes a CompilerListener from the model.
 void resetCompilerErrors()
          Resets the compiler error state to have no errors.
 void setActiveCompiler(CompilerInterface compiler)
          Sets which compiler is the "active" compiler.
 void smartDeleteClassFiles(java.util.Map<java.io.File,java.util.Set<java.lang.String>> sourceToTopLevelClassMap)
          Delete the .class files that match the following pattern: XXX.dj? --> XXX.class XXX$*.class
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_log

private static Log _log
for logging debug info


_compilers

private final java.util.List<CompilerInterface> _compilers
The available compilers


_active

private CompilerInterface _active
Current compiler -- one of _compilers, or a NoCompilerAvailable


_notifier

private final CompilerEventNotifier _notifier
Manages listeners to this model.


_model

private final GlobalModel _model
The global model to which this compiler model belongs.


_compilerErrorModel

private CompilerErrorModel _compilerErrorModel
The error model containing all current compiler errors.


_compilerLock

private java.lang.Object _compilerLock
The lock providing mutual exclustion between compilation and unit testing


_LLSTM

public LanguageLevelStackTraceMapper _LLSTM
The LanguageLevelStackTraceMapper that helps translate .java line numbers to .dj* line numbers when an error is thrown

Constructor Detail

DefaultCompilerModel

public DefaultCompilerModel(GlobalModel m,
                            java.lang.Iterable<? extends CompilerInterface> compilers)
Main constructor.

Parameters:
m - the GlobalModel that is the source of documents for this CompilerModel
compilers - The compilers to use. The first will be made active; all are assumed to be available. An empty list is acceptable.
Method Detail

getCompilerLock

public java.lang.Object getCompilerLock()
Returns the lock used to prevent simultaneous compilation and JUnit testing

Specified by:
getCompilerLock in interface CompilerModel

addListener

public void addListener(CompilerListener listener)
Adds a CompilerListener to the model. This operation is synchronized by the readers/writers protocol in EventNotifier.

Specified by:
addListener in interface CompilerModel
Parameters:
listener - A listener that reacts to compiler events.

removeListener

public void removeListener(CompilerListener listener)
Removes a CompilerListener from the model. If the listener is not installed, this method has no effect.

Specified by:
removeListener in interface CompilerModel
Parameters:
listener - a listener that reacts to compiler events This operation is synchronized by the readers/writers protocol in EventNotifier.

removeAllListeners

public void removeAllListeners()
Removes all CompilerListeners from this model.

Specified by:
removeAllListeners in interface CompilerModel

compileAll

public void compileAll()
                throws java.io.IOException
Compile all open documents.

Before compiling, all unsaved and untitled documents are saved, and compilation ends if the user cancels this step. The compilation classpath and sourcepath includes the build directory (if it exists), the source roots, the project "extra classpath" (if it exists), the global "extra classpath", and the current JVM's classpath (which includes drjava.jar, containing JUnit classes).

This method formerly only compiled documents which were out of sync with their class file, as a performance optimization. However, bug #634386 pointed out that unmodified files could depend on modified files, in which case this command would not recompile a file in some situations when it should. Since we value correctness over performance, we now always compile all open documents.

Specified by:
compileAll in interface CompilerModel
Throws:
java.io.IOException - if a filesystem-related problem prevents compilation

compileProject

public void compileProject()
                    throws java.io.IOException
Compiles all documents in the project source tree. Assumes DrJava currently contains an active project.

Before compiling, all unsaved and untitled documents are saved, and compilation ends if the user cancels this step. The compilation classpath and sourcepath includes the build directory (if it exists), the source roots, the project "extra classpath" (if it exists), the global "extra classpath", and the current JVM's classpath (which includes drjava.jar, containing JUnit classes).

This method formerly only compiled documents which were out of sync with their class file, as a performance optimization. However, bug #634386 pointed out that unmodified files could depend on modified files, in which case this command would not recompile a file in some situations when it should. Since we value correctness over performance, we now always compile all open documents.

Specified by:
compileProject in interface CompilerModel
Throws:
java.io.IOException - if a filesystem-related problem prevents compilation

compile

public void compile(java.util.List<OpenDefinitionsDocument> defDocs)
             throws java.io.IOException
Compiles all of the given files.

Before compiling, all unsaved and untitled documents are saved, and compilation ends if the user cancels this step. The compilation classpath and sourcepath includes the build directory (if it exists), the source roots, the project "extra classpath" (if it exists), the global "extra classpath", and the current JVM's classpath (which includes drjava.jar, containing JUnit classes).

This method formerly only compiled documents which were out of sync with their class file, as a performance optimization. However, bug #634386 pointed out that unmodified files could depend on modified files, in which case this command would not recompile a file in some situations when it should. Since we value correctness over performance, we now always compile all open documents.

Specified by:
compile in interface CompilerModel
Parameters:
defDocs - the documents to be compiled
Throws:
java.io.IOException - if a filesystem-related problem prevents compilation

compile

public void compile(OpenDefinitionsDocument doc)
             throws java.io.IOException
Compiles the given file.

Before compiling, all unsaved and untitled documents are saved, and compilation ends if the user cancels this step. The compilation classpath and sourcepath includes the build directory (if it exists), the source roots, the project "extra classpath" (if it exists), the global "extra classpath", and the current JVM's classpath (which includes drjava.jar, containing JUnit classes).

This method formerly only compiled documents which were out of sync with their class file, as a performance optimization. However, bug #634386 pointed out that unmodified files could depend on modified files, in which case this command would not recompile a file in some situations when it should. Since we value correctness over performance, we now always compile all open documents.

Specified by:
compile in interface CompilerModel
Parameters:
doc - the document to be compiled
Throws:
java.io.IOException - if a filesystem-related problem prevents compilation

_prepareForCompile

private boolean _prepareForCompile()
Check that there are no unsaved or untitled files currently open.

Returns:
@code{true} iff compilation should continue

_doCompile

private void _doCompile(java.util.List<OpenDefinitionsDocument> docs)
                 throws java.io.IOException
Compile the given documents.

Throws:
java.io.IOException

_parseExceptions2CompilerErrors

private java.util.LinkedList<DJError> _parseExceptions2CompilerErrors(java.util.LinkedList<JExprParseException> pes)
Converts JExprParseExceptions thrown by the JExprParser in language levels to CompilerErrors.


_visitorErrors2CompilerErrors

private java.util.LinkedList<DJError> _visitorErrors2CompilerErrors(java.util.LinkedList<Pair<java.lang.String,JExpressionIF>> visitorErrors)
Converts errors thrown by the language level visitors to CompilerErrors.


_compileFiles

private void _compileFiles(java.util.List<java.io.File> files,
                           java.io.File buildDir)
                    throws java.io.IOException
Compile the given files and update the model with any errors that result. Does not notify listeners. All public compile methods delegate to this one so this method is the only one that uses synchronization to prevent compiling and unit testing at the same time.

Parameters:
files - The files to be compiled
buildDir - The output directory for all the .class files; @code{null} means output to the same directory as the source file
Throws:
java.io.IOException

_testFileSort

private static java.util.List<java.io.File> _testFileSort(java.util.List<java.io.File> files)
Reorders files so that all file names containing "Test" are at the end.


_compileLanguageLevelsFiles

private java.util.List<java.io.File> _compileLanguageLevelsFiles(java.util.List<java.io.File> files,
                                                                 java.util.List<DJError> errors,
                                                                 java.lang.Iterable<java.io.File> classPath,
                                                                 java.lang.Iterable<java.io.File> bootClassPath)
Compiles the language levels files in the list. Adds any errors to the given error list.

Returns:
An updated list for compilation containing no Language Levels files, or @code{null} if there were no Language Levels files to process.

_distributeErrors

private void _distributeErrors(java.util.List<? extends DJError> errors)
                        throws java.io.IOException
Sorts the given array of CompilerErrors and divides it into groups based on the file, giving each group to the appropriate OpenDefinitionsDocument, opening files if necessary. Called immediately after compilations finishes.

Throws:
java.io.IOException

getCompilerErrorModel

public CompilerErrorModel getCompilerErrorModel()
Gets the CompilerErrorModel representing the last compile.

Specified by:
getCompilerErrorModel in interface CompilerModel

getNumErrors

public int getNumErrors()
Gets the total number of errors in this compiler model.

Specified by:
getNumErrors in interface CompilerModel

getNumCompErrors

public int getNumCompErrors()
Gets the total number of current compiler errors.


getNumWarnings

public int getNumWarnings()
Gets the total number of current warnings.


resetCompilerErrors

public void resetCompilerErrors()
Resets the compiler error state to have no errors.

Specified by:
resetCompilerErrors in interface CompilerModel

getAvailableCompilers

public java.lang.Iterable<CompilerInterface> getAvailableCompilers()
Returns all registered compilers that are actually available. If there are none, the result is NoCompilerAvailable.ONLY.

Specified by:
getAvailableCompilers in interface CompilerModel

getActiveCompiler

public CompilerInterface getActiveCompiler()
Gets the compiler that is the "active" compiler.

Specified by:
getActiveCompiler in interface CompilerModel
See Also:
setActiveCompiler(edu.rice.cs.drjava.model.compiler.CompilerInterface)

setActiveCompiler

public void setActiveCompiler(CompilerInterface compiler)
Sets which compiler is the "active" compiler.

Specified by:
setActiveCompiler in interface CompilerModel
Parameters:
compiler - Compiler to set active.
Throws:
java.lang.IllegalArgumentException - If the compiler is not in the list of available compilers
See Also:
getActiveCompiler()

addCompiler

public void addCompiler(CompilerInterface compiler)
Add a compiler to the active list

Specified by:
addCompiler in interface CompilerModel

smartDeleteClassFiles

public void smartDeleteClassFiles(java.util.Map<java.io.File,java.util.Set<java.lang.String>> sourceToTopLevelClassMap)
Delete the .class files that match the following pattern: XXX.dj? --> XXX.class XXX$*.class

Parameters:
sourceToTopLevelClassMap - a map from directories to classes in them

getLLSTM

public LanguageLevelStackTraceMapper getLLSTM()
returns the LanguageLevelStackTraceMapper

Specified by:
getLLSTM in interface CompilerModel
Returns:
the LanguageLevelStackTraceMapper