fix(transformer): Loggers now are per zone and each transform runs in its own zone

This commit is contained in:
Jacob MacDonald 2015-07-23 09:06:23 -07:00
parent 09226cdd75
commit bd65b63c65
18 changed files with 91 additions and 160 deletions

View File

@ -15,7 +15,7 @@ Future<String> createNgSettersAndGetters(
String code = ngDeps.code; String code = ngDeps.code;
var setters = _generateSetters(_createPropertiesMap(ngDeps)); var setters = _generateSetters(_createPropertiesMap(ngDeps));
var getters = _generateGetters( _createEventPropertiesList(ngDeps)); var getters = _generateGetters(_createEventPropertiesList(ngDeps));
if (setters.isEmpty && getters.isEmpty) return code; if (setters.isEmpty && getters.isEmpty) return code;
var out = new StringBuffer(); var out = new StringBuffer();
@ -97,7 +97,7 @@ List<String> _generateGetters(List<String> eventProperties) {
/// Collapses all `events` in {@link ngDeps} into a list of corresponding /// Collapses all `events` in {@link ngDeps} into a list of corresponding
/// property names. /// property names.
List<String> _createEventPropertiesList(NgDeps ngDeps) { List<String> _createEventPropertiesList(NgDeps ngDeps) {
var visitor = new ExtractNamedExpressionVisitor('events'); var visitor = new ExtractNamedExpressionVisitor('events');
var propertyNames = []; var propertyNames = [];
ngDeps.registeredTypes.forEach((RegisteredType t) { ngDeps.registeredTypes.forEach((RegisteredType t) {

View File

@ -26,18 +26,12 @@ class BindGenerator extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var id = transform.primaryInput.id; var id = transform.primaryInput.id;
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
var transformedCode = await createNgSettersAndGetters(reader, id); var transformedCode = await createNgSettersAndGetters(reader, id);
transform.addOutput(new Asset.fromString( transform.addOutput(new Asset.fromString(
id, formatter.format(transformedCode, uri: id.path))); id, formatter.format(transformedCode, uri: id.path)));
} catch (ex, stackTrace) { }, errorMessage: 'Creating ng setters/getters failed.');
log.logger.error('Creating ng setters/getters failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
} }
} }

View File

@ -88,7 +88,7 @@ class AnnotationMatcher extends ClassMatcherBase {
throw 'Unable to locate descriptor for ${annotation.name} in ${assetId}'; throw 'Unable to locate descriptor for ${annotation.name} in ${assetId}';
} }
return implements(descriptor, interfaces, return implements(descriptor, interfaces,
missingSuperClassWarning: 'Missing `custom_annotation` entry for `${descriptor.superClass}`.'); missingSuperClassWarning: 'Missing `custom_annotation` entry for `${descriptor.superClass}`.');
} }
/// Checks if an [Annotation] node implements [Injectable]. /// Checks if an [Annotation] node implements [Injectable].

View File

@ -5,24 +5,27 @@ import 'package:barback/barback.dart';
import 'package:code_transformers/messages/build_logger.dart'; import 'package:code_transformers/messages/build_logger.dart';
import 'package:source_span/source_span.dart'; import 'package:source_span/source_span.dart';
BuildLogger _logger; typedef _SimpleCallback();
/// Prepares {@link logger} for use throughout the transformer. // The key used to store the logger on the current zone.
void init(Transform t) { final _key = #loggingZonedLoggerKey;
_logger = new BuildLogger(t);
}
/// Sets {@link logger} directly. Used for testing - in general use {@link init}. /// Executes {@link fn} inside a new {@link Zone} with its own logger.
void setLogger(BuildLogger logger) { dynamic initZoned(Transform t, _SimpleCallback fn, {String errorMessage: ''}) =>
_logger = logger; setZoned(new BuildLogger(t), fn, errorMessage: errorMessage);
}
/// The logger the transformer should use for messaging. dynamic setZoned(BuildLogger logger, _SimpleCallback fn,
{String errorMessage: ''}) => runZoned(fn,
zoneValues: {_key: logger}, onError: (e, stackTrace) {
logger.error('$errorMessage\n'
'Exception: $e\n'
'Stack Trace: $stackTrace');
});
/// The logger for the current {@link Zone}.
BuildLogger get logger { BuildLogger get logger {
if (_logger == null) { var current = Zone.current[_key] as BuildLogger;
_logger = new PrintLogger(); return current == null ? new PrintLogger() : current;
}
return _logger;
} }
class PrintLogger implements BuildLogger { class PrintLogger implements BuildLogger {

View File

@ -24,9 +24,7 @@ class DeferredRewriter extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var asset = transform.primaryInput; var asset = transform.primaryInput;
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
var transformedCode = await rewriteDeferredLibraries(reader, asset.id); var transformedCode = await rewriteDeferredLibraries(reader, asset.id);
@ -34,11 +32,7 @@ class DeferredRewriter extends Transformer {
transform.addOutput( transform.addOutput(
new Asset.fromString(transform.primaryInput.id, transformedCode)); new Asset.fromString(transform.primaryInput.id, transformedCode));
} }
} catch (ex, stackTrace) { }, errorMessage: 'Rewritting deferred libraries failed.');
log.logger.warning('Rewritting deferred libraries failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
} }
} }

