FileDocCategorySizeDatePackage
SrcFileItem.javaAPI DocAndroid 1.5 API12004Wed May 06 22:41:16 BST 2009com.vladium.emma.report

SrcFileItem

public final class SrcFileItem extends Item
author
Vlad Roubtsov, (C) 2003

Fields Summary
private final String
m_name
private final String
m_fullVMName
private com.vladium.util.IntObjectMap
m_lineCoverage
private int
m_firstLine
private static final Item.ItemMetadata
METADATA
Constructors Summary
public SrcFileItem(IItem parent, String name, String fullVMName)

        super (parent);
        
        m_name = name;
        m_fullVMName = fullVMName;
    
Methods Summary
public voidaccept(IItemVisitor visitor, java.lang.Object ctx)

        visitor.visit (this, ctx);
    
public intgetAggregate(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 intgetFirstLine()

        // TODO: state validation
        
        if (m_firstLine == 0)
        {
            getAggregate (TOTAL_LINE_COUNT); // fault line coverage calculation
        }
        
        return m_firstLine;
    
public java.lang.StringgetFullVMName()

        return m_fullVMName;
    
public com.vladium.util.IntObjectMapgetLineCoverage()

        if (m_lineCoverage == null)
        {
            getAggregate (TOTAL_LINE_COUNT); // fault line coverage calculation
        }   
        
        return m_lineCoverage;
    
public final IItemMetadatagetMetadata()

        return METADATA;
    
public java.lang.StringgetName()

        return m_name;
    
public static IItemMetadatagetTypeMetadata()

        return METADATA;