feat(compiler): add change detector generation
Runtime and Codegen. Part of #3605 Closes #4057
This commit is contained in:
81
modules/angular2/src/compiler/change_detector_compiler.ts
Normal file
81
modules/angular2/src/compiler/change_detector_compiler.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import {TypeMetadata, SourceModule} from './api';
|
||||
import {
|
||||
ChangeDetectorJITGenerator
|
||||
} from 'angular2/src/core/change_detection/change_detection_jit_generator';
|
||||
|
||||
import {createChangeDetectorDefinitions} from './change_definition_factory';
|
||||
import {isJsObject, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
|
||||
import {
|
||||
ChangeDetectorGenConfig,
|
||||
ChangeDetectorDefinition,
|
||||
DynamicProtoChangeDetector,
|
||||
ChangeDetectionStrategy
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
import {TemplateAst} from './template_ast';
|
||||
import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen';
|
||||
|
||||
var IS_DART = !isJsObject({});
|
||||
|
||||
const ABSTRACT_CHANGE_DETECTOR = "AbstractChangeDetector";
|
||||
const UTIL = "ChangeDetectionUtil";
|
||||
|
||||
const JS_CHANGE_DETECTOR_IMPORTS = CONST_EXPR([
|
||||
['angular2/src/core/change_detection/abstract_change_detector', 'acd'],
|
||||
['angular2/src/core/change_detection/change_detection_util', 'cdu']
|
||||
]);
|
||||
|
||||
const DART_CHANGE_DETECTOR_IMPORTS =
|
||||
CONST_EXPR([['angular2/src/core/change_detection/pregen_proto_change_detector', '_gen']]);
|
||||
|
||||
export class ChangeDetectionCompiler {
|
||||
constructor(private _genConfig: ChangeDetectorGenConfig) {}
|
||||
|
||||
compileComponentRuntime(componentType: TypeMetadata, strategy: ChangeDetectionStrategy,
|
||||
parsedTemplate: TemplateAst[]): Function[] {
|
||||
var changeDetectorDefinitions =
|
||||
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||
return changeDetectorDefinitions.map(definition =>
|
||||
this._createChangeDetectorFactory(definition));
|
||||
}
|
||||
|
||||
private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function {
|
||||
if (IS_DART) {
|
||||
var proto = new DynamicProtoChangeDetector(definition);
|
||||
return (dispatcher) => proto.instantiate(dispatcher);
|
||||
} else {
|
||||
// TODO(tbosch): provide a flag in _genConfig whether to allow eval or fall back to dynamic
|
||||
// change detection as well!
|
||||
return new ChangeDetectorJITGenerator(definition, UTIL, ABSTRACT_CHANGE_DETECTOR).generate();
|
||||
}
|
||||
}
|
||||
|
||||
compileComponentCodeGen(componentType: TypeMetadata, strategy: ChangeDetectionStrategy,
|
||||
parsedTemplate: TemplateAst[]): SourceModule {
|
||||
var changeDetectorDefinitions =
|
||||
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||
var imports = IS_DART ? DART_CHANGE_DETECTOR_IMPORTS : JS_CHANGE_DETECTOR_IMPORTS;
|
||||
var factories = [];
|
||||
var sourceParts = changeDetectorDefinitions.map(definition => {
|
||||
var codegen: any;
|
||||
// TODO(tbosch): move the 2 code generators to the same place, one with .dart and one with .ts
|
||||
// suffix
|
||||
// and have the same API for calling them!
|
||||
if (IS_DART) {
|
||||
codegen = new Codegen();
|
||||
var className = definition.id;
|
||||
codegen.generate(componentType.typeName, className, definition);
|
||||
factories.push(`(dispatcher) => new ${className}(dispatcher)`);
|
||||
return codegen.toString();
|
||||
} else {
|
||||
codegen = new ChangeDetectorJITGenerator(definition, `cdu.${UTIL}`,
|
||||
`acd.${ABSTRACT_CHANGE_DETECTOR}`);
|
||||
factories.push(`function(dispatcher) { return new ${codegen.typeName}(dispatcher); }`);
|
||||
return codegen.generateSource();
|
||||
}
|
||||
});
|
||||
sourceParts.push(`var CHANGE_DETECTORS = [ ${factories.join(',')} ];`);
|
||||
return new SourceModule(componentType.typeUrl, sourceParts.join('\n'), imports);
|
||||
}
|
||||
}
|
@ -76,7 +76,7 @@ export class StyleCompiler {
|
||||
private _styleCodeGen(moduleName: string, plainStyles: string[], absUrls: string[], shim: boolean,
|
||||
suffix: string): SourceModule {
|
||||
var imports: string[][] = [];
|
||||
var moduleSource = `${codeGenExportVar('STYLES')} (`;
|
||||
var moduleSource = `var STYLES = (`;
|
||||
moduleSource +=
|
||||
`[${plainStyles.map( plainStyle => escapeString(this._shimIfNeeded(plainStyle, shim)) ).join(',')}]`;
|
||||
for (var i = 0; i < absUrls.length; i++) {
|
||||
@ -109,14 +109,6 @@ function escapeString(input: string): string {
|
||||
return `'${escapedInput}'`;
|
||||
}
|
||||
|
||||
function codeGenExportVar(name: string): string {
|
||||
if (IS_DART) {
|
||||
return `var ${name} =`;
|
||||
} else {
|
||||
return `var ${name} = exports.${name} =`;
|
||||
}
|
||||
}
|
||||
|
||||
function codeGenConcatArray(expression: string): string {
|
||||
return `${IS_DART ? '..addAll' : '.concat'}(${expression})`;
|
||||
}
|
||||
|
Reference in New Issue
Block a user