Skip to content

Commit

Permalink
[dart2js] Moving dart2js_info coverage helper classes into /lib
Browse files Browse the repository at this point in the history
Also updates the logic for resolving Angular Info items

Change-Id: Idb5fe1c00db04adc6dcbcf508b01bbf3f8055c2f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256603
Reviewed-by: Joshua Litt <[email protected]>
Commit-Queue: Mark Zhou <[email protected]>
  • Loading branch information
Markzipan authored and Commit Bot committed Aug 29, 2022
1 parent 3095c45 commit 18e4b40
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 98 deletions.
95 changes: 4 additions & 91 deletions pkg/dart2js_info/bin/src/runtime_coverage_analysis.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import 'package:collection/collection.dart';
import 'package:dart2js_info/info.dart';
import 'package:dart2js_info/src/io.dart';
import 'package:dart2js_info/src/util.dart';
import 'package:dart2js_info/src/runtime_coverage_utils.dart';

import 'usage_exception.dart';

Expand Down Expand Up @@ -274,12 +275,9 @@ Future<void> _reportWithClassFilter(
// The value associated with each coverage item isn't used for now.
Set<String> coverage = coverageRaw.keys.toSet();

final classFilterData = <String, RuntimeClassInfo>{};
for (final runtimeClassInfo in File(filterFile)
.readAsLinesSync()
.map((l) => RuntimeClassInfo.fromAngularInfo(l))) {
classFilterData[runtimeClassInfo.key] = runtimeClassInfo;
}
final classFilterData = {
for (final info in runtimeInfoFromAngularInfo(filterFile)) info.key: info
};

// Ensure that a used class's super, mixed in, and implemented classes are
// correctly marked as used.
Expand Down Expand Up @@ -445,88 +443,3 @@ void _show(String msg, int size, int total) {
void _leftPadded(String msg1, String msg2) {
print(' ${pad(msg1, 50, right: true)} $msg2');
}

class RuntimePackageInfo {
final elements = PriorityQueue<BasicInfo>((a, b) => b.size.compareTo(a.size));

num mainUnitSize = 0;
num totalSize = 0;
num unusedMainUnitSize = 0;
num unusedSize = 0;
num usedRatio = 0;
num usedSize = 0;

RuntimePackageInfo();

void add(BasicInfo i, {bool used = true}) {
totalSize += i.size;
if (used) {
usedSize += i.size;
} else {
unusedSize += i.size;
}
if (i.outputUnit!.name == 'main') {
mainUnitSize += i.size;
if (!used) {
unusedMainUnitSize += i.size;
}
}
elements.add(i);
usedRatio = usedSize / totalSize;
}
}

class RuntimeClassInfo {
late String scheme;
late String package;
late String? path;
late String name;

late num size;
late bool used;
late bool inMainUnit;
late ClassInfo info;

bool annotated = false;

RuntimeClassInfo();

/// Ingests the output from Angular's info generator.
///
/// Example: 'fully:qualified/path/to/file.dart - ClassName'
RuntimeClassInfo.fromAngularInfo(String input) {
final colonIndex = input.indexOf(':');
if (colonIndex < 0) {
throw ArgumentError('AngularInfo format cannot accept undefined schemes.'
' No scheme found for: $input');
}
final slashIndex = input.indexOf('/');
final spaceIndex = input.indexOf(' ');
final separatorSize = ' - '.length;
scheme = input.substring(0, colonIndex);
if (slashIndex < 0) {
path = null;
package = input.substring(colonIndex + 1, spaceIndex);
} else {
package = input.substring(colonIndex + 1, slashIndex);
path = input.substring(slashIndex + 1, spaceIndex);
}
name = input.substring(spaceIndex + separatorSize, input.length);
}

String get key =>
'$package${path == null ? '' : '/$path'}:$name'.replaceAll('/lib/', '/');

void annotateWithClassInfo(ClassInfo i, {bool used = true}) {
size = i.size;
this.used = used;
inMainUnit = i.outputUnit!.name == 'main';
info = i;
annotated = true;
}

@override
String toString() {
return '$package/$path - $name';
}
}
117 changes: 117 additions & 0 deletions pkg/dart2js_info/lib/src/runtime_coverage_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import 'dart:io';

import 'package:collection/collection.dart';
import 'package:dart2js_info/info.dart';

List<RuntimeClassInfo> runtimeInfoFromAngularInfo(String angularInfoFilePath) {
final angularInfoFile = File(angularInfoFilePath);
final runtimeInfo = <RuntimeClassInfo>[];
final separator = ' - ';
for (final line in angularInfoFile.readAsLinesSync()) {
// Ignore lines without two ' - ' separators.
if (separator.allMatches(line).length != 2) continue;
runtimeInfo.add(RuntimeClassInfo.fromAngularInfo(line));
}
return runtimeInfo;
}

class RuntimePackageInfo {
final elements = PriorityQueue<BasicInfo>((a, b) => b.size.compareTo(a.size));

num mainUnitSize = 0;
num totalSize = 0;
num unusedMainUnitSize = 0;
num unusedSize = 0;
num usedRatio = 0;
num usedSize = 0;

RuntimePackageInfo();

void add(BasicInfo i, {bool used = true}) {
totalSize += i.size;
if (used) {
usedSize += i.size;
} else {
unusedSize += i.size;
}
if (i.outputUnit!.name == 'main') {
mainUnitSize += i.size;
if (!used) {
unusedMainUnitSize += i.size;
}
}
elements.add(i);
usedRatio = usedSize / totalSize;
}
}

class RuntimeClassInfo {
late String scheme;
late String package;
late String? path;
late String name;

late num size;
late bool used;
late bool inMainUnit;
late ClassInfo info;

bool annotated = false;

RuntimeClassInfo();

RuntimeClassInfo.fromQualifiedName(String qualifiedName) {
final colonIndex = qualifiedName.indexOf(':');
final slashIndex = qualifiedName.indexOf('/');
final colonIndex2 = qualifiedName.lastIndexOf(':');
scheme = qualifiedName.substring(0, colonIndex);
package = qualifiedName.substring(colonIndex + 1, slashIndex);
path = qualifiedName.substring(slashIndex + 1, colonIndex2);
name = qualifiedName.substring(colonIndex2 + 1, qualifiedName.length);
}

/// Ingests the output from Angular's info generator.
///
/// Example: 'fully:qualified/path/to/file.dart - ClassName - 123 (bytes)'
RuntimeClassInfo.fromAngularInfo(String rawInput) {
final separator = ' - ';
final separatorSize = separator.length;
// Remove the size specification.
var input = rawInput;
if (separator.allMatches(rawInput).length > 1) {
input = rawInput.substring(0, rawInput.lastIndexOf(separator));
}
final colonIndex = input.indexOf(':');
if (colonIndex < 0) {
throw ArgumentError('AngularInfo format cannot accept undefined schemes.'
' No scheme found for: $input');
}
final slashIndex = input.indexOf('/');
final spaceIndex = input.indexOf(' ');
scheme = input.substring(0, colonIndex);
if (slashIndex < 0) {
path = null;
package = input.substring(colonIndex + 1, spaceIndex);
} else {
package = input.substring(colonIndex + 1, slashIndex);
path = input.substring(slashIndex + 1, spaceIndex);
}
name = input.substring(spaceIndex + separatorSize, input.length);
}

String get key =>
'$package${path == null ? '' : '/$path'}:$name'.replaceAll('/lib/', '/');

void annotateWithClassInfo(ClassInfo i, {bool used = true}) {
size = i.size;
this.used = used;
inMainUnit = i.outputUnit!.name == 'main';
info = i;
annotated = true;
}

@override
String toString() {
return '$package/$path - $name';
}
}
10 changes: 5 additions & 5 deletions pkg/dart2js_info/test/classes/class_filter.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
dart:_rti - _Universe
dart:core - Error
testroot:classes.dart - Subsub1
testroot:classes.dart - Super
package:expect/expect.dart - Expect
dart:_rti - _Universe - 300 (bytes)
dart:core - Error - 300 (bytes)
testroot:classes.dart - Subsub1 - 300 (bytes)
testroot:classes.dart - Super - 300 (bytes)
package:expect/expect.dart - Expect - 300 (bytes)
4 changes: 2 additions & 2 deletions pkg/dart2js_info/test/runtime_coverage_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
import 'dart:io';

import 'package:dart2js_info/binary_serialization.dart';
import 'package:dart2js_info/src/runtime_coverage_utils.dart';
import 'package:dart2js_info/src/util.dart';
import 'package:test/test.dart';

import '../bin/src/runtime_coverage_analysis.dart';
import 'package:test/test.dart';

void main() {
group('runtime coverage', () {
Expand Down

0 comments on commit 18e4b40

Please sign in to comment.