--- /dev/null
+package org.simantics.scl.compiler.internal.elaboration.transformations;
+
+import gnu.trove.procedure.TObjectObjectProcedure;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.query.QMapping;
+import org.simantics.scl.compiler.elaboration.query.Query;
+import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
+import org.simantics.scl.compiler.elaboration.rules.SectionName;
+import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
+
+public class DecomposedRule {
+ final TransformationRule rule;
+ final ArrayList<Query> sourceQueries = new ArrayList<Query>();
+ final ArrayList<QMapping> sourceMappings = new ArrayList<QMapping>();
+ final ArrayList<Query> targetQueries = new ArrayList<Query>();
+ final ArrayList<QMapping> targetMappings = new ArrayList<QMapping>();
+
+ LocalRelation ruleMatchingRelation;
+
+ private DecomposedRule(TransformationRule rule) {
+ this.rule = rule;
+ }
+
+ public static DecomposedRule decompose(final TypingContext context, TransformationRule rule, final boolean forwardDirection) {
+ final DecomposedRule result = new DecomposedRule(rule);
+ rule.forEachSection(new TObjectObjectProcedure<SectionName, Query[]>() {
+ @Override
+ public boolean execute(SectionName sectionName, Query[] queries) {
+ switch(forwardDirection ? sectionName.forwardRole : sectionName.backwardRole) {
+ case MATCH:
+ for(Query query : queries) {
+ if(query instanceof QMapping) {
+ QMapping mapping = (QMapping)query;
+ result.sourceMappings.add(mapping);
+ }
+ else
+ result.sourceQueries.add(query.copy(context));
+ }
+ break;
+ case ENFORCE:
+ case ENFORCE_FIRST_TIME: // Because this is one-shot, these two are equivalent
+ for(Query query : queries) {
+ if(query instanceof QMapping) {
+ QMapping mapping = (QMapping)query;
+ result.targetMappings.add(mapping);
+ }
+ else
+ result.targetQueries.add(query.copy(context));
+ }
+ break;
+ case IGNORE:
+ }
+ return true;
+ }
+ });
+ return result;
+ }
+}