View File

@ -22,9 +22,7 @@ class DirectiveLinker extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
var assetId = transform.primaryInput.id; var assetId = transform.primaryInput.id;
var assetPath = assetId.path; var assetPath = assetId.path;
@ -33,12 +31,7 @@ class DirectiveLinker extends Transformer {
var formattedCode = formatter.format(transformedCode, uri: assetPath); var formattedCode = formatter.format(transformedCode, uri: assetPath);
transform.addOutput(new Asset.fromString(assetId, formattedCode)); transform.addOutput(new Asset.fromString(assetId, formattedCode));
} }
} catch (ex, stackTrace) { }, errorMessage: 'Linking ng directives failed.');
log.logger.error('Linking ng directives failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
return null;
} }
} }
@ -52,18 +45,11 @@ class EmptyNgDepsRemover extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
if (!(await isNecessary(reader, transform.primaryInput.id))) { if (!(await isNecessary(reader, transform.primaryInput.id))) {
transform.consumePrimary(); transform.consumePrimary();
} }
} catch (ex, stackTrace) { }, errorMessage: 'Removing unnecessary ng deps failed.');
log.logger.error('Removing unnecessary ng deps failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
return null;
} }
} }

View File

@ -25,9 +25,7 @@ class DirectiveMetadataExtractor extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
var fromAssetId = transform.primaryInput.id; var fromAssetId = transform.primaryInput.id;
@ -40,12 +38,7 @@ class DirectiveMetadataExtractor extends Transformer {
transform.addOutput(new Asset.fromString( transform.addOutput(new Asset.fromString(
_outputAssetId(fromAssetId), _encoder.convert(jsonMap))); _outputAssetId(fromAssetId), _encoder.convert(jsonMap)));
} }
} catch (ex, stackTrace) { }, errorMessage: 'Extracting ng metadata failed.');
log.logger.error('Extracting ng metadata failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
return null;
} }
} }

View File

@ -29,9 +29,7 @@ class DirectiveProcessor extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var asset = transform.primaryInput; var asset = transform.primaryInput;
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
var ngDepsSrc = await createNgDeps( var ngDepsSrc = await createNgDeps(
@ -46,10 +44,6 @@ class DirectiveProcessor extends Transformer {
} }
transform.addOutput(new Asset.fromString(ngDepsAssetId, ngDepsSrc)); transform.addOutput(new Asset.fromString(ngDepsAssetId, ngDepsSrc));
} }
} catch (ex, stackTrace) { }, errorMessage: 'Processing ng directives failed.');
log.logger.warning('Processing ng directives failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
} }
} }

View File

