2015-02-18 12:51:12 -08:00
|
|
|
library angular2.src.transform;
|
2015-02-17 08:38:54 -08:00
|
|
|
|
|
|
|
import 'dart:async';
|
2015-02-19 12:00:09 -08:00
|
|
|
import 'package:analyzer/src/generated/ast.dart';
|
|
|
|
import 'package:analyzer/src/generated/element.dart';
|
2015-02-17 08:38:54 -08:00
|
|
|
import 'package:barback/barback.dart';
|
|
|
|
import 'package:code_transformers/resolver.dart';
|
|
|
|
|
|
|
|
import 'annotation_processor.dart';
|
|
|
|
import 'codegen.dart' as codegen;
|
2015-02-19 12:00:09 -08:00
|
|
|
import 'find_bootstrap.dart';
|
2015-02-20 15:16:59 -08:00
|
|
|
import 'find_reflection_capabilities.dart';
|
2015-02-19 12:00:09 -08:00
|
|
|
import 'logging.dart' as log;
|
2015-02-17 08:38:54 -08:00
|
|
|
import 'options.dart';
|
|
|
|
import 'resolvers.dart';
|
|
|
|
import 'traversal.dart';
|
|
|
|
|
|
|
|
export 'options.dart';
|
|
|
|
|
|
|
|
/// Removes the mirror-based initialization logic and replaces it with static
|
|
|
|
/// logic.
|
|
|
|
class AngularTransformer extends Transformer {
|
|
|
|
final Resolvers _resolvers;
|
|
|
|
final TransformerOptions options;
|
|
|
|
|
|
|
|
AngularTransformer(this.options) : _resolvers = createResolvers();
|
|
|
|
|
|
|
|
factory AngularTransformer.asPlugin(BarbackSettings settings) {
|
2015-02-20 15:16:59 -08:00
|
|
|
var config = settings.configuration;
|
2015-02-19 12:00:09 -08:00
|
|
|
return new AngularTransformer(new TransformerOptions(
|
2015-02-20 15:16:59 -08:00
|
|
|
config[entryPointParam],
|
|
|
|
reflectionEntryPoint: config[reflectionEntryPointParam],
|
|
|
|
newEntryPoint: config[newEntryPointParam]));
|
2015-02-17 08:38:54 -08:00
|
|
|
}
|
|
|
|
|
2015-02-20 15:16:59 -08:00
|
|
|
bool isPrimary(AssetId id) => options.reflectionEntryPoint == id.path;
|
2015-02-17 08:38:54 -08:00
|
|
|
|
|
|
|
Future apply(Transform transform) {
|
2015-02-19 12:00:09 -08:00
|
|
|
log.init(transform);
|
|
|
|
|
2015-02-20 15:16:59 -08:00
|
|
|
var entryPointId =
|
|
|
|
new AssetId(transform.primaryInput.id.package, options.entryPoint);
|
|
|
|
var reflectionEntryPointId = new AssetId(
|
|
|
|
transform.primaryInput.id.package, options.reflectionEntryPoint);
|
2015-02-17 08:38:54 -08:00
|
|
|
var newEntryPointId =
|
|
|
|
new AssetId(transform.primaryInput.id.package, options.newEntryPoint);
|
2015-02-20 15:16:59 -08:00
|
|
|
|
|
|
|
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]) {
|
2015-02-19 12:00:09 -08:00
|
|
|
log.logger
|
2015-02-17 08:38:54 -08:00
|
|
|
.error('New entry point file $newEntryPointId already exists.');
|
|
|
|
} else {
|
2015-02-20 15:16:59 -08:00
|
|
|
return _resolvers
|
|
|
|
.get(transform, [entryPointId, reflectionEntryPointId])
|
|
|
|
.then((resolver) {
|
|
|
|
myResolver = resolver;
|
2015-02-18 12:51:12 -08:00
|
|
|
try {
|
2015-02-20 15:16:59 -08:00
|
|
|
String reflectionCapabilitiesCreation = findReflectionCapabilities(
|
|
|
|
resolver, reflectionEntryPointId, newEntryPointId);
|
|
|
|
|
|
|
|
transform.addOutput(new Asset.fromString(
|
|
|
|
reflectionEntryPointId, reflectionCapabilitiesCreation));
|
|
|
|
// Find the call to `new ReflectionCapabilities()`
|
|
|
|
// Generate new source.
|
2015-02-19 12:00:09 -08:00
|
|
|
} catch (err, stackTrace) {
|
|
|
|
log.logger.error('${err}: ${stackTrace}',
|
2015-02-20 15:16:59 -08:00
|
|
|
asset: reflectionEntryPointId);
|
|
|
|
rethrow;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
new _BootstrapFileBuilder(
|
|
|
|
resolver, transform, entryPointId, newEntryPointId).run();
|
|
|
|
} catch (err, stackTrace) {
|
|
|
|
log.logger.error('${err}: ${stackTrace}',
|
|
|
|
asset: transform.primaryInput.id);
|
2015-02-19 12:00:09 -08:00
|
|
|
rethrow;
|
2015-02-18 12:51:12 -08:00
|
|
|
}
|
2015-02-17 08:38:54 -08:00
|
|
|
});
|
|
|
|
}
|
2015-02-20 15:16:59 -08:00
|
|
|
}).whenComplete(() {
|
|
|
|
if (myResolver != null) {
|
|
|
|
myResolver.release();
|
|
|
|
}
|
2015-02-17 08:38:54 -08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _BootstrapFileBuilder {
|
|
|
|
final Resolver _resolver;
|
|
|
|
final Transform _transform;
|
|
|
|
final AssetId _entryPoint;
|
|
|
|
final AssetId _newEntryPoint;
|
|
|
|
|
|
|
|
_BootstrapFileBuilder(Resolver resolver, Transform transform,
|
2015-02-20 15:16:59 -08:00
|
|
|
this._entryPoint, this._newEntryPoint)
|
2015-02-17 08:38:54 -08:00
|
|
|
: _resolver = resolver,
|
2015-02-19 12:00:09 -08:00
|
|
|
_transform = transform;
|
2015-02-17 08:38:54 -08:00
|
|
|
|
|
|
|
/// Adds the new entry point file to the transform. Should only be ran once.
|
|
|
|
void run() {
|
2015-02-20 15:16:59 -08:00
|
|
|
Set<BootstrapCallInfo> bootstrapCalls =
|
|
|
|
findBootstrapCalls(_resolver, _resolver.getLibrary(_entryPoint));
|
2015-02-19 12:00:09 -08:00
|
|
|
|
|
|
|
log.logger.info('found ${bootstrapCalls.length} call(s) to `bootstrap`');
|
|
|
|
bootstrapCalls.forEach((BootstrapCallInfo info) {
|
|
|
|
log.logger.info('Arg1: ${info.bootstrapType}');
|
|
|
|
});
|
|
|
|
|
|
|
|
var types = new Angular2Types(_resolver);
|
|
|
|
// TODO(kegluneq): Also match [Inject].
|
2015-02-23 17:38:34 -08:00
|
|
|
var matcher = new AnnotationMatcher(
|
|
|
|
new Set.from([types.directiveAnnotation, types.templateAnnotation]));
|
2015-02-19 12:00:09 -08:00
|
|
|
|
|
|
|
var traversal = new AngularVisibleTraversal(types, matcher);
|
|
|
|
bootstrapCalls.forEach((call) => traversal.traverse(call.bootstrapType));
|
2015-02-17 08:38:54 -08:00
|
|
|
|
2015-02-23 17:38:34 -08:00
|
|
|
var context = new codegen.Context();
|
2015-02-19 12:00:09 -08:00
|
|
|
matcher.matchQueue
|
2015-02-17 08:38:54 -08:00
|
|
|
.forEach((entry) => context.directiveRegistry.register(entry));
|
|
|
|
|
2015-02-20 15:16:59 -08:00
|
|
|
_transform.addOutput(new Asset.fromString(_newEntryPoint,
|
|
|
|
codegen.codegenEntryPoint(context, newEntryPoint: _newEntryPoint)));
|
2015-02-17 08:38:54 -08:00
|
|
|
}
|
|
|
|
}
|