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 java.util.Iterator;
023:
024: import polyglot.ast.ClassDecl;
025: import polyglot.ast.Node;
026: import polyglot.visit.NodeVisitor;
027: import polyglot.util.CodeWriter;
028: import soot.G;
029:
030: public abstract class ASTMetric extends NodeVisitor implements
031: MetricInterface {
032: polyglot.ast.Node astNode;
033: String className = null; //name of Class being currently processed
034:
035: public ASTMetric(polyglot.ast.Node astNode) {
036: this .astNode = astNode;
037: reset();
038: }
039:
040: /*
041: * Taking care of the change in classes within a polyglot ast
042: */
043: public final NodeVisitor enter(Node n) {
044: if (n instanceof ClassDecl) {
045: className = ((ClassDecl) n).name();
046: System.out.println("Starting processing: " + className);
047: }
048: return this ;
049: }
050:
051: /*
052: * When we leave a classDecl all the metrics for this classDecl
053: * must be stored and the metrics reset
054: *
055: * This is done by invoking the addMetrics abstract method
056: */
057:
058: public final Node leave(Node parent, Node old, Node n, NodeVisitor v) {
059: if (n instanceof ClassDecl) {
060: if (className == null)
061: throw new RuntimeException("className is null");
062:
063: System.out.println("Done with class " + className);
064:
065: //get the classData object for this class
066: ClassData data = getClassData();
067: addMetrics(data);
068: reset();
069: }
070: return leave(old, n, v);
071: }
072:
073: public abstract void reset();
074:
075: public abstract void addMetrics(ClassData data);
076:
077: /*
078: * Should be used to execute the traversal which will find the
079: * metric being calculated
080: */
081: public final void execute() {
082: astNode.visit(this );
083: // Testing testing testing
084: System.out.println("\n\n\n PRETTY P{RINTING");
085: if (this instanceof StmtSumWeightedByDepth) {
086: metricPrettyPrinter p = new metricPrettyPrinter(this );
087: p.printAst(astNode, new CodeWriter(System.out, 80));
088: }
089: }
090:
091: public void printAstMetric(Node n, CodeWriter w) {
092:
093: }
094:
095: /*
096: * Returns the classData object if one if present in the globals Metrics List
097: * otherwise creates new adds to globals metric list and returns that
098: */
099: public final ClassData getClassData() {
100: if (className == null)
101: throw new RuntimeException("className is null");
102:
103: Iterator<ClassData> it = G.v().ASTMetricsData.iterator();
104: while (it.hasNext()) {
105: ClassData tempData = it.next();
106:
107: if (tempData.classNameEquals(className)) {
108: return tempData;
109: }
110: }
111: ClassData data = new ClassData(className);
112: G.v().ASTMetricsData.add(data);
113: return data;
114: }
115: }
|