package org.simantics.scl.compiler.tests.unit; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint.IndexInfo; import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.chr.CHRRuntimeRulesetCodeGenerator; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy; import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder; import org.simantics.scl.compiler.module.repository.ModuleRepository; import org.simantics.scl.compiler.runtime.MutableClassLoader; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; import org.simantics.scl.compiler.tests.InitialRepository; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; public class TestCHRCodeGenerator { @Ignore @Test public void testCodeGenerator() throws Throwable { try { ModuleRepository repository = InitialRepository.getInitialRepository(); RuntimeEnvironment environment = repository.createRuntimeEnvironment(EnvironmentSpecification.of("StandardLibrary", "", "Builtin", ""), getClass().getClassLoader()); JavaNamingPolicy policy = new JavaNamingPolicy("Expression"); JavaTypeTranslator jtt = new JavaTypeTranslator(environment.getEnvironment()); CompilationContext compilationContext = new CompilationContext(); compilationContext.environment = environment.getEnvironment(); compilationContext.javaTypeTranslator = jtt; compilationContext.namingPolicy = policy; ModuleBuilder moduleBuilder = new ModuleBuilder(policy, jtt); CHRRuleset ruleset = new CHRRuleset(); CHRConstraint exampleFact = new CHRConstraint(Locations.NO_LOCATION, "ExampleFact", new Type[] { Types.INTEGER, Types.INTEGER }); ruleset.constraints.add(exampleFact); System.out.println("=============================================================================================="); ruleset.initializeCodeGeneration(compilationContext); exampleFact.indices.put(0, new IndexInfo(0, "ff", null, null)); exampleFact.indices.put(1, new IndexInfo(1, "bf", null, null)); exampleFact.indices.put(2, new IndexInfo(2, "fb", null, null)); exampleFact.indices.put(3, new IndexInfo(3, "bb", null, null)); exampleFact.setMayBeRemoved(); CHRRuntimeRulesetCodeGenerator.generateRuntimeRuleset(moduleBuilder, ruleset); MutableClassLoader classLoader = environment.getMutableClassLoader(); classLoader.addClasses(moduleBuilder.getClasses()); String storeClassName = ruleset.runtimeRulesetName.replace('/', '.'); Class storeClass = classLoader.loadClass(storeClassName); Class factClass = classLoader.loadClass(storeClassName+"$ExampleFact"); Constructor factConstructor = factClass.getConstructor(int.class, int.class, int.class); Method addMethod = factClass.getMethod("add", storeClass); Method removeMethod = factClass.getMethod("remove", storeClass); Method getMethod = storeClass.getMethod("ExampleFact$bf", int.class); Field nextField = factClass.getField("bfNext"); Object store = storeClass.newInstance(); Object fact1 = factConstructor.newInstance(0, 1,2); Object fact2 = factConstructor.newInstance(0, 1,3); Object fact3 = factConstructor.newInstance(0, 2,4); Object fact4 = factConstructor.newInstance(0, 1,4); addMethod.invoke(fact1, store); addMethod.invoke(fact4, store); addMethod.invoke(fact2, store); addMethod.invoke(fact3, store); removeMethod.invoke(fact4, store); { Object f1 = getMethod.invoke(store, 1); Assert.assertEquals(fact2, f1); Object f2 = nextField.get(f1); Assert.assertEquals(fact1, f2); Object f3 = nextField.get(f2); Assert.assertEquals(null, f3); } removeMethod.invoke(fact2, store); { Object f1 = getMethod.invoke(store, 1); Assert.assertEquals(fact1, f1); Object f2 = nextField.get(f1); Assert.assertEquals(null, f2); } addMethod.invoke(fact2, store); removeMethod.invoke(fact1, store); { Object f1 = getMethod.invoke(store, 1); Assert.assertEquals(fact2, f1); Object f2 = nextField.get(f1); Assert.assertEquals(null, f2); } removeMethod.invoke(fact2, store); { Object f1 = getMethod.invoke(store, 1); Assert.assertEquals(null, f1); } } catch(Throwable e) { e.printStackTrace(); throw e; } } }