refactor(LifecycleEvent): remove LifecycleEvent

fixes #3924

BREAKING CHANGE

The `lifecycle` configuration for directive has been dropped.

Before

    // Dart
    @Component({lifecycle: const [LifecycleEvent.OnChanges], ...})
    class MyComponent implements OnChanges {
      void onChanges() {...}
    }

    // Typescript
    @Component({lifecycle: [LifecycleEvent.OnChanges], ...})
    class MyComponent implements OnChanges {
      onChanges(): void {...}
    }

    // ES5
    var MyComponent = ng.
    Component({lifecycle: [LifecycleEvent.OnChanges], ...}).
    Class({
      onChanges: function() {...}
    });

After

    // Dart
    @Component({...})
    class MyComponent implements OnChanges {
      void onChanges() {...}
    }

    // Typescript
    @Component({...})
    class MyComponent implements OnChanges {
      onChanges(): void {...}
    }

    // ES5
    var MyComponent = ng
      .Component({...})
      .Class({
        onChanges: function() {
        }
      });
This commit is contained in:
Victor Berchet
2015-08-31 18:32:32 -07:00
parent 67b9414268
commit 8302afffb4
42 changed files with 311 additions and 842 deletions

View File

@ -61,7 +61,7 @@ class _DirectiveMetadataVisitor extends Object
String _exportAs;
bool _callOnDestroy;
bool _callOnChange;
bool _callOnCheck;
bool _callDoCheck;
bool _callOnInit;
bool _callAfterContentInit;
bool _callAfterContentChecked;
@ -84,7 +84,7 @@ class _DirectiveMetadataVisitor extends Object
_exportAs = null;
_callOnDestroy = false;
_callOnChange = false;
_callOnCheck = false;
_callDoCheck = false;
_callOnInit = false;
_callAfterContentInit = false;
_callAfterContentChecked = false;
@ -104,7 +104,7 @@ class _DirectiveMetadataVisitor extends Object
exportAs: _exportAs,
callOnDestroy: _callOnDestroy,
callOnChanges: _callOnChange,
callDoCheck: _callOnCheck,
callDoCheck: _callDoCheck,
callOnInit: _callOnInit,
callAfterContentInit: _callAfterContentInit,
callAfterContentChecked: _callAfterContentChecked,
@ -170,6 +170,7 @@ class _DirectiveMetadataVisitor extends Object
case 'host':
_populateHost(node.expression);
break;
// TODO(vicb) should come from the interfaces on the class
case 'lifecycle':
_populateLifecycle(node.expression);
break;
@ -281,7 +282,7 @@ class _DirectiveMetadataVisitor extends Object
var lifecycleEvents = l.elements.map((s) => s.toSource().split('.').last);
_callOnDestroy = lifecycleEvents.contains("OnDestroy");
_callOnChange = lifecycleEvents.contains("OnChanges");
_callOnCheck = lifecycleEvents.contains("DoCheck");
_callDoCheck = lifecycleEvents.contains("DoCheck");
_callOnInit = lifecycleEvents.contains("OnInit");
_callAfterContentInit = lifecycleEvents.contains("AfterContentInit");
_callAfterContentChecked = lifecycleEvents.contains("AfterContentChecked");

View File

