perf(dart/transform) Restructure transform to independent phases
Update summary: - Removes the need for resolution, gaining transform speed at the cost of some precision and ability to detect errors - Generates type registrations in the package alongside their declarations - Ensures that line numbers do not change in transformed user code
This commit is contained in:
56
modules/angular2/src/transform/directive_linker/linker.dart
Normal file
56
modules/angular2/src/transform/directive_linker/linker.dart
Normal file
@ -0,0 +1,56 @@
|
||||
library angular2.src.transform.directive_linker.linker;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:angular2/src/transform/common/logging.dart';
|
||||
import 'package:angular2/src/transform/common/names.dart';
|
||||
import 'package:angular2/src/transform/common/ngdata.dart';
|
||||
import 'package:barback/barback.dart';
|
||||
import 'package:code_transformers/assets.dart';
|
||||
import 'package:dart_style/dart_style.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
Future<String> linkNgDeps(Transform transform, String code, String path) async {
|
||||
var commentIdx = code.lastIndexOf('//');
|
||||
if (commentIdx < 0) return code;
|
||||
|
||||
var ngData = new NgData.fromJson(code.substring(commentIdx + 2));
|
||||
|
||||
StringBuffer importBuf =
|
||||
new StringBuffer(code.substring(0, ngData.importOffset));
|
||||
StringBuffer declarationBuf = new StringBuffer(
|
||||
code.substring(ngData.importOffset, ngData.registerOffset));
|
||||
String tail = code.substring(ngData.registerOffset, commentIdx);
|
||||
|
||||
var ngDeps = await _processNgImports(transform, ngData.imports);
|
||||
|
||||
for (var i = 0; i < ngDeps.length; ++i) {
|
||||
importBuf.write('import \'${ngDeps[i]}\' as i${i};');
|
||||
declarationBuf.write('i${i}.${SETUP_METHOD_NAME}(${REFLECTOR_VAR_NAME});');
|
||||
}
|
||||
|
||||
return '${importBuf}${declarationBuf}${tail}';
|
||||
}
|
||||
|
||||
String _toDepsUri(String importUri) =>
|
||||
'${path.withoutExtension(importUri)}${DEPS_EXTENSION}';
|
||||
|
||||
bool _isNotDartImport(String importUri) {
|
||||
return !importUri.startsWith('dart:');
|
||||
}
|
||||
|
||||
Future<List<String>> _processNgImports(
|
||||
Transform transform, List<String> imports) async {
|
||||
var retVal = <String>[];
|
||||
|
||||
return Future
|
||||
.wait(imports.where(_isNotDartImport).map(_toDepsUri).map((ngDepsUri) {
|
||||
var importAsset = uriToAssetId(
|
||||
transform.primaryInput.id, ngDepsUri, logger, null /* span */);
|
||||
return transform.hasInput(importAsset).then((hasInput) {
|
||||
if (hasInput) {
|
||||
retVal.add(ngDepsUri);
|
||||
}
|
||||
});
|
||||
})).then((_) => retVal);
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
library angular2.src.transform.directive_linker.transformer;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:angular2/src/transform/common/formatter.dart';
|
||||
import 'package:angular2/src/transform/common/logging.dart' as log;
|
||||
import 'package:angular2/src/transform/common/names.dart';
|
||||
import 'package:angular2/src/transform/common/options.dart';
|
||||
import 'package:barback/barback.dart';
|
||||
|
||||
import 'linker.dart';
|
||||
|
||||
/// Transformer responsible for processing .ngDeps.dart files created by
|
||||
/// [DirectiveProcessor] and ensuring that the generated calls to
|
||||
/// `setupReflection` call the necessary `setupReflection` method in all
|
||||
/// dependencies.
|
||||
class DirectiveLinker extends Transformer {
|
||||
final TransformerOptions options;
|
||||
|
||||
DirectiveLinker(this.options);
|
||||
|
||||
@override
|
||||
bool isPrimary(AssetId id) => id.path.endsWith(DEPS_EXTENSION);
|
||||
|
||||
@override
|
||||
Future apply(Transform transform) async {
|
||||
log.init(transform);
|
||||
|
||||
try {
|
||||
var assetCode = await transform.primaryInput.readAsString();
|
||||
var assetPath = transform.primaryInput.id.path;
|
||||
var transformedCode = await linkNgDeps(transform, assetCode, assetPath);
|
||||
var formattedCode = formatter.format(transformedCode, uri: assetPath);
|
||||
transform.addOutput(
|
||||
new Asset.fromString(transform.primaryInput.id, formattedCode));
|
||||
} catch (ex, stackTrace) {
|
||||
log.logger.error('Linking ng directives failed.\n'
|
||||
'Exception: $ex\n'
|
||||
'Stack Trace: $stackTrace');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user