Deal with multiple source files properly, don't throw all the constraints together

This commit is contained in:
Daniel Holle 2024-04-12 10:48:13 +02:00
parent 4fc78f494c
commit 39d02f792c
11 changed files with 109 additions and 101 deletions

View File

@ -2,6 +2,8 @@ package de.dhbwstuttgart.core;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.*;
public class ConsoleInterface {
private static final String directory = System.getProperty("user.dir");
@ -35,9 +37,9 @@ public class ConsoleInterface {
input.add(new File(arg));
}
}
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, new File(outputPath));
//compiler.typeInference();
compiler.generateBytecode(outputPath);
compiler.generateBytecode();
}

View File

@ -1,7 +1,6 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.environment.DirectoryClassLoader;
@ -31,7 +30,6 @@ import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.target.tree.expression.TargetBinaryOp;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
@ -59,7 +57,6 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.sql.Array;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
@ -79,13 +76,14 @@ public class JavaTXCompiler {
private final DirectoryClassLoader classLoader;
private final List<File> classPath;
private final File outputPath;
public DirectoryClassLoader getClassLoader() {
return classLoader;
}
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile), null);
this(Arrays.asList(sourceFile), null, new File(""));
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
@ -94,17 +92,20 @@ public class JavaTXCompiler {
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null);
this(sourceFiles, null, new File(""));
}
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
if (contextPath == null || contextPath.isEmpty()) {
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
var path = new ArrayList<>(contextPath);
if (contextPath.isEmpty()) {
// When no contextPaths are given, the working directory is the sources root
contextPath = Lists.newArrayList(new File(System.getProperty("user.dir")));
path.add(new File(System.getProperty("user.dir")));
}
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
path.add(outputPath);
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
environment = new CompilationEnvironment(sources);
classPath = contextPath;
this.outputPath = outputPath;
for (File s : sources) {
parse(s);
@ -130,7 +131,7 @@ public class JavaTXCompiler {
return null;
}
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
ClassOrInterface objectClass = ASTFactory.createClass(Object.class);
var recordClass = ASTFactory.createClass(Record.class);
@ -157,7 +158,7 @@ public class JavaTXCompiler {
sf_new.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, sf.availableClasses, objectClass));
allClasses.addAll(sf_new.getClasses());
}
TYPE ty = new TYPE(sourceFiles.values(), allClasses);
TYPE ty = new TYPE(sourceFiles.get(sourceFile), allClasses);
return ty.getConstraints();
}
@ -204,20 +205,19 @@ public class JavaTXCompiler {
cl.setMethodsAdded();
}
private List<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
Set<ClassOrInterface> allClasses = new HashSet<>();
if (loadJavaTXClass(name)) {
var file = findFileForClass(name);
var sf = sourceFiles.get(file);
if (sf != null) allClasses.addAll(sf.KlassenVektor);
} else {
var clazz = loadJavaTXClass(name);
if (clazz == null) {
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
allClasses.add(importedClass);
} else {
allClasses.add(clazz);
}
return new ArrayList<>(allClasses);
return allClasses;
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
public Set<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
// hinzugefuegt werden
// List<ClassOrInterface> allClasses = new
@ -227,7 +227,7 @@ public class JavaTXCompiler {
for (JavaClassName name : forSourceFile.getImports()) {
allClasses.addAll(getAvailableClasses(name));
}
return new ArrayList<>(allClasses);
return allClasses;
}
/*
@ -283,7 +283,11 @@ public class JavaTXCompiler {
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
}
final ConstraintSet<Pair> cons = getConstraints();
final ConstraintSet<Pair> cons = new ConstraintSet<>();
for (var f : this.sourceFiles.keySet()) {
cons.addAll(getConstraints(f));
}
Set<Set<UnifyPair>> results = new HashSet<>();
UnifyResultModel urm = null;
// urm.addUnifyResultListener(resultListener);
@ -310,8 +314,8 @@ public class JavaTXCompiler {
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile sf : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(sf));
for (SourceFile f : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(f));
}
logFile.flush();
@ -404,30 +408,27 @@ public class JavaTXCompiler {
return urm;
}
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (Entry<File, SourceFile> source : this.sourceFiles.entrySet()) {
SourceFile sf = source.getValue();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList());
for (var clazz : newClasses) {
// Don't load classes that get recompiled
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
continue;
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
allClasses.add(clazz);
}
public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(file);
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
for (var clazz : newClasses) {
// Don't load classes that get recompiled
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
continue;
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
allClasses.add(clazz);
}
final ConstraintSet<Pair> cons = getConstraints();
final ConstraintSet<Pair> cons = getConstraints(file);
Set<Set<UnifyPair>> results = new HashSet<>();
try {
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
if (log) logFolder.mkdirs();
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader, this);
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
System.out.println("xxx1");
@ -448,10 +449,8 @@ public class JavaTXCompiler {
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile sf : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
}
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
@ -670,10 +669,10 @@ public class JavaTXCompiler {
* if it doesn't exist it's going to compile it and add it to the source files list
* @param name
*/
public boolean loadJavaTXClass(JavaClassName name) {
public ClassOrInterface loadJavaTXClass(JavaClassName name) {
var file = findFileForClass(name);
if (file != null) {
if (classRegistry.contains(name)) return true;
if (classRegistry.contains(name)) return getClass(name);
try {
var tree = JavaTXParser.parse(file);
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
@ -683,12 +682,20 @@ public class JavaTXCompiler {
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
addSourceFile(file, sf);
generator.convert(classes, tree, environment.packageCrawler);
return true;
var classFiles = generateBytecode(file);
File path = outputPath;
if (outputPath == null) {
path = file.getParentFile(); // Set path to path of the parsed .jav file
}
writeClassFile(classFiles, path, outputPath == null);
return ASTFactory.createClass(classLoader.loadClass(name.toString()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return false;
return null;
}
public File findFileForClass(JavaClassName name) {
@ -702,25 +709,18 @@ public class JavaTXCompiler {
}
public void generateBytecode() throws ClassNotFoundException, IOException {
generateBytecode((File) null);
}
/**
* @param path - can be null, then class file output is in the same directory as the parsed source files
*/
public void generateBytecode(String path) throws ClassNotFoundException, IOException {
if (path != null)
generateBytecode(new File(path));
else
generateBytecode();
for (var file : sourceFiles.keySet()) {
generateBytecode(file);
}
}
/**
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
* @return
*/
public void generateBytecode(File path) throws ClassNotFoundException, IOException {
List<ResultSet> typeinferenceResult = this.typeInference();
generateBytecode(path, typeinferenceResult);
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
List<ResultSet> typeinferenceResult = this.typeInference(sourceFile);
return generateBytecode(sourceFiles.get(sourceFile), typeinferenceResult);
}
private Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();

View File

@ -140,7 +140,7 @@ public class GatherNames {
if (importDeclCtx.MUL() == null) {
var name = importDeclCtx.qualifiedName().getText();
var className = new JavaClassName(name);
if (compiler.loadJavaTXClass(className)) {
if (compiler.loadJavaTXClass(className) != null) {
ret.put(name, compiler.classRegistry.getNumberOfGenerics(name));
} else {
Class<?> cl = compiler.getClassLoader().loadClass(name);

View File

@ -15,24 +15,23 @@ import java.util.*;
public class TYPE {
private final Collection<SourceFile> sfs;
private final SourceFile sf;
private final Set<ClassOrInterface> allAvailableClasses;
public TYPE(Collection<SourceFile> sourceFiles, Set<ClassOrInterface> allAvailableClasses){
sfs = sourceFiles;
public TYPE(SourceFile sf, Set<ClassOrInterface> allAvailableClasses){
this.sf = sf;
this.allAvailableClasses = allAvailableClasses;
}
public ConstraintSet getConstraints() {
ConstraintSet ret = new ConstraintSet();
for(SourceFile sf : sfs)
for (ClassOrInterface cl : sf.KlassenVektor) {
System.out.println(sf.availableClasses);
var allClasses = new HashSet<ClassOrInterface>();
allClasses.addAll(allAvailableClasses);
allClasses.addAll(sf.availableClasses);
ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses)));
}
for (ClassOrInterface cl : sf.KlassenVektor) {
System.out.println(sf.availableClasses);
var allClasses = new HashSet<ClassOrInterface>();
allClasses.addAll(allAvailableClasses);
allClasses.addAll(sf.availableClasses);
ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses)));
}
return ret;
}

View File

@ -71,9 +71,10 @@ public class AllgemeinTest {
///*
compiler = new JavaTXCompiler(
Lists.newArrayList(new File(path)),
Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/")));
Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/")),
new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/"));
//*/
compiler.generateBytecode(System.getProperty("user.dir")+"/resources/bytecode/classFiles/");
compiler.generateBytecode(new File(path));
pathToClassFile = System.getProperty("user.dir")+"/resources/bytecode/classFiles/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass(className);

View File

@ -16,32 +16,36 @@ public class TestPackages {
new File("resources/packageTest/pkg/sub/Test1.jav") // This should pull in Test2
//new File("resources/packageTest/pkg/sub2/Test2.jav")
),
List.of(new File("resources/packageTest"))
List.of(new File("resources/packageTest")),
new File(bytecodeDirectory)
);
cmp.generateBytecode(bytecodeDirectory);
cmp.generateBytecode();
}
@Test
@Ignore("This doesn't work")
public void testPackagesCircular() throws Exception {
var cmp = new JavaTXCompiler(
List.of(
new File("resources/packageTest/pkg/sub/Cycle1.jav")
//new File("resources/packageTest/pkg/sub2/Cycle2.jav")
),
List.of(new File("resources/packageTest"))
List.of(new File("resources/packageTest")),
new File(bytecodeDirectory)
);
cmp.generateBytecode(bytecodeDirectory);
cmp.generateBytecode();
}
@Test
public void testPackageInterface() throws Exception {
var cmp = new JavaTXCompiler(
List.of(new File("resources/packageTest/pkg/sub/Interface.jav")),
List.of(new File("resources/packageTest"))
List.of(new File("resources/packageTest")),
new File(bytecodeDirectory)
);
cmp.generateBytecode(bytecodeDirectory);
cmp.generateBytecode();
}
}

View File

@ -20,7 +20,7 @@ public class TestTypeDeployment {
var file = path.toFile();
var compiler = new JavaTXCompiler(file, false);
var parsedSource = compiler.sourceFiles.get(file);
var tiResults = compiler.typeInference();
var tiResults = compiler.typeInference(file);
Set<TypeInsert> tips = new HashSet<>();
for (var sf : compiler.sourceFiles.values()) {

View File

@ -34,7 +34,7 @@ public class ASTToTypedTargetAST {
public void overloading() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Overloading.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -56,7 +56,7 @@ public class ASTToTypedTargetAST {
public void tphsAndGenerics() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Tph2.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -67,7 +67,7 @@ public class ASTToTypedTargetAST {
public void cycles() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Cycle.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -78,7 +78,7 @@ public class ASTToTypedTargetAST {
public void infimum() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Infimum.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -89,7 +89,7 @@ public class ASTToTypedTargetAST {
public void gen() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Gen.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -105,7 +105,7 @@ public class ASTToTypedTargetAST {
public void definedGenerics() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -123,7 +123,7 @@ public class ASTToTypedTargetAST {
public void definedGenerics2() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics2.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -139,7 +139,7 @@ public class ASTToTypedTargetAST {
public void definedGenerics3() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics3.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -150,7 +150,7 @@ public class ASTToTypedTargetAST {
public void definedGenerics4() throws Exception {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics4.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();

View File

@ -41,11 +41,12 @@ public class TestCodegen {
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, String... files) throws IOException, ClassNotFoundException {
Files.createDirectories(outputPath);
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()));
var resultSet = compiler.typeInference();
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()), outputPath.toFile());
var result = new HashMap<String, Class<?>>();
for (var file : filenames) {
var resultSet = compiler.typeInference(file);
var sourceFile = compiler.sourceFiles.get(file);
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
var classes = compiler.sourceFiles.get(file).getClasses();
@ -82,8 +83,8 @@ public class TestCodegen {
public static Map<String, ? extends Class<?>> generateClassFiles(String filename, IByteArrayClassLoader classLoader) throws IOException, ClassNotFoundException {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/", filename).toFile();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()));
var resultSet = compiler.typeInference();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), outputPath.toFile());
var resultSet = compiler.typeInference(file);
var sourceFile = compiler.sourceFiles.get(file);
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);

View File

@ -48,8 +48,8 @@ public class TestGenerics {
private static Result computeGenerics(String filename) throws IOException, ClassNotFoundException {
var file = Path.of(rootDirectory + filename).toFile();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()));
var inference = compiler.typeInference();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), new File(bytecodeDirectory));
var inference = compiler.typeInference(file);
compiler.generateBytecode(new File(bytecodeDirectory), inference);
var sf = compiler.sourceFiles.get(file);
var clazz = sf.getClasses().get(0);

View File

@ -166,9 +166,10 @@ public class JavaTXCompilerTest {
System.out.println(ASTTypePrinter.print(sf));
System.out.println(ASTPrinter.print(sf));
}
List<ResultSet> results = compiler.typeInference();
// compiler.generateBytecode(rootDirectory+"xxx.class", results, simplifyResultsForAllSourceFiles);
for (File f : compiler.sourceFiles.keySet()) {
List<ResultSet> results = compiler.typeInference(f);
SourceFile sf = compiler.sourceFiles.get(f);
System.out.println(ASTTypePrinter.print(sf));
System.out.println(ASTPrinter.print(sf));