| 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'; |
| } |
| } |