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:
parent
ed2dbf2db7
commit
8c36aa866a
|
@ -58,7 +58,7 @@ class AnnotationVisitor extends SimpleAstVisitor<AnnotationModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the format in which an [AnnotationModel] is expressed as Dart code
|
/// 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 {
|
abstract class AnnotationWriterMixin {
|
||||||
StringBuffer get buffer;
|
StringBuffer get buffer;
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,8 @@ void _populateCombinators(NamespaceDirective node, dynamic model) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the format in which an [ImportModel] is expressed as Dart code in a
|
/// Defines the format in which an [ImportModel] is expressed as Dart code when
|
||||||
/// `.ng_deps.dart` file.
|
/// registered with the reflector.
|
||||||
abstract class ImportWriterMixin {
|
abstract class ImportWriterMixin {
|
||||||
StringBuffer get buffer;
|
StringBuffer get buffer;
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ abstract class ImportWriterMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the format in which an [ExportModel] is expressed as Dart code in a
|
/// Defines the format in which an [ExportModel] is expressed as Dart code when
|
||||||
/// `.ng_deps.dart` file.
|
/// registered with the reflector.
|
||||||
abstract class ExportWriterMixin {
|
abstract class ExportWriterMixin {
|
||||||
StringBuffer get buffer;
|
StringBuffer get buffer;
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,7 @@ import 'reflection_info_code.dart';
|
||||||
import 'parameter_code.dart';
|
import 'parameter_code.dart';
|
||||||
import 'queries_code.dart';
|
import 'queries_code.dart';
|
||||||
|
|
||||||
/// Visitor responsible for parsing source Dart files (that is, not
|
/// Visitor responsible for parsing Dart source into [NgDepsModel] objects.
|
||||||
/// `.ng_deps.dart` files) into [NgDepsModel] objects.
|
|
||||||
class NgDepsVisitor extends RecursiveAstVisitor<Object> {
|
class NgDepsVisitor extends RecursiveAstVisitor<Object> {
|
||||||
final AssetId processedFile;
|
final AssetId processedFile;
|
||||||
final _importVisitor = new ImportVisitor();
|
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
|
/// 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
|
class NgDepsWriter extends Object
|
||||||
with
|
with
|
||||||
AnnotationWriterMixin,
|
AnnotationWriterMixin,
|
||||||
|
@ -139,10 +138,10 @@ abstract class NgDepsWriterMixin
|
||||||
|
|
||||||
void writeNgDepsModel(NgDepsModel model) {
|
void writeNgDepsModel(NgDepsModel model) {
|
||||||
if (model.libraryUri.isNotEmpty) {
|
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);
|
writeImportModel(new ImportModel()..uri = model.sourceFile);
|
||||||
|
|
||||||
// Used to register reflective information.
|
// Used to register reflective information.
|
||||||
|
|
|
@ -95,7 +95,7 @@ class ParameterVisitor extends SimpleAstVisitor<ParameterModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the format in which a [ParameterModel] is expressed as Dart code
|
/// 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 {
|
abstract class ParameterWriterMixin {
|
||||||
StringBuffer get buffer;
|
StringBuffer get buffer;
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,7 @@ class _PropertyMetadataVisitor
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the format in which an [ReflectionInfoModel] is expressed as Dart
|
/// 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
|
abstract class ReflectionWriterMixin
|
||||||
implements AnnotationWriterMixin, ParameterWriterMixin {
|
implements AnnotationWriterMixin, ParameterWriterMixin {
|
||||||
StringBuffer get buffer;
|
StringBuffer get buffer;
|
||||||
|
|
|
@ -1,35 +1,51 @@
|
||||||
library angular2.transform.common.code.source_module;
|
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: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].
|
/// Writes the full Dart code for the provided [SourceModule].
|
||||||
String writeSourceModule(SourceModule sourceModule, {String libraryName}) {
|
String writeSourceModule(SourceModule sourceModule, {String libraryName}) {
|
||||||
if (sourceModule == null) return null;
|
if (sourceModule == null) return null;
|
||||||
var buf = new StringBuffer();
|
var buf = new StringBuffer();
|
||||||
|
final writer = new NgDepsWriter(buf);
|
||||||
var sourceWithImports = sourceModule.getSourceWithImports();
|
var sourceWithImports = sourceModule.getSourceWithImports();
|
||||||
libraryName = _sanitizeLibName(
|
libraryName = _sanitizeLibName(
|
||||||
libraryName != null ? libraryName : sourceModule.moduleUrl);
|
libraryName != null ? libraryName : sourceModule.moduleUrl);
|
||||||
buf..writeln('library $libraryName;')..writeln();
|
buf..writeln('library $libraryName;')..writeln();
|
||||||
sourceWithImports.imports.forEach((import) {
|
|
||||||
// Format for importLine := [uri, prefix]
|
extractImports(sourceWithImports, sourceModule.moduleUrl).forEach((import) {
|
||||||
if (import.length != 2) {
|
writer.writeImportModel(import);
|
||||||
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));
|
|
||||||
});
|
});
|
||||||
buf..writeln()..writeln(sourceWithImports.source);
|
buf..writeln()..writeln(sourceWithImports.source);
|
||||||
|
|
||||||
return buf.toString();
|
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_\.]');
|
final _unsafeCharsPattern = new RegExp(r'[^a-zA-Z0-9_\.]');
|
||||||
String _sanitizeLibName(String moduleUrl) {
|
String _sanitizeLibName(String moduleUrl) {
|
||||||
var sanitized =
|
var sanitized =
|
||||||
|
|
|
@ -122,7 +122,7 @@ const NgDepsModel$json = const {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated with:
|
* Generated with:
|
||||||
* ng_deps_model.proto (64702efcc1d7fb434f3652943ba051104960ffd5)
|
* ng_deps_model.proto (03511db92c8cfa3c1279d845be8fd7de36de3ee1)
|
||||||
* libprotoc 2.6.1
|
* libprotoc 2.6.1
|
||||||
* dart-protoc-plugin (af5fc2bf1de367a434c3b1847ab260510878ffc0)
|
* dart-protoc-plugin (af5fc2bf1de367a434c3b1847ab260510878ffc0)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,7 +33,7 @@ message NgDepsModel {
|
||||||
// framework.
|
// framework.
|
||||||
repeated string methods = 9;
|
repeated string methods = 9;
|
||||||
|
|
||||||
// Imports for the .ng_deps.dart files associated with the declared `imports`
|
// Imports of the generated files associated with the declared `imports`
|
||||||
// and `exports` for this file.
|
// and `exports` of the source file.
|
||||||
repeated ImportModel dep_imports = 10;
|
repeated ImportModel dep_imports = 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
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,
|
/// If `fromAbsolute` is specified, `importPath` may be a relative path,
|
||||||
/// otherwise it is expected to be absolute.
|
/// 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 urlResolver = const TransformerUrlResolver();
|
||||||
var codegenImportPath;
|
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) {
|
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)
|
// For a relative import, the scheme, first (package) and second (lib|test|web)
|
|
@ -8,7 +8,6 @@ const TRANSFORM_DYNAMIC_MODE = 'transform_dynamic';
|
||||||
const CSS_EXTENSION = '.css';
|
const CSS_EXTENSION = '.css';
|
||||||
const SHIMMED_STYLESHEET_EXTENSION = '.css.shim.dart';
|
const SHIMMED_STYLESHEET_EXTENSION = '.css.shim.dart';
|
||||||
const NON_SHIMMED_STYLESHEET_EXTENSION = '.css.dart';
|
const NON_SHIMMED_STYLESHEET_EXTENSION = '.css.dart';
|
||||||
const DEPS_EXTENSION = '.ng_deps.dart';
|
|
||||||
const META_EXTENSION = '.ng_meta.json';
|
const META_EXTENSION = '.ng_meta.json';
|
||||||
const REFLECTION_CAPABILITIES_NAME = 'ReflectionCapabilities';
|
const REFLECTION_CAPABILITIES_NAME = 'ReflectionCapabilities';
|
||||||
const REFLECTOR_IMPORT = 'package:angular2/src/core/reflection/reflection.dart';
|
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
|
/// important. For example, putting '.dart' first in this list will cause
|
||||||
/// incorrect behavior.
|
/// incorrect behavior.
|
||||||
const ALL_EXTENSIONS = const [
|
const ALL_EXTENSIONS = const [
|
||||||
DEPS_EXTENSION,
|
|
||||||
META_EXTENSION,
|
META_EXTENSION,
|
||||||
SUMMARY_META_EXTENSION,
|
SUMMARY_META_EXTENSION,
|
||||||
TEMPLATE_EXTENSION,
|
TEMPLATE_EXTENSION,
|
||||||
|
@ -38,7 +36,6 @@ const ALL_EXTENSIONS = const [
|
||||||
/// any files named like transformer outputs will be reported as generated.
|
/// any files named like transformer outputs will be reported as generated.
|
||||||
bool isGenerated(String uri) {
|
bool isGenerated(String uri) {
|
||||||
return const [
|
return const [
|
||||||
DEPS_EXTENSION,
|
|
||||||
META_EXTENSION,
|
META_EXTENSION,
|
||||||
NON_SHIMMED_STYLESHEET_EXTENSION,
|
NON_SHIMMED_STYLESHEET_EXTENSION,
|
||||||
SHIMMED_STYLESHEET_EXTENSION,
|
SHIMMED_STYLESHEET_EXTENSION,
|
||||||
|
@ -51,10 +48,6 @@ bool isGenerated(String uri) {
|
||||||
String toMetaExtension(String uri) =>
|
String toMetaExtension(String uri) =>
|
||||||
_toExtension(uri, ALL_EXTENSIONS, META_EXTENSION);
|
_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].
|
/// Returns `uri` with its extension updated to [TEMPLATES_EXTENSION].
|
||||||
String toTemplateExtension(String uri) =>
|
String toTemplateExtension(String uri) =>
|
||||||
_toExtension(uri, ALL_EXTENSIONS, TEMPLATE_EXTENSION);
|
_toExtension(uri, ALL_EXTENSIONS, TEMPLATE_EXTENSION);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import 'logging.dart';
|
||||||
import 'model/ng_deps_model.pb.dart';
|
import 'model/ng_deps_model.pb.dart';
|
||||||
import 'url_resolver.dart' show isDartCoreUri;
|
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:
|
/// [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
|
/// 2. Use the [NgDepsModel] to write Dart code registering all injectable
|
||||||
/// values with the Angular 2 runtime reflection system.
|
/// 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]
|
/// 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 together if they were imported into a file with the same prefix.
|
||||||
///
|
///
|
||||||
/// Instances of this class are serialized into `.ng_meta.json` files as
|
/// Instances of this class are serialized into `.ng_summary.json` and
|
||||||
/// intermediate assets to make the compilation process easier.
|
/// `.ng_meta.json` files as intermediate assets during the compilation process.
|
||||||
class NgMeta {
|
class NgMeta {
|
||||||
static const _ALIAS_VALUE = 'alias';
|
static const _ALIAS_VALUE = 'alias';
|
||||||
static const _KIND_KEY = 'kind';
|
static const _KIND_KEY = 'kind';
|
||||||
|
@ -58,7 +58,8 @@ class NgMeta {
|
||||||
bool get isNgDepsEmpty {
|
bool get isNgDepsEmpty {
|
||||||
if (ngDeps == null) return true;
|
if (ngDeps == null) return true;
|
||||||
// If this file imports only dart: libraries and does not define any
|
// 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.reflectables == null || ngDeps.reflectables.isEmpty) {
|
||||||
if ((ngDeps.imports == null || ngDeps.imports.every(_isDartImport)) &&
|
if ((ngDeps.imports == null || ngDeps.imports.every(_isDartImport)) &&
|
||||||
(ngDeps.exports == null || ngDeps.exports.every(_isDartImport))) {
|
(ngDeps.exports == null || ngDeps.exports.every(_isDartImport))) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Rewriter {
|
||||||
/// `_entryPoint`
|
/// `_entryPoint`
|
||||||
/// 2. Removes any libraries that don't require angular codegen.
|
/// 2. Removes any libraries that don't require angular codegen.
|
||||||
/// 3. For the remaining libraries, rewrites the import to the corresponding
|
/// 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
|
/// 4. Chains a future to the `loadLibrary` call which initializes the
|
||||||
/// library.
|
/// library.
|
||||||
///
|
///
|
||||||
|
@ -62,11 +62,12 @@ class Rewriter {
|
||||||
var buf = new StringBuffer();
|
var buf = new StringBuffer();
|
||||||
var idx =
|
var idx =
|
||||||
_visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
|
_visitor.deferredImports.fold(0, (int lastIdx, ImportDirective node) {
|
||||||
buf.write(code.substring(lastIdx, node.offset));
|
// Write from where we left off until the start of the import uri.
|
||||||
|
buf.write(code.substring(lastIdx, node.uri.offset));
|
||||||
var import = code.substring(node.offset, node.end);
|
// Rewrite the uri to be that of the generated file.
|
||||||
buf.write(import.replaceFirst('.dart', DEPS_EXTENSION));
|
buf.write("'${toTemplateExtension('${node.uri.stringValue}')}'");
|
||||||
return node.end;
|
// Update the last index we've processed.
|
||||||
|
return node.uri.end;
|
||||||
});
|
});
|
||||||
|
|
||||||
idx = _visitor.loadLibraryInvocations.fold(idx,
|
idx = _visitor.loadLibraryInvocations.fold(idx,
|
||||||
|
@ -86,7 +87,7 @@ class Rewriter {
|
||||||
|
|
||||||
/// Visitor responsible for finding the deferred libraries that need angular
|
/// Visitor responsible for finding the deferred libraries that need angular
|
||||||
/// codegen. Those are the libraries that are loaded deferred and have a
|
/// 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> {
|
class _FindDeferredLibraries extends Object with RecursiveAstVisitor<Object> {
|
||||||
var deferredImports = new List<ImportDirective>();
|
var deferredImports = new List<ImportDirective>();
|
||||||
var loadLibraryInvocations = new List<MethodInvocation>();
|
var loadLibraryInvocations = new List<MethodInvocation>();
|
||||||
|
@ -132,25 +133,26 @@ class _FindDeferredLibraries extends Object with RecursiveAstVisitor<Object> {
|
||||||
Future cull() async {
|
Future cull() async {
|
||||||
var baseUri = toAssetUri(_entryPoint);
|
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
|
var hasInputs = await Future.wait(deferredImports
|
||||||
.map((import) => stringLiteralToString(import.uri))
|
.map((import) => stringLiteralToString(import.uri))
|
||||||
.map((uri) => toMetaExtension(uri))
|
.map((uri) => toMetaExtension(uri))
|
||||||
.map((metaUri) => fromUri(_urlResolver.resolve(baseUri, metaUri)))
|
.map((metaUri) => fromUri(_urlResolver.resolve(baseUri, metaUri)))
|
||||||
.map((asset) => _reader.hasInput(asset)));
|
.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])
|
deferredImports = it.zip([deferredImports, hasInputs])
|
||||||
.where((importHasInput) => importHasInput[1])
|
.where((importHasInput) => importHasInput[1])
|
||||||
.map((importHasInput) => importHasInput[0])
|
.map((importHasInput) => importHasInput[0])
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// Find the set of prefixes which have ng_deps.
|
// Find the set of prefixes which have associated generated files.
|
||||||
var prefixes =
|
var prefixes =
|
||||||
new Set.from(deferredImports.map((import) => import.prefix.name));
|
new Set.from(deferredImports.map((import) => import.prefix.name));
|
||||||
|
|
||||||
// Filters out any load library invocations where the prefix is not a known
|
// 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) {
|
loadLibraryInvocations = loadLibraryInvocations.where((library) {
|
||||||
var value = library.realTarget as SimpleIdentifier;
|
var value = library.realTarget as SimpleIdentifier;
|
||||||
return prefixes.contains(value.name);
|
return prefixes.contains(value.name);
|
||||||
|
|
|
@ -12,12 +12,13 @@ import 'package:angular2/src/transform/common/url_resolver.dart';
|
||||||
import 'package:barback/barback.dart';
|
import 'package:barback/barback.dart';
|
||||||
|
|
||||||
/// Modifies the [NgDepsModel] represented by `entryPoint` to import its
|
/// 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
|
/// For example, if entry_point.dart imports dependency.dart, this will check if
|
||||||
/// will check if dependency.ng_meta.json exists. If it does, we add an entry
|
/// dependency.ng_meta.json exists. If it does, we add an entry to the
|
||||||
/// to the `depImports` of [NgDepsModel] for dependency.ng_deps.dart. We can
|
/// `depImports` of [NgDepsModel] for dependency.template.dart.
|
||||||
/// use this information later to ensure that each file's dependencies are
|
///
|
||||||
|
/// We use this information later to ensure that each file's dependencies are
|
||||||
/// initialized when that file is initialized.
|
/// initialized when that file is initialized.
|
||||||
Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
|
Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
|
||||||
AssetId assetId, UrlResolver resolver) async {
|
AssetId assetId, UrlResolver resolver) async {
|
||||||
|
@ -29,7 +30,6 @@ Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
|
||||||
if (linkedDepsMap.isEmpty) {
|
if (linkedDepsMap.isEmpty) {
|
||||||
// We are not calling `initReflector` on any other libraries, but we still
|
// We are not calling `initReflector` on any other libraries, but we still
|
||||||
// return the model to ensure it is written to code.
|
// return the model to ensure it is written to code.
|
||||||
// TODO(kegluneq): Continue using the protobuf format after this phase.
|
|
||||||
return ngDepsModel;
|
return ngDepsModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ Future<NgDepsModel> linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader,
|
||||||
if (linkedDepsMap.containsKey(dep.uri) && !seen.contains(dep.uri)) {
|
if (linkedDepsMap.containsKey(dep.uri) && !seen.contains(dep.uri)) {
|
||||||
seen.add(dep.uri);
|
seen.add(dep.uri);
|
||||||
var linkedModel = new ImportModel()
|
var linkedModel = new ImportModel()
|
||||||
..uri = toDepsExtension(dep.uri)
|
..uri = toTemplateExtension(dep.uri)
|
||||||
..prefix = 'i${idx++}';
|
..prefix = 'i${idx++}';
|
||||||
// TODO(kegluneq): Preserve combinators?
|
// TODO(kegluneq): Preserve combinators?
|
||||||
ngDepsModel.depImports.add(linkedModel);
|
ngDepsModel.depImports.add(linkedModel);
|
||||||
|
|
|
@ -20,8 +20,8 @@ import 'ng_meta_linker.dart';
|
||||||
/// Said another way, after this step there should be an entry in this `NgMeta`
|
/// Said another way, after this step there should be an entry in this `NgMeta`
|
||||||
/// object for all `Directives` visible from its associated `.dart` file.
|
/// 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`
|
/// This step also ensures that, if `a.dart` imports `b.dart`, `a.template.dart`
|
||||||
/// imports `b.ng_deps.dart` (if it exists) and we note that this is a
|
/// 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
|
/// ngDeps dependency, ensuring that a's `initReflector` function calls b's
|
||||||
/// `initReflector' function.
|
/// `initReflector' function.
|
||||||
///
|
///
|
||||||
|
|
|
@ -35,7 +35,7 @@ Future<String> inlineParts(AssetReader reader, AssetId assetId) async {
|
||||||
.accept(directivesVisitor);
|
.accept(directivesVisitor);
|
||||||
|
|
||||||
// If this is part of another library, its contents will be processed by its
|
// 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;
|
if (directivesVisitor.isPart) return null;
|
||||||
|
|
||||||
return logElapsedAsync(() {
|
return logElapsedAsync(() {
|
||||||
|
|
|
@ -22,8 +22,8 @@ class Codegen {
|
||||||
/// The code generated here should follow the example of code generated for
|
/// The code generated here should follow the example of code generated for
|
||||||
/// an {@link ImportDirective} node.
|
/// an {@link ImportDirective} node.
|
||||||
String codegenImport() {
|
String codegenImport() {
|
||||||
var importUri = path
|
var importUri = path.basename(
|
||||||
.basename(reflectionEntryPoint.changeExtension(DEPS_EXTENSION).path);
|
reflectionEntryPoint.changeExtension(TEMPLATE_EXTENSION).path);
|
||||||
return '''import '$importUri' as $prefix;''';
|
return '''import '$importUri' as $prefix;''';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@ import 'remove_reflection_capabilities.dart';
|
||||||
/// The goal of this is to break the app's dependency on dart:mirrors.
|
/// The goal of this is to break the app's dependency on dart:mirrors.
|
||||||
///
|
///
|
||||||
/// This transformer assumes that {@link DirectiveProcessor} and {@link DirectiveLinker}
|
/// 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
|
/// {@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 {
|
class ReflectionRemover extends Transformer implements LazyTransformer {
|
||||||
final TransformerOptions options;
|
final TransformerOptions options;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class Codegen {
|
||||||
|
|
||||||
/// Generates a change detector class with name `changeDetectorTypeName`,
|
/// Generates a change detector class with name `changeDetectorTypeName`,
|
||||||
/// which must not conflict with other generated classes in the same
|
/// 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`.
|
/// Objects of type `typeName`.
|
||||||
void generate(String typeName, String changeDetectorTypeName,
|
void generate(String typeName, String changeDetectorTypeName,
|
||||||
ChangeDetectorDefinition def) {
|
ChangeDetectorDefinition def) {
|
||||||
|
|
|
@ -184,8 +184,8 @@ class _CompileDataCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a map from import prefix to the asset: uris of all `.dart`
|
/// Creates a map from import prefix to the asset: uris of all `.dart`
|
||||||
/// libraries visible from `entryPoint`, excluding `dart:` and `.ng_deps.dart`
|
/// libraries visible from `entryPoint`, excluding `dart:` and generated files
|
||||||
/// files it imports. Unprefixed imports have the empty string as their key.
|
/// it imports. Unprefixed imports have the empty string as their key.
|
||||||
/// `entryPoint` is included in the map with no prefix.
|
/// `entryPoint` is included in the map with no prefix.
|
||||||
Map<String, Iterable<String>> _createPrefixToImportsMap() {
|
Map<String, Iterable<String>> _createPrefixToImportsMap() {
|
||||||
final baseUri = toAssetUri(entryPoint);
|
final baseUri = toAssetUri(entryPoint);
|
||||||
|
|
|
@ -3,16 +3,13 @@ library angular2.transform.template_compiler.generator;
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:barback/barback.dart';
|
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/core/change_detection/interfaces.dart';
|
||||||
import 'package:angular2/src/facade/lang.dart';
|
import 'package:angular2/src/facade/lang.dart';
|
||||||
import 'package:angular2/src/core/reflection/reflection.dart';
|
import 'package:angular2/src/core/reflection/reflection.dart';
|
||||||
import 'package:angular2/src/transform/common/asset_reader.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/logging.dart';
|
||||||
import 'package:angular2/src/transform/common/model/annotation_model.pb.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/model/ng_deps_model.pb.dart';
|
||||||
import 'package:angular2/src/transform/common/names.dart';
|
import 'package:angular2/src/transform/common/names.dart';
|
||||||
import 'package:angular2/src/transform/common/ng_compiler.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 'reflection/reflection_capabilities.dart';
|
||||||
import 'compile_data_creator.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`.
|
/// `createCompileData`.
|
||||||
/// Uses the resulting `NgMeta` object to generate
|
/// - Uses the resulting `NgMeta` object to register `getter`s, `setter`s, and
|
||||||
/// `getter`s, `setter`s, and `method`s that would otherwise need to be
|
/// `method`s that would otherwise need to be reflectively accessed with the
|
||||||
/// reflectively accessed.
|
/// `NgDeps` object.
|
||||||
/// Passes the resulting `NormalizedComponentWithViewDirectives` instances
|
/// - Passes the resulting `NormalizedComponentWithViewDirectives` instance(s)
|
||||||
/// to the `TemplateCompiler` to generate compiled template(s).
|
/// to the `TemplateCompiler` to generate compiled template(s) as a
|
||||||
/// Uses the resulting `NgDeps` object to generate a .ng_deps.dart file which
|
/// `SourceModule`.
|
||||||
/// initializes the Angular2 reflective system.
|
/// - Uses the resulting `NgDeps` object to generate code which initializes the
|
||||||
|
/// Angular2 reflective system.
|
||||||
///
|
///
|
||||||
/// This method assumes a {@link DomAdapter} has been registered.
|
/// This method assumes a {@link DomAdapter} has been registered.
|
||||||
Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
|
Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
|
||||||
|
@ -77,29 +75,26 @@ Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
|
||||||
reflector.reflectionCapabilities = savedReflectionCapabilities;
|
reflector.reflectionCapabilities = savedReflectionCapabilities;
|
||||||
|
|
||||||
if (compiledTemplates != null) {
|
if (compiledTemplates != null) {
|
||||||
viewDefResults.ngMeta.ngDeps.imports.add(new ImportModel()
|
// We successfully compiled templates!
|
||||||
..uri = toTemplateExtension(path.basename(assetId.path))
|
// For each compiled template, add the compiled template class as an
|
||||||
..prefix = '_templates');
|
// "Annotation" on the code to be registered with the reflector.
|
||||||
for (var reflectable in viewDefResults.viewDefinitions.keys) {
|
for (var reflectable in viewDefResults.viewDefinitions.keys) {
|
||||||
|
// TODO(kegluneq): Avoid duplicating naming logic for generated classes.
|
||||||
reflectable.annotations.add(new AnnotationModel()
|
reflectable.annotations.add(new AnnotationModel()
|
||||||
..name = '_templates.hostViewFactory_${reflectable.name}'
|
..name = 'hostViewFactory_${reflectable.name}'
|
||||||
..isConstObject = true);
|
..isConstObject = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Outputs._(
|
return new Outputs._(viewDefResults.ngMeta.ngDeps, compiledTemplates);
|
||||||
viewDefResults.ngMeta.ngDeps, writeSourceModule(compiledTemplates));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetId ngDepsAssetId(AssetId primaryId) =>
|
|
||||||
new AssetId(primaryId.package, toDepsExtension(primaryId.path));
|
|
||||||
|
|
||||||
AssetId templatesAssetId(AssetId primaryId) =>
|
AssetId templatesAssetId(AssetId primaryId) =>
|
||||||
new AssetId(primaryId.package, toTemplateExtension(primaryId.path));
|
new AssetId(primaryId.package, toTemplateExtension(primaryId.path));
|
||||||
|
|
||||||
class Outputs {
|
class Outputs {
|
||||||
final NgDepsModel ngDeps;
|
final NgDepsModel ngDeps;
|
||||||
final String templatesCode;
|
final SourceModule templatesSource;
|
||||||
|
|
||||||
Outputs._(this.ngDeps, this.templatesCode);
|
Outputs._(this.ngDeps, this.templatesSource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:barback/barback.dart';
|
||||||
import 'package:angular2/src/platform/server/html_adapter.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/asset_reader.dart';
|
||||||
import 'package:angular2/src/transform/common/code/ng_deps_code.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/formatter.dart';
|
||||||
import 'package:angular2/src/transform/common/names.dart';
|
import 'package:angular2/src/transform/common/names.dart';
|
||||||
import 'package:angular2/src/transform/common/options.dart';
|
import 'package:angular2/src/transform/common/options.dart';
|
||||||
|
@ -33,7 +34,6 @@ class TemplateCompiler extends Transformer implements LazyTransformer {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
declareOutputs(DeclaringTransform transform) {
|
declareOutputs(DeclaringTransform transform) {
|
||||||
transform.declareOutput(ngDepsAssetId(transform.primaryId));
|
|
||||||
transform.declareOutput(templatesAssetId(transform.primaryId));
|
transform.declareOutput(templatesAssetId(transform.primaryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,22 +49,23 @@ class TemplateCompiler extends Transformer implements LazyTransformer {
|
||||||
platformDirectives: options.platformDirectives,
|
platformDirectives: options.platformDirectives,
|
||||||
platformPipes: options.platformPipes);
|
platformPipes: options.platformPipes);
|
||||||
var ngDepsCode = _emptyNgDepsContents;
|
var ngDepsCode = _emptyNgDepsContents;
|
||||||
var templatesCode = '';
|
|
||||||
if (outputs != null) {
|
if (outputs != null) {
|
||||||
if (outputs.ngDeps != null) {
|
if (outputs.ngDeps != null) {
|
||||||
final buf = new StringBuffer();
|
final buf = new StringBuffer();
|
||||||
final writer = new NgDepsWriter(buf);
|
writeTemplateFile(
|
||||||
writer.writeNgDepsModel(outputs.ngDeps);
|
new NgDepsWriter(buf), outputs.ngDeps, outputs.templatesSource);
|
||||||
ngDepsCode = formatter.format(buf.toString());
|
ngDepsCode = formatter.format(buf.toString());
|
||||||
}
|
|
||||||
if (outputs.templatesCode != null) {
|
if (primaryId.path.endsWith('index.ng_meta.json')) {
|
||||||
templatesCode = formatter.format(outputs.templatesCode);
|
final buf2 = new StringBuffer();
|
||||||
|
var writer = new NgDepsWriter(buf2);
|
||||||
|
outputs.ngDeps.imports.forEach(writer.writeImportModel);
|
||||||
|
print(buf2.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transform.addOutput(
|
transform.addOutput(
|
||||||
new Asset.fromString(ngDepsAssetId(primaryId), ngDepsCode));
|
new Asset.fromString(templatesAssetId(primaryId), ngDepsCode));
|
||||||
transform.addOutput(
|
|
||||||
new Asset.fromString(templatesAssetId(primaryId), templatesCode));
|
|
||||||
}, log: transform.logger);
|
}, log: transform.logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue