feat(dart/transform): Generate all code into <file>.template.dart

Previously, we generated the code to initialize the reflector into the
<file>.ng_deps.dart and the compiled template and change detector code
into <file>.template.dart.

Update the transformer to generate all code into <file>.template.dart to
avoid the additional HTTP requests necessary when debugging
applications in Dartium.
This commit is contained in:
Tim Blasi 2016-01-25 17:37:47 -08:00 committed by Timothy Blasi
parent ed2dbf2db7
commit 8c36aa866a
21 changed files with 141 additions and 108 deletions

View File

@ -58,7 +58,7 @@ class AnnotationVisitor extends SimpleAstVisitor<AnnotationModel> {
}
/// Defines the format in which an [AnnotationModel] is expressed as Dart code
/// in a `.ng_deps.dart` file.
/// when registered with the reflector.
abstract class AnnotationWriterMixin {
StringBuffer get buffer;

View File

@ -78,8 +78,8 @@ void _populateCombinators(NamespaceDirective node, dynamic model) {
}
}
/// Defines the format in which an [ImportModel] is expressed as Dart code in a
/// `.ng_deps.dart` file.
/// Defines the format in which an [ImportModel] is expressed as Dart code when
/// registered with the reflector.
abstract class ImportWriterMixin {
StringBuffer get buffer;
@ -96,8 +96,8 @@ abstract class ImportWriterMixin {
}
}
/// Defines the format in which an [ExportModel] is expressed as Dart code in a
/// `.ng_deps.dart` file.
/// Defines the format in which an [ExportModel] is expressed as Dart code when
/// registered with the reflector.
abstract class ExportWriterMixin {
StringBuffer get buffer;

View File

@ -14,8 +14,7 @@ import 'reflection_info_code.dart';
import 'parameter_code.dart';
import 'queries_code.dart';
/// Visitor responsible for parsing source Dart files (that is, not
/// `.ng_deps.dart` files) into [NgDepsModel] objects.
/// Visitor responsible for parsing Dart source into [NgDepsModel] objects.
class NgDepsVisitor extends RecursiveAstVisitor<Object> {
final AssetId processedFile;
final _importVisitor = new ImportVisitor();
@ -113,7 +112,7 @@ class NgDepsVisitor extends RecursiveAstVisitor<Object> {
}
/// Defines the format in which an [NgDepsModel] is expressed as Dart code
/// in a `.ng_deps.dart` file.
/// when registered with the reflector.
class NgDepsWriter extends Object
with
AnnotationWriterMixin,
@ -139,10 +138,10 @@ abstract class NgDepsWriterMixin
void writeNgDepsModel(NgDepsModel model) {
if (model.libraryUri.isNotEmpty) {
buffer.writeln('library ${model.libraryUri}${DEPS_EXTENSION};\n');
buffer.writeln('library ${model.libraryUri}${TEMPLATE_EXTENSION};\n');
}
// We need to import & export the source file.
// We need to import & export (see below) the source file.
writeImportModel(new ImportModel()..uri = model.sourceFile);
// Used to register reflective information.

View File

@ -95,7 +95,7 @@ class ParameterVisitor extends SimpleAstVisitor<ParameterModel> {
}
/// Defines the format in which a [ParameterModel] is expressed as Dart code
/// in a `.ng_deps.dart` file.
/// when registered with the reflector.
abstract class ParameterWriterMixin {
StringBuffer get buffer;

View File

@ -284,7 +284,7 @@ class _PropertyMetadataVisitor
}
/// Defines the format in which an [ReflectionInfoModel] is expressed as Dart
/// code in a `.ng_deps.dart` file.
/// code when registered with the reflector.
abstract class ReflectionWriterMixin
implements AnnotationWriterMixin, ParameterWriterMixin {
StringBuffer get buffer;

View File

@ -1,35 +1,51 @@
library angular2.transform.common.code.source_module;
import 'package:analyzer/src/generated/scanner.dart' show Keyword;
import 'package:angular2/src/compiler/source_module.dart';
import 'package:analyzer/src/generated/scanner.dart' show Keyword;
import 'package:angular2/src/transform/common/model/ng_deps_model.pb.dart';
import 'package:angular2/src/transform/common/model/source_module.dart';
import 'uri.dart';
import 'ng_deps_code.dart';
/// Writes the full Dart code for the provided [SourceModule].
String writeSourceModule(SourceModule sourceModule, {String libraryName}) {
if (sourceModule == null) return null;
var buf = new StringBuffer();
final writer = new NgDepsWriter(buf);
var sourceWithImports = sourceModule.getSourceWithImports();
libraryName = _sanitizeLibName(
libraryName != null ? libraryName : sourceModule.moduleUrl);
buf..writeln('library $libraryName;')..writeln();
sourceWithImports.imports.forEach((import) {
// Format for importLine := [uri, prefix]
if (import.length != 2) {
throw new FormatException(
'Unexpected import format! '
'Angular 2 compiler returned imports in an unexpected format. '
'Expected [<import_uri>, <prefix>].',
import.join(', '));
}
buf.writeln(writeImportUri(import[0],
prefix: import[1], fromAbsolute: sourceModule.moduleUrl));
extractImports(sourceWithImports, sourceModule.moduleUrl).forEach((import) {
writer.writeImportModel(import);
});
buf..writeln()..writeln(sourceWithImports.source);
return buf.toString();
}
/// Uses `writer` to write a Dart library representing `model` and
/// `sourceModule`.
void writeTemplateFile(
NgDepsWriterMixin writer, NgDepsModel model, SourceModule sourceModule) {
if (model == null) return null;
var sourceModuleCode = '';
if (sourceModule != null) {
var sourceWithImports = sourceModule.getSourceWithImports();
sourceModuleCode = sourceWithImports.source;
// Since we modify `imports`, make a copy to avoid changing the provided
// value.
var sourceModuleImports =
extractImports(sourceWithImports, sourceModule.moduleUrl);
model = model.clone();
model.imports.addAll(sourceModuleImports);
}
writer.writeNgDepsModel(model);
writer.buffer..writeln()..writeln(sourceModuleCode);
}
final _unsafeCharsPattern = new RegExp(r'[^a-zA-Z0-9_\.]');
String _sanitizeLibName(String moduleUrl) {
var sanitized =

View File

@ -122,7 +122,7 @@ const NgDepsModel$json = const {
/**
* Generated with:
* ng_deps_model.proto (64702efcc1d7fb434f3652943ba051104960ffd5)
* ng_deps_model.proto (03511db92c8cfa3c1279d845be8fd7de36de3ee1)
* libprotoc 2.6.1
* dart-protoc-plugin (af5fc2bf1de367a434c3b1847ab260510878ffc0)
*/

View File

@ -33,7 +33,7 @@ message NgDepsModel {
// framework.
repeated string methods = 9;
// Imports for the .ng_deps.dart files associated with the declared `imports`
// and `exports` for this file.
// Imports of the generated files associated with the declared `imports`
// and `exports` of the source file.
repeated ImportModel dep_imports = 10;
}

View File

@ -1,13 +1,37 @@
library angular2.transform.common.code.uri;
library angular2.transform.common.model.source_module;
import 'package:angular2/src/transform/common/url_resolver.dart';
import 'package:path/path.dart' as path;
/// Generates an `import` statement for the file specified by `importPath`.
import 'package:angular2/src/compiler/source_module.dart';
import 'package:angular2/src/transform/common/url_resolver.dart';
import 'import_export_model.pb.dart';
/// Generates [ImportModel]s for all imports in `sourceWithImports`.
///
/// Imports in `sourceWithImports` are resolved relative to `moduleUrl`.
List<ImportModel> extractImports(
SourceWithImports sourceWithImports, String moduleUrl) {
if (sourceWithImports == null) return const <ImportModel>[];
return sourceWithImports.imports.map((import) {
// Format for importLine := [uri, prefix]
if (import.length != 2) {
throw new FormatException(
'Internal Angular 2 compiler error. '
'Angular 2 compiler returned imports in an unexpected format. '
'Expected [<import_uri>, <prefix>].',
import.join(', '));
}
return toImportModel(import[0], prefix: import[1], fromAbsolute: moduleUrl);
}).toList();
}
/// Generates an [ImportModel] for the file specified by `importPath`.
///
/// If `fromAbsolute` is specified, `importPath` may be a relative path,
/// otherwise it is expected to be absolute.
String writeImportUri(String importPath, {String prefix, String fromAbsolute}) {
ImportModel toImportModel(String importPath,
{String prefix, String fromAbsolute}) {
var urlResolver = const TransformerUrlResolver();
var codegenImportPath;
@ -33,10 +57,12 @@ String writeImportUri(String importPath, {String prefix, String fromAbsolute}) {
}
}
final model = new ImportModel()..uri = codegenImportPath;
if (prefix != null && prefix.isNotEmpty) {
prefix = ' as $prefix';
model.prefix = prefix;
}
return 'import \'$codegenImportPath\'$prefix;';
return model;
}
// For a relative import, the scheme, first (package) and second (lib|test|web)

View File

@ -8,7 +8,6 @@ const TRANSFORM_DYNAMIC_MODE = 'transform_dynamic';
const CSS_EXTENSION = '.css';
const SHIMMED_STYLESHEET_EXTENSION = '.css.shim.dart';
const NON_SHIMMED_STYLESHEET_EXTENSION = '.css.dart';
const DEPS_EXTENSION = '.ng_deps.dart';
const META_EXTENSION = '.ng_meta.json';
const REFLECTION_CAPABILITIES_NAME = 'ReflectionCapabilities';
const REFLECTOR_IMPORT = 'package:angular2/src/core/reflection/reflection.dart';
@ -24,7 +23,6 @@ const TEMPLATE_EXTENSION = '.template.dart';
/// important. For example, putting '.dart' first in this list will cause
/// incorrect behavior.
const ALL_EXTENSIONS = const [
DEPS_EXTENSION,
META_EXTENSION,
SUMMARY_META_EXTENSION,
TEMPLATE_EXTENSION,
@ -38,7 +36,6 @@ const ALL_EXTENSIONS = const [
/// any files named like transformer outputs will be reported as generated.
bool isGenerated(String uri) {
return const [
DEPS_EXTENSION,
META_EXTENSION,
NON_SHIMMED_STYLESHEET_EXTENSION,
SHIMMED_STYLESHEET_EXTENSION,
@ -51,10 +48,6 @@ bool isGenerated(String uri) {
String toMetaExtension(String uri) =>
_toExtension(uri, ALL_EXTENSIONS, META_EXTENSION);
/// Returns `uri` with its extension updated to [DEPS_EXTENSION].
String toDepsExtension(String uri) =>
_toExtension(uri, ALL_EXTENSIONS, DEPS_EXTENSION);
/// Returns `uri` with its extension updated to [TEMPLATES_EXTENSION].
String toTemplateExtension(String uri) =>
_toExtension(uri, ALL_EXTENSIONS, TEMPLATE_EXTENSION);

View File

@ -5,7 +5,7 @@ import 'logging.dart';
import 'model/ng_deps_model.pb.dart';
import 'url_resolver.dart' show isDartCoreUri;
/// Metadata about directives, directive aliases, and injectable values.
/// Metadata about directives, pipes, directive aliases, and injectable values.
///
/// [NgMeta] is used in three stages of the transformation process:
///
@ -20,12 +20,12 @@ import 'url_resolver.dart' show isDartCoreUri;
/// 2. Use the [NgDepsModel] to write Dart code registering all injectable
/// values with the Angular 2 runtime reflection system.
///
/// Further down the compilation process, the template compiler needs to reason
/// Later in the compilation process, the template compiler needs to reason
/// about the namespace of import prefixes, so it will combine multiple [NgMeta]
/// instances together if they were imported into a file with the same prefix.
///
/// Instances of this class are serialized into `.ng_meta.json` files as
/// intermediate assets to make the compilation process easier.
/// Instances of this class are serialized into `.ng_summary.json` and
/// `.ng_meta.json` files as intermediate assets during the compilation process.
class NgMeta {
static const _ALIAS_VALUE = 'alias';
static const _KIND_KEY = 'kind';
@ -58,7 +58,8 @@ class NgMeta {
bool get isNgDepsEmpty {
if (ngDeps == null) return true;
// If this file imports only dart: libraries and does not define any
// reflectables of its own, it doesn't need a .ng_deps.dart file.
// reflectables of its own, we don't need to register any information from
// it with the Angular 2 reflector.
if (ngDeps.reflectables == null || ngDeps.reflectables.isEmpty) {
if ((ngDeps.imports == null || ngDeps.imports.every(_isDartImport)) &&
(ngDeps.exports == null || ngDeps.exports.every(_isDartImport))) {

View File

@ -27,7 +27,7 @@ class Rewriter {
/// `_entryPoint`
/// 2. Removes any libraries that don't require angular codegen.
/// 3. For the remaining libraries, rewrites the import to the corresponding
/// `ng_deps.dart` file.
/// `.template.dart` file.
/// 4. Chains a future to the `loadLibrary` call which initializes the
/// library.
///
@ -62,11 +62,12 @@ class Rewriter {
var buf = new StringBuffer();
var idx =
_visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
buf.write(code.substring(lastIdx, node.offset));
var import = code.substring(node.offset, node.end);
buf.write(import.replaceFirst('.dart', DEPS_EXTENSION));
return node.end;
// Write from where we left off until the start of the import uri.
buf.write(code.substring(lastIdx, node.uri.offset));
// Rewrite the uri to be that of the generated file.
buf.write("'${toTemplateExtension('${node.uri.stringValue}')}'");
// Update the last index we've processed.
return node.uri.end;
});
idx = _visitor.loadLibraryInvocations.fold(idx,
@ -86,7 +87,7 @@ class Rewriter {
/// Visitor responsible for finding the deferred libraries that need angular
/// codegen. Those are the libraries that are loaded deferred and have a
/// corresponding ng_deps file.
/// corresponding generated file.
class _FindDeferredLibraries extends Object with RecursiveAstVisitor<Object> {
var deferredImports = new List<ImportDirective>();
var loadLibraryInvocations = new List<MethodInvocation>();
@ -132,25 +133,26 @@ class _FindDeferredLibraries extends Object with RecursiveAstVisitor<Object> {
Future cull() async {
var baseUri = toAssetUri(_entryPoint);
// Determine whether a deferred import has ng_deps.
// Determine whether a deferred import has an associated generated file.
var hasInputs = await Future.wait(deferredImports
.map((import) => stringLiteralToString(import.uri))
.map((uri) => toMetaExtension(uri))
.map((metaUri) => fromUri(_urlResolver.resolve(baseUri, metaUri)))
.map((asset) => _reader.hasInput(asset)));
// Filter out any deferred imports that do not have ng_deps.
// Filter out any deferred imports that do not have an associated generated
// file.
deferredImports = it.zip([deferredImports, hasInputs])
.where((importHasInput) => importHasInput[1])
.map((importHasInput) => importHasInput[0])
.toList();
// Find the set of prefixes which have ng_deps.
// Find the set of prefixes which have associated generated files.
var prefixes =
new Set.from(deferredImports.map((import) => import.prefix.name));
// Filters out any load library invocations where the prefix is not a known
// library with ng_deps.
// library with associated generated file.
loadLibraryInvocations = loadLibraryInvocations.where((library) {
var value = library.realTarget as SimpleIdentifier;
return prefixes.contains(value.name);

View File

@ -12,12 +12,13 @@ import 'package:angular2/src/transform/common/url_resolver.dart';
import 'package:barback/barback.dart';
/// Modifies the [NgDepsModel] represented by `entryPoint` to import its
/// dependencies' associated `.ng_deps.dart` files.
/// dependencies' associated, generated files.
///
/// For example, if entry_point.ng_deps.dart imports dependency.dart, this
/// will check if dependency.ng_meta.json exists. If it does, we add an entry
/// to the `depImports` of [NgDepsModel] for dependency.ng_deps.dart. We can
/// use this information later to ensure that each file's dependencies are
/// For example, if entry_point.dart imports dependency.dart, this will check if
/// dependency.ng_meta.json exists. If it does, we add an entry to the
/// `depImports` of [NgDepsModel] for dependency.template.dart.
///
/// We use this information later to ensure that each file's dependencies are
/// initialized when that file is initialized.
Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
AssetId assetId, UrlResolver resolver) async {
@ -29,7 +30,6 @@ Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
if (linkedDepsMap.isEmpty) {
// We are not calling `initReflector` on any other libraries, but we still
// return the model to ensure it is written to code.
// TODO(kegluneq): Continue using the protobuf format after this phase.
return ngDepsModel;
}
@ -40,7 +40,7 @@ Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
if (linkedDepsMap.containsKey(dep.uri) && !seen.contains(dep.uri)) {
seen.add(dep.uri);
var linkedModel = new ImportModel()
..uri = toDepsExtension(dep.uri)
..uri = toTemplateExtension(dep.uri)
..prefix = 'i${idx++}';
// TODO(kegluneq): Preserve combinators?
ngDepsModel.depImports.add(linkedModel);

View File

@ -20,8 +20,8 @@ import 'ng_meta_linker.dart';
/// Said another way, after this step there should be an entry in this `NgMeta`
/// object for all `Directives` visible from its associated `.dart` file.
///
/// This step also ensures that, if `a.dart` imports `b.dart`, `a.ng_deps.dart`
/// imports `b.ng_deps.dart` (if it exists) and we note that this is a
/// This step also ensures that, if `a.dart` imports `b.dart`, `a.template.dart`
/// imports `b.template.dart` (if it exists) and we note that this is a
/// ngDeps dependency, ensuring that a's `initReflector` function calls b's
/// `initReflector' function.
///

View File

@ -35,7 +35,7 @@ Future<String> inlineParts(AssetReader reader, AssetId assetId) async {
.accept(directivesVisitor);
// If this is part of another library, its contents will be processed by its
// parent, so it does not need its own `.ng_deps.dart` file.
// parent, so it does not need its own generated file.
if (directivesVisitor.isPart) return null;
return logElapsedAsync(() {

View File

@ -22,8 +22,8 @@ class Codegen {
/// The code generated here should follow the example of code generated for
/// an {@link ImportDirective} node.
String codegenImport() {
var importUri = path
.basename(reflectionEntryPoint.changeExtension(DEPS_EXTENSION).path);
var importUri = path.basename(
reflectionEntryPoint.changeExtension(TEMPLATE_EXTENSION).path);
return '''import '$importUri' as $prefix;''';
}

View File

@ -18,9 +18,9 @@ import 'remove_reflection_capabilities.dart';
/// The goal of this is to break the app's dependency on dart:mirrors.
///
/// This transformer assumes that {@link DirectiveProcessor} and {@link DirectiveLinker}
/// have already been run and that a .ng_deps.dart file has been generated for
/// have already been run and that a .template.dart file has been generated for
/// {@link options.entryPoint}. The instantiation of {@link ReflectionCapabilities} is
/// replaced by calling `setupReflection` in that .ng_deps.dart file.
/// replaced by calling `initReflector` in that .template.dart file.
class ReflectionRemover extends Transformer implements LazyTransformer {
final TransformerOptions options;

View File

@ -37,7 +37,7 @@ class Codegen {
/// Generates a change detector class with name `changeDetectorTypeName`,
/// which must not conflict with other generated classes in the same
/// `.ng_deps.dart` file. The change detector is used to detect changes in
/// `.template.dart` file. The change detector is used to detect changes in
/// Objects of type `typeName`.
void generate(String typeName, String changeDetectorTypeName,
ChangeDetectorDefinition def) {

View File

@ -184,8 +184,8 @@ class _CompileDataCreator {
}
/// Creates a map from import prefix to the asset: uris of all `.dart`
/// libraries visible from `entryPoint`, excluding `dart:` and `.ng_deps.dart`
/// files it imports. Unprefixed imports have the empty string as their key.
/// libraries visible from `entryPoint`, excluding `dart:` and generated files
/// it imports. Unprefixed imports have the empty string as their key.
/// `entryPoint` is included in the map with no prefix.
Map<String, Iterable<String>> _createPrefixToImportsMap() {
final baseUri = toAssetUri(entryPoint);

View File

@ -3,16 +3,13 @@ library angular2.transform.template_compiler.generator;
import 'dart:async';
import 'package:barback/barback.dart';
import 'package:path/path.dart' as path;
import 'package:angular2/src/core/change_detection/interfaces.dart';
import 'package:angular2/src/facade/lang.dart';
import 'package:angular2/src/core/reflection/reflection.dart';
import 'package:angular2/src/transform/common/asset_reader.dart';
import 'package:angular2/src/transform/common/code/source_module.dart';
import 'package:angular2/src/transform/common/logging.dart';
import 'package:angular2/src/transform/common/model/annotation_model.pb.dart';
import 'package:angular2/src/transform/common/model/import_export_model.pb.dart';
import 'package:angular2/src/transform/common/model/ng_deps_model.pb.dart';
import 'package:angular2/src/transform/common/names.dart';
import 'package:angular2/src/transform/common/ng_compiler.dart';
@ -22,17 +19,18 @@ import 'reflection/processor.dart' as reg;
import 'reflection/reflection_capabilities.dart';
import 'compile_data_creator.dart';
/// Generates `.ng_deps.dart` files to initialize the Angular2 system.
/// Generates `.template.dart` files to initialize the Angular2 system.
///
/// Processes the `.ng_summary.json` file represented by `assetId`
/// - Processes the `.ng_meta.json` file represented by `assetId` using
/// `createCompileData`.
/// Uses the resulting `NgMeta` object to generate
/// `getter`s, `setter`s, and `method`s that would otherwise need to be
/// reflectively accessed.
/// Passes the resulting `NormalizedComponentWithViewDirectives` instances
/// to the `TemplateCompiler` to generate compiled template(s).
/// Uses the resulting `NgDeps` object to generate a .ng_deps.dart file which
/// initializes the Angular2 reflective system.
/// - Uses the resulting `NgMeta` object to register `getter`s, `setter`s, and
/// `method`s that would otherwise need to be reflectively accessed with the
/// `NgDeps` object.
/// - Passes the resulting `NormalizedComponentWithViewDirectives` instance(s)
/// to the `TemplateCompiler` to generate compiled template(s) as a
/// `SourceModule`.
/// - Uses the resulting `NgDeps` object to generate code which initializes the
/// Angular2 reflective system.
///
/// This method assumes a {@link DomAdapter} has been registered.
Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
@ -77,29 +75,26 @@ Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
reflector.reflectionCapabilities = savedReflectionCapabilities;
if (compiledTemplates != null) {
viewDefResults.ngMeta.ngDeps.imports.add(new ImportModel()
..uri = toTemplateExtension(path.basename(assetId.path))
..prefix = '_templates');
// We successfully compiled templates!
// For each compiled template, add the compiled template class as an
// "Annotation" on the code to be registered with the reflector.
for (var reflectable in viewDefResults.viewDefinitions.keys) {
// TODO(kegluneq): Avoid duplicating naming logic for generated classes.
reflectable.annotations.add(new AnnotationModel()
..name = '_templates.hostViewFactory_${reflectable.name}'
..name = 'hostViewFactory_${reflectable.name}'
..isConstObject = true);
}
}
return new Outputs._(
viewDefResults.ngMeta.ngDeps, writeSourceModule(compiledTemplates));
return new Outputs._(viewDefResults.ngMeta.ngDeps, compiledTemplates);
}
AssetId ngDepsAssetId(AssetId primaryId) =>
new AssetId(primaryId.package, toDepsExtension(primaryId.path));
AssetId templatesAssetId(AssetId primaryId) =>
new AssetId(primaryId.package, toTemplateExtension(primaryId.path));
class Outputs {
final NgDepsModel ngDeps;
final String templatesCode;
final SourceModule templatesSource;
Outputs._(this.ngDeps, this.templatesCode);
Outputs._(this.ngDeps, this.templatesSource);
}

View File

@ -7,6 +7,7 @@ import 'package:barback/barback.dart';
import 'package:angular2/src/platform/server/html_adapter.dart';
import 'package:angular2/src/transform/common/asset_reader.dart';
import 'package:angular2/src/transform/common/code/ng_deps_code.dart';
import 'package:angular2/src/transform/common/code/source_module.dart';
import 'package:angular2/src/transform/common/formatter.dart';
import 'package:angular2/src/transform/common/names.dart';
import 'package:angular2/src/transform/common/options.dart';
@ -33,7 +34,6 @@ class TemplateCompiler extends Transformer implements LazyTransformer {
@override
declareOutputs(DeclaringTransform transform) {
transform.declareOutput(ngDepsAssetId(transform.primaryId));
transform.declareOutput(templatesAssetId(transform.primaryId));
}
@ -49,22 +49,23 @@ class TemplateCompiler extends Transformer implements LazyTransformer {
platformDirectives: options.platformDirectives,
platformPipes: options.platformPipes);
var ngDepsCode = _emptyNgDepsContents;
var templatesCode = '';
if (outputs != null) {
if (outputs.ngDeps != null) {
final buf = new StringBuffer();
final writer = new NgDepsWriter(buf);
writer.writeNgDepsModel(outputs.ngDeps);
writeTemplateFile(
new NgDepsWriter(buf), outputs.ngDeps, outputs.templatesSource);
ngDepsCode = formatter.format(buf.toString());
if (primaryId.path.endsWith('index.ng_meta.json')) {
final buf2 = new StringBuffer();
var writer = new NgDepsWriter(buf2);
outputs.ngDeps.imports.forEach(writer.writeImportModel);
print(buf2.toString());
}
if (outputs.templatesCode != null) {
templatesCode = formatter.format(outputs.templatesCode);
}
}
transform.addOutput(
new Asset.fromString(ngDepsAssetId(primaryId), ngDepsCode));
transform.addOutput(
new Asset.fromString(templatesAssetId(primaryId), templatesCode));
new Asset.fromString(templatesAssetId(primaryId), ngDepsCode));
}, log: transform.logger);
}
}