• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // ----------------------------------------------------------------------------