/* * This is a prototype implementation of the concept of Feature-Sen * sitive Dataflow Analysis. More details in the AOSD'12 paper: * Dataflow Analysis for Software Product Lines * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package br.ufal.cideei.util; import soot.Body; import soot.Unit; import soot.toolkits.scalar.FlowSet; import soot.toolkits.scalar.ForwardFlowAnalysis; import br.ufal.cideei.soot.instrument.ConfigTag; import br.ufal.cideei.soot.instrument.FeatureTag; public class DebugUtil { public void f(Body body, ForwardFlowAnalysis<Unit, FlowSet> analysis) { if (body.getMethod().getSignature().contains("simple3")) { System.out.println(body.getTag(ConfigTag.CONFIG_TAG_NAME)); for (Unit unit : body.getUnits()) { System.out.println(unit + " [[" + unit.getTag(FeatureTag.FEAT_TAG_NAME) + "]]"); System.out.println(analysis.getFlowAfter(unit)); } } } // public void f2(Body body, LiftedReachingDefinitions analysis) { // DOTExporter<Unit, ValueContainerEdge<IConfigRep>> exporter = new DOTExporter<Unit, ValueContainerEdge<IConfigRep>>(new VertexLineNameProvider<Unit>(null), null, new // // ConfigurationEdgeNameProvider<ValueContainerEdge<IConfigRep>>()); // try { // exporter.export(new FileWriter(System.getProperty("user.home") + File.separator + "REACHES DATA" + ".dot"), createProvidesGraph(body.getUnits(), analysis, body)); // } catch (IOException e) { // e.printStackTrace(); // } // } // private DirectedMultigraph<Unit, ValueContainerEdge<IConfigRep>> createProvidesGraph(Collection<Unit> unitsInSelection, LiftedReachingDefinitions reachingDefinitions, Body body) { // ConfigTag configTag = (ConfigTag) body.getTag(ConfigTag.CONFIG_TAG_NAME); // // DirectedMultigraph<Unit, ValueContainerEdge<IConfigRep>> reachesData = new DirectedMultigraph<Unit, ValueContainerEdge<IConfigRep>>(ConfigurationEdgeFactory.getInstance()); // // // for every unit in the selection... // for (Unit unitFromSelection : unitsInSelection) { // if (unitFromSelection instanceof DefinitionStmt) { // /* // * exclude definitions when it's $temp on the leftOp. // */ // DefinitionStmt definition = (DefinitionStmt) unitFromSelection; // // Value leftOp = (Value) definition.getLeftOp(); // if (leftOp instanceof Local) { // if (((Local) leftOp).getName().contains("$")) { // continue; // } // } // // IFeatureRep featuresThatUseDefinition = null; // // // for every unit in the body... // Iterator<Unit> iterator = body.getUnits().snapshotIterator(); // while (iterator.hasNext()) { // Unit nextUnit = iterator.next(); // FeatureTag nextUnitTag = (FeatureTag) nextUnit.getTag("FeatureTag"); // // List useAndDefBoxes = nextUnit.getUseAndDefBoxes(); // for (Object object : useAndDefBoxes) { // ValueBox vbox = (ValueBox) object; // if (vbox.getValue().equivTo(leftOp)) { // if (featuresThatUseDefinition == null) { // featuresThatUseDefinition = nextUnitTag.getFeatureRep().clone(); // } else { // featuresThatUseDefinition.addAll(nextUnitTag.getFeatureRep()); // } // } // } // // MapLiftedFlowSet liftedFlowAfter = (MapLiftedFlowSet) reachingDefinitions.getFlowAfter(nextUnit); // Collection<IConfigRep> configurations = liftedFlowAfter.getConfigurations(); // for (IConfigRep currConfiguration : configurations) { // FlowSet flowSet = liftedFlowAfter.getLattice(currConfiguration); // // // if the unit belongs to the current configuration... // if (!nextUnitTag.getFeatureRep().belongsToConfiguration(currConfiguration)) { // continue; // } // // // if the definition reaches this unit... // if (flowSet.contains(definition)) { // List<ValueBox> useBoxes = nextUnit.getUseBoxes(); // for (ValueBox vbox : useBoxes) { // /* // * and the definition is used, add to the map (graph)... // */ // if (vbox.getValue().equivTo(leftOp)) { // if (!reachesData.containsVertex(definition)) { // reachesData.addVertex(definition); // } // if (!reachesData.containsVertex(nextUnit)) { // reachesData.addVertex(nextUnit); // } // // Set<ValueContainerEdge<IConfigRep>> allEdges = reachesData.getAllEdges(definition, nextUnit); // if (allEdges.size() >= 1) { // int diffCounter = 0; // Iterator<ValueContainerEdge<IConfigRep>> edgesIterator = allEdges.iterator(); // Set<ValueContainerEdge<IConfigRep>> edgeRemovalSchedule = new HashSet<ValueContainerEdge<IConfigRep>>(); // while (edgesIterator.hasNext()) { // ValueContainerEdge<IConfigRep> valueContainerEdge = (ValueContainerEdge<IConfigRep>) edgesIterator.next(); // IConfigRep valueConfiguration = valueContainerEdge.getValue(); // FlowSet flowSetFromOtherReached = liftedFlowAfter.getLattice(valueConfiguration); // // if (flowSetFromOtherReached.equals(flowSet)) { // /* // * Se a configura��o que estiver "querendo" entrar for menor, // * ent�o ela expulsar� os maiores. // */ // if (valueConfiguration.size() > currConfiguration.size() && featuresThatUseDefinition.belongsToConfiguration(currConfiguration)) { // edgeRemovalSchedule.add(valueContainerEdge); // ValueContainerEdge<IConfigRep> addEdge = reachesData.addEdge(definition, nextUnit); // addEdge.setValue(currConfiguration); // continue; // } // } else { // diffCounter++; // } // } // if (diffCounter == allEdges.size() && featuresThatUseDefinition.belongsToConfiguration(currConfiguration)) { // ValueContainerEdge<IConfigRep> addEdge = reachesData.addEdge(definition, nextUnit); // addEdge.setValue(currConfiguration); // } // reachesData.removeAllEdges(edgeRemovalSchedule); // } else { // ValueContainerEdge<IConfigRep> addEdge = reachesData.addEdge(definition, nextUnit); // addEdge.setValue(currConfiguration); // } // } // } // } // } // } // } // } // return reachesData; // } }