package backend;
import java.lang.reflect.Modifier;
import soot.SootClass;
import soot.SootField;
import soot.Type;
import ast.Declaration;
import ast.FieldDeclaration;
import ast.FunctionDeclaration;
import ast.Module;
import ast.VarDecl;
/**
* This class is in charge of generating Jimple code for a single module.
*/
/**
* No Changes
* @author Danyang
*
*/
public class ModuleCodeGenerator {
/** Convenience method for determining the modifiers of a declaration. */
public static int getModifiers(Declaration decl) {
return (decl.isPublic() ? Modifier.PUBLIC : 0) | Modifier.STATIC;
}
/** Reference to the {@link ProgramCodeGenerator} that instantiated this object. */
private final ProgramCodeGenerator pcg;
public ModuleCodeGenerator(ProgramCodeGenerator pcg) {
this.pcg = pcg;
}
/** Generate Soot/Jimple declarations for all declarations in this module.
* The Soot class itself is generated by the {@link ProgramCodeGenerator}.
* The module code generator walks over all declarations in the module and generates equivalent Soot
declarations for them. In particular, it creates, for every field, a static field declaration with the appropriate type,
accessibility, and name.
*/
public SootClass generate(Module module) {
SootClass klass = pcg.getSootClass(module);
for(Declaration decl : module.getDeclarations()) {
/**
* code generation for functions is handed off to the
FunctionCodeGenerator class, which generates a static method for each function declaration. Note that no code
is generated for type declarations: such declarations only introduce new names for existing types and do not really
define anything new.
*/
if(decl instanceof FunctionDeclaration) {
new FunctionCodeGenerator(this).generate((FunctionDeclaration)decl, klass);
} else if(decl instanceof FieldDeclaration) {
VarDecl vd = ((FieldDeclaration)decl).getVarDecl();
String fieldName = vd.getName();
Type fieldType = SootTypeUtil.getSootType(vd.getTypeName().getDescriptor());
int fieldModifiers = getModifiers(decl);
SootField sootField = new SootField(fieldName, fieldType, fieldModifiers);
klass.addField(sootField);
}
}
return klass;
}
/** Returns the {@link ProgramCodeGenerator} that instantiated this object. */
public ProgramCodeGenerator getProgramCodeGenerator() {
return pcg;
}
}