diff --git a/modules/angular2/change_detection.ts b/modules/angular2/change_detection.ts index 86e2e66db2..a4f1d68abd 100644 --- a/modules/angular2/change_detection.ts +++ b/modules/angular2/change_detection.ts @@ -38,10 +38,7 @@ export { ON_PUSH, DEFAULT } from './src/change_detection/constants'; -export { - DynamicProtoChangeDetector, - JitProtoChangeDetector -} from './src/change_detection/proto_change_detector'; +export {DynamicProtoChangeDetector} from './src/change_detection/proto_change_detector'; export {BindingRecord} from './src/change_detection/binding_record'; export {DirectiveIndex, DirectiveRecord} from './src/change_detection/directive_record'; export {DynamicChangeDetector} from './src/change_detection/dynamic_change_detector'; diff --git a/modules/angular2/src/change_detection/change_detection.ts b/modules/angular2/src/change_detection/change_detection.ts index eb57cfa465..5e554702e0 100644 --- a/modules/angular2/src/change_detection/change_detection.ts +++ b/modules/angular2/src/change_detection/change_detection.ts @@ -1,4 +1,6 @@ -import {DynamicProtoChangeDetector, JitProtoChangeDetector} from './proto_change_detector'; +import {JitProtoChangeDetector} from './jit_proto_change_detector'; +import {PregenProtoChangeDetector} from './pregen_proto_change_detector'; +import {DynamicProtoChangeDetector} from './proto_change_detector'; import {PipeFactory, Pipe} from './pipes/pipe'; import {PipeRegistry} from './pipes/pipe_registry'; import {IterableChangesFactory} from './pipes/iterable_changes'; @@ -10,9 +12,9 @@ import {LowerCaseFactory} from './pipes/lowercase_pipe'; import {JsonPipe} from './pipes/json_pipe'; import {NullPipeFactory} from './pipes/null_pipe'; import {ChangeDetection, ProtoChangeDetector, ChangeDetectorDefinition} from './interfaces'; -import {Injectable} from 'angular2/src/di/decorators'; -import {List, StringMapWrapper} from 'angular2/src/facade/collection'; -import {isPresent, BaseException} from 'angular2/src/facade/lang'; +import {Inject, Injectable, OpaqueToken, Optional} from 'angular2/di'; +import {List, StringMap, StringMapWrapper} from 'angular2/src/facade/collection'; +import {CONST_EXPR, isPresent, BaseException} from 'angular2/src/facade/lang'; /** * Structural diffing for `Object`s and `Map`s. @@ -66,29 +68,44 @@ export var defaultPipes = { "json": json }; -export var preGeneratedProtoDetectors = {}; +/** + * Map from {@link ChangeDetectorDefinition#id} to a factory method which takes a + * {@link PipeRegistry} and a {@link ChangeDetectorDefinition} and generates a + * {@link ProtoChangeDetector} associated with the definition. + */ +// TODO(kegluneq): Use PregenProtoChangeDetectorFactory rather than Function once possible in +// dart2js. See https://github.com/dart-lang/sdk/issues/23630 for details. +export var preGeneratedProtoDetectors: StringMap = {}; +export const PROTO_CHANGE_DETECTOR_KEY = CONST_EXPR(new OpaqueToken('ProtoChangeDetectors')); /** * Implements change detection using a map of pregenerated proto detectors. * * @exportedAs angular2/change_detection */ +@Injectable() export class PreGeneratedChangeDetection extends ChangeDetection { _dynamicChangeDetection: ChangeDetection; _protoChangeDetectorFactories: StringMap; - constructor(private registry: PipeRegistry, protoChangeDetectors?) { + constructor(private registry: PipeRegistry, + @Inject(PROTO_CHANGE_DETECTOR_KEY) @Optional() + protoChangeDetectorsForTest?: StringMap) { super(); this._dynamicChangeDetection = new DynamicChangeDetection(registry); - this._protoChangeDetectorFactories = - isPresent(protoChangeDetectors) ? protoChangeDetectors : preGeneratedProtoDetectors; + this._protoChangeDetectorFactories = isPresent(protoChangeDetectorsForTest) ? + protoChangeDetectorsForTest : + preGeneratedProtoDetectors; } + static isSupported(): boolean { return PregenProtoChangeDetector.isSupported(); } + createProtoChangeDetector(definition: ChangeDetectorDefinition): ProtoChangeDetector { var id = definition.id; if (StringMapWrapper.contains(this._protoChangeDetectorFactories, id)) { - return StringMapWrapper.get(this._protoChangeDetectorFactories, id)(this.registry); + return StringMapWrapper.get(this._protoChangeDetectorFactories, id)(this.registry, + definition); } return this._dynamicChangeDetection.createProtoChangeDetector(definition); } @@ -112,10 +129,10 @@ export class DynamicChangeDetection extends ChangeDetection { } /** - * Implements faster change detection, by generating source code. + * Implements faster change detection by generating source code. * * This requires `eval()`. For change detection that does not require `eval()`, see - * {@link DynamicChangeDetection}. + * {@link DynamicChangeDetection} and {@link PreGeneratedChangeDetection}. * * @exportedAs angular2/change_detection */ @@ -123,6 +140,8 @@ export class DynamicChangeDetection extends ChangeDetection { export class JitChangeDetection extends ChangeDetection { constructor(public registry: PipeRegistry) { super(); } + static isSupported(): boolean { return JitProtoChangeDetector.isSupported(); } + createProtoChangeDetector(definition: ChangeDetectorDefinition): ProtoChangeDetector { return new JitProtoChangeDetector(this.registry, definition); } diff --git a/modules/angular2/src/change_detection/change_detection_jit_generator.dart b/modules/angular2/src/change_detection/change_detection_jit_generator.dart index 3b72191152..04069bf189 100644 --- a/modules/angular2/src/change_detection/change_detection_jit_generator.dart +++ b/modules/angular2/src/change_detection/change_detection_jit_generator.dart @@ -1,4 +1,4 @@ -library change_detectoin.change_detection_jit_generator; +library change_detection.change_detection_jit_generator; /// Placeholder JIT generator for Dart. /// Dart does not support `eval`, so JIT generation is not an option. Instead, @@ -12,4 +12,6 @@ class ChangeDetectorJITGenerator { generate() { throw "Jit Change Detection is not supported in Dart"; } + + static bool isSupported() => false; } diff --git a/modules/angular2/src/change_detection/interfaces.ts b/modules/angular2/src/change_detection/interfaces.ts index d719358027..aae6d275b4 100644 --- a/modules/angular2/src/change_detection/interfaces.ts +++ b/modules/angular2/src/change_detection/interfaces.ts @@ -24,7 +24,7 @@ export class ProtoChangeDetector { * `JitChangeDetection` strategy at compile time. * * - * See: {@link DynamicChangeDetection}, {@link JitChangeDetection} + * See: {@link DynamicChangeDetection}, {@link JitChangeDetection}, {@link PregenChangeDetection} * * # Example * ```javascript diff --git a/modules/angular2/src/change_detection/jit_proto_change_detector.dart b/modules/angular2/src/change_detection/jit_proto_change_detector.dart new file mode 100644 index 0000000000..ccbd30eaeb --- /dev/null +++ b/modules/angular2/src/change_detection/jit_proto_change_detector.dart @@ -0,0 +1,13 @@ +library change_detection.jit_proto_change_detector; + +import 'interfaces.dart' show ChangeDetector, ProtoChangeDetector; + +class JitProtoChangeDetector implements ProtoChangeDetector { + JitProtoChangeDetector(registry, definition) : super(); + + static bool isSupported() => false; + + ChangeDetector instantiate(dispatcher) { + throw "Jit Change Detection not supported in Dart"; + } +} diff --git a/modules/angular2/src/change_detection/jit_proto_change_detector.ts b/modules/angular2/src/change_detection/jit_proto_change_detector.ts new file mode 100644 index 0000000000..f808c94d39 --- /dev/null +++ b/modules/angular2/src/change_detection/jit_proto_change_detector.ts @@ -0,0 +1,35 @@ +import {ListWrapper} from 'angular2/src/facade/collection'; + +import {ProtoChangeDetector, ChangeDetector, ChangeDetectorDefinition} from './interfaces'; +import {ChangeDetectorJITGenerator} from './change_detection_jit_generator'; + +import {coalesce} from './coalesce'; +import {ProtoRecordBuilder} from './proto_change_detector'; + +var _jitProtoChangeDetectorClassCounter: number = 0; +export class JitProtoChangeDetector extends ProtoChangeDetector { + _factory: Function; + + constructor(private _pipeRegistry, private definition: ChangeDetectorDefinition) { + super(); + this._factory = this._createFactory(definition); + } + + static isSupported(): boolean { return true; } + + instantiate(dispatcher: any): ChangeDetector { + return this._factory(dispatcher, this._pipeRegistry); + } + + _createFactory(definition: ChangeDetectorDefinition) { + var recordBuilder = new ProtoRecordBuilder(); + ListWrapper.forEach(definition.bindingRecords, + (b) => { recordBuilder.add(b, definition.variableNames); }); + var c = _jitProtoChangeDetectorClassCounter++; + var records = coalesce(recordBuilder.records); + var typeName = `ChangeDetector${c}`; + return new ChangeDetectorJITGenerator(typeName, definition.strategy, records, + this.definition.directiveRecords) + .generate(); + } +} diff --git a/modules/angular2/src/change_detection/pregen_proto_change_detector.dart b/modules/angular2/src/change_detection/pregen_proto_change_detector.dart index 87df3f33b7..51dac4b28f 100644 --- a/modules/angular2/src/change_detection/pregen_proto_change_detector.dart +++ b/modules/angular2/src/change_detection/pregen_proto_change_detector.dart @@ -10,6 +10,8 @@ import 'package:angular2/src/change_detection/proto_record.dart'; export 'dart:core' show List; export 'package:angular2/src/change_detection/abstract_change_detector.dart' show AbstractChangeDetector; +export 'package:angular2/src/change_detection/change_detection.dart' + show preGeneratedProtoDetectors; export 'package:angular2/src/change_detection/directive_record.dart' show DirectiveIndex, DirectiveRecord; export 'package:angular2/src/change_detection/interfaces.dart' @@ -22,6 +24,9 @@ export 'package:angular2/src/change_detection/change_detection_util.dart' show ChangeDetectionUtil; export 'package:angular2/src/facade/lang.dart' show looseIdentical; +typedef ProtoChangeDetector PregenProtoChangeDetectorFactory( + PipeRegistry registry, ChangeDetectorDefinition definition); + typedef ChangeDetector InstantiateMethod(dynamic dispatcher, PipeRegistry registry, List protoRecords, List directiveRecords); @@ -47,6 +52,8 @@ class PregenProtoChangeDetector extends ProtoChangeDetector { PregenProtoChangeDetector._(this.id, this._instantiateMethod, this._pipeRegistry, this._protoRecords, this._directiveRecords); + static bool isSupported() => true; + factory PregenProtoChangeDetector(InstantiateMethod instantiateMethod, PipeRegistry registry, ChangeDetectorDefinition def) { // TODO(kegluneq): Pre-generate these (#2067). diff --git a/modules/angular2/src/change_detection/pregen_proto_change_detector.ts b/modules/angular2/src/change_detection/pregen_proto_change_detector.ts new file mode 100644 index 0000000000..c61d5392ad --- /dev/null +++ b/modules/angular2/src/change_detection/pregen_proto_change_detector.ts @@ -0,0 +1,16 @@ +import {BaseException} from 'angular2/src/facade/lang'; + +import {ProtoChangeDetector, ChangeDetector} from './interfaces'; +import {coalesce} from './coalesce'; + +export {Function as PregenProtoChangeDetectorFactory}; + +export class PregenProtoChangeDetector extends ProtoChangeDetector { + constructor() { super(); } + + static isSupported(): boolean { return false; } + + instantiate(dispatcher: any): ChangeDetector { + throw new BaseException('Pregen change detection not supported in Js'); + } +} diff --git a/modules/angular2/src/change_detection/proto_change_detector.ts b/modules/angular2/src/change_detection/proto_change_detector.ts index aac415757f..1d542ce76c 100644 --- a/modules/angular2/src/change_detection/proto_change_detector.ts +++ b/modules/angular2/src/change_detection/proto_change_detector.ts @@ -32,7 +32,6 @@ import { } from './interfaces'; import {ChangeDetectionUtil} from './change_detection_util'; import {DynamicChangeDetector} from './dynamic_change_detector'; -import {ChangeDetectorJITGenerator} from './change_detection_jit_generator'; import {PipeRegistry} from './pipes/pipe_registry'; import {BindingRecord} from './binding_record'; import {DirectiveRecord, DirectiveIndex} from './directive_record'; @@ -62,31 +61,7 @@ export class DynamicProtoChangeDetector extends ProtoChangeDetector { } } -var _jitProtoChangeDetectorClassCounter: number = 0; -export class JitProtoChangeDetector extends ProtoChangeDetector { - _factory: Function; - - constructor(private _pipeRegistry, private definition: ChangeDetectorDefinition) { - super(); - this._factory = this._createFactory(definition); - } - - instantiate(dispatcher: any) { return this._factory(dispatcher, this._pipeRegistry); } - - _createFactory(definition: ChangeDetectorDefinition) { - var recordBuilder = new ProtoRecordBuilder(); - ListWrapper.forEach(definition.bindingRecords, - (b) => { recordBuilder.add(b, definition.variableNames); }); - var c = _jitProtoChangeDetectorClassCounter++; - var records = coalesce(recordBuilder.records); - var typeName = `ChangeDetector${c}`; - return new ChangeDetectorJITGenerator(typeName, definition.strategy, records, - this.definition.directiveRecords) - .generate(); - } -} - -class ProtoRecordBuilder { +export class ProtoRecordBuilder { records: List; constructor() { this.records = []; } diff --git a/modules/angular2/src/core/application.ts b/modules/angular2/src/core/application.ts index 4bc6fa6ee9..3157a752f9 100644 --- a/modules/angular2/src/core/application.ts +++ b/modules/angular2/src/core/application.ts @@ -18,6 +18,8 @@ import { Lexer, ChangeDetection, DynamicChangeDetection, + JitChangeDetection, + PreGeneratedChangeDetection, PipeRegistry, defaultPipeRegistry } from 'angular2/change_detection'; @@ -66,6 +68,12 @@ var _rootInjector: Injector; var _rootBindings = [bind(Reflector).toValue(reflector), TestabilityRegistry]; function _injectorBindings(appComponentType): List> { + var bestChangeDetection: Type = DynamicChangeDetection; + if (PreGeneratedChangeDetection.isSupported()) { + bestChangeDetection = PreGeneratedChangeDetection; + } else if (JitChangeDetection.isSupported()) { + bestChangeDetection = JitChangeDetection; + } return [ bind(DOCUMENT_TOKEN) .toValue(DOM.defaultDoc()), @@ -117,7 +125,7 @@ function _injectorBindings(appComponentType): List> { CompilerCache, TemplateResolver, bind(PipeRegistry).toValue(defaultPipeRegistry), - bind(ChangeDetection).toClass(DynamicChangeDetection), + bind(ChangeDetection).toClass(bestChangeDetection), TemplateLoader, DirectiveResolver, Parser, diff --git a/modules/angular2/src/transform/common/directive_metadata_reader.dart b/modules/angular2/src/transform/common/directive_metadata_reader.dart index 454f9114f7..071168ade7 100644 --- a/modules/angular2/src/transform/common/directive_metadata_reader.dart +++ b/modules/angular2/src/transform/common/directive_metadata_reader.dart @@ -88,20 +88,20 @@ class _DirectiveMetadataVisitor extends Object } DirectiveMetadata get meta => DirectiveMetadata.create( - type: _type, - selector: _selector, - compileChildren: _compileChildren, - properties: _properties, - host: _host, - readAttributes: _readAttributes, - exportAs: _exportAs, - callOnDestroy: _callOnDestroy, - callOnChange: _callOnChange, - callOnCheck: _callOnCheck, - callOnInit: _callOnInit, - callOnAllChangesDone: _callOnAllChangesDone, - changeDetection: _changeDetection, - events: _events); + type: _type, + selector: _selector, + compileChildren: _compileChildren, + properties: _properties, + host: _host, + readAttributes: _readAttributes, + exportAs: _exportAs, + callOnDestroy: _callOnDestroy, + callOnChange: _callOnChange, + callOnCheck: _callOnCheck, + callOnInit: _callOnInit, + callOnAllChangesDone: _callOnAllChangesDone, + changeDetection: _changeDetection, + events: _events); @override Object visitAnnotation(Annotation node) { diff --git a/modules/angular2/src/transform/common/options.dart b/modules/angular2/src/transform/common/options.dart index 6fc9d772ed..da296c6eab 100644 --- a/modules/angular2/src/transform/common/options.dart +++ b/modules/angular2/src/transform/common/options.dart @@ -8,6 +8,9 @@ const DEFAULT_OPTIMIZATION_PHASES = 5; const CUSTOM_ANNOTATIONS_PARAM = 'custom_annotations'; const ENTRY_POINT_PARAM = 'entry_points'; +const GENERATE_CHANGE_DETECTORS_PARAM = 'generate_change_detectors'; +const INIT_REFLECTOR_PARAM = 'init_reflector'; +const MIRROR_MODE_PARAM = 'mirror_mode'; const OPTIMIZATION_PHASES_PARAM = 'optimization_phases'; const REFLECTION_ENTRY_POINT_PARAM = 'reflection_entry_points'; @@ -32,6 +35,9 @@ class TransformerOptions { /// The [AnnotationMatcher] which is used to identify angular annotations. final AnnotationMatcher annotationMatcher; + /// Whether to create change detector classes for discovered `@View`s. + final bool generateChangeDetectors; + /// The number of phases to spend optimizing output size. /// Each additional phase adds time to the transformation but may decrease /// final output size. There is a limit beyond which this will no longer @@ -43,13 +49,15 @@ class TransformerOptions { TransformerOptions._internal(this.entryPoints, this.reflectionEntryPoints, this.modeName, this.mirrorMode, this.initReflector, - this.annotationMatcher, this.optimizationPhases); + this.annotationMatcher, this.optimizationPhases, + this.generateChangeDetectors); factory TransformerOptions(List entryPoints, {List reflectionEntryPoints, String modeName: 'release', MirrorMode mirrorMode: MirrorMode.none, bool initReflector: true, List customAnnotationDescriptors: const [], - int optimizationPhases: DEFAULT_OPTIMIZATION_PHASES}) { + int optimizationPhases: DEFAULT_OPTIMIZATION_PHASES, + bool generateChangeDetectors: true}) { if (reflectionEntryPoints == null || reflectionEntryPoints.isEmpty) { reflectionEntryPoints = entryPoints; } @@ -58,6 +66,6 @@ class TransformerOptions { optimizationPhases = optimizationPhases.isNegative ? 0 : optimizationPhases; return new TransformerOptions._internal(entryPoints, reflectionEntryPoints, modeName, mirrorMode, initReflector, annotationMatcher, - optimizationPhases); + optimizationPhases, generateChangeDetectors); } } diff --git a/modules/angular2/src/transform/common/options_reader.dart b/modules/angular2/src/transform/common/options_reader.dart index f352e66bd0..56c3e661aa 100644 --- a/modules/angular2/src/transform/common/options_reader.dart +++ b/modules/angular2/src/transform/common/options_reader.dart @@ -10,10 +10,12 @@ TransformerOptions parseBarbackSettings(BarbackSettings settings) { var entryPoints = _readFileList(config, ENTRY_POINT_PARAM); var reflectionEntryPoints = _readFileList(config, REFLECTION_ENTRY_POINT_PARAM); - var initReflector = !config.containsKey('init_reflector') || - config['init_reflector'] != false; + var initReflector = + _readBool(config, INIT_REFLECTOR_PARAM, defaultValue: true); + var generateChangeDetectors = + _readBool(config, GENERATE_CHANGE_DETECTORS_PARAM, defaultValue: true); String mirrorModeVal = - config.containsKey('mirror_mode') ? config['mirror_mode'] : ''; + config.containsKey(MIRROR_MODE_PARAM) ? config[MIRROR_MODE_PARAM] : ''; var mirrorMode = MirrorMode.none; switch (mirrorModeVal) { case 'debug': @@ -34,7 +36,14 @@ TransformerOptions parseBarbackSettings(BarbackSettings settings) { mirrorMode: mirrorMode, initReflector: initReflector, customAnnotationDescriptors: _readCustomAnnotations(config), - optimizationPhases: optimizationPhases); + optimizationPhases: optimizationPhases, + generateChangeDetectors: generateChangeDetectors); +} + +bool _readBool(Map config, String paramName, {bool defaultValue}) { + return config.containsKey(paramName) + ? config[paramName] != false + : defaultValue; } /// Cribbed from the polymer project. diff --git a/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart b/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart index 7a1c33330d..1d5eee2090 100644 --- a/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart +++ b/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart @@ -14,15 +14,31 @@ import 'package:angular2/src/facade/lang.dart' show BaseException; /// This code should be kept in sync with the `ChangeDetectorJITGenerator` /// class. If you make updates here, please make equivalent changes there. class Codegen { + /// Stores the generated class definitions. final StringBuffer _buf = new StringBuffer(); + /// Stores all generated initialization code. + final StringBuffer _initBuf = new StringBuffer(); + /// The names of already generated classes. + final Set _names = new Set(); - /// Generates a change detector class with name `changeDetectorTypeName` - /// which is used to detect changes in Objects of type `typeName`. + /// Generates a change detector class with name `changeDetectorTypeName`, + /// which must not conflict with other generated classes in the same + /// `.ng_deps.dart` file. The change detector is used to detect changes in + /// Objects of type `typeName`. void generate(String typeName, String changeDetectorTypeName, ChangeDetectorDefinition def) { - new _CodegenState(typeName, changeDetectorTypeName, def)._writeToBuf(_buf); + if (_names.contains(changeDetectorTypeName)) { + throw new BaseException( + 'Change detector named "${changeDetectorTypeName}" for ${typeName} ' + 'conflicts with an earlier generated change detector class.'); + } + _names.add(changeDetectorTypeName); + new _CodegenState(typeName, changeDetectorTypeName, def) + .._writeToBuf(_buf) + .._writeInitToBuf(_initBuf); } + /// Gets all imports necessary for the generated code. String get imports { return _buf.isEmpty ? '' @@ -31,13 +47,27 @@ class Codegen { bool get isEmpty => _buf.isEmpty; + /// Gets the initilization code that registers the generated classes with + /// the Angular 2 change detection system. + String get initialize => '$_initBuf'; + @override String toString() => '$_buf'; } /// The state needed to generate a change detector for a single `Component`. class _CodegenState { + /// The `id` of the `ChangeDetectorDefinition` we are generating this class + /// for. + final String _changeDetectorDefId; + + /// The name of the `Type` this change detector is generated for. For example, + /// this is `MyComponent` if the generated class will detect changes in + /// `MyComponent` objects. final String _contextTypeName; + + /// The name of the generated change detector class. This is an implementation + /// detail and should not be visible to users. final String _changeDetectorTypeName; final String _changeDetectionMode; final List _records; @@ -47,9 +77,9 @@ class _CodegenState { final List _fieldNames; final List _pipeNames; - _CodegenState._(this._contextTypeName, this._changeDetectorTypeName, - String changeDetectionStrategy, this._records, this._directiveRecords, - List localNames) + _CodegenState._(this._changeDetectorDefId, this._contextTypeName, + this._changeDetectorTypeName, String changeDetectionStrategy, + this._records, this._directiveRecords, List localNames) : this._localNames = localNames, _changeNames = _getChangeNames(localNames), _fieldNames = _getFieldNames(localNames), @@ -63,8 +93,8 @@ class _CodegenState { def.bindingRecords .forEach((rec) => protoRecords.add(rec, def.variableNames)); var records = coalesce(protoRecords.records); - return new _CodegenState._(typeName, changeDetectorTypeName, def.strategy, - records, def.directiveRecords, _getLocalNames(records)); + return new _CodegenState._(def.id, typeName, changeDetectorTypeName, + def.strategy, records, def.directiveRecords, _getLocalNames(records)); } /// Generates sanitized names for use as local variables. @@ -167,6 +197,13 @@ class _CodegenState { '''); } + void _writeInitToBuf(StringBuffer buf) { + buf.write(''' + $_GEN_PREFIX.preGeneratedProtoDetectors['$_changeDetectorDefId'] = + $_changeDetectorTypeName.newProtoChangeDetector; + '''); + } + List _genGetDirectiveFieldNames() { return _directiveRecords .map((d) => _genGetDirective(d.directiveIndex)) diff --git a/modules/angular2/src/transform/template_compiler/generator.dart b/modules/angular2/src/transform/template_compiler/generator.dart index e22266bad9..fe0f515f5a 100644 --- a/modules/angular2/src/transform/template_compiler/generator.dart +++ b/modules/angular2/src/transform/template_compiler/generator.dart @@ -64,11 +64,14 @@ Future processTemplates(AssetReader reader, AssetId entryPoint, viewDefResults.ngDeps.lib != null ? viewDefResults.ngDeps.lib.end : 0; var codeInjectIdx = viewDefResults.ngDeps.registeredTypes.last.registerMethod.end; + var initInjectIdx = viewDefResults.ngDeps.setupMethod.end - 1; return '${code.substring(0, importInjectIdx)}' '${changeDetectorClasses.imports}' '${code.substring(importInjectIdx, codeInjectIdx)}' '${registrations}' - '${code.substring(codeInjectIdx)}' + '${code.substring(codeInjectIdx, initInjectIdx)}' + '${changeDetectorClasses.initialize}' + '${code.substring(initInjectIdx)}' '$changeDetectorClasses'; } @@ -100,8 +103,8 @@ class _TemplateExtractor { var pipeline = new CompilePipeline(_factory.createSteps(viewDef, subtaskPromises)); - var compileElements = pipeline.process( - templateEl, ViewType.COMPONENT, viewDef.componentId); + var compileElements = + pipeline.process(templateEl, ViewType.COMPONENT, viewDef.componentId); var protoViewDto = compileElements[0].inheritedProtoView .build(new PropertySetterFactory()); diff --git a/modules/angular2/src/transform/template_compiler/transformer.dart b/modules/angular2/src/transform/template_compiler/transformer.dart index 563c3126c7..575a89d2e1 100644 --- a/modules/angular2/src/transform/template_compiler/transformer.dart +++ b/modules/angular2/src/transform/template_compiler/transformer.dart @@ -34,8 +34,8 @@ class TemplateCompiler extends Transformer { Html5LibDomAdapter.makeCurrent(); var id = transform.primaryInput.id; var reader = new AssetReader.fromTransform(transform); - var transformedCode = - formatter.format(await processTemplates(reader, id)); + var transformedCode = formatter.format(await processTemplates(reader, id, + generateChangeDetectors: options.generateChangeDetectors)); transform.addOutput(new Asset.fromString(id, transformedCode)); } catch (ex, stackTrace) { log.logger.error('Parsing ng templates failed.\n' diff --git a/modules/angular2/src/transform/template_compiler/view_definition_creator.dart b/modules/angular2/src/transform/template_compiler/view_definition_creator.dart index 0e62d61ffd..f876f593ed 100644 --- a/modules/angular2/src/transform/template_compiler/view_definition_creator.dart +++ b/modules/angular2/src/transform/template_compiler/view_definition_creator.dart @@ -33,8 +33,7 @@ class ViewDefinitionEntry { ViewDefinitionEntry._(this.hostMetadata, this.viewDef); } -String _getComponentId(AssetId assetId, String className) => - '$assetId:$className'; +String _getComponentId(AssetId assetId, String className) => '$className'; // TODO(kegluenq): Improve this test. bool _isViewAnnotation(InstanceCreationExpression node) => diff --git a/modules/angular2/test/change_detection/change_detection_spec.ts b/modules/angular2/test/change_detection/change_detection_spec.ts index 912c3b5b74..f908b99137 100644 --- a/modules/angular2/test/change_detection/change_detection_spec.ts +++ b/modules/angular2/test/change_detection/change_detection_spec.ts @@ -20,7 +20,7 @@ export function main() { }); it("should return a proto change detector when one is available", () => { - var map = {'id': (registry) => proto}; + var map = {'id': (registry, def) => proto}; var cd = new PreGeneratedChangeDetection(null, map); expect(cd.createProtoChangeDetector(def)).toBe(proto) diff --git a/modules/angular2/test/change_detection/change_detector_spec.ts b/modules/angular2/test/change_detection/change_detector_spec.ts index 22e4796a9b..a7befbd9d1 100644 --- a/modules/angular2/test/change_detection/change_detector_spec.ts +++ b/modules/angular2/test/change_detection/change_detector_spec.ts @@ -37,7 +37,6 @@ import { ON_PUSH, DEFAULT, WrappedValue, - JitProtoChangeDetector, DynamicProtoChangeDetector, ChangeDetectorDefinition, Lexer, @@ -45,6 +44,7 @@ import { Locals, ProtoChangeDetector } from 'angular2/change_detection'; +import {JitProtoChangeDetector} from 'angular2/src/change_detection/jit_proto_change_detector'; import {getDefinition} from './change_detector_config'; import {getFactoryById} from './generated/change_detector_classes'; diff --git a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/changeDetection.ng_deps.dart b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/changeDetection.ng_deps.dart index f4f1df6591..fca8e31f23 100644 --- a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/changeDetection.ng_deps.dart +++ b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/changeDetection.ng_deps.dart @@ -22,8 +22,6 @@ void initReflector(reflector) { ..registerType(HelloCmp, { 'factory': () => new HelloCmp(), 'parameters': const [const []], - 'annotations': const [ - const Component(changeDetection: 'CHECK_ONCE') - ] + 'annotations': const [const Component(changeDetection: 'CHECK_ONCE')] }); } diff --git a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/events.ng_deps.dart b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/events.ng_deps.dart index 2e6bd5995f..9227814796 100644 --- a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/events.ng_deps.dart +++ b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/events.ng_deps.dart @@ -22,8 +22,6 @@ void initReflector(reflector) { ..registerType(HelloCmp, { 'factory': () => new HelloCmp(), 'parameters': const [const []], - 'annotations': const [ - const Component(events: ['onFoo', 'onBar']) - ] + 'annotations': const [const Component(events: ['onFoo', 'onBar'])] }); } diff --git a/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart b/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart index 9485a9f2ff..29e2bb0b09 100644 --- a/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart +++ b/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart @@ -20,6 +20,8 @@ void initReflector(reflector) { const View(template: 'Salad') ] }); + _gen.preGeneratedProtoDetectors['MyComponent_comp_0'] = + _MyComponent_ChangeDetector0.newProtoChangeDetector; } class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector { final dynamic _dispatcher; diff --git a/modules/benchmarks/pubspec.yaml b/modules/benchmarks/pubspec.yaml index 3a98921857..5556e136b5 100644 --- a/modules/benchmarks/pubspec.yaml +++ b/modules/benchmarks/pubspec.yaml @@ -24,6 +24,7 @@ transformers: - web/src/largetable/largetable_benchmark.dart - web/src/naive_infinite_scroll/index.dart - web/src/tree/tree_benchmark.dart + generate_change_detectors: false - $dart2js: minify: false commandLineOptions: diff --git a/modules/benchmarks/src/naive_infinite_scroll/index.ts b/modules/benchmarks/src/naive_infinite_scroll/index.ts index 5c76087cbd..58df2ef0ad 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/index.ts +++ b/modules/benchmarks/src/naive_infinite_scroll/index.ts @@ -28,12 +28,4 @@ export function setupReflector() { MapWrapper.forEach(m, function(v, k) { o.style.setProperty(k, v); }); } }); - - reflector.registerMethods({ - 'onScroll': (o, args) => { - // HACK - o.onScroll(args[0]); - }, - 'setStage': (o, args) => o.setStage(args[0]) - }); }