Skip to content

Commit

Permalink
add diff tool (flutter#19)
Browse files Browse the repository at this point in the history
* add diff tool
  • Loading branch information
Harry Terkelsen authored Jun 15, 2017
1 parent bd163f4 commit dfcbd59
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 36 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.5.5

- Added `diff` tool.

## 0.5.4+2

- Updated minimum SDK dependency to align with package dependencies.
Expand Down
89 changes: 65 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ The following tools are a available today:
dependency between functions and fields in your program. Currently it only
supports the `some_path` query, which shows a dependency path from one
function to another.

* [`diff`][diff]: a tool that diffs two info files and reports which
program elements have been added, removed, or changed size. This also
tells which elements are no longer deferred or have become deferred.

* [`library_size_split`][lib_split]: a tool that shows how much code was
attributed to each library. This tool is configurable so it can group data
Expand Down Expand Up @@ -102,10 +106,10 @@ this tool only supports the `some_path` query, which gives you the shortest path
for how one function depends on another.

Run this tool as follows:
```bash
```console
# activate is only needed once to install the dart2js_info* executables
pub global activate dart2js_info
dart2js_info_code_deps out.js.info.json some_path main foo
$ pub global activate dart2js_info
$ dart2js_info_code_deps out.js.info.json some_path main foo
```

The arguments to the query are regular expressions that can be used to
Expand All @@ -120,22 +124,58 @@ a fully qualified element name, which includes the library and class name
If the name of a function your are looking for is unique enough, it might be
sufficient to just write that name as your regular expression.

### Diff tool

This command-line tool shows a diff between two info files. It can be run
as follows:

```console
$ pub global activate dart2js_info # only needed once
$ dart2js_info_diff old.js.info.json new.js.info.json
```

The tool gives a breakdown of the difference between the two info files.
Here's an example output:

```
OVERALL SIZE DIFFERENCE
========================================================================
3 bytes
ADDED
========================================================================
REMOVED
========================================================================
file:///home/het/Code/foo/foo.dart::A.y: 0 bytes
CHANGED SIZE
========================================================================
BECAME DEFERRED
========================================================================
NO LONGER DEFERRED
========================================================================
```

### Library size split tool

This command-line tool shows the size distribution of generated code among
libraries. It can be run as follows:

```bash
pub global activate dart2js_info # only needed once
dart2js_info_library_size_split out.js.info.json
```console
$ pub global activate dart2js_info # only needed once
$ dart2js_info_library_size_split out.js.info.json
```


Libraries can be grouped using regular expressions. You can
specify what regular expressions to use by providing a `grouping.yaml` file:

```bash
dart2js_info_library_size_split out.js.info.json grouping.yaml
```console
$ dart2js_info_library_size_split out.js.info.json grouping.yaml
```

The format of the `grouping.yaml` file is as follows:
Expand Down Expand Up @@ -205,9 +245,9 @@ bootstrapping code and lazy static initializers are missing.
This tool checks that the output from dart2js meets a given specification,
given in a YAML file. It can be run as follows:

```bash
pub global activate dart2js_info # only needed once
dart2js_info_deferred_library_check out.js.info.json manifest.yaml
```console
$ pub global activate dart2js_info # only needed once
$ dart2js_info_deferred_library_check out.js.info.json manifest.yaml
```

The format of the YAML file is:
Expand Down Expand Up @@ -253,7 +293,7 @@ This tool gives a breakdown of all of the deferred code in the program by size.
It can show how much of the total code size is deferred. It can be run as
follows:

```bash
```console
pub global activate dart2js_info # only needed once
dart2js_info_deferred_library_size out.js.info.json
```
Expand All @@ -278,9 +318,9 @@ Percent of code deferred 41.86%
This tool reports which code is included in each output unit. It can be run as
follows:

```bash
pub global activate dart2js_info # only needed once
dart2js_info_deferred_library_layout out.js.info.json
```console
$ pub global activate dart2js_info # only needed once
$ dart2js_info_deferred_library_layout out.js.info.json
```

The tool will output a table listing all of the deferred output units or chunks,
Expand Down Expand Up @@ -322,9 +362,9 @@ code of your application. We use dependency information to compute dominance
and reachability data as well.

When you run:
```bash
pub global activate dart2js_info # only needed once
dart2js_info_function_size_analysis out.js.info.json
```console
$ pub global activate dart2js_info # only needed once
$ dart2js_info_function_size_analysis out.js.info.json
```

the tool produces a table output with lots of entries. Here is an example entry
Expand Down Expand Up @@ -355,8 +395,8 @@ steps are as follows:
* Compile an app with dart2js using `--dump-info` and defining the
Dart environment `traceCalls=post`:

```
DART_VM_OPTIONS="-DtraceCalls=post" dart2js --dump-info main.dart
```console
$ DART_VM_OPTIONS="-DtraceCalls=post" dart2js --dump-info main.dart
```

Because coverage/tracing data is currently experimental, the feature is
Expand All @@ -365,8 +405,8 @@ DART_VM_OPTIONS="-DtraceCalls=post" dart2js --dump-info main.dart

* Launch the coverage server tool to serve up the JS code of your app:

```bash
dart2js_info_coverage_log_server main.dart.js
```console
$ dart2js_info_coverage_log_server main.dart.js
```

* (optional) If you have a complex application setup, you may need to serve an
Expand All @@ -382,8 +422,8 @@ dart2js_info_coverage_log_server main.dart.js
* Finally, run the live code analysis tool given it both the info and
coverage json files:

```bash
dart2js_info_live_code_size_analysis main.dart.info.json main.dart.coverage.json
```console
$ dart2js_info_live_code_size_analysis main.dart.info.json main.dart.coverage.json
```

## Code location, features and bugs
Expand All @@ -394,6 +434,7 @@ bugs at the [issue tracker][tracker].
[repo]: https://github.com/dart-lang/dart2js_info/
[tracker]: https://github.com/dart-lang/dart2js_info/issues
[code_deps]: https://github.com/dart-lang/dart2js_info/blob/master/bin/code_deps.dart
[diff]: https://github.com/dart-lang/dart2js_info/blob/master/bin/diff.dart
[lib_split]: https://github.com/dart-lang/dart2js_info/blob/master/bin/library_size_split.dart
[deferred_lib]: https://github.com/dart-lang/dart2js_info/blob/master/bin/deferred_library_check.dart
[deferred_size]: https://github.com/dart-lang/dart2js_info/blob/master/bin/deferred_library_size.dart
Expand Down
92 changes: 92 additions & 0 deletions bin/diff.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:dart2js_info/src/diff.dart';
import 'package:dart2js_info/src/util.dart';

/// A command-line tool that computes the diff between two info files.
main(List<String> args) async {
if (args.length != 2) {
print('usage: dart2js_info_diff old.info.json new.info.json');
return;
}
var oldInfo = await infoFromFile(args[0]);
var newInfo = await infoFromFile(args[1]);

var diffs = diff(oldInfo, newInfo);

// Categorize the diffs
var adds = <AddDiff>[];
var removals = <RemoveDiff>[];
var sizeChanges = <SizeDiff>[];
var becameDeferred = <DeferredStatusDiff>[];
var becameUndeferred = <DeferredStatusDiff>[];

for (var diff in diffs) {
switch (diff.kind) {
case DiffKind.add:
adds.add(diff as AddDiff);
break;
case DiffKind.remove:
removals.add(diff as RemoveDiff);
break;
case DiffKind.size:
sizeChanges.add(diff as SizeDiff);
break;
case DiffKind.deferred:
var deferredDiff = diff as DeferredStatusDiff;
if (deferredDiff.wasDeferredBefore) {
becameUndeferred.add(deferredDiff);
} else {
becameDeferred.add(deferredDiff);
}
break;
}
}

// TODO(het): Improve this output. Siggi has good suggestions in
// https://github.com/dart-lang/dart2js_info/pull/19
var overallSizeDiff = newInfo.program.size - oldInfo.program.size;
_section('OVERALL SIZE DIFFERENCE');
print('$overallSizeDiff bytes');
print('');

_section('ADDED');
for (var add in adds) {
print('${longName(add.info, useLibraryUri: true)}: ${add.info.size} bytes');
}
print('');

_section('REMOVED');
for (var removal in removals) {
print('${longName(removal.info, useLibraryUri: true)}: '
'${removal.info.size} bytes');
}
print('');

_section('CHANGED SIZE');
for (var sizeChange in sizeChanges) {
print('${longName(sizeChange.info, useLibraryUri: true)}: '
'${sizeChange.sizeDifference} bytes');
}
print('');

_section('BECAME DEFERRED');
for (var diff in becameDeferred) {
print('${longName(diff.info, useLibraryUri: true)}: '
'${diff.info.size} bytes');
}
print('');

_section('NO LONGER DEFERRED');
for (var diff in becameUndeferred) {
print('${longName(diff.info, useLibraryUri: true)}: '
'${diff.info.size} bytes');
}
}

void _section(String title) {
print(title);
print('=' * 72);
}
22 changes: 11 additions & 11 deletions lib/info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ abstract class Info {
/// Info of the enclosing element.
Info parent;

dynamic accept(InfoVisitor visitor);
T accept<T>(InfoVisitor<T> visitor);
}

/// Common information used for most kind of elements.
Expand Down Expand Up @@ -171,7 +171,7 @@ class AllInfo {

AllInfo();

dynamic accept(InfoVisitor visitor) => visitor.visitAll(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitAll(this);
}

class ProgramInfo {
Expand All @@ -196,7 +196,7 @@ class ProgramInfo {
this.noSuchMethodEnabled,
this.minified});

dynamic accept(InfoVisitor visitor) => visitor.visitProgram(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitProgram(this);
}

/// Info associated with a library element.
Expand Down Expand Up @@ -229,7 +229,7 @@ class LibraryInfo extends BasicInfo {

LibraryInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitLibrary(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitLibrary(this);
}

/// Information about an output unit. Normally there is just one for the entire
Expand All @@ -244,7 +244,7 @@ class OutputUnitInfo extends BasicInfo {

OutputUnitInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitOutput(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitOutput(this);
}

/// Information about a class element.
Expand All @@ -267,7 +267,7 @@ class ClassInfo extends BasicInfo {

ClassInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitClass(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitClass(this);
}

/// Information about a constant value.
Expand All @@ -282,7 +282,7 @@ class ConstantInfo extends BasicInfo {

ConstantInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitConstant(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitConstant(this);
}

/// Information about a field element.
Expand Down Expand Up @@ -319,7 +319,7 @@ class FieldInfo extends BasicInfo with CodeInfo {

FieldInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitField(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitField(this);
}

/// Information about a typedef declaration.
Expand All @@ -332,7 +332,7 @@ class TypedefInfo extends BasicInfo {

TypedefInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitTypedef(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitTypedef(this);
}

/// Information about a function or method.
Expand Down Expand Up @@ -396,7 +396,7 @@ class FunctionInfo extends BasicInfo with CodeInfo {

FunctionInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitFunction(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitFunction(this);
}

/// Information about a closure, also known as a local function.
Expand All @@ -410,7 +410,7 @@ class ClosureInfo extends BasicInfo {

ClosureInfo._(String serializedId) : super._fromId(serializedId);

dynamic accept(InfoVisitor visitor) => visitor.visitClosure(this);
T accept<T>(InfoVisitor<T> visitor) => visitor.visitClosure(this);
}

/// Information about how a dependency is used.
Expand Down
Loading

0 comments on commit dfcbd59

Please sign in to comment.