adds support for fields as well as local variables.
authorChris Jaekl <cejaekl@yahoo.com>
Sat, 7 Jan 2017 12:23:56 +0000 (21:23 +0900)
committerChris Jaekl <cejaekl@yahoo.com>
Sat, 7 Jan 2017 12:23:56 +0000 (21:23 +0900)
prod/net/jaekl/cfb/analyze/HtmlReport.java
prod/net/jaekl/cfb/store/DbStore.java
prod/net/jaekl/cfb/xml/BugInstance.java
prod/net/jaekl/cfb/xml/Field.java [new file with mode: 0644]
prod/net/jaekl/cfb/xml/LocalVariable.java
prod/net/jaekl/cfb/xml/Variable.java [new file with mode: 0644]
test/net/jaekl/cfb/analyze/HtmlReportTest.java

index 7ff69629e5d2994c45718378f1ea8ffee648cebf..75e39a94c4d09933a63a83a426337a325d0f292d 100644 (file)
@@ -9,7 +9,7 @@ import net.jaekl.cfb.store.Location;
 import net.jaekl.cfb.util.Command;
 import net.jaekl.cfb.util.XmlEscape;
 import net.jaekl.cfb.xml.BugInstance;
-import net.jaekl.cfb.xml.LocalVariable;
+import net.jaekl.cfb.xml.Variable;
 import net.jaekl.cfb.xml.messages.BugPattern;
 import net.jaekl.cfb.xml.messages.MessageCollection;
 
@@ -127,16 +127,11 @@ public class HtmlReport {
        
        void writeBugVariables(PrintWriter pw, BugInstance bug)
        {
-               for (LocalVariable var : bug.getVariables()) {
+               for (Variable var : bug.getVariables()) {
                        StringBuffer sb = new StringBuffer();
                        
                        if (null != var) {
-                               String name = var.getName();
-                               String role = var.getRole();
-                               sb.append(name);
-                               if (null != role) {
-                                       sb.append(" (").append(role).append(")");
-                               }
+                               sb.append(var.getDescription() + "<BR/>");
                        }
                        
                        pw.println("        <TR><TD COLSPAN=\"2\" CLASS=\"Var\">" + sb.toString() + "</TD></TR>");                                      
index bbf2a721340ec3b6792e3d5721009b72fd992671..dd8f77733ac2fde4e921d12028021f59e66771b4 100644 (file)
@@ -17,6 +17,7 @@ import net.jaekl.cfb.db.driver.DbDriver;
 import net.jaekl.cfb.xml.BugCollection;
 import net.jaekl.cfb.xml.BugInstance;
 import net.jaekl.cfb.xml.LocalVariable;
+import net.jaekl.cfb.xml.Variable;
 import net.jaekl.cfb.xml.messages.BugCategory;
 import net.jaekl.cfb.xml.messages.BugPattern;
 import net.jaekl.cfb.xml.messages.MessageCollection;
@@ -217,7 +218,7 @@ public class DbStore {
                        return null;
                }
                
-               List<LocalVariable> vars = bug.getVariables();
+               List<Variable> vars = bug.getVariables();
                if ((null == vars) || (0 == vars.size())) {
                        return null;
                }
@@ -249,7 +250,7 @@ public class DbStore {
                return new LocalVariable(varId, varName, varRole);
        }
        
-       Long getVarId(LocalVariable var) throws SQLException, TypeMismatchException
+       Long getVarId(Variable var) throws SQLException, TypeMismatchException
        {
                if (null == var) {
                        return null;
@@ -264,7 +265,7 @@ public class DbStore {
                return storeVar(var);
        }
        
-       Long findVarId(LocalVariable var) throws SQLException, TypeMismatchException
+       Long findVarId(Variable var) throws SQLException, TypeMismatchException
        {
                Column[] columns = { CfbSchema.VARID_PK };
                Table[] tables = { CfbSchema.VARIABLES };
@@ -283,7 +284,7 @@ public class DbStore {
                return null;    // not found
        }
        
-       Long storeVar(LocalVariable var) throws SQLException
+       Long storeVar(Variable var) throws SQLException
        {
                long varId = m_driver.nextVal(m_con, CfbSchema.VARIABLE_SEQ);
                
index b805096c67551c7f3a35847b12f6660bc35acca0..9e0395fd0334b1863c02abf5560dc6bddba7d011 100644 (file)
@@ -18,10 +18,11 @@ public class BugInstance extends ParseResult {
 
        static final String TAG = "BugInstance";
        static final String[] INTERNAL = {  };
-       static final Object[][] EXTERNAL = { { BugClass.TAG, BugClass.class},
-                                                { BugMethod.TAG, BugMethod.class},
-                                                { LocalVariable.TAG, LocalVariable.class},
-                                                { SourceLine.TAG, SourceLine.class} };
+       static final Object[][] EXTERNAL = { { BugClass.TAG, BugClass.class },
+                                                { BugMethod.TAG, BugMethod.class },
+                                                { Field.TAG, Field.class },
+                                                { LocalVariable.TAG, LocalVariable.class },
+                                                { SourceLine.TAG, SourceLine.class } };
        static final String CATEGORY = "category";
        static final String TYPE = "type";
 
@@ -30,7 +31,7 @@ public class BugInstance extends ParseResult {
        String m_type;
        ArrayList<BugClass> m_classes;
        ArrayList<BugMethod> m_methods;
-       ArrayList<LocalVariable> m_locals;
+       ArrayList<Variable> m_vars;
        ArrayList<SourceLine> m_lines;
        ArrayList<Location> m_locations;
        
@@ -41,7 +42,7 @@ public class BugInstance extends ParseResult {
                m_category = m_type = null;
                m_classes = new ArrayList<BugClass>();
                m_methods = new ArrayList<BugMethod>();
-               m_locals = new ArrayList<LocalVariable>();
+               m_vars = new ArrayList<Variable>();
                m_lines = new ArrayList<SourceLine>();
                m_locations = new ArrayList<Location>();
        }
@@ -50,7 +51,7 @@ public class BugInstance extends ParseResult {
                                   String category, 
                                   String type,
                                   Location[] locations,
-                                  LocalVariable[] variables)
+                                  Variable[] variables)
        {
                super(TAG, INTERNAL, EXTERNAL);
                
@@ -63,12 +64,12 @@ public class BugInstance extends ParseResult {
                m_lines = new ArrayList<SourceLine>();
 
                m_locations = new ArrayList<Location>(Arrays.asList(locations));
-               m_locals = new ArrayList<LocalVariable>(Arrays.asList(variables));
+               m_vars = new ArrayList<Variable>(Arrays.asList(variables));
        }
        
        public String getCategory() { return m_category; }
        public String getType() { return m_type; }
-       public List<LocalVariable> getVariables() { return Collections.unmodifiableList(m_locals); }
+       public List<Variable> getVariables() { return Collections.unmodifiableList(m_vars); }
        public List<Location> getLocations() { return Collections.unmodifiableList(m_locations); }
        
        @Override
@@ -102,11 +103,18 @@ public class BugInstance extends ParseResult {
                                m_methods.add((BugMethod)pr);
                        }                       
                }
+               else if (Field.TAG.equals(localName)) {
+                       ParseResult[] collected = collectParsedChildren(Field.class);
+                       for (ParseResult pr : collected) {
+                               assert(pr instanceof Field);
+                               m_vars.add((Field)pr);
+                       }                                               
+               }
                else if (LocalVariable.TAG.equals(localName)) {
                        ParseResult[] collected = collectParsedChildren(LocalVariable.class);
                        for (ParseResult pr : collected) {
                                assert(pr instanceof LocalVariable);
-                               m_locals.add((LocalVariable)pr);
+                               m_vars.add((LocalVariable)pr);
                        }                       
                }
                else if (SourceLine.TAG.equals(localName)) {
@@ -139,10 +147,8 @@ public class BugInstance extends ParseResult {
                for (BugMethod bm : m_methods) {
                        bm.dump(pw, childIndent);
                }
-               for (LocalVariable lv : m_locals) {
-                       if (null != lv) {
-                               lv.dump(pw, childIndent);
-                       }
+               for (Variable var : m_vars) {
+                       pw.println(margin + "  " + var.getDescription());
                }
                for (SourceLine sl : m_lines) {
                        sl.dump(pw, childIndent);
diff --git a/prod/net/jaekl/cfb/xml/Field.java b/prod/net/jaekl/cfb/xml/Field.java
new file mode 100644 (file)
index 0000000..0beedbc
--- /dev/null
@@ -0,0 +1,122 @@
+package net.jaekl.cfb.xml;
+
+import java.io.PrintWriter;
+
+import org.xml.sax.Attributes;
+
+import net.jaekl.cfb.util.Util;
+import net.jaekl.qd.xml.MissingAttributeException;
+import net.jaekl.qd.xml.ParseResult;
+import net.jaekl.qd.xml.XmlParseException;
+
+public class Field extends ParseResult implements Variable {
+       static final String TAG = "Field";
+       static final String[] INTERNAL = { };
+       static final Object[][] EXTERNAL = { };
+
+       static final String CLASSNAME = "classname";
+       static final String FIELD = "FIELD";
+       static final String IS_STATIC = "isStatic";
+       static final String NAME = "name";
+       static final String SIGNATURE = "signature";
+       
+       String m_className;
+       String m_name;
+       String m_signature;
+       boolean m_isStatic;
+       
+       public Field() {
+               super(TAG, INTERNAL, EXTERNAL);
+               
+               m_className = m_name = m_signature = null;
+               m_isStatic = false;
+       }
+       
+       public String getClassName() { return m_className; }
+       public String getSignature() { return m_signature; }
+       public boolean isStatic() { return m_isStatic; }
+       
+       @Override
+       public String getDescription() 
+       {
+               String result = "";
+               if (isStatic()) {
+                       result += "static ";
+               }
+               if (null != getClassName()) {
+                       result += getClassName() + ".";
+               }
+               result += getName();
+               return result;
+       }
+       
+       @Override
+       public String getName() { return m_name; }
+       
+       @Override
+       public String getRole() { return FIELD; }
+
+       @Override
+       public void handleMainAttributes(Attributes attr)
+               throws MissingAttributeException
+       {
+               m_className = getRequiredAttr(TAG, attr, CLASSNAME);
+               
+               String isStaticStr = getRequiredAttr(TAG, attr, CLASSNAME);
+               m_isStatic = "true".equals(isStaticStr);
+               
+               m_name = getRequiredAttr(TAG, attr, NAME);
+               
+               m_signature = getRequiredAttr(TAG, attr, SIGNATURE);
+       }
+       
+       @Override
+       public void endContents(String uri, String localName, String qName, String chars) 
+               throws XmlParseException 
+       {
+       }
+
+       @Override
+       public void endExternal(String uri, String localName, String qName)
+               throws XmlParseException 
+       {
+               // no-op
+       }
+       
+       @Override
+       public void dump(PrintWriter pw, int indent) 
+       {
+               super.dump(pw, indent);
+               String tab = String.format("%" + (indent + 2) + "s", "");
+
+               pw.println(tab + CLASSNAME + "=" + m_className);
+               pw.println(tab + IS_STATIC + "=" + (m_isStatic ? "true" : "false"));
+               pw.println(tab + NAME + "=" + m_name);
+               pw.println(tab + SIGNATURE + "=" + m_signature);
+       }
+       
+       @Override
+       public boolean equals(Object obj) 
+       {
+               if (null == obj) {
+                       return false;
+               }
+               if (obj instanceof Field) {
+                       Field that = (Field)obj;
+                       return (   Util.objsAreEqual(this.m_className, that.m_className)
+                                       && (this.m_isStatic == that.m_isStatic)
+                                   && Util.objsAreEqual(this.m_name, that.m_name)
+                                   && Util.objsAreEqual(this.m_signature, that.m_signature) );
+               }
+               return false;
+       }
+       
+       @Override
+       public int hashCode()
+       {
+               return (  (Util.objHashCode(m_className))
+                               ^ (Boolean.valueOf(m_isStatic).hashCode())
+                               ^ (Util.objHashCode(m_name)) 
+                               ^ (Util.objHashCode(m_signature)) );
+       }
+}
index 8043821844c89f0085292dae231058a6a5bce847..1a590ae7df6cbaa9ca2a9eabc81bec4bdda5cbcd 100644 (file)
@@ -9,7 +9,7 @@ import net.jaekl.qd.xml.MissingAttributeException;
 import net.jaekl.qd.xml.ParseResult;
 import net.jaekl.qd.xml.XmlParseException;
 
-public class LocalVariable extends ParseResult {
+public class LocalVariable extends ParseResult implements Variable {
 
        static final String TAG = "LocalVariable";
        static final String[] INTERNAL = { };
@@ -38,7 +38,21 @@ public class LocalVariable extends ParseResult {
        }
        
        public Long getId() { return m_id; }
+       
+       @Override
+       public String getDescription()
+       {
+               String result = getName();
+               if (null != getRole()) {
+                       result += " (" + getRole() + ")";
+               }
+               return result;
+       }
+       
+       @Override
        public String getName() { return m_name; }
+       
+       @Override
        public String getRole() { return m_role; }
        
        @Override
diff --git a/prod/net/jaekl/cfb/xml/Variable.java b/prod/net/jaekl/cfb/xml/Variable.java
new file mode 100644 (file)
index 0000000..d5e3b11
--- /dev/null
@@ -0,0 +1,7 @@
+package net.jaekl.cfb.xml;
+
+public interface Variable {
+       public String getDescription();
+       public String getName();
+       public String getRole();
+}
index 26f9f8e13f06522d203dbe7b3872a463b556c251..0938cb73f186102c10e77ca5eca5c094b8ec6ce5 100644 (file)
@@ -196,4 +196,23 @@ public class HtmlReportTest {
                assertTrue(pos > 0);
                assertFalse(html.substring(pos + expected.length()).contains(expected));
        }
+       
+       @Test
+       public void testField() throws FileNotFoundException, IOException, SAXException, ParserConfigurationException 
+       {
+               String xml = BugReportData.getPrologue()
+                                  + BugReportData.getVoVolatileIncrement()
+                                  + BugReportData.getEpilogue();
+
+               String html = createReport(null, xml);
+               validateReport(html);
+               
+               String expected = "junit.extensions.ActiveTestSuite.fActiveTestDeathCount";
+               
+               // expected string should be present exactly once
+               int pos = html.indexOf(expected);
+               assertTrue(pos > 0);
+               assertFalse(html.substring(pos + expected.length()).contains(expected));
+       }
+
 }