1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. 2 * 3 * This program and the accompanying materials are made available under 4 * the terms of the Common Public License v1.0 which accompanies this distribution, 5 * and is available at http://www.eclipse.org/legal/cpl-v10.html 6 * 7 * $Id: ClassItem.java,v 1.1.1.1.2.1 2004/06/20 20:07:22 vlad_r Exp $ 8 */ 9 package com.vladium.emma.report; 10 11 import java.util.Iterator; 12 13 import com.vladium.util.IntObjectMap; 14 import com.vladium.util.asserts.$assert; 15 import com.vladium.emma.data.ClassDescriptor; 16 import com.vladium.emma.data.MethodDescriptor; 17 18 // ---------------------------------------------------------------------------- 19 /** 20 * @author Vlad Roubtsov, (C) 2003 21 */ 22 public 23 final class ClassItem extends Item 24 { 25 // public: ................................................................ 26 ClassItem(final IItem parent, final ClassDescriptor cls, final boolean [][] coverage)27 public ClassItem (final IItem parent, final ClassDescriptor cls, final boolean [][] coverage) 28 { 29 super (parent); 30 31 m_cls = cls; 32 m_coverage = coverage; 33 } 34 getName()35 public String getName () 36 { 37 return m_cls.getName (); 38 } 39 getSrcFileName()40 public String getSrcFileName () 41 { 42 return m_cls.getSrcFileName (); 43 } 44 45 // TODO: SrcFileItem could benefit from this method for its own getFirstLine() getFirstLine()46 public int getFirstLine () 47 { 48 // TODO: state validation 49 50 if (m_firstLine == 0) 51 { 52 final MethodDescriptor [] methods = m_cls.getMethods (); 53 54 int firstLine = Integer.MAX_VALUE; 55 for (int m = 0, mLimit = methods.length; m < mLimit; ++ m) 56 { 57 final int mFirstLine = methods [m].getFirstLine (); 58 if ((mFirstLine > 0) && (mFirstLine < firstLine)) 59 firstLine = mFirstLine; 60 } 61 62 m_firstLine = firstLine; 63 return firstLine; 64 } 65 66 return m_firstLine; 67 } 68 getClassDescriptor()69 public ClassDescriptor getClassDescriptor () 70 { 71 return m_cls; 72 } 73 getCoverage()74 public boolean [][] getCoverage () 75 { 76 return m_coverage; 77 } 78 loaded()79 public boolean loaded () 80 { 81 return m_coverage != null; 82 } 83 getAggregate(final int type)84 public int getAggregate (final int type) 85 { 86 final int [] aggregates = m_aggregates; 87 88 int value = aggregates [type]; 89 90 if (value < 0) 91 { 92 switch (type) 93 { 94 case COVERAGE_CLASS_COUNT: 95 case TOTAL_CLASS_COUNT: 96 { 97 aggregates [TOTAL_CLASS_COUNT] = 1; 98 aggregates [COVERAGE_CLASS_COUNT] = m_coverage != null ? 1 : 0; 99 100 return aggregates [type]; 101 } 102 //break; 103 104 105 case COVERAGE_LINE_COUNT: 106 case TOTAL_LINE_COUNT: 107 108 case COVERAGE_LINE_INSTR: 109 { 110 // line aggregate types are special when used on clsfile items: 111 // unlike all others, they do not simply add up when the line 112 // info is available; instead, lines from all methods belonging 113 // to the same clsfile parent are set-merged 114 115 final boolean [][] ccoverage = m_coverage; // this can be null 116 117 final IntObjectMap /* line -> int[2] */ cldata = new IntObjectMap (); 118 final MethodDescriptor [] methoddescs = m_cls.getMethods (); 119 120 for (Iterator methods = getChildren (); methods.hasNext (); ) 121 { 122 final MethodItem method = (MethodItem) methods.next (); 123 final int methodID = method.getID (); 124 125 final boolean [] mcoverage = ccoverage == null ? null : ccoverage [methodID]; 126 127 final MethodDescriptor methoddesc = methoddescs [methodID]; 128 final int [] mbsizes = methoddesc.getBlockSizes (); 129 final IntObjectMap mlineMap = methoddesc.getLineMap (); 130 if ($assert.ENABLED) $assert.ASSERT (mlineMap != null); 131 132 133 final int [] mlines = mlineMap.keys (); 134 for (int ml = 0, mlLimit = mlines.length; ml < mlLimit; ++ ml) 135 { 136 final int mline = mlines [ml]; 137 138 int [] data = (int []) cldata.get (mline); 139 if (data == null) 140 { 141 data = new int [4]; // { totalcount, totalinstr, coveragecount, coverageinstr } 142 cldata.put (mline, data); 143 } 144 145 final int [] lblocks = (int []) mlineMap.get (mline); 146 147 final int bCount = lblocks.length; 148 data [0] += bCount; 149 150 for (int bID = 0; bID < bCount; ++ bID) 151 { 152 final int block = lblocks [bID]; 153 154 final boolean bcovered = mcoverage != null && mcoverage [block]; 155 final int instr = mbsizes [block]; 156 157 data [1] += instr; 158 if (bcovered) 159 { 160 ++ data [2]; 161 data [3] += instr; 162 } 163 } 164 } 165 } 166 167 aggregates [TOTAL_LINE_COUNT] = cldata.size (); 168 169 int coverageLineCount = 0; 170 int coverageLineInstr = 0; 171 172 final int [] clines = cldata.keys (); 173 for (int cl = 0, clLimit = clines.length; cl < clLimit; ++ cl) 174 { 175 final int cline = clines [cl]; 176 final int [] data = (int []) cldata.get (cline); 177 178 final int ltotalCount = data [0]; 179 final int ltotalInstr = data [1]; 180 final int lcoverageCount = data [2]; 181 final int lcoverageInstr = data [3]; 182 183 if (lcoverageInstr > 0) 184 { 185 coverageLineCount += (PRECISION * lcoverageCount) / ltotalCount; 186 coverageLineInstr += (PRECISION * lcoverageInstr) / ltotalInstr; 187 } 188 } 189 190 aggregates [COVERAGE_LINE_COUNT] = coverageLineCount; 191 aggregates [COVERAGE_LINE_INSTR] = coverageLineInstr; 192 193 return aggregates [type]; 194 } 195 //break; 196 197 198 default: return super.getAggregate (type); 199 } 200 } 201 202 return value; 203 } 204 accept(final IItemVisitor visitor, final Object ctx)205 public void accept (final IItemVisitor visitor, final Object ctx) 206 { 207 visitor.visit (this, ctx); 208 } 209 getMetadata()210 public final IItemMetadata getMetadata () 211 { 212 return METADATA; 213 } 214 getTypeMetadata()215 public static IItemMetadata getTypeMetadata () 216 { 217 return METADATA; 218 } 219 220 // protected: ............................................................. 221 222 // package: ............................................................... 223 224 225 final ClassDescriptor m_cls; 226 final boolean [][] m_coverage; 227 228 // private: ............................................................... 229 230 231 private int m_firstLine; 232 233 private static final Item.ItemMetadata METADATA; // set in <clinit> 234 235 static 236 { 237 METADATA = new Item.ItemMetadata (IItemMetadata.TYPE_ID_CLASS, "class", 238 1 << IItemAttribute.ATTRIBUTE_NAME_ID | 239 1 << IItemAttribute.ATTRIBUTE_CLASS_COVERAGE_ID | 240 1 << IItemAttribute.ATTRIBUTE_METHOD_COVERAGE_ID | 241 1 << IItemAttribute.ATTRIBUTE_BLOCK_COVERAGE_ID | 242 1 << IItemAttribute.ATTRIBUTE_LINE_COVERAGE_ID); 243 } 244 245 } // end of class 246 // ----------------------------------------------------------------------------