@ -21,7 +21,7 @@ const _ON_DESTROY_INTERFACES = const [
const ClassDescriptor(
'OnDestroy', 'package:angular2/src/core/compiler/interfaces.dart'),
];
const _ON_CHECK_INTERFACES = const [
const _DO_CHECK_INTERFACES = const [
const ClassDescriptor('DoCheck', 'package:angular2/angular2.dart'),
const ClassDescriptor('DoCheck', 'package:angular2/metadata.dart'),
const ClassDescriptor(
@ -71,7 +71,7 @@ class InterfaceMatcher extends ClassMatcherBase {
return new InterfaceMatcher._([]
..addAll(_ON_CHANGE_INTERFACES)
..addAll(_ON_DESTROY_INTERFACES)
..addAll(_ON_CHECK_INTERFACES)
..addAll(_DO_CHECK_INTERFACES)
..addAll(_ON_INIT_INTERFACES)
..addAll(_ON_AFTER_CONTENT_INIT_INTERFACES)
..addAll(_ON_AFTER_CONTENT_CHECKED_INTERFACES)
@ -88,8 +88,8 @@ class InterfaceMatcher extends ClassMatcherBase {
implements(firstMatch(typeName, assetId), _ON_DESTROY_INTERFACES);
/// Checks if an [Identifier] implements [DoCheck].
bool isOnCheck(Identifier typeName, AssetId assetId) =>
implements(firstMatch(typeName, assetId), _ON_CHECK_INTERFACES);
bool isDoCheck(Identifier typeName, AssetId assetId) =>
implements(firstMatch(typeName, assetId), _DO_CHECK_INTERFACES);
/// Checks if an [Identifier] implements [OnInit].
bool isOnInit(Identifier typeName, AssetId assetId) =>

View File

@ -298,8 +298,7 @@ class _NgDepsDeclarationsVisitor extends Object with SimpleAstVisitor<Object> {
_factoryVisitor = new FactoryTransformVisitor(writer),
_paramsVisitor = new ParameterTransformVisitor(writer),
_metaVisitor = new AnnotationsTransformVisitor(
writer, xhr, annotationMatcher, interfaceMatcher, assetId,
inlineViews: inlineViews),
writer, xhr, annotationMatcher, assetId, inlineViews: inlineViews),
_annotationMatcher = annotationMatcher,
_interfaceMatcher = interfaceMatcher,
this.assetId = assetId,

View File

@ -3,11 +3,9 @@ library angular2.transform.directive_processor.visitors;
import 'dart:async';
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:angular2/metadata.dart' show LifecycleEvent;
import 'package:angular2/src/core/render/xhr.dart' show XHR;
import 'package:angular2/src/transform/common/annotation_matcher.dart';
import 'package:angular2/src/transform/common/async_string_writer.dart';
import 'package:angular2/src/transform/common/interface_matcher.dart';
import 'package:angular2/src/transform/common/logging.dart';
import 'package:barback/barback.dart';
@ -214,92 +212,24 @@ class AnnotationsTransformVisitor extends ToSourceVisitor {
final AsyncStringWriter writer;
final XHR _xhr;
final AnnotationMatcher _annotationMatcher;
final InterfaceMatcher _interfaceMatcher;
final AssetId _assetId;
final bool _inlineViews;
final ConstantEvaluator _evaluator = new ConstantEvaluator();
final Set<String> _ifaceLifecycleEntries = new Set<String>();
bool _isLifecycleWritten = false;
bool _isProcessingView = false;
bool _isProcessingDirective = false;
String _ifaceLifecyclePrefix = '';
AnnotationsTransformVisitor(AsyncStringWriter writer, this._xhr,
this._annotationMatcher, this._interfaceMatcher, this._assetId,
{bool inlineViews})
: this.writer = writer,
this._annotationMatcher, this._assetId, {bool inlineViews})
: writer = writer,
_inlineViews = inlineViews,
super(writer);
/// Determines if the `node` has interface-based lifecycle methods and
/// populates `_lifecycleValue` with the appropriate values if so. If none are
/// present, `_lifecycleValue` is not modified.
void _populateLifecycleValue(ClassDeclaration node) {
var populateImport = (Identifier name) {
if (_ifaceLifecyclePrefix.isNotEmpty) return;
var import = _interfaceMatcher.getMatchingImport(name, _assetId);
_ifaceLifecyclePrefix =
import != null && import.prefix != null ? '${import.prefix}.' : '';
};
var namesToTest = [];
if (node.implementsClause != null &&
node.implementsClause.interfaces != null &&
node.implementsClause.interfaces.isNotEmpty) {
namesToTest.addAll(node.implementsClause.interfaces.map((i) => i.name));
}
if (node.extendsClause != null) {
namesToTest.add(node.extendsClause.superclass.name);
}
namesToTest.forEach((name) {
if (_interfaceMatcher.isOnChange(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.OnChanges}');
populateImport(name);
}
if (_interfaceMatcher.isOnDestroy(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.OnDestroy}');
populateImport(name);
}
if (_interfaceMatcher.isOnCheck(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.DoCheck}');
populateImport(name);
}
if (_interfaceMatcher.isOnInit(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.OnInit}');
populateImport(name);
}
if (_interfaceMatcher.isAfterContentInit(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterContentInit}');
populateImport(name);
}
if (_interfaceMatcher.isAfterContentChecked(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterContentChecked}');
populateImport(name);
}
if (_interfaceMatcher.isAfterViewInit(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterViewInit}');
populateImport(name);
}
if (_interfaceMatcher.isAfterViewChecked(name, _assetId)) {
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterViewChecked}');
populateImport(name);
}
});
}
void _resetState() {
_isLifecycleWritten = _isProcessingView = _isProcessingDirective = false;
_ifaceLifecycleEntries.clear();
_ifaceLifecyclePrefix = '';
_isProcessingView = _isProcessingDirective = false;
}
@override
Object visitClassDeclaration(ClassDeclaration node) {
_populateLifecycleValue(node);
writer.print('const [');
var size = node.metadata.length;
for (var i = 0; i < size; ++i) {
@ -338,28 +268,11 @@ class AnnotationsTransformVisitor extends ToSourceVisitor {
}
args[i].accept(this);
}
if (!_isLifecycleWritten && _isProcessingDirective) {
var lifecycleValue = _getLifecycleValue();
if (lifecycleValue.isNotEmpty) {
writer.print(', lifecycle: $lifecycleValue');
_isLifecycleWritten = true;
}
}
writer.print(')');
}
return null;
}
String _getLifecycleValue() {
if (_ifaceLifecycleEntries.isNotEmpty) {
var entries = _ifaceLifecycleEntries.toList();
entries.sort();
return 'const [${_ifaceLifecyclePrefix}'
'${entries.join(", ${_ifaceLifecyclePrefix}")}]';
}
return '';
}
/// These correspond to the annotation parameters.
@override
Object visitNamedExpression(NamedExpression node) {
@ -375,37 +288,9 @@ class AnnotationsTransformVisitor extends ToSourceVisitor {
var isSuccess = this._inlineView(keyString, node.expression);
if (isSuccess) return null;
}
if (_isProcessingDirective && keyString == 'lifecycle') {
var isSuccess = _populateLifecycleFromNamedExpression(node.expression);
if (isSuccess) {
_isLifecycleWritten = true;
writer.print('lifecycle: ${_getLifecycleValue()}');
return null;
} else {
logger.warning('Failed to parse `lifecycle` value. '
'The following `LifecycleEvent`s may not be called: '
'(${_ifaceLifecycleEntries.join(', ')})');
_isLifecycleWritten = true;
// Do not return -- we will use the default processing here, maintaining
// the original value for `lifecycle`.
}
}
return super.visitNamedExpression(node);
}
/// Populates the lifecycle values from explicitly declared values.
/// Returns whether `node` was successfully processed.
bool _populateLifecycleFromNamedExpression(AstNode node) {
var nodeVal = node.toSource();
for (var evt in LifecycleEvent.values) {
var evtStr = '$evt';
if (nodeVal.contains(evtStr)) {
_ifaceLifecycleEntries.add(evtStr);
}
}
return true;
}
/// Inlines the template and/or style refered to by `keyString`.
/// Returns whether the `keyString` value was successfully processed.
bool _inlineView(String keyString, AstNode node) {