package org.simantics.scl.compiler.internal.elaboration.transformations; 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; import gnu.trove.procedure.TObjectObjectProcedure; public class DecomposedRule { final TransformationRule rule; final ArrayList sourceQueries = new ArrayList(); final ArrayList sourceMappings = new ArrayList(); final ArrayList targetQueries = new ArrayList(); final ArrayList targetMappings = new ArrayList(); 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() { @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; } }