Skip to content

Commit 0757265

Browse files
author
Tim Blasi
committed
feat(dart/transform): Track timing of transform tasks
1 parent aee1761 commit 0757265

File tree

17 files changed

+250
-187
lines changed

17 files changed

+250
-187
lines changed

modules_dart/transform/lib/src/transform/common/logging.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ BuildLogger get logger {
5151
return current == null ? new PrintLogger() : current;
5252
}
5353

54+
/// Writes a log entry at `LogLevel.FINE` granularity with the time taken by
55+
/// `asyncOperation`.
56+
///
57+
/// Returns the result of executing `asyncOperation`.
58+
Future logElapsedAsync(Future asyncOperation(),
59+
{String operationName: 'unknown', AssetId assetId}) async {
60+
final timer = new Stopwatch()..start();
61+
final result = await asyncOperation();
62+
timer.stop();
63+
final buf =
64+
new StringBuffer('[$operationName] took ${timer.elapsedMilliseconds} ms');
65+
if (assetId != null) {
66+
buf.write(' on $assetId');
67+
}
68+
logger.fine(buf.toString(), asset: assetId);
69+
return result;
70+
}
71+
5472
class PrintLogger implements BuildLogger {
5573
@override
5674
final String detailsUri = '';

modules_dart/transform/lib/src/transform/deferred_rewriter/rewriter.dart

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,42 @@ class Rewriter {
3030
var node = parseCompilationUnit(code);
3131
if (node == null) return null;
3232

33-
var visitor = new _FindDeferredLibraries(_reader, _entryPoint);
34-
node.accept(visitor);
35-
// Look to see if we found any deferred libraries
36-
if (!visitor.hasDeferredLibrariesToRewrite()) return null;
37-
// Remove any libraries that don't need angular codegen.
38-
await visitor.cull();
39-
// Check again if there are any deferred libraries.
40-
if (!visitor.hasDeferredLibrariesToRewrite()) return null;
41-
42-
var compare = (AstNode a, AstNode b) => a.offset - b.offset;
43-
visitor.deferredImports.sort(compare);
44-
visitor.loadLibraryInvocations.sort(compare);
45-
46-
var buf = new StringBuffer();
47-
var idx =
48-
visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
49-
buf.write(code.substring(lastIdx, node.offset));
50-
51-
var import = code.substring(node.offset, node.end);
52-
buf.write(import.replaceFirst('.dart', DEPS_EXTENSION));
53-
return node.end;
54-
});
55-
56-
idx = visitor.loadLibraryInvocations.fold(idx,
57-
(int lastIdx, MethodInvocation node) {
58-
buf.write(code.substring(lastIdx, node.offset));
59-
var value = node.realTarget as SimpleIdentifier;
60-
var prefix = value.name;
61-
// Chain a future that initializes the reflector.
62-
buf.write('$prefix.loadLibrary().then((_) {$prefix.initReflector();})');
63-
return node.end;
64-
});
65-
if (idx < code.length) buf.write(code.substring(idx));
66-
return '$buf';
33+
return logElapsedAsync(() async {
34+
var visitor = new _FindDeferredLibraries(_reader, _entryPoint);
35+
node.accept(visitor);
36+
// Look to see if we found any deferred libraries
37+
if (!visitor.hasDeferredLibrariesToRewrite()) return null;
38+
// Remove any libraries that don't need angular codegen.
39+
await visitor.cull();
40+
// Check again if there are any deferred libraries.
41+
if (!visitor.hasDeferredLibrariesToRewrite()) return null;
42+
43+
var compare = (AstNode a, AstNode b) => a.offset - b.offset;
44+
visitor.deferredImports.sort(compare);
45+
visitor.loadLibraryInvocations.sort(compare);
46+
47+
var buf = new StringBuffer();
48+
var idx =
49+
visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
50+
buf.write(code.substring(lastIdx, node.offset));
51+
52+
var import = code.substring(node.offset, node.end);
53+
buf.write(import.replaceFirst('.dart', DEPS_EXTENSION));
54+
return node.end;
55+
});
56+
57+
idx = visitor.loadLibraryInvocations.fold(idx,
58+
(int lastIdx, MethodInvocation node) {
59+
buf.write(code.substring(lastIdx, node.offset));
60+
var value = node.realTarget as SimpleIdentifier;
61+
var prefix = value.name;
62+
// Chain a future that initializes the reflector.
63+
buf.write('$prefix.loadLibrary().then((_) {$prefix.initReflector();})');
64+
return node.end;
65+
});
66+
if (idx < code.length) buf.write(code.substring(idx));
67+
return '$buf';
68+
}, operationName: 'rewriteDeferredLibraries', assetId: _entryPoint);
6769
}
6870
}
6971

modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_deps_linker.dart

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,43 @@ import 'package:barback/barback.dart';
2020
/// `isNgDeps` to `true` to signify that it is a dependency on which we need to
2121
/// call `initReflector`.
2222
Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
23-
AssetId entryPoint, UrlResolver resolver) async {
23+
AssetId assetId, UrlResolver resolver) async {
2424
if (ngDepsModel == null) return null;
25-
var linkedDepsMap =
26-
await _processNgImports(ngDepsModel, reader, entryPoint, resolver);
25+
return logElapsedAsync(() async {
26+
var linkedDepsMap =
27+
await _processNgImports(ngDepsModel, reader, assetId, resolver);
2728

28-
if (linkedDepsMap.isEmpty) {
29-
// We are not calling `initReflector` on any other libraries, but we still
30-
// return the model to ensure it is written to code.
31-
// TODO(kegluneq): Continue using the protobuf format after this phase.
32-
return ngDepsModel;
33-
}
29+
if (linkedDepsMap.isEmpty) {
30+
// We are not calling `initReflector` on any other libraries, but we still
31+
// return the model to ensure it is written to code.
32+
// TODO(kegluneq): Continue using the protobuf format after this phase.
33+
return ngDepsModel;
34+
}
3435

35-
for (var i = ngDepsModel.imports.length - 1; i >= 0; --i) {
36-
var import = ngDepsModel.imports[i];
37-
if (linkedDepsMap.containsKey(import.uri)) {
38-
var linkedModel = new ImportModel()
39-
..isNgDeps = true
40-
..uri = toDepsExtension(import.uri)
41-
..prefix = 'i$i';
42-
// TODO(kegluneq): Preserve combinators?
43-
ngDepsModel.imports.insert(i + 1, linkedModel);
36+
for (var i = ngDepsModel.imports.length - 1; i >= 0; --i) {
37+
var import = ngDepsModel.imports[i];
38+
if (linkedDepsMap.containsKey(import.uri)) {
39+
var linkedModel = new ImportModel()
40+
..isNgDeps = true
41+
..uri = toDepsExtension(import.uri)
42+
..prefix = 'i$i';
43+
// TODO(kegluneq): Preserve combinators?
44+
ngDepsModel.imports.insert(i + 1, linkedModel);
45+
}
4446
}
45-
}
46-
for (var i = 0, iLen = ngDepsModel.exports.length; i < iLen; ++i) {
47-
var export = ngDepsModel.exports[i];
48-
if (linkedDepsMap.containsKey(export.uri)) {
49-
var linkedModel = new ImportModel()
50-
..isNgDeps = true
51-
..uri = toDepsExtension(export.uri)
52-
..prefix = 'i${ngDepsModel.imports.length}';
53-
// TODO(kegluneq): Preserve combinators?
54-
ngDepsModel.imports.add(linkedModel);
47+
for (var i = 0, iLen = ngDepsModel.exports.length; i < iLen; ++i) {
48+
var export = ngDepsModel.exports[i];
49+
if (linkedDepsMap.containsKey(export.uri)) {
50+
var linkedModel = new ImportModel()
51+
..isNgDeps = true
52+
..uri = toDepsExtension(export.uri)
53+
..prefix = 'i${ngDepsModel.imports.length}';
54+
// TODO(kegluneq): Preserve combinators?
55+
ngDepsModel.imports.add(linkedModel);
56+
}
5557
}
56-
}
57-
58-
return ngDepsModel;
58+
return ngDepsModel;
59+
}, operationName: 'linkNgDeps', assetId: assetId);
5960
}
6061

6162
bool _isNotDartDirective(dynamic model) => !isDartCoreUri(model.uri);

modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_meta_linker.dart

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,16 @@ import 'ng_deps_linker.dart';
2727
/// Returns an empty [NgMeta] if there are no `Directive`-annotated classes or
2828
/// `DirectiveAlias` annotated constants in `entryPoint`.
2929
Future<NgMeta> linkDirectiveMetadata(
30-
AssetReader reader, AssetId entryPoint) async {
31-
var ngMeta = await _readNgMeta(reader, entryPoint);
30+
AssetReader reader, AssetId assetId) async {
31+
var ngMeta = await _readNgMeta(reader, assetId);
3232
if (ngMeta == null || ngMeta.isEmpty) return null;
3333

3434
await Future.wait([
35-
linkNgDeps(ngMeta.ngDeps, reader, entryPoint, _urlResolver),
36-
_linkDirectiveMetadataRecursive(
37-
ngMeta, reader, entryPoint, new Set<String>())
35+
linkNgDeps(ngMeta.ngDeps, reader, assetId, _urlResolver),
36+
logElapsedAsync(() async {
37+
await _linkRecursive(ngMeta, reader, assetId, new Set<String>());
38+
return ngMeta;
39+
}, operationName: 'linkDirectiveMetadata', assetId: assetId)
3840
]);
3941
return ngMeta;
4042
}
@@ -50,39 +52,32 @@ Future<NgMeta> _readNgMeta(AssetReader reader, AssetId ngMetaAssetId) async {
5052

5153
final _urlResolver = const TransformerUrlResolver();
5254

53-
Future<NgMeta> _linkDirectiveMetadataRecursive(NgMeta ngMeta,
54-
AssetReader reader, AssetId assetId, Set<String> seen) async {
55+
Future _linkRecursive(NgMeta ngMeta, AssetReader reader, AssetId assetId,
56+
Set<String> seen) async {
5557
if (ngMeta == null ||
5658
ngMeta.ngDeps == null ||
5759
ngMeta.ngDeps.exports == null) {
5860
return ngMeta;
5961
}
6062
var assetUri = toAssetUri(assetId);
6163

62-
return Future
63-
.wait(ngMeta.ngDeps.exports
64-
.where((export) => !isDartCoreUri(export.uri))
65-
.map((export) =>
66-
_urlResolver.resolve(assetUri, toMetaExtension(export.uri)))
67-
.where((uri) => !seen.contains(uri))
68-
.map((uri) async {
64+
return Future.wait(ngMeta.ngDeps.exports
65+
.where((export) => !isDartCoreUri(export.uri))
66+
.map((export) =>
67+
_urlResolver.resolve(assetUri, toMetaExtension(export.uri)))
68+
.where((uri) => !seen.contains(uri))
69+
.map((uri) async {
6970
seen.add(uri);
7071
try {
7172
final exportAssetId = fromUri(uri);
72-
if (await reader.hasInput(exportAssetId)) {
73-
var exportNgMetaJson = await reader.readAsString(exportAssetId);
74-
if (exportNgMetaJson == null) return null;
75-
var exportNgMeta = new NgMeta.fromJson(JSON.decode(exportNgMetaJson));
76-
await _linkDirectiveMetadataRecursive(
77-
exportNgMeta, reader, exportAssetId, seen);
78-
if (exportNgMeta != null) {
79-
ngMeta.addAll(exportNgMeta);
80-
}
73+
final exportNgMeta = await _readNgMeta(reader, exportAssetId);
74+
if (exportNgMeta != null) {
75+
await _linkRecursive(exportNgMeta, reader, exportAssetId, seen);
76+
ngMeta.addAll(exportNgMeta);
8177
}
8278
} catch (err, st) {
8379
// Log and continue.
8480
logger.warning('Failed to fetch $uri. Message: $err.\n$st');
8581
}
86-
}))
87-
.then((_) => ngMeta);
82+
}));
8883
}

modules_dart/transform/lib/src/transform/directive_processor/inliner.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ Future<String> inlineParts(AssetReader reader, AssetId assetId) async {
3737
// parent, so it does not need its own `.ng_deps.dart` file.
3838
if (directivesVisitor.isPart) return null;
3939

40-
return _getAllDeclarations(reader, assetId, code, directivesVisitor);
40+
return logElapsedAsync(() {
41+
return _getAllDeclarations(reader, assetId, code, directivesVisitor);
42+
}, operationName: 'inlineParts', assetId: assetId);
4143
}
4244

4345
/// Processes `visitor.parts`, reading and appending their contents to the

modules_dart/transform/lib/src/transform/directive_processor/rewriter.dart

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import 'package:angular2/src/core/compiler/template_compiler.dart';
1717
import 'inliner.dart';
1818

1919
/// Generates an instance of [NgMeta] describing the file at `assetId`.
20-
Future<NgMeta> createNgDeps(AssetReader reader, AssetId assetId,
20+
Future<NgMeta> createNgMeta(AssetReader reader, AssetId assetId,
2121
AnnotationMatcher annotationMatcher) async {
2222
// TODO(kegluneq): Shortcut if we can determine that there are no
2323
// [Directive]s present, taking into account `export`s.
@@ -26,18 +26,22 @@ Future<NgMeta> createNgDeps(AssetReader reader, AssetId assetId,
2626
var parsedCode =
2727
parseCompilationUnit(codeWithParts, name: '${assetId.path} and parts');
2828

29-
var ngDepsVisitor = new NgDepsVisitor(assetId, annotationMatcher);
30-
parsedCode.accept(ngDepsVisitor);
31-
32-
var ngMeta = new NgMeta(ngDeps: ngDepsVisitor.model);
33-
34-
var templateCompiler = createTemplateCompiler(reader);
35-
var ngMetaVisitor = new _NgMetaVisitor(
36-
ngMeta, assetId, annotationMatcher, _interfaceMatcher, templateCompiler);
37-
parsedCode.accept(ngMetaVisitor);
38-
await ngMetaVisitor.whenDone();
39-
40-
return ngMeta;
29+
final ngDepsVisitor = await logElapsedAsync(() async {
30+
var ngDepsVisitor = new NgDepsVisitor(assetId, annotationMatcher);
31+
parsedCode.accept(ngDepsVisitor);
32+
return ngDepsVisitor;
33+
}, operationName: 'createNgDeps', assetId: assetId);
34+
35+
return logElapsedAsync(() async {
36+
var ngMeta = new NgMeta(ngDeps: ngDepsVisitor.model);
37+
38+
var templateCompiler = createTemplateCompiler(reader);
39+
var ngMetaVisitor = new _NgMetaVisitor(ngMeta, assetId, annotationMatcher,
40+
_interfaceMatcher, templateCompiler);
41+
parsedCode.accept(ngMetaVisitor);
42+
await ngMetaVisitor.whenDone();
43+
return ngMeta;
44+
}, operationName: 'createNgMeta', assetId: assetId);
4145
}
4246

4347
// TODO(kegluneq): Allow the caller to provide an InterfaceMatcher.

modules_dart/transform/lib/src/transform/directive_processor/transformer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class DirectiveProcessor extends Transformer implements DeclaringTransformer {
4545
var primaryId = transform.primaryInput.id;
4646
var reader = new AssetReader.fromTransform(transform);
4747
var ngMeta =
48-
await createNgDeps(reader, primaryId, options.annotationMatcher);
48+
await createNgMeta(reader, primaryId, options.annotationMatcher);
4949
if (ngMeta == null || ngMeta.isEmpty) {
5050
return;
5151
}

modules_dart/transform/lib/src/transform/stylesheet_compiler/processor.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'dart:async';
44

55
import 'package:angular2/src/transform/common/asset_reader.dart';
66
import 'package:angular2/src/transform/common/code/source_module.dart';
7+
import 'package:angular2/src/transform/common/logging.dart';
78
import 'package:angular2/src/transform/common/names.dart';
89
import 'package:angular2/src/transform/common/ng_compiler.dart';
910
import 'package:angular2/src/core/compiler/source_module.dart';
@@ -21,11 +22,11 @@ Future<Iterable<Asset>> processStylesheet(
2122
final stylesheetUrl = '${stylesheetId.package}|${stylesheetId.path}';
2223
final templateCompiler = createTemplateCompiler(reader);
2324
final cssText = await reader.readAsString(stylesheetId);
24-
final sourceModules =
25-
templateCompiler.compileStylesheetCodeGen(stylesheetUrl, cssText);
25+
return logElapsedAsync(() async {
26+
final sourceModules =
27+
templateCompiler.compileStylesheetCodeGen(stylesheetUrl, cssText);
2628

27-
return sourceModules.map((SourceModule module) => new Asset.fromString(
28-
new AssetId.parse('${module.moduleUrl}'),
29-
writeSourceModule(module)));
29+
return sourceModules.map((SourceModule module) => new Asset.fromString(
30+
new AssetId.parse('${module.moduleUrl}'), writeSourceModule(module)));
31+
}, operationName: 'processStylesheet', assetId: stylesheetId);
3032
}
31-

modules_dart/transform/lib/src/transform/template_compiler/compile_data_creator.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ import 'package:code_transformers/assets.dart';
1919
///
2020
/// The returned value wraps the [NgDeps] at `entryPoint` as well as these
2121
/// created objects.
22-
Future<CompileDataResults> createCompileData(AssetReader reader,
23-
AssetId entryPoint) async {
24-
return new _CompileDataCreator(reader, entryPoint).createCompileData();
22+
Future<CompileDataResults> createCompileData(
23+
AssetReader reader, AssetId assetId) async {
24+
return logElapsedAsync(() {
25+
return new _CompileDataCreator(reader, assetId).createCompileData();
26+
}, operationName: 'createCompileData', assetId: assetId);
2527
}
2628

2729
class CompileDataResults {

0 commit comments

Comments
 (0)