diff options
Diffstat (limited to 'core/java12/com/vladium/emma/report/SrcFileItem.java')
-rw-r--r-- | core/java12/com/vladium/emma/report/SrcFileItem.java | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/core/java12/com/vladium/emma/report/SrcFileItem.java b/core/java12/com/vladium/emma/report/SrcFileItem.java new file mode 100644 index 0000000..4b06847 --- /dev/null +++ b/core/java12/com/vladium/emma/report/SrcFileItem.java @@ -0,0 +1,303 @@ +/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. + * + * This program and the accompanying materials are made available under + * the terms of the Common Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/cpl-v10.html + * + * $Id: SrcFileItem.java,v 1.1.1.1.2.1 2004/06/20 20:07:22 vlad_r Exp $ + */ +package com.vladium.emma.report; + +import java.util.Iterator; + +import com.vladium.util.IntObjectMap; +import com.vladium.util.asserts.$assert; +import com.vladium.emma.data.ClassDescriptor; +import com.vladium.emma.data.MethodDescriptor; + +// ---------------------------------------------------------------------------- +/** + * @author Vlad Roubtsov, (C) 2003 + */ +public +final class SrcFileItem extends Item +{ + // public: ................................................................ + + + public final class LineCoverageData + { + public static final int LINE_COVERAGE_ZERO = 0; + public static final int LINE_COVERAGE_PARTIAL = 1; + public static final int LINE_COVERAGE_COMPLETE = 2; + + public final int m_coverageStatus; + public final int [/* units mode */][/* total, coverage */] m_coverageRatio; // not null in LINE_COVERAGE_PARTIAL status only] + + LineCoverageData (final int coverageStatus, final int [][] coverageRatio) + { + m_coverageStatus = coverageStatus; + m_coverageRatio = coverageRatio; + } + + } // end of nested class + + + public SrcFileItem (final IItem parent, final String name, final String fullVMName) + { + super (parent); + + m_name = name; + m_fullVMName = fullVMName; + } + + public String getName () + { + return m_name; + } + + public String getFullVMName () + { + return m_fullVMName; + } + + public int getFirstLine () + { + // TODO: state validation + + if (m_firstLine == 0) + { + getAggregate (TOTAL_LINE_COUNT); // fault line coverage calculation + } + + return m_firstLine; + } + + + + + public IntObjectMap /* line_no:int -> LineCoverageData */ getLineCoverage () + { + if (m_lineCoverage == null) + { + getAggregate (TOTAL_LINE_COUNT); // fault line coverage calculation + } + + return m_lineCoverage; + } + + + public int getAggregate (final int type) + { + final int [] aggregates = m_aggregates; + + int value = aggregates [type]; + + if (value < 0) + { + switch (type) + { + case COVERAGE_CLASS_COUNT: + case TOTAL_CLASS_COUNT: + { + aggregates [TOTAL_CLASS_COUNT] = getChildCount (); + + value = 0; + for (Iterator children = getChildren (); children.hasNext (); ) + { + // SF BUG 972725: this was incorrectly using 'type' instead + // of the COVERAGE_CLASS_COUNT aggregate type, making class + // coverage computation dependent on the order of how item + // nodes were traversed in report generators + value += ((IItem) children.next ()).getAggregate (COVERAGE_CLASS_COUNT); + } + aggregates [COVERAGE_CLASS_COUNT] = value; + + return aggregates [type]; + } + //break; + + + case TOTAL_SRCFILE_COUNT: + { + return aggregates [TOTAL_SRCFILE_COUNT] = 1; + } + //break; + + + case COVERAGE_LINE_COUNT: + case TOTAL_LINE_COUNT: + + case COVERAGE_LINE_INSTR: + { + // line aggregate types are special when used on srcfile items: + // unlike all others, they do not simply add up when the line + // info is available; instead, lines from all classes belonging + // to the same srcfile parent are set-merged + + final IntObjectMap /* line -> int[2] */ fldata = new IntObjectMap (); + + for (Iterator classes = getChildren (); classes.hasNext (); ) + { + final ClassItem cls = (ClassItem) classes.next (); + + final boolean [][] ccoverage = cls.getCoverage (); // this can be null + final ClassDescriptor clsdesc = cls.getClassDescriptor (); + final MethodDescriptor [] methoddescs = clsdesc.getMethods (); + + for (Iterator methods = cls.getChildren (); methods.hasNext (); ) + { + final MethodItem method = (MethodItem) methods.next (); + final int methodID = method.getID (); + + final boolean [] mcoverage = ccoverage == null ? null : ccoverage [methodID]; + + final MethodDescriptor methoddesc = methoddescs [methodID]; + final int [] mbsizes = methoddesc.getBlockSizes (); + final IntObjectMap mlineMap = methoddesc.getLineMap (); + if ($assert.ENABLED) $assert.ASSERT (mlineMap != null); + + final int [] mlines = mlineMap.keys (); + for (int ml = 0, mlLimit = mlines.length; ml < mlLimit; ++ ml) + { + final int mline = mlines [ml]; + + int [] data = (int []) fldata.get (mline); + if (data == null) + { + data = new int [4]; // { totalcount, totalinstr, coveragecount, coverageinstr } + fldata.put (mline, data); + } + + final int [] lblocks = (int []) mlineMap.get (mline); + + final int bCount = lblocks.length; + data [0] += bCount; + + for (int bID = 0; bID < bCount; ++ bID) + { + final int block = lblocks [bID]; + + final boolean bcovered = mcoverage != null && mcoverage [block]; + final int instr = mbsizes [block]; + + data [1] += instr; + if (bcovered) + { + ++ data [2]; + data [3] += instr; + } + } + } + } + } + + final int lineCount = fldata.size (); + + aggregates [TOTAL_LINE_COUNT] = lineCount; + + int coverageLineCount = 0; + int coverageLineInstr = 0; + + final IntObjectMap /* line_no:int -> LineCoverageData */ lineCoverage = new IntObjectMap (lineCount); + int firstLine = Integer.MAX_VALUE; + + final int [] clines = fldata.keys (); + + for (int cl = 0; cl < lineCount; ++ cl) + { + final int cline = clines [cl]; + final int [] data = (int []) fldata.get (cline); + + final int ltotalCount = data [0]; + final int ltotalInstr = data [1]; + final int lcoverageCount = data [2]; + final int lcoverageInstr = data [3]; + + if (lcoverageInstr > 0) + { + coverageLineCount += (PRECISION * lcoverageCount) / ltotalCount; + coverageLineInstr += (PRECISION * lcoverageInstr) / ltotalInstr; + } + + // side effect: populate line coverage data map [used by getLineCoverage()] + + final int lcoverageStatus; + int [][] lcoverageRatio = null; + + if (lcoverageInstr == 0) + lcoverageStatus = LineCoverageData.LINE_COVERAGE_ZERO; + else if (lcoverageInstr == ltotalInstr) + lcoverageStatus = LineCoverageData.LINE_COVERAGE_COMPLETE; + else + { + lcoverageStatus = LineCoverageData.LINE_COVERAGE_PARTIAL; + lcoverageRatio = new int [][] {{ltotalCount, lcoverageCount}, {ltotalInstr, lcoverageInstr}}; // note: ordering depends on IItemAttribute.UNITS_xxx + } + + lineCoverage.put (cline, new LineCoverageData (lcoverageStatus, lcoverageRatio)); + + // side effect: compute m_firstLine + + if (cline < firstLine) firstLine = cline; + } + + m_lineCoverage = lineCoverage; // side effect + m_firstLine = firstLine; // side effect + + aggregates [COVERAGE_LINE_COUNT] = coverageLineCount; + aggregates [COVERAGE_LINE_INSTR] = coverageLineInstr; + + return aggregates [type]; + } + //break; + + + default: return super.getAggregate (type); + } + } + + return value; + } + + + public void accept (final IItemVisitor visitor, final Object ctx) + { + visitor.visit (this, ctx); + } + + public final IItemMetadata getMetadata () + { + return METADATA; + } + + public static IItemMetadata getTypeMetadata () + { + return METADATA; + } + + // protected: ............................................................. + + // package: ............................................................... + + // private: ............................................................... + + + private final String m_name, m_fullVMName; + private IntObjectMap /* line_no:int -> LineCoverageData */ m_lineCoverage; + private int m_firstLine; + + private static final Item.ItemMetadata METADATA; // set in <clinit> + + static + { + METADATA = new Item.ItemMetadata (IItemMetadata.TYPE_ID_SRCFILE, "srcfile", + 1 << IItemAttribute.ATTRIBUTE_NAME_ID | + 1 << IItemAttribute.ATTRIBUTE_CLASS_COVERAGE_ID | + 1 << IItemAttribute.ATTRIBUTE_METHOD_COVERAGE_ID | + 1 << IItemAttribute.ATTRIBUTE_BLOCK_COVERAGE_ID | + 1 << IItemAttribute.ATTRIBUTE_LINE_COVERAGE_ID); + } + +} // end of class +// ----------------------------------------------------------------------------
\ No newline at end of file |