/** * <copyright> * Copyright (c) 2010-2012 Henshin developers. All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * </copyright> */ package org.eclipse.emf.henshin.interpreter.jit; import java.util.List; import org.eclipse.emf.henshin.interpreter.EGraph; import org.eclipse.emf.henshin.interpreter.Match; import org.eclipse.emf.henshin.interpreter.impl.EGraphImpl; import org.eclipse.emf.henshin.model.Edge; import org.eclipse.emf.henshin.model.Graph; import org.eclipse.emf.henshin.model.MappingList; import org.eclipse.emf.henshin.model.Node; import org.eclipse.emf.henshin.model.Rule; import org.eclipse.emf.henshin.model.resource.HenshinResourceSet; public class TreeJITMatcherCompiler extends AbstractJITMatcherCompiler { /* * (non-Javadoc) * @see org.eclipse.emf.henshin.interpreter.matching.jit.AbstractJITCompiler#generateNextMatchMethod(org.eclipse.emf.henshin.model.Rule, org.eclipse.emf.henshin.interpreter.matching.jit.AbstractJITCompiler.MatchingCodeGenerator) */ @Override protected boolean generateNextMatchMethod(Rule rule, MatchingCodeGenerator gen) { // Find the root node: Node root = null; for (Node node : rule.getLhs().getNodes()) { if (node.getOutgoing().size()==rule.getLhs().getEdges().size() && node.getOutgoing().size()==rule.getLhs().getNodes().size()-1) { root = node; break; } } if (root==null) { return false; } // Ok, create the rule model fields: initRuleFields(rule, gen); // Domain of the root node: gen.matcherFields.println("List<EObject> rootDomain = graph.getDomain(" + typeField(root) + ", false);"); // Declare the index fields for the node matches: for (Node node : rule.getLhs().getNodes()) { gen.matcherFields.println("int " + indexField(node) + " = 0;"); } /* --- Matching code --- */ gen.matcherCode.println("boolean valid = false;"); gen.matcherCode.println("while (!valid) {"); // Check whether a target for the root node is left: gen.matcherCode.println(" if (" + indexField(root) + "<rootDomain.size()) {"); gen.matcherCode.println(" break;"); gen.matcherCode.println(" }"); gen.matcherCode.println(" EObject root = rootDomain.get(" + indexField(root) + ");"); // Check whether the rest of the nodes can be matched: for (Node node : rule.getLhs().getNodes()) { if (node==root) continue; } gen.matcherCode.println("}"); // Match found? gen.matcherCode.println("if (!valid) {"); gen.matcherCode.println(" return null;"); gen.matcherCode.println("}"); // Construct the match: gen.matcherCode.println("Match rootMatch = new MatchImpl(" + objField(rule) + ");"); // gen.matcherCode.println("rootMatch.setNodeTarget(node" + root.hashCode() + ", rootDomain.get(rootIndex));"); // gen.matcherCode.println("Match match = rootMatch;"); // Matching code for the multi-rules: //if (!generateMultiRuleCode(rule, root, gen)) { // return false; //} // Increase the root index for the next match: // gen.matcherCode.println("rootIndex++;"); // Return the generated match: gen.matcherCode.println("return rootMatch;"); // Success. return true; } @SuppressWarnings("unused") private boolean generateMultiRuleCode(Rule rule, Node parent, MatchingCodeGenerator gen) { // No multi-rule? Ok! if (rule.getMultiRules().isEmpty()) { return true; } // At most one multi-rule: if (rule.getMultiRules().size()>1) { return false; } // The multi-rule: Rule multiRule = rule.getMultiRules().get(0); Graph multiLhs = multiRule.getLhs(); List<Node> multiNodes = multiLhs.getNodes(); List<Edge> multiEdges = multiLhs.getEdges(); MappingList multiMappings = multiRule.getMultiMappings(); if (multiNodes.size()!=2) { return false; } // Get the parent and child node in the multi-rule: Node parentImage = multiMappings.getImage(parent, multiLhs); if (parentImage==null) { return false; } int childIndex = (multiNodes.get(0)==parentImage) ? 1 : 0; Node child = multiNodes.get(childIndex); if (multiMappings.getOrigin(child)!=null) { return false; } // Edge that connects parent and child: if (multiEdges.size()!=1) { return false; } Edge edge = multiLhs.getEdges().get(0); if (multiMappings.getOrigin(edge)!=null) { return false; } if (edge.getSource()!=parentImage || edge.getTarget()!=child) { return false; } return true; } public static void main(String[] args) throws Throwable { HenshinResourceSet resourceSet = new HenshinResourceSet( "../org.eclipse.emf.henshin.examples/src/org/eclipse/emf/henshin/examples/probbroadcast"); Rule rule = (Rule) resourceSet.getModule("probbroadcast.henshin", false).getUnit("send"); JITMatcher finder = JITMatcherCompiler.INSTANCE.generateMatcher(rule, null); EGraph graph = new EGraphImpl(resourceSet.getEObject("init-grid4x4.xmi")); for (Match match : finder.findMatches(graph)) { System.out.println(match); } } }