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

@ -40,7 +40,7 @@ class _DirectiveMetadataVisitor extends Object
}
meta = new DirectiveMetadata(
type: directiveType,
compileChildren: false,
compileChildren: true,
properties: {},
hostListeners: {},
hostProperties: {},

View File

@ -8,7 +8,7 @@ DartFormatter _formatter = null;
void init(DartFormatter formatter) {
if (_formatter != null) {
logger.warning('Formatter is being overwritten.');
logger.info('Formatter is being overwritten.');
}
_formatter = formatter;
}

View File

@ -4,9 +4,32 @@ const SETUP_METHOD_NAME = 'initReflector';
const REFLECTOR_VAR_NAME = 'reflector';
const TRANSFORM_DYNAMIC_MODE = 'transform_dynamic';
const DEPS_EXTENSION = '.ng_deps.dart';
const META_EXTENSION = '.ng_meta.dart';
const META_EXTENSION = '.ng_meta.json';
const REFLECTION_CAPABILITIES_NAME = 'ReflectionCapabilities';
const REGISTER_TYPE_METHOD_NAME = 'registerType';
const REGISTER_GETTERS_METHOD_NAME = 'registerGetters';
const REGISTER_SETTERS_METHOD_NAME = 'registerSetters';
const REGISTER_METHODS_METHOD_NAME = 'registerMethods';
/// Returns `uri` with its extension updated to [META_EXTENSION].
String toMetaExtension(String uri) =>
_toExtension(uri, const [DEPS_EXTENSION, '.dart'], META_EXTENSION);
/// Returns `uri` with its extension updated to [DEPS_EXTENSION].
String toDepsExtension(String uri) =>
_toExtension(uri, const [META_EXTENSION, '.dart'], DEPS_EXTENSION);
/// Returns `uri` with its extension updated to `toExtension` if its
/// extension is currently in `fromExtension`.
String _toExtension(
String uri, Iterable<String> fromExtensions, String toExtension) {
if (uri == null) return null;
if (uri.endsWith(toExtension)) return uri;
for (var extension in fromExtensions) {
if (uri.endsWith(extension)) {
return '${uri.substring(0, uri.length-extension.length)}'
'$toExtension';
}
}
return uri;
}

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));
}