package me.tomassetti.turin.compiler;
import com.google.common.collect.ImmutableList;
import me.tomassetti.turin.classloading.TurinClassLoader;
import me.tomassetti.turin.classloading.ClassFileDefinition;
import me.tomassetti.turin.parser.Parser;
import me.tomassetti.turin.resolvers.SymbolResolver;
import me.tomassetti.turin.parser.ast.TurinFile;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class ReferencesInOtherSrcFileTest extends AbstractCompilerTest {
@Test
public void referenceFunctionTypeFromOtherSrcFile() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TurinFile turinFileSrc = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/referencetypefromothersrcfile/foo.to"));
TurinFile turinFileTest = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/referencetypefromothersrcfile/foo_test.to"));
SymbolResolver resolver = getResolverFor(ImmutableList.of(turinFileSrc, turinFileTest),
Collections.emptyList(),
Collections.emptyList());
Compiler instance = new Compiler(resolver, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsSrc = instance.compile(turinFileSrc, new MyErrorCollector());
assertEquals(1, classFileDefinitionsSrc.size());
saveClassFile(classFileDefinitionsSrc.get(0), "tmp");
List<ClassFileDefinition> classFileDefinitionsTest = instance.compile(turinFileTest, new MyErrorCollector());
assertEquals(1, classFileDefinitionsTest.size());
saveClassFile(classFileDefinitionsTest.get(0), "tmp");
TurinClassLoader turinClassLoader = new TurinClassLoader();
turinClassLoader.addClass(classFileDefinitionsSrc.get(0));
Class testClass = turinClassLoader.addClass(classFileDefinitionsTest.get(0));
assertEquals(9876, testClass.getMethod("invoke").invoke(null));
}
@Test
public void referenceFunctionFromOtherSrcFile() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TurinFile turinFileSrc = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/referencefunctionfromothersrcfile/foo.to"));
TurinFile turinFileTest = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/referencefunctionfromothersrcfile/foo_test.to"));
SymbolResolver resolver = getResolverFor(ImmutableList.of(turinFileSrc, turinFileTest),
ImmutableList.of("src/test/resources/jars/junit-4.12.jar"),
Collections.emptyList());
Compiler instance = new Compiler(resolver, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsSrc = instance.compile(turinFileSrc, new MyErrorCollector());
assertEquals(1, classFileDefinitionsSrc.size());
List<ClassFileDefinition> classFileDefinitionsTest = instance.compile(turinFileTest, new MyErrorCollector());
assertEquals(1, classFileDefinitionsTest.size());
TurinClassLoader turinClassLoader = new TurinClassLoader();
turinClassLoader.addClass(classFileDefinitionsSrc.get(0));
Class testClass = turinClassLoader.addClass(classFileDefinitionsTest.get(0));
testClass.getMethod("invoke").invoke(null);
}
@Test
public void resolveToRightVersionOfAssertEquals() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TurinFile turinFileSrc = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/overloadresolution/foo.to"));
TurinFile turinFileTest = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/overloadresolution/foo_test.to"));
SymbolResolver resolver = getResolverFor(ImmutableList.of(turinFileSrc, turinFileTest),
ImmutableList.of("src/test/resources/jars/junit-4.12.jar"),
Collections.emptyList());
Compiler instance = new Compiler(resolver, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsSrc = instance.compile(turinFileSrc, new MyErrorCollector());
assertEquals(1, classFileDefinitionsSrc.size());
List<ClassFileDefinition> classFileDefinitionsTest = instance.compile(turinFileTest, new MyErrorCollector());
assertEquals(1, classFileDefinitionsTest.size());
TurinClassLoader turinClassLoader = new TurinClassLoader();
turinClassLoader.addClass(classFileDefinitionsSrc.get(0));
Class testClass = turinClassLoader.addClass(classFileDefinitionsTest.get(0));
testClass.getMethod("invoke").invoke(null);
}
@Test
public void referenceFunctionTypeFromOtherClassesDir() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TurinFile turinFileSrc = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/referencetoseparateclassdir/classdira/foo.to"));
SymbolResolver resolver1 = getResolverFor(ImmutableList.of(turinFileSrc),
Collections.emptyList(),
Collections.emptyList());
File tmpDir = Files.createTempDirectory("classes").toFile();
tmpDir.deleteOnExit();
// generate bytecode
Compiler instance1 = new Compiler(resolver1, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsSrc = instance1.compile(turinFileSrc, new MyErrorCollector());
assertEquals(1, classFileDefinitionsSrc.size());
saveClassFile(classFileDefinitionsSrc.get(0), tmpDir.getAbsolutePath());
TurinFile turinFileTest = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/referencetoseparateclassdir/classdirb/foo_test.to"));
SymbolResolver resolver2 = getResolverFor(ImmutableList.of(turinFileTest),
Collections.emptyList(),
ImmutableList.of(tmpDir.getAbsolutePath()));
Compiler instance2 = new Compiler(resolver2, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsTest = instance2.compile(turinFileTest, new MyErrorCollector());
assertEquals(1, classFileDefinitionsTest.size());
// if it compiles that is enough
}
@Test
public void referenceConstructorFromOtherClassesDir() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TurinFile turinFileSrc = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/constructorinseparateclassdir/classdira/foo.to"));
SymbolResolver resolver1 = getResolverFor(ImmutableList.of(turinFileSrc),
Collections.emptyList(),
Collections.emptyList());
File tmpDir = Files.createTempDirectory("classes").toFile();
tmpDir.deleteOnExit();
// generate bytecode
Compiler instance1 = new Compiler(resolver1, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsSrc = instance1.compile(turinFileSrc, new MyErrorCollector());
assertEquals(1, classFileDefinitionsSrc.size());
saveClassFile(classFileDefinitionsSrc.get(0), tmpDir.getAbsolutePath());
TurinFile turinFileTest = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/constructorinseparateclassdir/classdirb/foo_test.to"));
SymbolResolver resolver2 = getResolverFor(ImmutableList.of(turinFileTest),
Collections.emptyList(),
ImmutableList.of(tmpDir.getAbsolutePath()));
Compiler instance2 = new Compiler(resolver2, new Compiler.Options());
List<ClassFileDefinition> classFileDefinitionsTest = instance2.compile(turinFileTest, new MyErrorCollector());
assertEquals(3, classFileDefinitionsTest.size());
// if it compiles that is enough
// we need to add it, otherwise we cannot invoke the methods by reflection
TurinClassLoader classLoader = new TurinClassLoader();
Class abc = classLoader.addClass(classFileDefinitionsSrc.get(0));
Class foo1 = classLoader.addClass(classFileDefinitionsTest.get(0));
Object res1 = foo1.getMethod("invoke").invoke(null);
assertEquals(27, res1.getClass().getMethod("getA").invoke(res1));
assertEquals(5, res1.getClass().getMethod("getB").invoke(res1));
Class foo2 = classLoader.addClass(classFileDefinitionsTest.get(1));
Object res2 = foo2.getMethod("invoke").invoke(null);
assertEquals(27, res2.getClass().getMethod("getA").invoke(res2));
assertEquals(28, res2.getClass().getMethod("getB").invoke(res2));
Class foo3 = classLoader.addClass(classFileDefinitionsTest.get(2));
Object res3 = foo3.getMethod("invoke").invoke(null);
assertEquals(28, res3.getClass().getMethod("getA").invoke(res3));
assertEquals(27, res3.getClass().getMethod("getB").invoke(res3));
}
}