@ -45,8 +45,7 @@ class Rewriter {
/// ///
/// This breaks our dependency on dart:mirrors, which enables smaller code /// This breaks our dependency on dart:mirrors, which enables smaller code
/// size and better performance. /// size and better performance.
class _RewriterVisitor extends Object class _RewriterVisitor extends Object with RecursiveAstVisitor<Object> {
with RecursiveAstVisitor<Object> {
final Rewriter _rewriter; final Rewriter _rewriter;
final buf = new StringBuffer(); final buf = new StringBuffer();
final reflectionCapabilityAssignments = []; final reflectionCapabilityAssignments = [];

View File

@ -30,9 +30,7 @@ class ReflectionRemover extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
var newEntryPoints = options.entryPoints.map((entryPoint) { var newEntryPoints = options.entryPoints.map((entryPoint) {
return new AssetId(transform.primaryInput.id.package, entryPoint) return new AssetId(transform.primaryInput.id.package, entryPoint)
.changeExtension(DEPS_EXTENSION); .changeExtension(DEPS_EXTENSION);
@ -54,10 +52,6 @@ class ReflectionRemover extends Transformer {
mirrorMode: mirrorMode, writeStaticInit: writeStaticInit); mirrorMode: mirrorMode, writeStaticInit: writeStaticInit);
transform.addOutput( transform.addOutput(
new Asset.fromString(transform.primaryInput.id, transformedCode)); new Asset.fromString(transform.primaryInput.id, transformedCode));
} catch (ex, stackTrace) { }, errorMessage: 'Removing reflection failed.');
log.logger.error('Removing reflection failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
} }
} }

View File

@ -28,19 +28,13 @@ class TemplateCompiler extends Transformer {
@override @override
Future apply(Transform transform) async { Future apply(Transform transform) async {
log.init(transform); await log.initZoned(transform, () async {
try {
Html5LibDomAdapter.makeCurrent(); Html5LibDomAdapter.makeCurrent();
var id = transform.primaryInput.id; var id = transform.primaryInput.id;
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
var transformedCode = formatter.format(await processTemplates(reader, id, var transformedCode = formatter.format(await processTemplates(reader, id,
generateChangeDetectors: options.generateChangeDetectors)); generateChangeDetectors: options.generateChangeDetectors));
transform.addOutput(new Asset.fromString(id, transformedCode)); transform.addOutput(new Asset.fromString(id, transformedCode));
} catch (ex, stackTrace) { }, errorMessage: 'Parsing ng templates failed.');
log.logger.error('Parsing ng templates failed.\n'
'Exception: $ex\n'
'Stack Trace: $stackTrace');
}
} }
} }

View File

