feat(dart/transform): Generate DirectiveMetadata for exports

For all files that export another library, include `DirectiveMetadata`
for the exported library in that file's associated `ng_meta.json` file.
This commit is contained in:
Tim Blasi
2015-05-06 10:00:25 -07:00
parent 6651aa1e1d
commit c8ebd11d63
14 changed files with 260 additions and 62 deletions

View File

@ -2,20 +2,59 @@ library angular2.transform.directive_metadata_extractor.extractor;
import 'dart:async';
import 'package:analyzer/analyzer.dart';
import 'package:angular2/src/render/api.dart';
import 'package:angular2/src/transform/common/asset_reader.dart';
import 'package:angular2/src/transform/common/directive_metadata_reader.dart';
import 'package:angular2/src/transform/common/logging.dart';
import 'package:angular2/src/transform/common/names.dart';
import 'package:angular2/src/transform/common/parser.dart';
import 'package:barback/barback.dart';
import 'package:code_transformers/assets.dart';
/// Returns a map from a class name (that is, its `Identifier` stringified)
/// to its [DirectiveMetadata].
/// Will return `null` if there are no `Directive`-annotated classes in
/// to [DirectiveMetadata] for all `Directive`-annotated classes visible
/// in a file importing `entryPoint`. That is, this includes all
/// `Directive` annotated classes in `entryPoint` and any assets which it
/// `export`s.
/// Returns `null` if there are no `Directive`-annotated classes in
/// `entryPoint`.
Future<Map<String, DirectiveMetadata>> extractDirectiveMetadata(
AssetReader reader, AssetId entryPoint) async {
var parser = new Parser(reader);
NgDeps ngDeps = await parser.parse(entryPoint);
return _extractDirectiveMetadataRecursive(
reader, new Parser(reader), entryPoint);
}
var _nullFuture = new Future.value(null);
Future<Map<String, DirectiveMetadata>> _extractDirectiveMetadataRecursive(
AssetReader reader, Parser parser, AssetId entryPoint) async {
if (!(await reader.hasInput(entryPoint))) return null;
var ngDeps = await parser.parse(entryPoint);
var baseMap = _metadataMapFromNgDeps(ngDeps);
return Future.wait(ngDeps.exports.map((export) {
var uri = stringLiteralToString(export.uri);
if (uri.startsWith('dart:')) return _nullFuture;
uri = toDepsExtension(uri);
var assetId = uriToAssetId(entryPoint, uri, logger, null /* span */);
if (assetId == entryPoint) return _nullFuture;
return _extractDirectiveMetadataRecursive(reader, parser, assetId)
.then((exportMap) {
if (exportMap != null) {
if (baseMap == null) {
baseMap = exportMap;
} else {
baseMap.addAll(exportMap);
}
}
});
})).then((_) => baseMap);
}
Map<String, DirectiveMetadata> _metadataMapFromNgDeps(NgDeps ngDeps) {
if (ngDeps == null || ngDeps.registeredTypes.isEmpty) return null;
var retVal = <String, DirectiveMetadata>{};
ngDeps.registeredTypes.forEach((rType) {

View File

@ -36,7 +36,7 @@ class DirectiveMetadataExtractor extends Transformer {
jsonMap[k] = directiveMetadataToMap(v);
});
transform.addOutput(new Asset.fromString(
_outputAssetId(fromAssetId), '// ${JSON.encode(jsonMap)}'));
_outputAssetId(fromAssetId), JSON.encode(jsonMap)));
}
} catch (ex, stackTrace) {
log.logger.error('Extracting ng metadata failed.\n'
@ -49,8 +49,5 @@ class DirectiveMetadataExtractor extends Transformer {
AssetId _outputAssetId(AssetId inputAssetId) {
assert(inputAssetId.path.endsWith(DEPS_EXTENSION));
var pathIn = inputAssetId.path;
return new AssetId(inputAssetId.package,
'${pathIn.substring(0, pathIn.length - DEPS_EXTENSION.length)}'
'${META_EXTENSION}');
return new AssetId(inputAssetId.package, toMetaExtension(inputAssetId.path));
}