feat(dart/transform) Remove import of dart:mirrors
+ Precede the call to `new ReflectionCapabilities()` with our generated code which populates the reflection map statically. + Add the import of our generated code. + Once we are generating all necessary code, we will remove the import of reflection_capabilities.dart and the instantiation of `ReflectionCapabilities`, cutting the dependency on dart:mirrors. Closes #761
This commit is contained in:
parent
fad25c2b10
commit
3b6aaf9054
|
@ -54,7 +54,7 @@ class AnnotationMatcher {
|
|||
}
|
||||
}
|
||||
|
||||
/// [ConstructorElement] / [ElementAnnotation] pair, where the Constructor
|
||||
/// [ClassElement] / [ElementAnnotation] pair.
|
||||
class AnnotationMatch {
|
||||
/// The resolved element corresponding to [node].
|
||||
final ClassElement element;
|
||||
|
|
|
@ -60,6 +60,12 @@ abstract class DirectiveRegistry {
|
|||
void register(AnnotationMatch entry);
|
||||
}
|
||||
|
||||
const setupReflectionMethodName = 'setupReflection';
|
||||
|
||||
const _libraryDeclaration = '''
|
||||
library angular2.src.transform.generated;
|
||||
''';
|
||||
|
||||
const _reflectorImport = '''
|
||||
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||
''';
|
||||
|
@ -70,18 +76,17 @@ AssetId _assetIdFromLibraryElement(LibraryElement el) {
|
|||
return (el.source as dynamic).assetId;
|
||||
}
|
||||
|
||||
String codegenEntryPoint(Context context,
|
||||
{LibraryElement entryPoint, AssetId newEntryPoint}) {
|
||||
// This must be called prior to [codegenImports] or the entry point
|
||||
// library will not be imported.
|
||||
var entryPointPrefix = context._getPrefixDot(entryPoint);
|
||||
String codegenEntryPoint(Context context, {AssetId newEntryPoint}) {
|
||||
if (newEntryPoint == null) {
|
||||
throw new ArgumentError.notNull('newEntryPoint');
|
||||
}
|
||||
// TODO(jakemac): copyright and library declaration
|
||||
var outBuffer = new StringBuffer(_reflectorImport);
|
||||
var outBuffer = new StringBuffer()
|
||||
..write(_libraryDeclaration)
|
||||
..write(_reflectorImport);
|
||||
_codegenImports(context, newEntryPoint, outBuffer);
|
||||
outBuffer
|
||||
..write('main() {')
|
||||
..write(context.directiveRegistry.toString())
|
||||
..write('${entryPointPrefix}main();}');
|
||||
.write('${setupReflectionMethodName}() {${context.directiveRegistry}}');
|
||||
|
||||
return new DartFormatter().format(outBuffer.toString());
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
library angular2.src.transform;
|
||||
|
||||
import 'package:analyzer/src/generated/ast.dart';
|
||||
import 'package:analyzer/src/generated/element.dart';
|
||||
import 'package:code_transformers/resolver.dart';
|
||||
|
@ -60,8 +62,8 @@ class _ParseBootstrapTypeVisitor extends SimpleAstVisitor<Object> {
|
|||
// TODO(kegluneq): Allow non-SimpleIdentifier expressions.
|
||||
|
||||
@override
|
||||
Object visitSimpleIdentifier(SimpleIdentifier e) {
|
||||
bootstrapType = (e.bestElement as ClassElement);
|
||||
Object visitSimpleIdentifier(SimpleIdentifier node) {
|
||||
bootstrapType = (node.bestElement as ClassElement);
|
||||
if (!_types.isComponent(bootstrapType)) {
|
||||
throw new ArgumentError('Class passed to `${bootstrapMethodName}` must '
|
||||
'be a @${_types.componentAnnotation.name}');
|
||||
|
@ -71,7 +73,7 @@ class _ParseBootstrapTypeVisitor extends SimpleAstVisitor<Object> {
|
|||
|
||||
/// Recursively visits all nodes in an Ast structure, recording all encountered
|
||||
/// calls to the provided [FunctionElement].
|
||||
class _FindFunctionVisitor extends UnifyingAstVisitor<Object> {
|
||||
class _FindFunctionVisitor extends RecursiveAstVisitor<Object> {
|
||||
final FunctionElement _target;
|
||||
_FindFunctionVisitor(this._target);
|
||||
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
library angular2.src.transform;
|
||||
|
||||
import 'package:analyzer/src/generated/ast.dart';
|
||||
import 'package:analyzer/src/generated/element.dart';
|
||||
import 'package:analyzer/src/generated/java_core.dart';
|
||||
import 'package:barback/barback.dart';
|
||||
import 'package:code_transformers/resolver.dart';
|
||||
import 'package:dart_style/dart_style.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'codegen.dart';
|
||||
import 'logging.dart';
|
||||
import 'resolvers.dart';
|
||||
|
||||
/// Finds all calls to the Angular2 [ReflectionCapabilities] constructor
|
||||
/// defined in [library].
|
||||
/// This only searches the code defined in the file
|
||||
// represented by [library], not `part`s, `import`s, `export`s, etc.
|
||||
String findReflectionCapabilities(
|
||||
Resolver resolver, AssetId reflectionEntryPoint, AssetId newEntryPoint) {
|
||||
var types = new Angular2Types(resolver);
|
||||
if (types.reflectionCapabilities == null) {
|
||||
throw new ArgumentError(
|
||||
'Could not find class for ${reflectionCapabilitiesTypeName}.');
|
||||
}
|
||||
|
||||
var codegen = new _SetupReflectionCodegen(
|
||||
resolver, reflectionEntryPoint, newEntryPoint);
|
||||
|
||||
var writer = new PrintStringWriter();
|
||||
var visitor = new _RewriteReflectionEntryPointVisitor(
|
||||
writer, types.reflectionCapabilities, codegen);
|
||||
|
||||
// TODO(kegluneq): Determine how to get nodes without querying Element#node.
|
||||
// Root of file defining that library (main part).
|
||||
resolver.getLibrary(reflectionEntryPoint).definingCompilationUnit.node
|
||||
.accept(visitor);
|
||||
|
||||
return new DartFormatter().format(writer.toString());
|
||||
}
|
||||
|
||||
class _SetupReflectionCodegen {
|
||||
static const _prefixBase = 'ngStaticInit';
|
||||
|
||||
final String prefix;
|
||||
final String importUri;
|
||||
|
||||
_SetupReflectionCodegen._internal(this.prefix, this.importUri);
|
||||
|
||||
factory _SetupReflectionCodegen(
|
||||
Resolver resolver, AssetId reflectionEntryPoint, AssetId newEntryPoint) {
|
||||
var lib = resolver.getLibrary(reflectionEntryPoint);
|
||||
var prefix = _prefixBase;
|
||||
var idx = 0;
|
||||
while (lib.imports.any((import) {
|
||||
return import.prefix != null && import.prefix == prefix;
|
||||
})) {
|
||||
prefix = '${_prefixBase}${idx++}';
|
||||
}
|
||||
|
||||
var importPath = path.relative(newEntryPoint.path,
|
||||
from: path.dirname(reflectionEntryPoint.path));
|
||||
return new _SetupReflectionCodegen._internal(prefix, importPath);
|
||||
}
|
||||
|
||||
/// Generates code to import the library containing the method which sets up
|
||||
/// Angular2 reflection statically.
|
||||
///
|
||||
/// The code generated here should follow the example of code generated for
|
||||
/// an [ImportDirective] node.
|
||||
String codegenImport() {
|
||||
return 'import \'${importUri}\' as ${prefix};';
|
||||
}
|
||||
|
||||
/// Generates code to call the method which sets up Angular2 reflection
|
||||
/// statically.
|
||||
///
|
||||
/// The code generated here should follow the example of code generated for
|
||||
/// a [MethodInvocation] node, that is, it should be prefixed as necessary
|
||||
/// and not be followed by a ';'.
|
||||
String codegenSetupReflectionCall() {
|
||||
return '${prefix}.${setupReflectionMethodName}()';
|
||||
}
|
||||
}
|
||||
|
||||
class _RewriteReflectionEntryPointVisitor extends ToSourceVisitor {
|
||||
final PrintWriter _writer;
|
||||
final ClassElement _forbiddenClass;
|
||||
final _SetupReflectionCodegen _codegen;
|
||||
|
||||
_RewriteReflectionEntryPointVisitor(
|
||||
PrintWriter writer, this._forbiddenClass, this._codegen)
|
||||
: _writer = writer,
|
||||
super(writer);
|
||||
|
||||
bool _isNewReflectionCapabilities(InstanceCreationExpression node) {
|
||||
var typeElement = node.constructorName.type.name.bestElement;
|
||||
return typeElement != null && typeElement == _forbiddenClass;
|
||||
}
|
||||
|
||||
bool _isReflectionCapabilitiesImport(ImportDirective node) {
|
||||
return node.uriElement == _forbiddenClass.library;
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitImportDirective(ImportDirective node) {
|
||||
if (_isReflectionCapabilitiesImport(node)) {
|
||||
// TODO(kegluneq): Remove newlines once dart_style bug is fixed.
|
||||
// https://github.com/dart-lang/dart_style/issues/178
|
||||
// _writer.print('\n/* ReflectionCapabilities import removed */\n');
|
||||
_writer.print(_codegen.codegenImport());
|
||||
// TODO(kegluneq): Remove once we generate all needed code.
|
||||
{
|
||||
super.visitImportDirective(node);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return super.visitImportDirective(node);
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitAssignmentExpression(AssignmentExpression node) {
|
||||
if (node.rightHandSide is InstanceCreationExpression &&
|
||||
_isNewReflectionCapabilities(node.rightHandSide)) {
|
||||
// TODO(kegluneq): Remove newlines once dart_style bug is fixed.
|
||||
// https://github.com/dart-lang/dart_style/issues/178
|
||||
// _writer.print('/* Creation of ReflectionCapabilities removed */\n');
|
||||
_writer.print(_codegen.codegenSetupReflectionCall());
|
||||
|
||||
// TODO(kegluneq): Remove once we generate all needed code.
|
||||
{
|
||||
_writer.print(';');
|
||||
node.leftHandSide.accept(this);
|
||||
_writer.print(' ${node.operator.lexeme} ');
|
||||
super.visitInstanceCreationExpression(node.rightHandSide);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return super.visitAssignmentExpression(node);
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
|
||||
if (_isNewReflectionCapabilities(node)) {
|
||||
logger.error('Unexpected format in creation of '
|
||||
'${reflectionCapabilitiesTypeName}');
|
||||
} else {
|
||||
return super.visitInstanceCreationExpression(node);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
library angular2.src.transform;
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:barback/barback.dart';
|
||||
import 'package:html5lib/dom.dart' as dom;
|
||||
import 'package:html5lib/parser.dart' show parse;
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'options.dart';
|
||||
|
||||
Future transformHtmlEntryPoint(
|
||||
TransformerOptions options, Transform transform) {
|
||||
// For now at least, [options.htmlEntryPoint], [options.entryPoint], and
|
||||
// [options.newEntryPoint] need to be in the same folder.
|
||||
// TODO(jakemac): support package urls with [options.entryPoint] or
|
||||
// [options.newEntryPoint] in `lib`, and [options.htmlEntryPoint] in another
|
||||
// directory.
|
||||
var _expectedDir = path.split(options.htmlEntryPoint)[0];
|
||||
if (!options.inSameTopLevelDir()) {
|
||||
transform.logger.error(
|
||||
'${options.htmlEntryPointParam}, ${options.entryPointParam}, and '
|
||||
'${options.newEntryPointParam} (if supplied) all must be in the '
|
||||
'same top level directory.');
|
||||
}
|
||||
|
||||
// The relative path from [options.htmlEntryPoint] to [dartEntry]. You must
|
||||
// ensure that neither of these is null before calling this function.
|
||||
String _relativeDartEntryPath(String dartEntry) =>
|
||||
path.relative(dartEntry, from: path.dirname(options.htmlEntryPoint));
|
||||
|
||||
// Checks if the src of this script tag is pointing at `options.entryPoint`.
|
||||
bool _isEntryPointScript(dom.Element script) =>
|
||||
path.normalize(script.attributes['src']) ==
|
||||
_relativeDartEntryPath(options.entryPoint);
|
||||
|
||||
return transform.primaryInput.readAsString().then((String html) {
|
||||
var found = false;
|
||||
var doc = parse(html);
|
||||
var scripts = doc.querySelectorAll('script[type="application/dart"]');
|
||||
for (dom.Element script in scripts) {
|
||||
if (!_isEntryPointScript(script)) continue;
|
||||
script.attributes['src'] = _relativeDartEntryPath(options.newEntryPoint);
|
||||
found = true;
|
||||
}
|
||||
if (!found) {
|
||||
transform.logger.error('Unable to find script for ${options.entryPoint} '
|
||||
'in ${options.htmlEntryPoint}.');
|
||||
}
|
||||
return transform.addOutput(
|
||||
new Asset.fromString(transform.primaryInput.id, doc.outerHtml));
|
||||
});
|
||||
}
|
|
@ -1,28 +1,41 @@
|
|||
library angular2.src.transform;
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
const entryPointParam = 'entry_point';
|
||||
const reflectionEntryPointParam = 'reflection_entry_point';
|
||||
const newEntryPointParam = 'new_entry_point';
|
||||
|
||||
/// Provides information necessary to transform an Angular2 app.
|
||||
class TransformerOptions {
|
||||
/// The file where the application's call to [bootstrap] is.
|
||||
// TODO(kegluenq): Allow multiple bootstrap entry points.
|
||||
final String bootstrapEntryPoint;
|
||||
|
||||
/// The Dart entry point, that is, where the initial call to [main] occurs.
|
||||
// TODO(kegluneq): Allow multiple entry points.
|
||||
final String entryPoint;
|
||||
|
||||
/// The reflection entry point, that is, where the
|
||||
/// application's [ReflectionCapabilities] are set.
|
||||
final String reflectionEntryPoint;
|
||||
|
||||
/// The path where we should generate code.
|
||||
final String newEntryPoint;
|
||||
|
||||
/// The html file that includes [entryPoint].
|
||||
final String htmlEntryPoint;
|
||||
TransformerOptions._internal(
|
||||
this.entryPoint, this.reflectionEntryPoint, this.newEntryPoint);
|
||||
|
||||
TransformerOptions(this.bootstrapEntryPoint, this.entryPoint,
|
||||
this.newEntryPoint, this.htmlEntryPoint);
|
||||
|
||||
bool inSameTopLevelDir() {
|
||||
var expectedDir = path.split(htmlEntryPoint)[0];
|
||||
return (expectedDir == path.split(entryPoint)[0] &&
|
||||
expectedDir == path.split(newEntryPoint)[0]);
|
||||
factory TransformerOptions(String entryPoint,
|
||||
{String reflectionEntryPoint, String newEntryPoint}) {
|
||||
if (entryPoint == null || entryPoint.isEmpty) {
|
||||
throw new ArgumentError.notNull(entryPointParam);
|
||||
}
|
||||
if (reflectionEntryPoint == null || entryPoint.isEmpty) {
|
||||
reflectionEntryPoint = entryPoint;
|
||||
}
|
||||
if (newEntryPoint == null || newEntryPoint.isEmpty) {
|
||||
newEntryPoint =
|
||||
reflectionEntryPoint.replaceFirst('.dart', '.bootstrap.dart');
|
||||
if (newEntryPoint == reflectionEntryPoint) {
|
||||
newEntryPoint = 'bootstrap.${newEntryPoint}';
|
||||
}
|
||||
}
|
||||
return new TransformerOptions._internal(
|
||||
entryPoint, reflectionEntryPoint, newEntryPoint);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ Resolvers createResolvers() {
|
|||
}
|
||||
|
||||
const bootstrapMethodName = 'bootstrap';
|
||||
const reflectionCapabilitiesTypeName = 'ReflectionCapabilities';
|
||||
|
||||
/// Provides resolved [Elements] for well-known Angular2 symbols.
|
||||
class Angular2Types {
|
||||
|
@ -57,6 +58,8 @@ class Angular2Types {
|
|||
new AssetId('angular2', 'lib/src/core/application.dart');
|
||||
static final _templateLibAssetId =
|
||||
new AssetId('angular2', 'lib/src/core/annotations/template.dart');
|
||||
static final _reflectionCapabilitiesLibAssetId = new AssetId(
|
||||
'angular2', 'lib/src/reflection/reflection_capabilities.dart');
|
||||
|
||||
final Resolver _resolver;
|
||||
FunctionElement _bootstrapMethod;
|
||||
|
@ -84,6 +87,12 @@ class Angular2Types {
|
|||
|
||||
ClassElement get templateAnnotation => _getTypeSafe(templateLib, 'Template');
|
||||
|
||||
LibraryElement get reflectionCapabilitiesLib =>
|
||||
_resolver.getLibrary(_reflectionCapabilitiesLibAssetId);
|
||||
|
||||
ClassElement get reflectionCapabilities =>
|
||||
_getTypeSafe(reflectionCapabilitiesLib, reflectionCapabilitiesTypeName);
|
||||
|
||||
LibraryElement get applicationLib =>
|
||||
_resolver.getLibrary(_applicationLibAssetId);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:code_transformers/resolver.dart';
|
|||
import 'annotation_processor.dart';
|
||||
import 'codegen.dart' as codegen;
|
||||
import 'find_bootstrap.dart';
|
||||
import 'html_transform.dart';
|
||||
import 'find_reflection_capabilities.dart';
|
||||
import 'logging.dart' as log;
|
||||
import 'options.dart';
|
||||
import 'resolvers.dart';
|
||||
|
@ -25,61 +25,72 @@ class AngularTransformer extends Transformer {
|
|||
|
||||
AngularTransformer(this.options) : _resolvers = createResolvers();
|
||||
|
||||
static const _bootstrapEntryPointParam = 'bootstrap_entry_point';
|
||||
static const _entryPointParam = 'entry_point';
|
||||
static const _newEntryPointParam = 'new_entry_point';
|
||||
static const _htmlEntryPointParam = 'html_entry_point';
|
||||
|
||||
factory AngularTransformer.asPlugin(BarbackSettings settings) {
|
||||
var bootstrapEntryPoint = settings.configuration[_bootstrapEntryPointParam];
|
||||
var entryPoint = settings.configuration[_entryPointParam];
|
||||
var newEntryPoint = settings.configuration[_newEntryPointParam];
|
||||
if (newEntryPoint == null) {
|
||||
newEntryPoint = entryPoint.replaceFirst('.dart', '.bootstrap.dart');
|
||||
}
|
||||
var htmlEntryPoint = settings.configuration[_htmlEntryPointParam];
|
||||
var config = settings.configuration;
|
||||
return new AngularTransformer(new TransformerOptions(
|
||||
bootstrapEntryPoint, entryPoint, newEntryPoint, htmlEntryPoint));
|
||||
config[entryPointParam],
|
||||
reflectionEntryPoint: config[reflectionEntryPointParam],
|
||||
newEntryPoint: config[newEntryPointParam]));
|
||||
}
|
||||
|
||||
bool isPrimary(AssetId id) =>
|
||||
options.entryPoint == id.path || options.htmlEntryPoint == id.path;
|
||||
bool isPrimary(AssetId id) => options.reflectionEntryPoint == id.path;
|
||||
|
||||
Future apply(Transform transform) {
|
||||
log.init(transform);
|
||||
|
||||
if (transform.primaryInput.id.path == options.entryPoint) {
|
||||
return _buildBootstrapFile(transform);
|
||||
} else if (transform.primaryInput.id.path == options.htmlEntryPoint) {
|
||||
return transformHtmlEntryPoint(options, transform);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future _buildBootstrapFile(Transform transform) {
|
||||
var bootstrapEntryPointId = new AssetId(
|
||||
transform.primaryInput.id.package, options.bootstrapEntryPoint);
|
||||
var entryPointId =
|
||||
new AssetId(transform.primaryInput.id.package, options.entryPoint);
|
||||
var reflectionEntryPointId = new AssetId(
|
||||
transform.primaryInput.id.package, options.reflectionEntryPoint);
|
||||
var newEntryPointId =
|
||||
new AssetId(transform.primaryInput.id.package, options.newEntryPoint);
|
||||
return transform.hasInput(newEntryPointId).then((exists) {
|
||||
if (exists) {
|
||||
|
||||
var reflectionExists = transform.hasInput(reflectionEntryPointId);
|
||||
var newEntryPointExists = transform.hasInput(newEntryPointId);
|
||||
|
||||
Resolver myResolver;
|
||||
return Future
|
||||
.wait([reflectionExists, newEntryPointExists])
|
||||
.then((existsList) {
|
||||
if (!existsList[0]) {
|
||||
log.logger.error('Reflection entry point file '
|
||||
'${reflectionEntryPointId} does not exist.');
|
||||
} else if (existsList[1]) {
|
||||
log.logger
|
||||
.error('New entry point file $newEntryPointId already exists.');
|
||||
} else {
|
||||
return _resolvers.get(transform).then((resolver) {
|
||||
return _resolvers
|
||||
.get(transform, [entryPointId, reflectionEntryPointId])
|
||||
.then((resolver) {
|
||||
myResolver = resolver;
|
||||
try {
|
||||
new _BootstrapFileBuilder(resolver, transform,
|
||||
transform.primaryInput.id, bootstrapEntryPointId,
|
||||
newEntryPointId).run();
|
||||
String reflectionCapabilitiesCreation = findReflectionCapabilities(
|
||||
resolver, reflectionEntryPointId, newEntryPointId);
|
||||
|
||||
transform.addOutput(new Asset.fromString(
|
||||
reflectionEntryPointId, reflectionCapabilitiesCreation));
|
||||
// Find the call to `new ReflectionCapabilities()`
|
||||
// Generate new source.
|
||||
} catch (err, stackTrace) {
|
||||
log.logger.error('${err}: ${stackTrace}',
|
||||
asset: bootstrapEntryPointId);
|
||||
asset: reflectionEntryPointId);
|
||||
rethrow;
|
||||
}
|
||||
|
||||
try {
|
||||
new _BootstrapFileBuilder(
|
||||
resolver, transform, entryPointId, newEntryPointId).run();
|
||||
} catch (err, stackTrace) {
|
||||
log.logger.error('${err}: ${stackTrace}',
|
||||
asset: transform.primaryInput.id);
|
||||
rethrow;
|
||||
} finally {
|
||||
resolver.release();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).whenComplete(() {
|
||||
if (myResolver != null) {
|
||||
myResolver.release();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -87,21 +98,18 @@ class AngularTransformer extends Transformer {
|
|||
class _BootstrapFileBuilder {
|
||||
final Resolver _resolver;
|
||||
final Transform _transform;
|
||||
final AssetId _bootstrapEntryPoint;
|
||||
final AssetId _entryPoint;
|
||||
final AssetId _newEntryPoint;
|
||||
|
||||
_BootstrapFileBuilder(Resolver resolver, Transform transform,
|
||||
this._entryPoint, this._bootstrapEntryPoint, this._newEntryPoint)
|
||||
this._entryPoint, this._newEntryPoint)
|
||||
: _resolver = resolver,
|
||||
_transform = transform;
|
||||
|
||||
/// Adds the new entry point file to the transform. Should only be ran once.
|
||||
void run() {
|
||||
var entryLib = _resolver.getLibrary(_entryPoint);
|
||||
|
||||
Set<BootstrapCallInfo> bootstrapCalls = findBootstrapCalls(
|
||||
_resolver, _resolver.getLibrary(_bootstrapEntryPoint));
|
||||
Set<BootstrapCallInfo> bootstrapCalls =
|
||||
findBootstrapCalls(_resolver, _resolver.getLibrary(_entryPoint));
|
||||
|
||||
log.logger.info('found ${bootstrapCalls.length} call(s) to `bootstrap`');
|
||||
bootstrapCalls.forEach((BootstrapCallInfo info) {
|
||||
|
@ -123,8 +131,7 @@ class _BootstrapFileBuilder {
|
|||
matcher.matchQueue
|
||||
.forEach((entry) => context.directiveRegistry.register(entry));
|
||||
|
||||
_transform.addOutput(new Asset.fromString(_newEntryPoint, codegen
|
||||
.codegenEntryPoint(context,
|
||||
entryPoint: entryLib, newEntryPoint: _newEntryPoint)));
|
||||
_transform.addOutput(new Asset.fromString(_newEntryPoint,
|
||||
codegen.codegenEntryPoint(context, newEntryPoint: _newEntryPoint)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<html><head></head><body>
|
||||
<script type="application/dart" src="index.dart"></script>
|
||||
</body></html>
|
|
@ -1,3 +0,0 @@
|
|||
<html><head></head><body>
|
||||
<script type="application/dart" src="index.bootstrap.dart"></script>
|
||||
</body></html>
|
|
@ -1,6 +0,0 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/annotations/annotations.dart';
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
|
||||
void main() {}
|
|
@ -1,10 +1,11 @@
|
|||
library angular2.src.transform.generated;
|
||||
|
||||
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||
import 'bar.dart' as i0;
|
||||
import 'foo.dart' as i1;
|
||||
import 'package:angular2/src/core/annotations/annotations.dart' as i2;
|
||||
import 'index.dart' as i3;
|
||||
|
||||
main() {
|
||||
setupReflection() {
|
||||
reflector
|
||||
..registerType(i0.MyComponent, {
|
||||
"factory": (i1.MyContext c) => new i0.MyComponent(c),
|
||||
|
@ -13,5 +14,4 @@ main() {
|
|||
const i2.Component(componentServices: const [i1.MyContext])
|
||||
]
|
||||
});
|
||||
i3.main();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
import 'package:angular2/src/reflection/reflection_capabilities.dart';
|
||||
import 'bar.dart';
|
||||
|
||||
void main() {
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
bootstrap(MyComponent);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
library angular2.test.transform;
|
||||
|
||||
/// Mocked out version of [ReflectionCapabilities], defined in
|
||||
/// src/reflection/reflection_capabilities.dart. Importing the actual file in
|
||||
/// tests causes issues with resolution due to transitive dependencies.
|
||||
class ReflectionCapabilities {}
|
|
@ -1,14 +1,14 @@
|
|||
library angular2.src.transform.generated;
|
||||
|
||||
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||
import 'bar.dart' as i0;
|
||||
import 'package:angular2/src/core/annotations/annotations.dart' as i1;
|
||||
import 'index.dart' as i2;
|
||||
|
||||
main() {
|
||||
setupReflection() {
|
||||
reflector
|
||||
..registerType(i0.MyComponent, {
|
||||
"factory": () => new i0.MyComponent(),
|
||||
"parameters": const [const []],
|
||||
"annotations": const [const i1.Component(selector: '[soup]')]
|
||||
});
|
||||
i2.main();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
import 'package:angular2/src/reflection/reflection.dart';
|
||||
import 'index.bootstrap.dart' as ngStaticInit;
|
||||
import 'package:angular2/src/reflection/reflection_capabilities.dart';
|
||||
import 'bar.dart';
|
||||
|
||||
void main() {
|
||||
ngStaticInit.setupReflection();
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
bootstrap(MyComponent);
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
import 'package:angular2/src/reflection/reflection.dart';
|
||||
import 'package:angular2/src/reflection/reflection_capabilities.dart';
|
||||
import 'bar.dart';
|
||||
|
||||
void main() {
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
bootstrap(MyComponent);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
library angular2.src.transform.generated;
|
||||
|
||||
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||
import 'bar.dart' as i0;
|
||||
import 'package:angular2/src/core/annotations/annotations.dart' as i1;
|
||||
import 'index.dart' as i2;
|
||||
|
||||
main() {
|
||||
setupReflection() {
|
||||
reflector
|
||||
..registerType(i0.MyComponent, {
|
||||
"factory": () => new i0.MyComponent(),
|
||||
"parameters": const [const []],
|
||||
"annotations": const [const i1.Component(selector: '[soup]')]
|
||||
});
|
||||
i2.main();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
import 'package:angular2/src/reflection/reflection_capabilities.dart';
|
||||
import 'bar.dart';
|
||||
|
||||
void main() {
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
bootstrap(MyComponent);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ main() {
|
|||
|
||||
var formatter = new DartFormatter();
|
||||
var transform = new AngularTransformer(new TransformerOptions('web/index.dart',
|
||||
'web/index.dart', 'web/index.bootstrap.dart', 'web/index.html'));
|
||||
reflectionEntryPoint: 'web/index.dart',
|
||||
newEntryPoint: 'web/index.bootstrap.dart'));
|
||||
|
||||
class TestConfig {
|
||||
final String name;
|
||||
|
@ -32,42 +33,37 @@ class TestConfig {
|
|||
}
|
||||
|
||||
void _runTests() {
|
||||
// Each test has its own directory for inputs & an `expected` directory for
|
||||
// expected outputs.
|
||||
/*
|
||||
* Each test has its own directory for inputs & an `expected` directory for
|
||||
* expected outputs.
|
||||
*
|
||||
* In addition to these declared inputs, we inject a set of common inputs for
|
||||
* every test.
|
||||
*/
|
||||
var commonInputs = {
|
||||
'angular2|lib/src/core/annotations/annotations.dart':
|
||||
'../../lib/src/core/annotations/annotations.dart',
|
||||
'angular2|lib/src/core/application.dart': 'common.dart',
|
||||
'angular2|lib/src/reflection/reflection_capabilities.dart':
|
||||
'reflection_capabilities.dart'
|
||||
};
|
||||
|
||||
var tests = [
|
||||
new TestConfig('Html entry point',
|
||||
inputs: {
|
||||
'a|web/index.html': 'common.html',
|
||||
'a|web/index.dart': 'html_entry_point_files/index.dart',
|
||||
'angular2|lib/src/core/annotations/annotations.dart':
|
||||
'../../lib/src/core/annotations/annotations.dart',
|
||||
'angular2|lib/src/core/application.dart': 'common.dart'
|
||||
},
|
||||
outputs: {
|
||||
'a|web/index.html': 'html_entry_point_files/expected/index.html'
|
||||
}),
|
||||
new TestConfig('Simple',
|
||||
inputs: {
|
||||
'a|web/index.html': 'common.html',
|
||||
'a|web/index.dart': 'simple_annotation_files/index.dart',
|
||||
'a|web/bar.dart': 'simple_annotation_files/bar.dart',
|
||||
'angular2|lib/src/core/annotations/annotations.dart':
|
||||
'../../lib/src/core/annotations/annotations.dart',
|
||||
'angular2|lib/src/core/application.dart': 'common.dart'
|
||||
'a|web/bar.dart': 'simple_annotation_files/bar.dart'
|
||||
},
|
||||
outputs: {
|
||||
'a|web/index.bootstrap.dart':
|
||||
'simple_annotation_files/expected/index.bootstrap.dart'
|
||||
'simple_annotation_files/expected/index.bootstrap.dart',
|
||||
'a|web/index.dart': 'simple_annotation_files/expected/index.dart',
|
||||
}),
|
||||
new TestConfig('Two injected dependencies',
|
||||
inputs: {
|
||||
'a|web/index.html': 'common.html',
|
||||
'a|web/index.dart': 'two_deps_files/index.dart',
|
||||
'a|web/foo.dart': 'two_deps_files/foo.dart',
|
||||
'a|web/bar.dart': 'two_deps_files/bar.dart',
|
||||
'angular2|lib/src/core/annotations/annotations.dart':
|
||||
'../../lib/src/core/annotations/annotations.dart',
|
||||
'angular2|lib/src/core/application.dart': 'common.dart'
|
||||
'a|web/bar.dart': 'two_deps_files/bar.dart'
|
||||
},
|
||||
outputs: {
|
||||
'a|web/index.bootstrap.dart':
|
||||
|
@ -75,7 +71,6 @@ void _runTests() {
|
|||
}),
|
||||
new TestConfig('List of types',
|
||||
inputs: {
|
||||
'a|web/index.html': 'common.html',
|
||||
'a|web/index.dart': 'list_of_types_files/index.dart',
|
||||
'a|web/foo.dart': 'list_of_types_files/foo.dart',
|
||||
'a|web/bar.dart': 'list_of_types_files/bar.dart',
|
||||
|
@ -89,7 +84,6 @@ void _runTests() {
|
|||
}),
|
||||
new TestConfig('Component with synthetic Constructor',
|
||||
inputs: {
|
||||
'a|web/index.html': 'common.html',
|
||||
'a|web/index.dart': 'synthetic_ctor_files/index.dart',
|
||||
'a|web/bar.dart': 'synthetic_ctor_files/bar.dart',
|
||||
'angular2|lib/src/core/annotations/annotations.dart':
|
||||
|
@ -102,7 +96,6 @@ void _runTests() {
|
|||
}),
|
||||
new TestConfig('Component with two annotations',
|
||||
inputs: {
|
||||
'a|web/index.html': 'common.html',
|
||||
'a|web/index.dart': 'two_annotations_files/index.dart',
|
||||
'a|web/bar.dart': 'two_annotations_files/bar.dart',
|
||||
'angular2|lib/src/core/annotations/annotations.dart':
|
||||
|
@ -114,17 +107,20 @@ void _runTests() {
|
|||
outputs: {
|
||||
'a|web/index.bootstrap.dart':
|
||||
'two_annotations_files/expected/index.bootstrap.dart'
|
||||
}),
|
||||
})
|
||||
];
|
||||
|
||||
var cache = {};
|
||||
|
||||
for (var config in tests) {
|
||||
|
||||
// Read in input & output files.
|
||||
config.assetPathToInputPath.forEach((key, value) {
|
||||
config.assetPathToInputPath[key] =
|
||||
cache.putIfAbsent(value, () => new File('test/transform/${value}').readAsStringSync());
|
||||
});
|
||||
config.assetPathToInputPath
|
||||
..addAll(commonInputs)
|
||||
..forEach((key, value) {
|
||||
config.assetPathToInputPath[key] = cache.putIfAbsent(value,
|
||||
() => new File('test/transform/${value}').readAsStringSync());
|
||||
});
|
||||
config.assetPathToExpectedOutputPath.forEach((key, value) {
|
||||
config.assetPathToExpectedOutputPath[key] = cache.putIfAbsent(value, () {
|
||||
var code = new File('test/transform/${value}').readAsStringSync();
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
library angular2.src.transform.generated;
|
||||
|
||||
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||
import 'bar.dart' as i0;
|
||||
import 'package:angular2/src/core/annotations/annotations.dart' as i1;
|
||||
import 'package:angular2/src/core/annotations/template.dart' as i2;
|
||||
import 'index.dart' as i3;
|
||||
|
||||
main() {
|
||||
setupReflection() {
|
||||
reflector
|
||||
..registerType(i0.MyComponent, {
|
||||
"factory": () => new i0.MyComponent(),
|
||||
|
@ -14,5 +15,4 @@ main() {
|
|||
const i2.Template(inline: 'Salad')
|
||||
]
|
||||
});
|
||||
i3.main();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
import 'package:angular2/src/reflection/reflection_capabilities.dart';
|
||||
import 'bar.dart';
|
||||
|
||||
void main() {
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
bootstrap(MyComponent);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
library angular2.src.transform.generated;
|
||||
|
||||
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||
import 'bar.dart' as i0;
|
||||
import 'foo.dart' as i1;
|
||||
import 'package:angular2/src/core/annotations/annotations.dart' as i2;
|
||||
import 'index.dart' as i3;
|
||||
|
||||
main() {
|
||||
setupReflection() {
|
||||
reflector
|
||||
..registerType(i0.MyComponent, {
|
||||
"factory":
|
||||
|
@ -12,5 +13,4 @@ main() {
|
|||
"parameters": const [const [i1.MyContext, String]],
|
||||
"annotations": const [const i2.Component(selector: i1.preDefinedSelector)]
|
||||
});
|
||||
i3.main();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
library web_foo;
|
||||
|
||||
import 'package:angular2/src/core/application.dart';
|
||||
import 'package:angular2/src/reflection/reflection_capabilities.dart';
|
||||
import 'bar.dart';
|
||||
|
||||
void main() {
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
bootstrap(MyComponent);
|
||||
}
|
||||
|
|
|
@ -11,9 +11,8 @@ dev_dependencies:
|
|||
path: ../benchpress
|
||||
transformers:
|
||||
- angular2:
|
||||
bootstrap_entry_point: web/src/hello_world/index_common.dart
|
||||
entry_point: web/src/hello_world/index.dart
|
||||
html_entry_point: web/src/hello_world/index.html
|
||||
entry_point: web/src/hello_world/index_common.dart
|
||||
reflection_entry_point: web/src/hello_world/index.dart
|
||||
- $dart2js:
|
||||
minify: true
|
||||
commandLineOptions: [--trust-type-annotations, --trust-primitives, --dump-info]
|
||||
|
|
Loading…
Reference in New Issue