From: Chris Jaekl Date: Sat, 7 Jan 2017 12:23:56 +0000 (+0900) Subject: adds support for fields as well as local variables. X-Git-Url: http://jaekl.net/gitweb/?p=cfb.git;a=commitdiff_plain;h=1b9389a8ec38485bbe14e9aa572af4510758e7a5 adds support for fields as well as local variables. --- diff --git a/prod/net/jaekl/cfb/analyze/HtmlReport.java b/prod/net/jaekl/cfb/analyze/HtmlReport.java index 7ff6962..75e39a9 100644 --- a/prod/net/jaekl/cfb/analyze/HtmlReport.java +++ b/prod/net/jaekl/cfb/analyze/HtmlReport.java @@ -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() + "
"); } pw.println(" " + sb.toString() + ""); diff --git a/prod/net/jaekl/cfb/store/DbStore.java b/prod/net/jaekl/cfb/store/DbStore.java index bbf2a72..dd8f777 100644 --- a/prod/net/jaekl/cfb/store/DbStore.java +++ b/prod/net/jaekl/cfb/store/DbStore.java @@ -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 vars = bug.getVariables(); + List 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); diff --git a/prod/net/jaekl/cfb/xml/BugInstance.java b/prod/net/jaekl/cfb/xml/BugInstance.java index b805096..9e0395f 100644 --- a/prod/net/jaekl/cfb/xml/BugInstance.java +++ b/prod/net/jaekl/cfb/xml/BugInstance.java @@ -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 m_classes; ArrayList m_methods; - ArrayList m_locals; + ArrayList m_vars; ArrayList m_lines; ArrayList m_locations; @@ -41,7 +42,7 @@ public class BugInstance extends ParseResult { m_category = m_type = null; m_classes = new ArrayList(); m_methods = new ArrayList(); - m_locals = new ArrayList(); + m_vars = new ArrayList(); m_lines = new ArrayList(); m_locations = new ArrayList(); } @@ -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(); m_locations = new ArrayList(Arrays.asList(locations)); - m_locals = new ArrayList(Arrays.asList(variables)); + m_vars = new ArrayList(Arrays.asList(variables)); } public String getCategory() { return m_category; } public String getType() { return m_type; } - public List getVariables() { return Collections.unmodifiableList(m_locals); } + public List getVariables() { return Collections.unmodifiableList(m_vars); } public List 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 index 0000000..0beedbc --- /dev/null +++ b/prod/net/jaekl/cfb/xml/Field.java @@ -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)) ); + } +} diff --git a/prod/net/jaekl/cfb/xml/LocalVariable.java b/prod/net/jaekl/cfb/xml/LocalVariable.java index 8043821..1a590ae 100644 --- a/prod/net/jaekl/cfb/xml/LocalVariable.java +++ b/prod/net/jaekl/cfb/xml/LocalVariable.java @@ -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 index 0000000..d5e3b11 --- /dev/null +++ b/prod/net/jaekl/cfb/xml/Variable.java @@ -0,0 +1,7 @@ +package net.jaekl.cfb.xml; + +public interface Variable { + public String getDescription(); + public String getName(); + public String getRole(); +} diff --git a/test/net/jaekl/cfb/analyze/HtmlReportTest.java b/test/net/jaekl/cfb/analyze/HtmlReportTest.java index 26f9f8e..0938cb7 100644 --- a/test/net/jaekl/cfb/analyze/HtmlReportTest.java +++ b/test/net/jaekl/cfb/analyze/HtmlReportTest.java @@ -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)); + } + }