| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of observatory; | 5 part of observatory; |
| 6 | 6 |
| 7 class CodeInstruction extends Observable { | 7 class CodeInstruction extends Observable { |
| 8 @observable final int address; | 8 @observable final int address; |
| 9 @observable final String machine; | 9 @observable final String machine; |
| 10 @observable final String human; | 10 @observable final String human; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 List<Code> inclusive = isolate.codes; | 237 List<Code> inclusive = isolate.codes; |
| 238 inclusive.sort((Code a, Code b) { | 238 inclusive.sort((Code a, Code b) { |
| 239 return b.inclusiveTicks - a.inclusiveTicks; | 239 return b.inclusiveTicks - a.inclusiveTicks; |
| 240 }); | 240 }); |
| 241 if ((inclusive.length < count) || (count == 0)) { | 241 if ((inclusive.length < count) || (count == 0)) { |
| 242 return inclusive; | 242 return inclusive; |
| 243 } | 243 } |
| 244 return inclusive.sublist(0, count); | 244 return inclusive.sublist(0, count); |
| 245 } | 245 } |
| 246 } | 246 } |
| 247 |
| 248 class ScriptLine extends Observable { |
| 249 @observable final int line; |
| 250 @observable int hits = -1; |
| 251 @observable String text = ''; |
| 252 /// Is this a line of executable code? |
| 253 bool get executable => hits >= 0; |
| 254 /// Has this line executed before? |
| 255 bool get covered => hits > 0; |
| 256 ScriptLine(this.line); |
| 257 } |
| 258 |
| 259 class Script extends Observable { |
| 260 @observable String kind = null; |
| 261 @observable Map scriptRef = toObservable({}); |
| 262 @observable Map libraryRef = toObservable({}); |
| 263 @observable final List<ScriptLine> lines = |
| 264 toObservable(new List<ScriptLine>()); |
| 265 bool _needsSource = true; |
| 266 bool get needsSource => _needsSource; |
| 267 Script.fromMap(Map map) { |
| 268 scriptRef = toObservable({ |
| 269 'id': map['id'], |
| 270 'name': map['name'], |
| 271 'user_name': map['user_name'] |
| 272 }); |
| 273 libraryRef = toObservable(map['library']); |
| 274 kind = map['kind']; |
| 275 _processSource(map['source']); |
| 276 } |
| 277 |
| 278 // Iterable of lines for display. Skips line '0'. |
| 279 @observable Iterable get linesForDisplay { |
| 280 return lines.skip(1); |
| 281 } |
| 282 |
| 283 // Fetch (possibly create) the ScriptLine for [lineNumber]. |
| 284 ScriptLine _getLine(int lineNumber) { |
| 285 assert(lineNumber != 0); |
| 286 if (lineNumber >= lines.length) { |
| 287 // Grow lines list. |
| 288 lines.length = lineNumber + 1; |
| 289 } |
| 290 var line = lines[lineNumber]; |
| 291 if (line == null) { |
| 292 // Create this line. |
| 293 line = new ScriptLine(lineNumber); |
| 294 lines[lineNumber] = line; |
| 295 } |
| 296 return line; |
| 297 } |
| 298 |
| 299 void _processSource(String source) { |
| 300 if (source == null) { |
| 301 return; |
| 302 } |
| 303 Logger.root.info('Loading source for ${scriptRef['name']}'); |
| 304 var sourceLines = source.split('\n'); |
| 305 _needsSource = sourceLines.length == 0; |
| 306 for (var i = 0; i < sourceLines.length; i++) { |
| 307 var line = _getLine(i + 1); |
| 308 line.text = sourceLines[i]; |
| 309 } |
| 310 } |
| 311 |
| 312 void _processCoverageHits(List hits) { |
| 313 for (var i = 0; i < hits.length; i += 2) { |
| 314 var line = _getLine(hits[i]); |
| 315 line.hits = hits[i + 1]; |
| 316 } |
| 317 notifyPropertyChange(#coveredPercentageFormatted, '', |
| 318 coveredPercentageFormatted()); |
| 319 } |
| 320 |
| 321 /// What percentage of lines in this script have been covered? |
| 322 @observable double coveredPercentage() { |
| 323 int coveredLines = 0; |
| 324 int executableLines = 0; |
| 325 for (var line in lines) { |
| 326 if (line == null) { |
| 327 continue; |
| 328 } |
| 329 if (!line.executable) { |
| 330 continue; |
| 331 } |
| 332 executableLines++; |
| 333 if (!line.covered) { |
| 334 continue; |
| 335 } |
| 336 coveredLines++; |
| 337 } |
| 338 if (executableLines == 0) { |
| 339 return 0.0; |
| 340 } |
| 341 return (coveredLines / executableLines) * 100.0; |
| 342 } |
| 343 |
| 344 @observable String coveredPercentageFormatted() { |
| 345 return '(' + coveredPercentage().toStringAsFixed(1) + '% covered)'; |
| 346 } |
| 347 } |
| OLD | NEW |