@@ -68,19 +68,13 @@ public ParserResult Parse(XContainer report)
68
68
69
69
var assemblies = new List < Assembly > ( ) ;
70
70
71
- var modules = report . Descendants ( "package" )
72
- . ToArray ( ) ;
71
+ var assemblyElementGrouping = report . Descendants ( "package" )
72
+ . GroupBy ( m => m . Attribute ( "name" ) . Value )
73
+ . Where ( a => this . AssemblyFilter . IsElementIncludedInReport ( a . Key ) ) ;
73
74
74
- var assemblyNames = modules
75
- . Select ( m => m . Attribute ( "name" ) . Value )
76
- . Distinct ( )
77
- . Where ( a => this . AssemblyFilter . IsElementIncludedInReport ( a ) )
78
- . OrderBy ( a => a )
79
- . ToArray ( ) ;
80
-
81
- foreach ( var assemblyName in assemblyNames )
75
+ foreach ( var elements in assemblyElementGrouping )
82
76
{
83
- assemblies . Add ( this . ProcessAssembly ( modules , assemblyName ) ) ;
77
+ assemblies . Add ( this . ProcessAssembly ( elements , elements . Key ) ) ;
84
78
}
85
79
86
80
var result = new ParserResult ( assemblies . OrderBy ( a => a . Name ) . ToList ( ) , true , this . ToString ( ) ) ;
@@ -92,7 +86,7 @@ public ParserResult Parse(XContainer report)
92
86
93
87
try
94
88
{
95
- if ( report . Element ( "sources" ) . Parent . Attribute ( "timestamp" ) != null )
89
+ if ( report . Element ( "sources" ) ? . Parent . Attribute ( "timestamp" ) != null )
96
90
{
97
91
DateTime timeStamp = new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
98
92
timeStamp = timeStamp . AddSeconds ( double . Parse ( report . Element ( "sources" ) . Parent . Attribute ( "timestamp" ) . Value ) ) . ToLocalTime ( ) ;
@@ -115,14 +109,16 @@ public ParserResult Parse(XContainer report)
115
109
/// <param name="modules">The modules.</param>
116
110
/// <param name="assemblyName">Name of the assembly.</param>
117
111
/// <returns>The <see cref="Assembly"/>.</returns>
118
- private Assembly ProcessAssembly ( XElement [ ] modules , string assemblyName )
112
+ private Assembly ProcessAssembly ( IEnumerable < XElement > modules , string assemblyName )
119
113
{
120
114
Logger . DebugFormat ( Resources . CurrentAssembly , assemblyName ) ;
121
115
122
- var classNames = modules
123
- . Where ( m => m . Attribute ( "name" ) . Value . Equals ( assemblyName ) )
116
+ var classes = modules
124
117
. Elements ( "classes" )
125
118
. Elements ( "class" )
119
+ . ToArray ( ) ;
120
+
121
+ var classNames = classes
126
122
. Select ( c => ClassNameParser . ParseClassName ( c . Attribute ( "name" ) . Value , this . RawMode ) )
127
123
. Where ( c => c . Include )
128
124
. Distinct ( )
@@ -132,29 +128,37 @@ private Assembly ProcessAssembly(XElement[] modules, string assemblyName)
132
128
133
129
var assembly = new Assembly ( assemblyName ) ;
134
130
135
- Parallel . ForEach ( classNames , c => this . ProcessClass ( modules , assembly , c . Name , c . DisplayName ) ) ;
131
+ Parallel . ForEach ( classNames , c => this . ProcessClass ( classes , assembly , c . Name , c . DisplayName ) ) ;
136
132
137
133
return assembly ;
138
134
}
139
135
140
136
/// <summary>
141
137
/// Processes the given class.
142
138
/// </summary>
143
- /// <param name="modules">The modules. </param>
139
+ /// <param name="allClasses">All class elements </param>
144
140
/// <param name="assembly">The assembly.</param>
145
141
/// <param name="className">Name of the class.</param>
146
142
/// <param name="classDisplayName">Diesplay name of the class.</param>
147
- private void ProcessClass ( XElement [ ] modules , Assembly assembly , string className , string classDisplayName )
143
+ private void ProcessClass ( XElement [ ] allClasses , Assembly assembly , string className , string classDisplayName )
148
144
{
149
- var files = modules
150
- . Where ( m => m . Attribute ( "name" ) . Value . Equals ( assembly . Name ) )
151
- . Elements ( "classes" )
152
- . Elements ( "class" )
153
- . Where ( c => c . Attribute ( " name" ) . Value . Equals ( className )
145
+ bool FilterClass ( XElement element )
146
+ {
147
+ var name = element . Attribute ( "name" ) . Value ;
148
+
149
+ return name . Equals ( className )
154
150
|| ( ! this . RawMode
155
- && ( c . Attribute ( "name" ) . Value . StartsWith ( className + "$" , StringComparison . Ordinal )
156
- || c . Attribute ( "name" ) . Value . StartsWith ( className + "/" , StringComparison . Ordinal )
157
- || c . Attribute ( "name" ) . Value . StartsWith ( className + "." , StringComparison . Ordinal ) ) ) )
151
+ && name . StartsWith ( className , StringComparison . Ordinal )
152
+ && ( name [ className . Length ] == '$'
153
+ || name [ className . Length ] == '/'
154
+ || name [ className . Length ] == '.' ) ) ;
155
+ }
156
+
157
+ var classes = allClasses
158
+ . Where ( FilterClass )
159
+ . ToArray ( ) ;
160
+
161
+ var files = classes
158
162
. Select ( c => c . Attribute ( "filename" ) . Value )
159
163
. Distinct ( )
160
164
. ToArray ( ) ;
@@ -170,7 +174,10 @@ private void ProcessClass(XElement[] modules, Assembly assembly, string classNam
170
174
171
175
foreach ( var file in filteredFiles )
172
176
{
173
- @class . AddFile ( this . ProcessFile ( modules , @class , className , file ) ) ;
177
+ var fileClasses = classes
178
+ . Where ( c => c . Attribute ( "filename" ) . Value . Equals ( file ) )
179
+ . ToArray ( ) ;
180
+ @class . AddFile ( this . ProcessFile ( fileClasses , @class , className , file ) ) ;
174
181
}
175
182
176
183
assembly . AddClass ( @class ) ;
@@ -180,35 +187,27 @@ private void ProcessClass(XElement[] modules, Assembly assembly, string classNam
180
187
/// <summary>
181
188
/// Processes the file.
182
189
/// </summary>
183
- /// <param name="modules ">The modules .</param>
190
+ /// <param name="classElements ">The class elements for the file .</param>
184
191
/// <param name="class">The class.</param>
185
192
/// <param name="className">Name of the class.</param>
186
193
/// <param name="filePath">The file path.</param>
187
194
/// <returns>The <see cref="CodeFile"/>.</returns>
188
- private CodeFile ProcessFile ( XElement [ ] modules , Class @class , string className , string filePath )
195
+ private CodeFile ProcessFile ( XElement [ ] classElements , Class @class , string className , string filePath )
189
196
{
190
- var classes = modules
191
- . Where ( m => m . Attribute ( "name" ) . Value . Equals ( @class . Assembly . Name ) )
192
- . Elements ( "classes" )
193
- . Elements ( "class" )
194
- . Where ( c => c . Attribute ( "name" ) . Value . Equals ( className )
195
- || ( ! this . RawMode
196
- && ( c . Attribute ( "name" ) . Value . StartsWith ( className + "$" , StringComparison . Ordinal )
197
- || c . Attribute ( "name" ) . Value . StartsWith ( className + "/" , StringComparison . Ordinal )
198
- || c . Attribute ( "name" ) . Value . StartsWith ( className + "." , StringComparison . Ordinal ) ) ) )
199
- . Where ( c => c . Attribute ( "filename" ) . Value . Equals ( filePath ) )
200
- . ToArray ( ) ;
201
-
202
- var lines = classes . Elements ( "lines" )
197
+ var lines = classElements . Elements ( "lines" )
203
198
. Elements ( "line" )
204
199
. ToArray ( ) ;
205
200
206
201
var lineNumbers = lines
207
202
. Select ( l => l . Attribute ( "number" ) . Value )
208
203
. ToHashSet ( ) ;
209
204
210
- var additionalLinesInMethodElement = classes . Elements ( "methods" )
205
+ var methodsOfFile = classElements
206
+ . Elements ( "methods" )
211
207
. Elements ( "method" )
208
+ . ToArray ( ) ;
209
+
210
+ var additionalLinesInMethodElement = methodsOfFile
212
211
. Elements ( "lines" )
213
212
. Elements ( "line" )
214
213
. Where ( l => ! lineNumbers . Contains ( l . Attribute ( "number" ) . Value ) )
@@ -254,11 +253,6 @@ private CodeFile ProcessFile(XElement[] modules, Class @class, string className,
254
253
}
255
254
}
256
255
257
- var methodsOfFile = classes
258
- . Elements ( "methods" )
259
- . Elements ( "method" )
260
- . ToArray ( ) ;
261
-
262
256
var codeFile = new CodeFile ( filePath , coverage , lineVisitStatus , branches ) ;
263
257
264
258
SetMethodMetrics ( codeFile , methodsOfFile ) ;
0 commit comments