refactor(dart/transform): Fix potential import collision
Previously, importing a library twice using different prefixes could cause the template compiler step to incorrect omit `Directive` dependencies provided by that library.
This commit is contained in:
parent
26044026c9
commit
d69bd021ee
@ -7,7 +7,6 @@ import 'package:angular2/src/core/compiler/directive_metadata.dart';
|
|||||||
import 'package:angular2/src/core/compiler/template_compiler.dart';
|
import 'package:angular2/src/core/compiler/template_compiler.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/logging.dart';
|
import 'package:angular2/src/transform/common/logging.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/model/reflection_info_model.pb.dart';
|
import 'package:angular2/src/transform/common/model/reflection_info_model.pb.dart';
|
||||||
import 'package:angular2/src/transform/common/names.dart';
|
import 'package:angular2/src/transform/common/names.dart';
|
||||||
@ -32,10 +31,8 @@ class CompileDataResults {
|
|||||||
final NgMeta ngMeta;
|
final NgMeta ngMeta;
|
||||||
final Map<ReflectionInfoModel,
|
final Map<ReflectionInfoModel,
|
||||||
NormalizedComponentWithViewDirectives> viewDefinitions;
|
NormalizedComponentWithViewDirectives> viewDefinitions;
|
||||||
final List<CompileDirectiveMetadata> directiveMetadatas;
|
|
||||||
|
|
||||||
CompileDataResults._(
|
CompileDataResults._(this.ngMeta, this.viewDefinitions);
|
||||||
this.ngMeta, this.viewDefinitions, this.directiveMetadatas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates [ViewDefinition] objects for all `View` `Directive`s defined in
|
/// Creates [ViewDefinition] objects for all `View` `Directive`s defined in
|
||||||
@ -44,7 +41,6 @@ class _CompileDataCreator {
|
|||||||
final AssetReader reader;
|
final AssetReader reader;
|
||||||
final AssetId entryPoint;
|
final AssetId entryPoint;
|
||||||
final NgMeta ngMeta;
|
final NgMeta ngMeta;
|
||||||
final directiveMetadatas = <CompileDirectiveMetadata>[];
|
|
||||||
|
|
||||||
_CompileDataCreator(this.reader, this.entryPoint, this.ngMeta);
|
_CompileDataCreator(this.reader, this.entryPoint, this.ngMeta);
|
||||||
|
|
||||||
@ -62,7 +58,7 @@ class _CompileDataCreator {
|
|||||||
|
|
||||||
Future<CompileDataResults> createCompileData() async {
|
Future<CompileDataResults> createCompileData() async {
|
||||||
if (ngDeps == null || ngDeps.reflectables == null) {
|
if (ngDeps == null || ngDeps.reflectables == null) {
|
||||||
return new CompileDataResults._(ngMeta, const {}, directiveMetadatas);
|
return new CompileDataResults._(ngMeta, const {});
|
||||||
}
|
}
|
||||||
|
|
||||||
final compileData =
|
final compileData =
|
||||||
@ -100,30 +96,30 @@ class _CompileDataCreator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new CompileDataResults._(ngMeta, compileData, directiveMetadatas);
|
return new CompileDataResults._(ngMeta, compileData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a map from [AssetId] to import prefix for `.dart` libraries
|
/// Creates a map from import prefix to the asset: uris of all `.dart`
|
||||||
/// imported by `entryPoint`, excluding any `.ng_deps.dart` files it imports.
|
/// libraries visible from `entryPoint`, excluding `dart:` and `.ng_deps.dart`
|
||||||
/// Unprefixed imports have `null` as their value. `entryPoint` is included
|
/// files it imports. Unprefixed imports have the empty string as their key.
|
||||||
/// in the map with no prefix.
|
/// `entryPoint` is included in the map with no prefix.
|
||||||
Future<Map<AssetId, String>> _createImportAssetToPrefixMap() async {
|
Map<String, Iterable<String>> _createPrefixToImportsMap() {
|
||||||
final importAssetToPrefix = <AssetId, String>{entryPoint: null};
|
|
||||||
if (ngDeps == null || ngDeps.imports == null || ngDeps.imports.isEmpty) {
|
|
||||||
return importAssetToPrefix;
|
|
||||||
}
|
|
||||||
final baseUri = toAssetUri(entryPoint);
|
final baseUri = toAssetUri(entryPoint);
|
||||||
|
final map = <String, Set<String>>{'': new Set<String>()..add(baseUri)};
|
||||||
|
if (ngDeps == null || ngDeps.imports == null || ngDeps.imports.isEmpty) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
final resolver = const TransformerUrlResolver();
|
final resolver = const TransformerUrlResolver();
|
||||||
|
|
||||||
for (ImportModel model in ngMeta.ngDeps.imports) {
|
ngMeta.ngDeps.imports
|
||||||
if (model.uri.endsWith('.dart') && !model.isNgDeps) {
|
.where((model) => !model.isNgDeps && !isDartCoreUri(model.uri))
|
||||||
var prefix =
|
.forEach((model) {
|
||||||
model.prefix != null && model.prefix.isEmpty ? null : model.prefix;
|
var prefix = model.prefix == null ? '' : model.prefix;
|
||||||
importAssetToPrefix[fromUri(resolver.resolve(baseUri, model.uri))] =
|
map
|
||||||
prefix;
|
.putIfAbsent(prefix, () => new Set<String>())
|
||||||
}
|
.add(resolver.resolve(baseUri, model.uri));
|
||||||
}
|
});
|
||||||
return importAssetToPrefix;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the `.ng_meta.json` files associated with all of `entryPoint`'s
|
/// Reads the `.ng_meta.json` files associated with all of `entryPoint`'s
|
||||||
@ -155,29 +151,24 @@ class _CompileDataCreator {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
Future<Map<String, NgMeta>> _extractNgMeta() async {
|
Future<Map<String, NgMeta>> _extractNgMeta() async {
|
||||||
var importAssetToPrefix = await _createImportAssetToPrefixMap();
|
var prefixToImports = _createPrefixToImportsMap();
|
||||||
|
|
||||||
var retVal = <String, NgMeta>{};
|
final retVal = <String, NgMeta>{};
|
||||||
for (var importAssetId in importAssetToPrefix.keys) {
|
for (var prefix in prefixToImports.keys) {
|
||||||
var prefix = importAssetToPrefix[importAssetId];
|
var ngMeta = retVal[prefix] = new NgMeta.empty();
|
||||||
if (prefix == null) prefix = '';
|
for (var importAssetUri in prefixToImports[prefix]) {
|
||||||
var ngMeta = retVal.putIfAbsent(prefix, () => new NgMeta.empty());
|
var metaAssetId = fromUri(toMetaExtension(importAssetUri));
|
||||||
var metaAssetId = new AssetId(
|
if (await reader.hasInput(metaAssetId)) {
|
||||||
importAssetId.package, toMetaExtension(importAssetId.path));
|
try {
|
||||||
if (await reader.hasInput(metaAssetId)) {
|
var jsonString = await reader.readAsString(metaAssetId);
|
||||||
try {
|
if (jsonString != null && jsonString.isNotEmpty) {
|
||||||
var jsonString = await reader.readAsString(metaAssetId);
|
var newMetadata = new NgMeta.fromJson(JSON.decode(jsonString));
|
||||||
if (jsonString != null && jsonString.isNotEmpty) {
|
ngMeta.addAll(newMetadata);
|
||||||
var json = JSON.decode(jsonString);
|
|
||||||
var newMetadata = new NgMeta.fromJson(json);
|
|
||||||
if (importAssetId == entryPoint) {
|
|
||||||
this.directiveMetadatas.addAll(newMetadata.types.values);
|
|
||||||
}
|
}
|
||||||
ngMeta.addAll(newMetadata);
|
} catch (ex, stackTrace) {
|
||||||
|
logger.warning('Failed to decode: $ex, $stackTrace',
|
||||||
|
asset: metaAssetId);
|
||||||
}
|
}
|
||||||
} catch (ex, stackTrace) {
|
|
||||||
logger.warning('Failed to decode: $ex, $stackTrace',
|
|
||||||
asset: metaAssetId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,10 @@ import 'compile_data_creator.dart';
|
|||||||
Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
|
Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
|
||||||
{bool reflectPropertiesAsAttributes: false}) async {
|
{bool reflectPropertiesAsAttributes: false}) async {
|
||||||
var viewDefResults = await createCompileData(reader, assetId);
|
var viewDefResults = await createCompileData(reader, assetId);
|
||||||
if (viewDefResults.directiveMetadatas.isNotEmpty) {
|
final directiveMetadatas = viewDefResults.ngMeta.types.values;
|
||||||
|
if (directiveMetadatas.isNotEmpty) {
|
||||||
var processor = new reg.Processor();
|
var processor = new reg.Processor();
|
||||||
viewDefResults.directiveMetadatas.forEach(processor.process);
|
directiveMetadatas.forEach(processor.process);
|
||||||
viewDefResults.ngMeta.ngDeps.getters
|
viewDefResults.ngMeta.ngDeps.getters
|
||||||
.addAll(processor.getterNames.map((e) => e.sanitizedName));
|
.addAll(processor.getterNames.map((e) => e.sanitizedName));
|
||||||
viewDefResults.ngMeta.ngDeps.setters
|
viewDefResults.ngMeta.ngDeps.setters
|
||||||
|
Loading…
x
Reference in New Issue
Block a user