001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2003 Jennifer Lhotak
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.jimple.toolkits.annotation.nullcheck;
021:
022: import soot.*;
023: import soot.tagkit.*;
024: import soot.toolkits.graph.*;
025: import java.util.*;
026: import soot.toolkits.scalar.*;
027: import soot.jimple.*;
028:
029: public class NullPointerColorer extends BodyTransformer {
030:
031: public NullPointerColorer(Singletons.Global g) {
032: }
033:
034: public static NullPointerColorer v() {
035: return G
036: .v()
037: .soot_jimple_toolkits_annotation_nullcheck_NullPointerColorer();
038: }
039:
040: protected void internalTransform(Body b, String phaseName,
041: Map options) {
042:
043: BranchedRefVarsAnalysis analysis = new BranchedRefVarsAnalysis(
044: new ExceptionalUnitGraph(b));
045:
046: Iterator it = b.getUnits().iterator();
047:
048: while (it.hasNext()) {
049: Stmt s = (Stmt) it.next();
050:
051: Iterator usesIt = s.getUseBoxes().iterator();
052: FlowSet beforeSet = (FlowSet) analysis.getFlowBefore(s);
053:
054: while (usesIt.hasNext()) {
055: ValueBox vBox = (ValueBox) usesIt.next();
056: addColorTags(vBox, beforeSet, s, analysis);
057: }
058:
059: Iterator defsIt = s.getDefBoxes().iterator();
060: FlowSet afterSet = (FlowSet) analysis.getFallFlowAfter(s);
061:
062: while (defsIt.hasNext()) {
063: ValueBox vBox = (ValueBox) defsIt.next();
064: addColorTags(vBox, afterSet, s, analysis);
065: }
066: }
067:
068: Iterator keysIt = b.getMethod().getDeclaringClass().getTags()
069: .iterator();
070: boolean keysAdded = false;
071: while (keysIt.hasNext()) {
072: Object next = keysIt.next();
073: if (next instanceof KeyTag) {
074: if (((KeyTag) next).analysisType().equals(
075: "NullCheckTag")) {
076: keysAdded = true;
077: }
078: }
079: }
080: if (!keysAdded) {
081: b.getMethod().getDeclaringClass().addTag(
082: new KeyTag(ColorTag.RED, "Nullness: Null",
083: "NullCheckTag"));
084: b.getMethod().getDeclaringClass().addTag(
085: new KeyTag(ColorTag.GREEN, "Nullness: Not Null",
086: "NullCheckTag"));
087: b.getMethod().getDeclaringClass().addTag(
088: new KeyTag(ColorTag.BLUE,
089: "Nullness: Nullness Unknown",
090: "NullCheckTag"));
091: }
092: }
093:
094: private void addColorTags(ValueBox vBox, FlowSet set, Stmt s,
095: BranchedRefVarsAnalysis analysis) {
096:
097: Value val = vBox.getValue();
098: if (val.getType() instanceof RefLikeType) {
099: //G.v().out.println(val+": "+val.getClass().toString());
100:
101: int vInfo = analysis.anyRefInfo(val, set);
102:
103: switch (vInfo) {
104: case 1: {
105: // analysis.kNull
106: s.addTag(new StringTag(val + ": Null", "NullCheckTag"));
107: vBox.addTag(new ColorTag(ColorTag.RED, "NullCheckTag"));
108: break;
109: }
110: case 2: {
111: // analysis.kNonNull
112: s.addTag(new StringTag(val + ": NonNull",
113: "NullCheckTag"));
114: vBox
115: .addTag(new ColorTag(ColorTag.GREEN,
116: "NullCheckTag"));
117: break;
118: }
119: case 99: {
120: // analysis.KTop:
121: s.addTag(new StringTag(val + ": Nullness Unknown",
122: "NullCheckTag"));
123: vBox
124: .addTag(new ColorTag(ColorTag.BLUE,
125: "NullCheckTag"));
126: break;
127: }
128: case 0: {
129: // analysis.kBottom
130: s.addTag(new StringTag(val + ": Nullness Unknown",
131: "NullCheckTag"));
132: vBox
133: .addTag(new ColorTag(ColorTag.BLUE,
134: "NullCheckTag"));
135: break;
136: }
137: }
138: } else {
139:
140: }
141: }
142: }
|