001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2006 Nomair A. Naeem
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package soot.toolkits.astmetrics;
021:
022: import polyglot.ast.Branch;
023: import polyglot.ast.Node;
024: import polyglot.visit.NodeVisitor;
025:
026: /*
027: * Should take care of the following metrics:
028: *
029: * Break Statements
030:
031: 1. of implicit breaks (breaking inner most loop) DONE
032: 2. of explicit breaks (breaking an outer loop) NOTQUITE DONE
033: 3. of explicit breaks (breaking other constructs) DONE (any explicit break)
034:
035: * Continue Statements
036:
037: 1. of implicit continues (breaking inner most loop) DONE
038: 2. of explicit continues (breaking outer loops) DONE
039: */
040: public class AbruptEdgesMetric extends ASTMetric {
041:
042: private int iBreaks, eBreaks;
043: private int iContinues, eContinues;
044:
045: public AbruptEdgesMetric(polyglot.ast.Node astNode) {
046: super (astNode);
047: }
048:
049: /*
050: * (non-Javadoc)
051: * @see soot.toolkits.astmetrics.ASTMetric#reset()
052: * Implementation of the abstract method which is
053: * invoked by parent constructor and whenever the classDecl in the polyglot changes
054: */
055: public void reset() {
056: iBreaks = eBreaks = iContinues = eContinues = 0;
057: }
058:
059: /*
060: * Implementation of the abstract method
061: *
062: * Should add the metrics to the data object sent
063: */
064: public void addMetrics(ClassData data) {
065:
066: data.addMetric(new MetricData("Total-breaks", new Integer(
067: iBreaks + eBreaks)));
068: data
069: .addMetric(new MetricData("I-breaks", new Integer(
070: iBreaks)));
071: data
072: .addMetric(new MetricData("E-breaks", new Integer(
073: eBreaks)));
074:
075: data.addMetric(new MetricData("Total-continues", new Integer(
076: iContinues + eContinues)));
077: data.addMetric(new MetricData("I-continues", new Integer(
078: iContinues)));
079: data.addMetric(new MetricData("E-continues", new Integer(
080: eContinues)));
081:
082: data.addMetric(new MetricData("Total-Abrupt", new Integer(
083: iBreaks + eBreaks + iContinues + eContinues)));
084: }
085:
086: /*
087: * A branch in polyglot is either a break or continue
088: */
089: public NodeVisitor enter(Node parent, Node n) {
090: if (n instanceof Branch) {
091: Branch branch = (Branch) n;
092: if (branch.kind().equals(Branch.BREAK)) {
093: if (branch.label() != null)
094: eBreaks++;
095: else
096: iBreaks++;
097: } else if (branch.kind().equals(Branch.CONTINUE)) {
098: if (branch.label() != null)
099: eContinues++;
100: else
101: iContinues++;
102: } else {
103: System.out.println("\t Error:'" + branch.toString()
104: + "'");
105: }
106: }
107: return enter(n);
108: }
109: }
|