UnitTask.java
package edu.udel.cis.vsl.abc.main;
import java.io.File;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import edu.udel.cis.vsl.abc.config.IF.Configurations;
import edu.udel.cis.vsl.abc.config.IF.Configurations.Language;
import edu.udel.cis.vsl.abc.err.IF.ABCException;
import edu.udel.cis.vsl.abc.transform.IF.Transform;
import edu.udel.cis.vsl.abc.transform.IF.TransformRecord;
/**
* A {@link UnitTask} specifies how a single source unit will be processed in
* order to form an AST representing a single translation unit. A single source
* unit may be specified as a sequence of files.
*
* @author siegel
*
*/
public class UnitTask {
/**
* The source files to read and preprocess. These files are essentially
* concatenated before being preprocessed. There is no default value; these
* must be specified at construction.
*/
private File[] sourceFiles;
/**
* The language in which the source files are all written. Default is
* determined by file suffix(es).
*/
private Language language;
/**
* List of system include paths for the preprocessor. The default is the
* constant {@link ABC#DEFAULT_SYSTEM_INCLUDE_PATHS}.
*/
private File[] systemIncludes = ABC.DEFAULT_SYSTEM_INCLUDE_PATHS;
/**
* List of user include paths for the preprocessor. The default is the
* constant {@link ABC#DEFAULT_USER_INCLUDE_PATHS}.
*/
private File[] userIncludes = ABC.DEFAULT_USER_INCLUDE_PATHS;
/**
* Predefined macros, mapping the macro name to its body. Typically these
* are specified on command line with "-Dname=body". Default is empty list.
*/
private Map<String, String> macros = new LinkedHashMap<>();
/**
* Allow GNU C features in the source files? Default is <code>false</code>.
*/
private boolean gnuc = false;
/**
* Should comments beginning with @ be interpreted as ACSL annotations?
*/
private boolean acsl = false;
/**
* Records for the transformations to apply to the translation unit after
* analysis. Default is empty list.
*/
private List<TransformRecord> transformRecords = new LinkedList<>();
/**
* Constructs new unit task with the given sequence of source files and
* default values for all other parameters.
*
* @param sourceFiles
* the sequence of files to read in and preprocess as a single
* unit
*/
public UnitTask(File[] sourceFiles) {
assert sourceFiles != null;
assert sourceFiles.length >= 1;
this.sourceFiles = sourceFiles;
LinkedList<String> names = new LinkedList<>();
for (File file : sourceFiles)
names.add(file.getName());
this.language = Configurations.bestLanguage(names);
}
/**
* Gets the language in which the source files are written. Default is
* determined by file suffix(es).
*
* @return the language in which all the source files are written
*/
public Language getLanguage() {
return language;
}
/**
* Sets the language in which all source files are written. Default is
* determined from file suffix(es).
*
* @param language
* the language in which all the source files are written
*/
public void setLanguage(Language language) {
this.language = language;
}
/**
* Gets the system include path sequence. The default is the constant
* {@link ABC#DEFAULT_SYSTEM_INCLUDE_PATHS}.
*
* @return the system include path sequence
*/
public File[] getSystemIncludes() {
return systemIncludes;
}
/**
* Sets the system include path sequence. The default is the constant
* {@link ABC#DEFAULT_SYSTEM_INCLUDE_PATHS}.
*
* @param systemIncludes
* the system include path sequence
*/
public void setSystemIncludes(File[] systemIncludes) {
this.systemIncludes = systemIncludes;
}
/**
* Gets the user include path sequence. The default is the constant
* {@link ABC#DEFAULT_USER_INCLUDE_PATHS}.
*
* @return the userIncludes the user include path sequence
*/
public File[] getUserIncludes() {
return userIncludes;
}
/**
* Sets the user include path sequence. The default is the constant
* {@link ABC#DEFAULT_USER_INCLUDE_PATHS}.
*
* @param userIncludes
* the user include path sequence
*/
public void setUserIncludes(File[] userIncludes) {
this.userIncludes = userIncludes;
}
/**
* Gets the predefined macro map. This is map which maps a macro name to its
* body. These are typically defined on the command line using
* "-Dname=body".
*
* @return the map mapping predefined macro names to their bodies
*/
public Map<String, String> getMacros() {
return this.macros;
}
/**
* Sets the predefined macro map. This is map which maps a macro name to its
* body. These are typically defined on the command line using
* "-Dname=body".
*
* @param macros
* the map mapping predefined macro names to their bodies
*/
public void setMacros(Map<String, String> macros) {
this.macros = macros;
}
/**
* Gets the source files that comprise this preprocessor translation unit.
* Must be specified at construction time.
*
* @return the source files
*/
public File[] getSourceFiles() {
return sourceFiles;
}
/**
* Returns the sequence of transform records as a Java {@link Collection} .
* The order does matter. These are the transformations that will be applied
* to the translation unit AST after analysis.
*
* @return the sequence of transformers
*/
public Collection<TransformRecord> getTransformRecords() {
return transformRecords;
}
/**
* Adds the given transform record to the end of the transform record
* sequence.
*
* @param record
* a non-<code>null</code> transform record
*/
public void addTransformRecord(TransformRecord record) {
transformRecords.add(record);
}
/**
* Adds the transformation record specified by the given code to the end of
* the transform record sequence. These are the transformations that will be
* applied to the translation unit AST after analysis.
*
* @param code
* an AST transformation code
* @throws ABCException
* if no record for that code exists
*/
public void addTransformCode(String code) throws ABCException {
TransformRecord record = Transform.getRecord(code);
if (record == null)
throw new ABCException("Unknown transformer code: " + code);
transformRecords.add(record);
}
/**
* Add records for all of the given transformation codes (in order) to the
* transform record sequence of this translation task.
*
* @param codes
* a sequence of AST transformation codes
* @throws ABCException
* if for some code in the collection, no record for that code
* exists
*/
public void addAllTransformCodes(Collection<String> codes)
throws ABCException {
for (String code : codes)
addTransformCode(code);
}
/**
* Are the GNU C extensions allowed in the source files for this translation
* unit? Default is <code>false</code>.
*
* @return <code>true</code> iff the GNU C extensions are allowed
*/
public boolean getGNUC() {
return gnuc;
}
/**
* Should comments beginning with "@" be interpreted as ACSL annotations?
*
* @return the value of the ACSL annotation flag
*/
public boolean getACSL() {
return acsl;
}
/**
* Specifies whether comments beginning with "@" should be interpreted as
* ACSL annotations
*
* @param value
* the new value for the ACSL annotation flag
*/
public void setACSL(boolean value) {
acsl = value;
}
/**
* Specifies whether the GNU C extensions are allowed in the source files
* for this translation unit. Default is <code>false</code>.
*
* @param flag
* <code>true</code> iff the GNU C extensions are allowed
*/
public void setGNUC(boolean flag) {
this.gnuc = flag;
}
}