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