@ -20,7 +20,6 @@ void allTests() {
TestAssetReader reader = null; TestAssetReader reader = null;
beforeEach(() { beforeEach(() {
setLogger(new PrintLogger());
reader = new TestAssetReader(); reader = new TestAssetReader();
}); });

View File

@ -2,12 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
import 'hello.dart'; import 'hello.dart';
import 'package:angular2/angular2.dart' import 'package:angular2/angular2.dart'
show show Component, Directive, View, NgElement, LifecycleEvent;
Component,
Directive,
View,
NgElement,
LifecycleEvent;
var _visited = false; var _visited = false;
void initReflector(reflector) { void initReflector(reflector) {

View File

@ -2,12 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
import 'hello.dart'; import 'hello.dart';
import 'package:angular2/angular2.dart' import 'package:angular2/angular2.dart'
show show Component, Directive, View, NgElement, LifecycleEvent;
Component,
Directive,
View,
NgElement,
LifecycleEvent;
var _visited = false; var _visited = false;
void initReflector(reflector) { void initReflector(reflector) {

View File

@ -2,12 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
import 'hello.dart'; import 'hello.dart';
import 'package:angular2/angular2.dart' import 'package:angular2/angular2.dart'
show show Component, Directive, View, NgElement, LifecycleEvent;
Component,
Directive,
View,
NgElement,
LifecycleEvent;
var _visited = false; var _visited = false;
void initReflector(reflector) { void initReflector(reflector) {

View File

@ -2,12 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
import 'hello.dart'; import 'hello.dart';
import 'package:angular2/angular2.dart' import 'package:angular2/angular2.dart'
show show Component, Directive, View, NgElement, LifecycleEvent;
Component,
Directive,
View,
NgElement,
LifecycleEvent;
var _visited = false; var _visited = false;
void initReflector(reflector) { void initReflector(reflector) {
@ -19,8 +14,13 @@ void initReflector(reflector) {
'parameters': const [const []], 'parameters': const [const []],
'annotations': const [ 'annotations': const [
const Component( const Component(
lifecycle: [LifecycleEvent.onChange, LifecycleEvent.onDestroy, LifecycleEvent.onInit, lifecycle: [
LifecycleEvent.onCheck, LifecycleEvent.onAllChangesDone]) LifecycleEvent.onChange,
LifecycleEvent.onDestroy,
LifecycleEvent.onInit,
LifecycleEvent.onCheck,
LifecycleEvent.onAllChangesDone
])
] ]
}); });
} }

View File

@ -120,34 +120,34 @@ void _testNgDeps(String name, String inputPath,
bool isolate: false}) { bool isolate: false}) {
var testFn = isolate ? iit : it; var testFn = isolate ? iit : it;
testFn(name, () async { testFn(name, () async {
if (expectedLogs != null) { var logger = new RecordingLogger();
log.setLogger(new RecordingLogger()); await log.setZoned(logger, () async {
} var inputId = _assetIdForPath(inputPath);
if (reader == null) {
reader = new TestAssetReader();
}
if (assetId != null) {
reader.addAsset(assetId, await reader.readAsString(inputId));
inputId = assetId;
}
var expectedPath = path.join(path.dirname(inputPath), 'expected',
path.basename(inputPath).replaceFirst('.dart', '.ng_deps.dart'));
var expectedId = _assetIdForPath(expectedPath);
var inputId = _assetIdForPath(inputPath); var annotationMatcher = new AnnotationMatcher()
if (reader == null) { ..addAll(customDescriptors);
reader = new TestAssetReader(); var output = await createNgDeps(reader, inputId, annotationMatcher,
} inlineViews: inlineViews);
if (assetId != null) { if (output == null) {
reader.addAsset(assetId, await reader.readAsString(inputId)); expect(await reader.hasInput(expectedId)).toBeFalse();
inputId = assetId; } else {
} var input = await reader.readAsString(expectedId);
var expectedPath = path.join(path.dirname(inputPath), 'expected', expect(formatter.format(output)).toEqual(formatter.format(input));
path.basename(inputPath).replaceFirst('.dart', '.ng_deps.dart')); }
var expectedId = _assetIdForPath(expectedPath); });
var annotationMatcher = new AnnotationMatcher()..addAll(customDescriptors);
var output = await createNgDeps(reader, inputId, annotationMatcher,
inlineViews: inlineViews);
if (output == null) {
expect(await reader.hasInput(expectedId)).toBeFalse();
} else {
var input = await reader.readAsString(expectedId);
expect(formatter.format(output)).toEqual(formatter.format(input));
}
if (expectedLogs != null) { if (expectedLogs != null) {
expect((log.logger as RecordingLogger).logs, expectedLogs); expect(logger.logs, expectedLogs);
} }
}); });
} }

View File

@ -18,7 +18,6 @@ main() => allTests();
void allTests() { void allTests() {
Html5LibDomAdapter.makeCurrent(); Html5LibDomAdapter.makeCurrent();
beforeEach(() => setLogger(new PrintLogger()));
describe('registrations', () { describe('registrations', () {
noChangeDetectorTests(); noChangeDetectorTests();
@ -34,7 +33,7 @@ void changeDetectorTests() {
// when https://github.com/angular/angular/issues/3019 is solved. // when https://github.com/angular/angular/issues/3019 is solved.
it('shouldn always notifyBinding for template variables', () async { it('shouldn always notifyBinding for template variables', () async {
var inputPath = 'template_compiler/ng_for_files/hello.ng_deps.dart'; var inputPath = 'template_compiler/ng_for_files/hello.ng_deps.dart';
var output = await(process(new AssetId('a', inputPath))); var output = await (process(new AssetId('a', inputPath)));
expect(output).toContain('notifyOnBinding'); expect(output).toContain('notifyOnBinding');
}); });
} }
@ -45,27 +44,25 @@ void noChangeDetectorTests() {
it('should parse simple expressions in inline templates.', () async { it('should parse simple expressions in inline templates.', () async {
var inputPath = var inputPath =
'template_compiler/inline_expression_files/hello.ng_deps.dart'; 'template_compiler/inline_expression_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/inline_expression_files/expected/hello.ng_deps.dart'); 'template_compiler/inline_expression_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
}); });
it('should parse simple methods in inline templates.', () async { it('should parse simple methods in inline templates.', () async {
var inputPath = var inputPath = 'template_compiler/inline_method_files/hello.ng_deps.dart';
'template_compiler/inline_method_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/inline_method_files/expected/hello.ng_deps.dart'); 'template_compiler/inline_method_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
}); });
it('should parse simple expressions in linked templates.', () async { it('should parse simple expressions in linked templates.', () async {
var inputPath = var inputPath = 'template_compiler/url_expression_files/hello.ng_deps.dart';
'template_compiler/url_expression_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/url_expression_files/expected/hello.ng_deps.dart'); 'template_compiler/url_expression_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
}); });
@ -73,7 +70,7 @@ void noChangeDetectorTests() {
it('should parse simple methods in linked templates.', () async { it('should parse simple methods in linked templates.', () async {
var inputPath = 'template_compiler/url_method_files/hello.ng_deps.dart'; var inputPath = 'template_compiler/url_method_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/url_method_files/expected/hello.ng_deps.dart'); 'template_compiler/url_method_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
}); });
@ -81,33 +78,32 @@ void noChangeDetectorTests() {
it('should not generated duplicate getters/setters', () async { it('should not generated duplicate getters/setters', () async {
var inputPath = 'template_compiler/duplicate_files/hello.ng_deps.dart'; var inputPath = 'template_compiler/duplicate_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/duplicate_files/expected/hello.ng_deps.dart'); 'template_compiler/duplicate_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
}); });
it('should parse `View` directives with a single dependency.', () async { it('should parse `View` directives with a single dependency.', () async {
var inputPath = var inputPath = 'template_compiler/one_directive_files/hello.ng_deps.dart';
'template_compiler/one_directive_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/one_directive_files/expected/hello.ng_deps.dart'); 'template_compiler/one_directive_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
}); });
it('should parse `View` directives with a single prefixed dependency.', it('should parse `View` directives with a single prefixed dependency.',
() async { () async {
var inputPath = 'template_compiler/with_prefix_files/hello.ng_deps.dart'; var inputPath = 'template_compiler/with_prefix_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/with_prefix_files/expected/hello.ng_deps.dart'); 'template_compiler/with_prefix_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
inputPath = 'template_compiler/with_prefix_files/goodbye.ng_deps.dart'; inputPath = 'template_compiler/with_prefix_files/goodbye.ng_deps.dart';
expected = readFile( expected = readFile(
'template_compiler/with_prefix_files/expected/goodbye.ng_deps.dart'); 'template_compiler/with_prefix_files/expected/goodbye.ng_deps.dart');
output = await process(new AssetId('a', inputPath)); output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
@ -115,9 +111,9 @@ void noChangeDetectorTests() {
it('should parse angular directives with a prefix', () async { it('should parse angular directives with a prefix', () async {
var inputPath = var inputPath =
'template_compiler/with_prefix_files/ng2_prefix.ng_deps.dart'; 'template_compiler/with_prefix_files/ng2_prefix.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/with_prefix_files/expected/ng2_prefix.ng_deps.dart'); 'template_compiler/with_prefix_files/expected/ng2_prefix.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
@ -125,9 +121,9 @@ void noChangeDetectorTests() {
it('should create the same output for multiple calls.', () async { it('should create the same output for multiple calls.', () async {
var inputPath = var inputPath =
'template_compiler/inline_expression_files/hello.ng_deps.dart'; 'template_compiler/inline_expression_files/hello.ng_deps.dart';
var expected = readFile( var expected = readFile(
'template_compiler/inline_expression_files/expected/hello.ng_deps.dart'); 'template_compiler/inline_expression_files/expected/hello.ng_deps.dart');
var output = await process(new AssetId('a', inputPath)); var output = await process(new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected); _formatThenExpectEquals(output, expected);
output = await process(new AssetId('a', inputPath)); output = await process(new AssetId('a', inputPath));