style(lint): re-format modules/@angular

This commit is contained in:
Alex Eagle
2016-06-08 16:38:52 -07:00
parent bbed364e7b
commit f39c9c9e75
589 changed files with 21829 additions and 24259 deletions
@@ -20,9 +20,9 @@ export interface AnimationAstVisitor {
}
export class AnimationEntryAst extends AnimationAst {
constructor(public name: string,
public stateDeclarations: AnimationStateDeclarationAst[],
public stateTransitions: AnimationStateTransitionAst[]) {
constructor(
public name: string, public stateDeclarations: AnimationStateDeclarationAst[],
public stateTransitions: AnimationStateTransitionAst[]) {
super();
}
visit(visitor: AnimationAstVisitor, context: any): any {
@@ -31,9 +31,7 @@ export class AnimationEntryAst extends AnimationAst {
}
export class AnimationStateDeclarationAst extends AnimationStateAst {
constructor(public stateName: string, public styles: AnimationStylesAst) {
super();
}
constructor(public stateName: string, public styles: AnimationStylesAst) { super(); }
visit(visitor: AnimationAstVisitor, context: any): any {
return visitor.visitAnimationStateDeclaration(this, context);
}
@@ -44,7 +42,9 @@ export class AnimationStateTransitionExpression {
}
export class AnimationStateTransitionAst extends AnimationStateAst {
constructor(public stateChanges: AnimationStateTransitionExpression[], public animation: AnimationSequenceAst) {
constructor(
public stateChanges: AnimationStateTransitionExpression[],
public animation: AnimationSequenceAst) {
super();
}
visit(visitor: AnimationAstVisitor, context: any): any {
@@ -53,11 +53,9 @@ export class AnimationStateTransitionAst extends AnimationStateAst {
}
export class AnimationStepAst extends AnimationAst {
constructor(public startingStyles: AnimationStylesAst,
public keyframes: AnimationKeyframeAst[],
public duration: number,
public delay: number,
public easing: string) {
constructor(
public startingStyles: AnimationStylesAst, public keyframes: AnimationKeyframeAst[],
public duration: number, public delay: number, public easing: string) {
super();
}
visit(visitor: AnimationAstVisitor, context: any): any {
@@ -1,41 +1,21 @@
import {BaseException} from '../facade/exceptions';
import {ListWrapper, Map, StringMapWrapper} from '../facade/collection';
import {isPresent, isBlank, isArray} from '../facade/lang';
import {AUTO_STYLE} from '@angular/core';
import {ANY_STATE, DEFAULT_STATE, EMPTY_STATE} from '../../core_private';
import {CompileDirectiveMetadata} from '../compile_metadata';
import {ListWrapper, Map, StringMapWrapper} from '../facade/collection';
import {BaseException} from '../facade/exceptions';
import {isArray, isBlank, isPresent} from '../facade/lang';
import {Identifiers} from '../identifiers';
import * as o from '../output/output_ast';
import {AUTO_STYLE} from '@angular/core';
import {DEFAULT_STATE, ANY_STATE, EMPTY_STATE} from '../../core_private';
import {
AnimationParseError,
ParsedAnimationResult,
parseAnimationEntry
} from './animation_parser';
import {CompileDirectiveMetadata} from "../compile_metadata";
import {
AnimationAst,
AnimationEntryAst,
AnimationStateAst,
AnimationStateDeclarationAst,
AnimationStateTransitionAst,
AnimationKeyframeAst,
AnimationStylesAst,
AnimationSequenceAst,
AnimationGroupAst,
AnimationStepAst,
AnimationAstVisitor
} from './animation_ast';
import {AnimationAst, AnimationAstVisitor, AnimationEntryAst, AnimationGroupAst, AnimationKeyframeAst, AnimationSequenceAst, AnimationStateAst, AnimationStateDeclarationAst, AnimationStateTransitionAst, AnimationStepAst, AnimationStylesAst} from './animation_ast';
import {AnimationParseError, ParsedAnimationResult, parseAnimationEntry} from './animation_parser';
export class CompiledAnimation {
constructor(public name: string,
public statesMapStatement: o.Statement,
public statesVariableName: string,
public fnStatement: o.Statement,
public fnVariable: o.Expression) {}
constructor(
public name: string, public statesMapStatement: o.Statement,
public statesVariableName: string, public fnStatement: o.Statement,
public fnVariable: o.Expression) {}
}
export class AnimationCompiler {
@@ -46,11 +26,12 @@ export class AnimationCompiler {
var result = parseAnimationEntry(entry);
if (result.errors.length > 0) {
var errorMessage = '';
result.errors.forEach((error: AnimationParseError) => { errorMessage += "\n- " + error.msg; });
result.errors.forEach(
(error: AnimationParseError) => { errorMessage += '\n- ' + error.msg; });
// todo (matsko): include the component name when throwing
throw new BaseException(
`Unable to parse the animation sequence for "${entry.name}" due to the following errors: ` +
errorMessage);
`Unable to parse the animation sequence for "${entry.name}" due to the following errors: ` +
errorMessage);
}
var factoryName = `${component.type.name}_${entry.name}_${index}`;
@@ -86,8 +67,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
this._statesMapVar = o.variable(this._statesMapVarName);
}
visitAnimationStyles(ast: AnimationStylesAst,
context: _AnimationBuilderContext): o.Expression {
visitAnimationStyles(ast: AnimationStylesAst, context: _AnimationBuilderContext): o.Expression {
var stylesArr: any[] /** TODO #9100 */ = [];
if (context.isExpectingFirstStyleStep) {
stylesArr.push(_ANIMATION_START_STATE_STYLES_VAR);
@@ -95,22 +75,21 @@ class _AnimationBuilder implements AnimationAstVisitor {
}
ast.styles.forEach(entry => {
stylesArr.push(o.literalMap(StringMapWrapper.keys(entry).map(key => [key, o.literal(entry[key])])));
stylesArr.push(
o.literalMap(StringMapWrapper.keys(entry).map(key => [key, o.literal(entry[key])])));
});
return o.importExpr(Identifiers.AnimationStyles).instantiate([
o.importExpr(Identifiers.collectAndResolveStyles).callFn([
_ANIMATION_COLLECTED_STYLES,
o.literalArr(stylesArr)
_ANIMATION_COLLECTED_STYLES, o.literalArr(stylesArr)
])
]);
}
visitAnimationKeyframe(ast: AnimationKeyframeAst,
context: _AnimationBuilderContext): o.Expression {
visitAnimationKeyframe(ast: AnimationKeyframeAst, context: _AnimationBuilderContext):
o.Expression {
return o.importExpr(Identifiers.AnimationKeyframe).instantiate([
o.literal(ast.offset),
ast.styles.visit(this, context)
o.literal(ast.offset), ast.styles.visit(this, context)
]);
}
@@ -120,18 +99,17 @@ class _AnimationBuilder implements AnimationAstVisitor {
}
var startingStylesExpr = ast.startingStyles.visit(this, context);
var keyframeExpressions = ast.keyframes.map(keyframeEntry => keyframeEntry.visit(this, context));
var keyframeExpressions =
ast.keyframes.map(keyframeEntry => keyframeEntry.visit(this, context));
return this._callAnimateMethod(ast, startingStylesExpr, o.literalArr(keyframeExpressions));
}
/** @internal */
_visitEndStateAnimation(ast: AnimationStepAst,
context: _AnimationBuilderContext): o.Expression {
_visitEndStateAnimation(ast: AnimationStepAst, context: _AnimationBuilderContext): o.Expression {
var startingStylesExpr = ast.startingStyles.visit(this, context);
var keyframeExpressions = ast.keyframes.map(keyframe => keyframe.visit(this, context));
var keyframesExpr = o.importExpr(Identifiers.balanceAnimationKeyframes).callFn([
_ANIMATION_COLLECTED_STYLES,
_ANIMATION_END_STATE_STYLES_VAR,
_ANIMATION_COLLECTED_STYLES, _ANIMATION_END_STATE_STYLES_VAR,
o.literalArr(keyframeExpressions)
]);
@@ -139,41 +117,41 @@ class _AnimationBuilder implements AnimationAstVisitor {
}
/** @internal */
_callAnimateMethod(ast: AnimationStepAst, startingStylesExpr: any /** TODO #9100 */, keyframesExpr: any /** TODO #9100 */) {
_callAnimateMethod(
ast: AnimationStepAst, startingStylesExpr: any /** TODO #9100 */,
keyframesExpr: any /** TODO #9100 */) {
return _ANIMATION_FACTORY_RENDERER_VAR.callMethod('animate', [
_ANIMATION_FACTORY_ELEMENT_VAR,
startingStylesExpr,
keyframesExpr,
o.literal(ast.duration),
o.literal(ast.delay),
o.literal(ast.easing)
_ANIMATION_FACTORY_ELEMENT_VAR, startingStylesExpr, keyframesExpr, o.literal(ast.duration),
o.literal(ast.delay), o.literal(ast.easing)
]);
}
visitAnimationSequence(ast: AnimationSequenceAst,
context: _AnimationBuilderContext): o.Expression {
visitAnimationSequence(ast: AnimationSequenceAst, context: _AnimationBuilderContext):
o.Expression {
var playerExprs = ast.steps.map(step => step.visit(this, context));
return o.importExpr(Identifiers.AnimationSequencePlayer).instantiate([
o.literalArr(playerExprs)]);
return o.importExpr(Identifiers.AnimationSequencePlayer).instantiate([o.literalArr(
playerExprs)]);
}
visitAnimationGroup(ast: AnimationGroupAst, context: _AnimationBuilderContext): o.Expression {
var playerExprs = ast.steps.map(step => step.visit(this, context));
return o.importExpr(Identifiers.AnimationGroupPlayer).instantiate([
o.literalArr(playerExprs)]);
return o.importExpr(Identifiers.AnimationGroupPlayer).instantiate([o.literalArr(playerExprs)]);
}
visitAnimationStateDeclaration(ast: AnimationStateDeclarationAst, context: _AnimationBuilderContext): void {
var flatStyles: {[key: string]: string|number} = {};
visitAnimationStateDeclaration(
ast: AnimationStateDeclarationAst, context: _AnimationBuilderContext): void {
var flatStyles: {[key: string]: string | number} = {};
_getStylesArray(ast).forEach((entry: any /** TODO #9100 */) => {
StringMapWrapper.forEach(entry, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
flatStyles[key] = value;
});
StringMapWrapper.forEach(
entry, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
flatStyles[key] = value;
});
});
context.stateMap.registerState(ast.stateName, flatStyles);
}
visitAnimationStateTransition(ast: AnimationStateTransitionAst, context: _AnimationBuilderContext): any {
visitAnimationStateTransition(
ast: AnimationStateTransitionAst, context: _AnimationBuilderContext): any {
var steps = ast.animation.steps;
var lastStep = steps[steps.length - 1];
if (_isEndStateAnimateStep(lastStep)) {
@@ -186,9 +164,8 @@ class _AnimationBuilder implements AnimationAstVisitor {
ast.stateChanges.forEach(stateChange => {
stateChangePreconditions.push(
_compareToAnimationStateExpr(_ANIMATION_CURRENT_STATE_VAR, stateChange.fromState)
.and(_compareToAnimationStateExpr(_ANIMATION_NEXT_STATE_VAR, stateChange.toState))
);
_compareToAnimationStateExpr(_ANIMATION_CURRENT_STATE_VAR, stateChange.fromState)
.and(_compareToAnimationStateExpr(_ANIMATION_NEXT_STATE_VAR, stateChange.toState)));
if (stateChange.fromState != ANY_STATE) {
context.stateMap.registerState(stateChange.fromState);
@@ -201,56 +178,52 @@ class _AnimationBuilder implements AnimationAstVisitor {
var animationPlayerExpr = ast.animation.visit(this, context);
var reducedStateChangesPrecondition = stateChangePreconditions.reduce((a,b) => a.or(b));
var precondition = _ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR).and(reducedStateChangesPrecondition);
var reducedStateChangesPrecondition = stateChangePreconditions.reduce((a, b) => a.or(b));
var precondition =
_ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR).and(reducedStateChangesPrecondition);
return new o.IfStmt(precondition, [
_ANIMATION_PLAYER_VAR.set(animationPlayerExpr).toStmt()
]);
return new o.IfStmt(precondition, [_ANIMATION_PLAYER_VAR.set(animationPlayerExpr).toStmt()]);
}
visitAnimationEntry(ast: AnimationEntryAst, context: _AnimationBuilderContext): any {
//visit each of the declarations first to build the context state map
// visit each of the declarations first to build the context state map
ast.stateDeclarations.forEach(def => def.visit(this, context));
//this should always be defined even if the user overrides it
// this should always be defined even if the user overrides it
context.stateMap.registerState(DEFAULT_STATE, {});
var statements: any[] /** TODO #9100 */ = [];
statements.push(
_ANIMATION_FACTORY_VIEW_VAR.callMethod('cancelActiveAnimation', [
_ANIMATION_FACTORY_ELEMENT_VAR,
o.literal(this.animationName),
_ANIMATION_NEXT_STATE_VAR.equals(o.literal(EMPTY_STATE))
]).toStmt());
statements.push(_ANIMATION_FACTORY_VIEW_VAR
.callMethod(
'cancelActiveAnimation',
[
_ANIMATION_FACTORY_ELEMENT_VAR, o.literal(this.animationName),
_ANIMATION_NEXT_STATE_VAR.equals(o.literal(EMPTY_STATE))
])
.toStmt());
statements.push(_ANIMATION_COLLECTED_STYLES.set(EMPTY_MAP).toDeclStmt());
statements.push(_ANIMATION_PLAYER_VAR.set(o.NULL_EXPR).toDeclStmt());
statements.push(
_ANIMATION_DEFAULT_STATE_VAR.set(
this._statesMapVar.key(o.literal(DEFAULT_STATE))
).toDeclStmt());
_ANIMATION_DEFAULT_STATE_VAR.set(this._statesMapVar.key(o.literal(DEFAULT_STATE)))
.toDeclStmt());
statements.push(
_ANIMATION_START_STATE_STYLES_VAR.set(
this._statesMapVar.key(_ANIMATION_CURRENT_STATE_VAR)
).toDeclStmt());
_ANIMATION_START_STATE_STYLES_VAR.set(this._statesMapVar.key(_ANIMATION_CURRENT_STATE_VAR))
.toDeclStmt());
statements.push(new o.IfStmt(
_ANIMATION_START_STATE_STYLES_VAR.equals(o.NULL_EXPR),
[_ANIMATION_START_STATE_STYLES_VAR.set(_ANIMATION_DEFAULT_STATE_VAR).toStmt()]));
statements.push(
new o.IfStmt(_ANIMATION_START_STATE_STYLES_VAR.equals(o.NULL_EXPR), [
_ANIMATION_START_STATE_STYLES_VAR.set(_ANIMATION_DEFAULT_STATE_VAR).toStmt()
]));
_ANIMATION_END_STATE_STYLES_VAR.set(this._statesMapVar.key(_ANIMATION_NEXT_STATE_VAR))
.toDeclStmt());
statements.push(
_ANIMATION_END_STATE_STYLES_VAR.set(
this._statesMapVar.key(_ANIMATION_NEXT_STATE_VAR)
).toDeclStmt());
statements.push(
new o.IfStmt(_ANIMATION_END_STATE_STYLES_VAR.equals(o.NULL_EXPR), [
_ANIMATION_END_STATE_STYLES_VAR.set(_ANIMATION_DEFAULT_STATE_VAR).toStmt()
]));
statements.push(new o.IfStmt(
_ANIMATION_END_STATE_STYLES_VAR.equals(o.NULL_EXPR),
[_ANIMATION_END_STATE_STYLES_VAR.set(_ANIMATION_DEFAULT_STATE_VAR).toStmt()]));
var RENDER_STYLES_FN = o.importExpr(Identifiers.renderStyles);
@@ -259,53 +232,59 @@ class _AnimationBuilder implements AnimationAstVisitor {
// styles from the element's style property (since they were placed
// there at the end of the last animation
statements.push(
RENDER_STYLES_FN.callFn([
_ANIMATION_FACTORY_ELEMENT_VAR,
_ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(Identifiers.clearStyles).callFn([_ANIMATION_START_STATE_STYLES_VAR])
]).toStmt());
RENDER_STYLES_FN
.callFn([
_ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(Identifiers.clearStyles).callFn([_ANIMATION_START_STATE_STYLES_VAR])
])
.toStmt());
ast.stateTransitions.forEach(transAst => statements.push(transAst.visit(this, context)));
// this check ensures that the animation factory always returns a player
// so that the onDone callback can be used for tracking
statements.push(
new o.IfStmt(_ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR), [
_ANIMATION_PLAYER_VAR.set(
o.importExpr(Identifiers.NoOpAnimationPlayer).instantiate([])
).toStmt()
]));
statements.push(new o.IfStmt(
_ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR),
[_ANIMATION_PLAYER_VAR.set(o.importExpr(Identifiers.NoOpAnimationPlayer).instantiate([]))
.toStmt()]));
// once complete we want to apply the styles on the element
// since the destination state's values should persist once
// the animation sequence has completed.
statements.push(
_ANIMATION_PLAYER_VAR.callMethod('onDone', [
o.fn([], [
RENDER_STYLES_FN.callFn([
_ANIMATION_FACTORY_ELEMENT_VAR,
_ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(Identifiers.balanceAnimationStyles).callFn([
_ANIMATION_START_STATE_STYLES_VAR,
_ANIMATION_END_STATE_STYLES_VAR
])
]).toStmt()
])
]).toStmt());
statements.push(
_ANIMATION_FACTORY_VIEW_VAR.callMethod('registerAndStartAnimation', [
_ANIMATION_FACTORY_ELEMENT_VAR,
o.literal(this.animationName),
_ANIMATION_PLAYER_VAR
]).toStmt());
.callMethod(
'onDone',
[o.fn(
[], [RENDER_STYLES_FN
.callFn([
_ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(Identifiers.balanceAnimationStyles).callFn([
_ANIMATION_START_STATE_STYLES_VAR, _ANIMATION_END_STATE_STYLES_VAR
])
])
.toStmt()])])
.toStmt());
return o.fn([
new o.FnParam(_ANIMATION_FACTORY_VIEW_VAR.name, o.importType(Identifiers.AppView, [o.DYNAMIC_TYPE])),
new o.FnParam(_ANIMATION_FACTORY_ELEMENT_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(_ANIMATION_CURRENT_STATE_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(_ANIMATION_NEXT_STATE_VAR.name, o.DYNAMIC_TYPE)
], statements);
statements.push(_ANIMATION_FACTORY_VIEW_VAR
.callMethod(
'registerAndStartAnimation',
[
_ANIMATION_FACTORY_ELEMENT_VAR, o.literal(this.animationName),
_ANIMATION_PLAYER_VAR
])
.toStmt());
return o.fn(
[
new o.FnParam(
_ANIMATION_FACTORY_VIEW_VAR.name,
o.importType(Identifiers.AppView, [o.DYNAMIC_TYPE])),
new o.FnParam(_ANIMATION_FACTORY_ELEMENT_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(_ANIMATION_CURRENT_STATE_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(_ANIMATION_NEXT_STATE_VAR.name, o.DYNAMIC_TYPE)
],
statements);
}
build(ast: AnimationAst): CompiledAnimation {
@@ -314,24 +293,24 @@ class _AnimationBuilder implements AnimationAstVisitor {
var fnVariable = o.variable(this._fnVarName);
var lookupMap: any[] /** TODO #9100 */ = [];
StringMapWrapper.forEach(context.stateMap.states, (value: any /** TODO #9100 */, stateName: any /** TODO #9100 */) => {
var variableValue = EMPTY_MAP;
if (isPresent(value)) {
let styleMap: any[] /** TODO #9100 */ = [];
StringMapWrapper.forEach(value, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
styleMap.push([key, o.literal(value)]);
StringMapWrapper.forEach(
context.stateMap.states,
(value: any /** TODO #9100 */, stateName: any /** TODO #9100 */) => {
var variableValue = EMPTY_MAP;
if (isPresent(value)) {
let styleMap: any[] /** TODO #9100 */ = [];
StringMapWrapper.forEach(
value, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
styleMap.push([key, o.literal(value)]);
});
variableValue = o.literalMap(styleMap);
}
lookupMap.push([stateName, variableValue]);
});
variableValue = o.literalMap(styleMap);
}
lookupMap.push([stateName, variableValue]);
});
var compiledStatesMapExpr = this._statesMapVar.set(o.literalMap(lookupMap)).toDeclStmt();
return new CompiledAnimation(this.animationName,
compiledStatesMapExpr,
this._statesMapVarName,
fnStatement,
fnVariable);
return new CompiledAnimation(
this.animationName, compiledStatesMapExpr, this._statesMapVarName, fnStatement, fnVariable);
}
}
@@ -342,9 +321,9 @@ class _AnimationBuilderContext {
}
class _AnimationBuilderStateMap {
private _states: {[key: string]: {[prop: string]: string|number}} = {};
private _states: {[key: string]: {[prop: string]: string | number}} = {};
get states() { return this._states; }
registerState(name: string, value: {[prop: string]: string|number} = null): void {
registerState(name: string, value: {[prop: string]: string | number} = null): void {
var existingEntry = this._states[name];
if (isBlank(existingEntry)) {
this._states[name] = value;
@@ -369,9 +348,7 @@ function _compareToAnimationStateExpr(value: o.Expression, animationState: strin
function _isEndStateAnimateStep(step: AnimationAst): boolean {
// the final animation step is characterized by having only TWO
// keyframe values and it must have zero styles for both keyframes
if (step instanceof AnimationStepAst
&& step.duration > 0
&& step.keyframes.length == 2) {
if (step instanceof AnimationStepAst && step.duration > 0 && step.keyframes.length == 2) {
var styles1 = _getStylesArray(step.keyframes[0])[0];
var styles2 = _getStylesArray(step.keyframes[1])[0];
return StringMapWrapper.isEmpty(styles1) && StringMapWrapper.isEmpty(styles2);
@@ -1,46 +1,13 @@
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {Math} from '../facade/math';
import {ANY_STATE, FILL_STYLE_FLAG} from '../../core_private';
import {
RegExpWrapper,
isArray,
isPresent,
isBlank,
isString,
isStringMap,
NumberWrapper
} from '../facade/lang';
import {
CompileAnimationEntryMetadata,
CompileAnimationStateDeclarationMetadata,
CompileAnimationStateTransitionMetadata,
CompileAnimationMetadata,
CompileAnimationWithStepsMetadata,
CompileAnimationStyleMetadata,
CompileAnimationAnimateMetadata,
CompileAnimationGroupMetadata,
CompileAnimationSequenceMetadata,
CompileAnimationKeyframesSequenceMetadata
} from '../compile_metadata';
import {
AnimationAst,
AnimationEntryAst,
AnimationStateTransitionAst,
AnimationStateDeclarationAst,
AnimationKeyframeAst,
AnimationStylesAst,
AnimationWithStepsAst,
AnimationSequenceAst,
AnimationGroupAst,
AnimationStepAst,
AnimationStateTransitionExpression
} from './animation_ast';
import {StylesCollection} from './styles_collection';
import {CompileAnimationAnimateMetadata, CompileAnimationEntryMetadata, CompileAnimationGroupMetadata, CompileAnimationKeyframesSequenceMetadata, CompileAnimationMetadata, CompileAnimationSequenceMetadata, CompileAnimationStateDeclarationMetadata, CompileAnimationStateTransitionMetadata, CompileAnimationStyleMetadata, CompileAnimationWithStepsMetadata} from '../compile_metadata';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {NumberWrapper, RegExpWrapper, isArray, isBlank, isPresent, isString, isStringMap} from '../facade/lang';
import {Math} from '../facade/math';
import {ParseError} from '../parse_util';
import {AnimationAst, AnimationEntryAst, AnimationGroupAst, AnimationKeyframeAst, AnimationSequenceAst, AnimationStateDeclarationAst, AnimationStateTransitionAst, AnimationStateTransitionExpression, AnimationStepAst, AnimationStylesAst, AnimationWithStepsAst} from './animation_ast';
import {StylesCollection} from './styles_collection';
const _INITIAL_KEYFRAME = 0;
const _TERMINAL_KEYFRAME = 1;
const _ONE_SECOND = 1000;
@@ -71,21 +38,24 @@ export function parseAnimationEntry(entry: CompileAnimationEntryMetadata): Parse
}
});
var stateTransitionAsts = transitions.map(transDef =>
_parseAnimationStateTransition(transDef, stateStyles, errors));
var stateTransitionAsts =
transitions.map(transDef => _parseAnimationStateTransition(transDef, stateStyles, errors));
var ast = new AnimationEntryAst(entry.name, stateDeclarationAsts, stateTransitionAsts);
return new ParsedAnimationResult(ast, errors);
}
function _parseAnimationDeclarationStates(stateMetadata: CompileAnimationStateDeclarationMetadata, errors: AnimationParseError[]): AnimationStateDeclarationAst[] {
var styleValues: {[key: string]: string|number}[] = [];
function _parseAnimationDeclarationStates(
stateMetadata: CompileAnimationStateDeclarationMetadata,
errors: AnimationParseError[]): AnimationStateDeclarationAst[] {
var styleValues: {[key: string]: string | number}[] = [];
stateMetadata.styles.styles.forEach(stylesEntry => {
// TODO (matsko): change this when we get CSS class integration support
if (isStringMap(stylesEntry)) {
styleValues.push(<{[key: string]: string|number}>stylesEntry);
styleValues.push(<{[key: string]: string | number}>stylesEntry);
} else {
errors.push(new AnimationParseError(`State based animations cannot contain references to other states`));
errors.push(new AnimationParseError(
`State based animations cannot contain references to other states`));
}
});
var defStyles = new AnimationStylesAst(styleValues);
@@ -94,9 +64,10 @@ function _parseAnimationDeclarationStates(stateMetadata: CompileAnimationStateDe
return states.map(state => new AnimationStateDeclarationAst(state, defStyles));
}
function _parseAnimationStateTransition(transitionStateMetadata: CompileAnimationStateTransitionMetadata,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): AnimationStateTransitionAst {
function _parseAnimationStateTransition(
transitionStateMetadata: CompileAnimationStateTransitionMetadata,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): AnimationStateTransitionAst {
var styles = new StylesCollection();
var transitionExprs: any[] /** TODO #9100 */ = [];
var transitionStates = transitionStateMetadata.stateChangeExpr.split(/\s*,\s*/);
@@ -112,14 +83,15 @@ function _parseAnimationStateTransition(transitionStateMetadata: CompileAnimatio
_fillAnimationAstStartingKeyframes(animationAst, styles, errors);
}
var sequenceAst = (animationAst instanceof AnimationSequenceAst)
? <AnimationSequenceAst>animationAst
: new AnimationSequenceAst([animationAst]);
var sequenceAst = (animationAst instanceof AnimationSequenceAst) ?
<AnimationSequenceAst>animationAst :
new AnimationSequenceAst([animationAst]);
return new AnimationStateTransitionAst(transitionExprs, sequenceAst);
}
function _parseAnimationTransitionExpr(eventStr: string, errors: AnimationParseError[]): AnimationStateTransitionExpression[] {
function _parseAnimationTransitionExpr(
eventStr: string, errors: AnimationParseError[]): AnimationStateTransitionExpression[] {
var expressions: any[] /** TODO #9100 */ = [];
var match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
if (!isPresent(match) || match.length < 4) {
@@ -130,19 +102,17 @@ function _parseAnimationTransitionExpr(eventStr: string, errors: AnimationParseE
var fromState = match[1];
var separator = match[2];
var toState = match[3];
expressions.push(
new AnimationStateTransitionExpression(fromState, toState));
expressions.push(new AnimationStateTransitionExpression(fromState, toState));
var isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;
if (separator[0] == '<' && !isFullAnyStateExpr) {
expressions.push(
new AnimationStateTransitionExpression(toState, fromState));
expressions.push(new AnimationStateTransitionExpression(toState, fromState));
}
return expressions;
}
function _fetchSylesFromState(stateName: string,
stateStyles: {[key: string]: AnimationStylesAst}): CompileAnimationStyleMetadata {
function _fetchSylesFromState(stateName: string, stateStyles: {[key: string]: AnimationStylesAst}):
CompileAnimationStyleMetadata {
var entry = stateStyles[stateName];
if (isPresent(entry)) {
var styles = <{[key: string]: string | number}[]>entry.styles;
@@ -151,20 +121,20 @@ function _fetchSylesFromState(stateName: string,
return null;
}
function _normalizeAnimationEntry(entry: CompileAnimationMetadata | CompileAnimationMetadata[])
:CompileAnimationMetadata {
return isArray(entry)
? new CompileAnimationSequenceMetadata(<CompileAnimationMetadata[]>entry)
: <CompileAnimationMetadata>entry;
function _normalizeAnimationEntry(entry: CompileAnimationMetadata | CompileAnimationMetadata[]):
CompileAnimationMetadata {
return isArray(entry) ? new CompileAnimationSequenceMetadata(<CompileAnimationMetadata[]>entry) :
<CompileAnimationMetadata>entry;
}
function _normalizeStyleMetadata(entry: CompileAnimationStyleMetadata,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): Array<{[key: string]: string|number}> {
function _normalizeStyleMetadata(
entry: CompileAnimationStyleMetadata, stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): Array<{[key: string]: string | number}> {
var normalizedStyles: any[] /** TODO #9100 */ = [];
entry.styles.forEach(styleEntry => {
if (isString(styleEntry)) {
ListWrapper.addAll(normalizedStyles, _resolveStylesFromState(<string>styleEntry, stateStyles, errors));
ListWrapper.addAll(
normalizedStyles, _resolveStylesFromState(<string>styleEntry, stateStyles, errors));
} else {
normalizedStyles.push(<{[key: string]: string | number}>styleEntry);
}
@@ -172,31 +142,30 @@ function _normalizeStyleMetadata(entry: CompileAnimationStyleMetadata,
return normalizedStyles;
}
function _normalizeStyleSteps(entry: CompileAnimationMetadata,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): CompileAnimationMetadata {
function _normalizeStyleSteps(
entry: CompileAnimationMetadata, stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): CompileAnimationMetadata {
var steps = _normalizeStyleStepEntry(entry, stateStyles, errors);
return new CompileAnimationSequenceMetadata(steps);
}
function _mergeAnimationStyles(stylesList: any[], newItem: {[key: string]: string|number}|string) {
function _mergeAnimationStyles(
stylesList: any[], newItem: {[key: string]: string | number} | string) {
if (isStringMap(newItem) && stylesList.length > 0) {
var lastIndex = stylesList.length - 1;
var lastItem = stylesList[lastIndex];
if (isStringMap(lastItem)) {
stylesList[lastIndex] = StringMapWrapper.merge(
<{[key: string]: string|number}>lastItem,
<{[key: string]: string|number}>newItem
);
<{[key: string]: string | number}>lastItem, <{[key: string]: string | number}>newItem);
return;
}
}
stylesList.push(newItem);
}
function _normalizeStyleStepEntry(entry: CompileAnimationMetadata,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): CompileAnimationMetadata[] {
function _normalizeStyleStepEntry(
entry: CompileAnimationMetadata, stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): CompileAnimationMetadata[] {
var steps: CompileAnimationMetadata[];
if (entry instanceof CompileAnimationWithStepsMetadata) {
steps = entry.steps;
@@ -215,9 +184,8 @@ function _normalizeStyleStepEntry(entry: CompileAnimationMetadata,
if (!isPresent(combinedStyles)) {
combinedStyles = [];
}
_normalizeStyleMetadata(<CompileAnimationStyleMetadata>step, stateStyles, errors).forEach(entry => {
_mergeAnimationStyles(combinedStyles, entry);
});
_normalizeStyleMetadata(<CompileAnimationStyleMetadata>step, stateStyles, errors)
.forEach(entry => { _mergeAnimationStyles(combinedStyles, entry); });
} else {
// it is important that we create a metadata entry of the combined styles
// before we go on an process the animate, sequence or group metadata steps.
@@ -233,17 +201,17 @@ function _normalizeStyleStepEntry(entry: CompileAnimationMetadata,
// those style steps are not going to be squashed
var animateStyleValue = (<CompileAnimationAnimateMetadata>step).styles;
if (animateStyleValue instanceof CompileAnimationStyleMetadata) {
animateStyleValue.styles = _normalizeStyleMetadata(animateStyleValue, stateStyles, errors);
animateStyleValue.styles =
_normalizeStyleMetadata(animateStyleValue, stateStyles, errors);
} else if (animateStyleValue instanceof CompileAnimationKeyframesSequenceMetadata) {
animateStyleValue.steps.forEach(step => {
step.styles = _normalizeStyleMetadata(step, stateStyles, errors);
});
animateStyleValue.steps.forEach(
step => { step.styles = _normalizeStyleMetadata(step, stateStyles, errors); });
}
} else if (step instanceof CompileAnimationWithStepsMetadata) {
let innerSteps = _normalizeStyleStepEntry(step, stateStyles, errors);
step = step instanceof CompileAnimationGroupMetadata
? new CompileAnimationGroupMetadata(innerSteps)
: new CompileAnimationSequenceMetadata(innerSteps);
step = step instanceof CompileAnimationGroupMetadata ?
new CompileAnimationGroupMetadata(innerSteps) :
new CompileAnimationSequenceMetadata(innerSteps);
}
newSteps.push(step);
@@ -259,15 +227,18 @@ function _normalizeStyleStepEntry(entry: CompileAnimationMetadata,
}
function _resolveStylesFromState(stateName: string, stateStyles: {[key: string]: AnimationStylesAst}, errors: AnimationParseError[]) {
var styles: {[key: string]: string|number}[] = [];
function _resolveStylesFromState(
stateName: string, stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]) {
var styles: {[key: string]: string | number}[] = [];
if (stateName[0] != ':') {
errors.push(new AnimationParseError(`Animation states via styles must be prefixed with a ":"`));
} else {
var normalizedStateName = stateName.substring(1);
var value = stateStyles[normalizedStateName];
if (!isPresent(value)) {
errors.push(new AnimationParseError(`Unable to apply styles due to missing a state: "${normalizedStateName}"`));
errors.push(new AnimationParseError(
`Unable to apply styles due to missing a state: "${normalizedStateName}"`));
} else {
value.styles.forEach(stylesEntry => {
if (isStringMap(stylesEntry)) {
@@ -283,17 +254,17 @@ class _AnimationTimings {
constructor(public duration: number, public delay: number, public easing: string) {}
}
function _parseAnimationKeyframes(keyframeSequence: CompileAnimationKeyframesSequenceMetadata,
currentTime: number,
collectedStyles: StylesCollection,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): AnimationKeyframeAst[] {
function _parseAnimationKeyframes(
keyframeSequence: CompileAnimationKeyframesSequenceMetadata, currentTime: number,
collectedStyles: StylesCollection, stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): AnimationKeyframeAst[] {
var totalEntries = keyframeSequence.steps.length;
var totalOffsets = 0;
keyframeSequence.steps.forEach(step => totalOffsets += (isPresent(step.offset) ? 1 : 0));
if (totalOffsets > 0 && totalOffsets < totalEntries) {
errors.push(new AnimationParseError(`Not all style() entries contain an offset for the provided keyframe()`));
errors.push(new AnimationParseError(
`Not all style() entries contain an offset for the provided keyframe()`));
totalOffsets = totalEntries;
}
@@ -305,13 +276,15 @@ function _parseAnimationKeyframes(keyframeSequence: CompileAnimationKeyframesSeq
var lastOffset = 0;
keyframeSequence.steps.forEach(styleMetadata => {
var offset = styleMetadata.offset;
var keyframeStyles: {[key: string]: string|number} = {};
var keyframeStyles: {[key: string]: string | number} = {};
styleMetadata.styles.forEach(entry => {
StringMapWrapper.forEach(<{[key: string]: string|number}>entry, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (prop != 'offset') {
keyframeStyles[prop] = value;
}
});
StringMapWrapper.forEach(
<{[key: string]: string | number}>entry,
(value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (prop != 'offset') {
keyframeStyles[prop] = value;
}
});
});
if (isPresent(offset)) {
@@ -326,7 +299,7 @@ function _parseAnimationKeyframes(keyframeSequence: CompileAnimationKeyframesSeq
});
if (doSortKeyframes) {
ListWrapper.sort(rawKeyframes, (a,b) => a[0] <= b[0] ? -1 : 1);
ListWrapper.sort(rawKeyframes, (a, b) => a[0] <= b[0] ? -1 : 1);
}
var i: any /** TODO #9100 */;
@@ -348,32 +321,33 @@ function _parseAnimationKeyframes(keyframeSequence: CompileAnimationKeyframesSeq
let entry = rawKeyframes[i];
let styles = entry[1];
StringMapWrapper.forEach(styles, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (!isPresent(firstKeyframeStyles[prop])) {
firstKeyframeStyles[prop] = FILL_STYLE_FLAG;
}
});
StringMapWrapper.forEach(
styles, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (!isPresent(firstKeyframeStyles[prop])) {
firstKeyframeStyles[prop] = FILL_STYLE_FLAG;
}
});
}
for (i = limit - 1; i >= 0; i--) {
let entry = rawKeyframes[i];
let styles = entry[1];
StringMapWrapper.forEach(styles, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (!isPresent(lastKeyframeStyles[prop])) {
lastKeyframeStyles[prop] = value;
}
});
StringMapWrapper.forEach(
styles, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (!isPresent(lastKeyframeStyles[prop])) {
lastKeyframeStyles[prop] = value;
}
});
}
return rawKeyframes.map(entry => new AnimationKeyframeAst(entry[0], new AnimationStylesAst([entry[1]])));
return rawKeyframes.map(
entry => new AnimationKeyframeAst(entry[0], new AnimationStylesAst([entry[1]])));
}
function _parseTransitionAnimation(entry: CompileAnimationMetadata,
currentTime: number,
collectedStyles: StylesCollection,
stateStyles: {[key: string]: AnimationStylesAst},
errors: AnimationParseError[]): AnimationAst {
function _parseTransitionAnimation(
entry: CompileAnimationMetadata, currentTime: number, collectedStyles: StylesCollection,
stateStyles: {[key: string]: AnimationStylesAst}, errors: AnimationParseError[]): AnimationAst {
var ast: any /** TODO #9100 */;
var playTime = 0;
var startingTime = currentTime;
@@ -388,10 +362,11 @@ function _parseTransitionAnimation(entry: CompileAnimationMetadata,
if (entry instanceof CompileAnimationStyleMetadata) {
entry.styles.forEach(stylesEntry => {
// by this point we know that we only have stringmap values
var map = <{[key: string]: string|number}>stylesEntry;
StringMapWrapper.forEach(map, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
collectedStyles.insertAtTime(prop, time, value);
});
var map = <{[key: string]: string | number}>stylesEntry;
StringMapWrapper.forEach(
map, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
collectedStyles.insertAtTime(prop, time, value);
});
});
previousStyles = entry.styles;
return;
@@ -432,25 +407,26 @@ function _parseTransitionAnimation(entry: CompileAnimationMetadata,
var keyframes: any /** TODO #9100 */;
if (styles instanceof CompileAnimationKeyframesSequenceMetadata) {
keyframes = _parseAnimationKeyframes(styles, currentTime, collectedStyles, stateStyles, errors);
keyframes =
_parseAnimationKeyframes(styles, currentTime, collectedStyles, stateStyles, errors);
} else {
let styleData = <CompileAnimationStyleMetadata>styles;
let offset = _TERMINAL_KEYFRAME;
let styleAst = new AnimationStylesAst(<{[key: string]: string|number}[]>styleData.styles);
let styleAst = new AnimationStylesAst(<{[key: string]: string | number}[]>styleData.styles);
var keyframe = new AnimationKeyframeAst(offset, styleAst);
keyframes = [keyframe];
}
ast = new AnimationStepAst(new AnimationStylesAst([]), keyframes, timings.duration, timings.delay, timings.easing);
ast = new AnimationStepAst(
new AnimationStylesAst([]), keyframes, timings.duration, timings.delay, timings.easing);
playTime = timings.duration + timings.delay;
currentTime += playTime;
keyframes.forEach((keyframe: any /** TODO #9100 */) =>
keyframe.styles.styles.forEach((entry: any /** TODO #9100 */) =>
StringMapWrapper.forEach(entry, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) =>
collectedStyles.insertAtTime(prop, currentTime, value))
)
);
keyframes.forEach(
(keyframe: any /** TODO #9100 */) => keyframe.styles.styles.forEach(
(entry: any /** TODO #9100 */) => StringMapWrapper.forEach(
entry, (value: any /** TODO #9100 */, prop: any /** TODO #9100 */) =>
collectedStyles.insertAtTime(prop, currentTime, value))));
} else {
// if the code reaches this stage then an error
// has already been populated within the _normalizeStyleSteps()
@@ -463,15 +439,15 @@ function _parseTransitionAnimation(entry: CompileAnimationMetadata,
return ast;
}
function _fillAnimationAstStartingKeyframes(ast: AnimationAst, collectedStyles: StylesCollection,
errors: AnimationParseError[]): void {
function _fillAnimationAstStartingKeyframes(
ast: AnimationAst, collectedStyles: StylesCollection, errors: AnimationParseError[]): void {
// steps that only contain style will not be filled
if ((ast instanceof AnimationStepAst) && ast.keyframes.length > 0) {
var keyframes = ast.keyframes;
if (keyframes.length == 1) {
var endKeyframe = keyframes[0];
var startKeyframe = _createStartKeyframeFromEndKeyframe(endKeyframe, ast.startTime,
ast.playTime, collectedStyles, errors);
var startKeyframe = _createStartKeyframeFromEndKeyframe(
endKeyframe, ast.startTime, ast.playTime, collectedStyles, errors);
ast.keyframes = [startKeyframe, endKeyframe];
}
} else if (ast instanceof AnimationWithStepsAst) {
@@ -479,8 +455,8 @@ function _fillAnimationAstStartingKeyframes(ast: AnimationAst, collectedStyles:
}
}
function _parseTimeExpression(exp: string | number,
errors: AnimationParseError[]): _AnimationTimings {
function _parseTimeExpression(
exp: string | number, errors: AnimationParseError[]): _AnimationTimings {
var regex = /^([\.\d]+)(m?s)(?:\s+([\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?/gi;
var duration: number;
var delay: number = 0;
@@ -520,17 +496,18 @@ function _parseTimeExpression(exp: string | number,
return new _AnimationTimings(duration, delay, easing);
}
function _createStartKeyframeFromEndKeyframe(endKeyframe: AnimationKeyframeAst, startTime: number,
duration: number, collectedStyles: StylesCollection,
errors: AnimationParseError[]): AnimationKeyframeAst {
function _createStartKeyframeFromEndKeyframe(
endKeyframe: AnimationKeyframeAst, startTime: number, duration: number,
collectedStyles: StylesCollection, errors: AnimationParseError[]): AnimationKeyframeAst {
var values: {[key: string]: string | number} = {};
var endTime = startTime + duration;
endKeyframe.styles.styles.forEach((styleData: {[key: string]: string|number}) => {
endKeyframe.styles.styles.forEach((styleData: {[key: string]: string | number}) => {
StringMapWrapper.forEach(styleData, (val: any /** TODO #9100 */, prop: any /** TODO #9100 */) => {
if (prop == 'offset') return;
var resultIndex = collectedStyles.indexOfAtOrBeforeTime(prop, startTime);
var resultEntry: any /** TODO #9100 */, nextEntry: any /** TODO #9100 */, value: any /** TODO #9100 */;
var resultEntry: any /** TODO #9100 */, nextEntry: any /** TODO #9100 */,
value: any /** TODO #9100 */;
if (isPresent(resultIndex)) {
resultEntry = collectedStyles.getByIndex(prop, resultIndex);
value = resultEntry.value;
@@ -1,10 +1,10 @@
import {isPresent} from '../facade/lang';
import {ListWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
export class StylesCollectionEntry {
constructor(public time: number, public value: string | number) {}
constructor(public time: number, public value: string|number) {}
matches(time: number, value: string | number): boolean {
matches(time: number, value: string|number): boolean {
return time == this.time && value == this.value;
}
}
@@ -12,7 +12,7 @@ export class StylesCollectionEntry {
export class StylesCollection {
styles: {[key: string]: StylesCollectionEntry[]} = {};
insertAtTime(property: string, time: number, value: string | number) {
insertAtTime(property: string, time: number, value: string|number) {
var tuple = new StylesCollectionEntry(time, value);
var entries = this.styles[property];
if (!isPresent(entries)) {
+1 -1
View File
@@ -1,5 +1,5 @@
import {isArray, isString, isBlank, assertionsEnabled} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {assertionsEnabled, isArray, isBlank, isString} from '../src/facade/lang';
export function assertArrayOfStrings(identifier: string, value: any) {
if (!assertionsEnabled() || isBlank(value)) {
+128 -162
View File
@@ -1,32 +1,14 @@
import {ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
import {
CHANGE_DETECTION_STRATEGY_VALUES,
VIEW_ENCAPSULATION_VALUES,
LifecycleHooks,
LIFECYCLE_HOOKS_VALUES,
reflector
} from '../core_private';
import {
isPresent,
isBlank,
isNumber,
isBoolean,
normalizeBool,
normalizeBlank,
serializeEnum,
Type,
isString,
RegExpWrapper,
StringWrapper,
NumberWrapper,
isArray
} from '../src/facade/lang';
import {unimplemented, BaseException} from '../src/facade/exceptions';
import {StringMapWrapper, ListWrapper} from '../src/facade/collection';
import {CHANGE_DETECTION_STRATEGY_VALUES, LIFECYCLE_HOOKS_VALUES, LifecycleHooks, VIEW_ENCAPSULATION_VALUES, reflector} from '../core_private';
import {ListWrapper, StringMapWrapper} from '../src/facade/collection';
import {BaseException, unimplemented} from '../src/facade/exceptions';
import {NumberWrapper, RegExpWrapper, StringWrapper, Type, isArray, isBlank, isBoolean, isNumber, isPresent, isString, normalizeBlank, normalizeBool, serializeEnum} from '../src/facade/lang';
import {CssSelector} from './selector';
import {splitAtColon, sanitizeIdentifier} from './util';
import {getUrlScheme} from './url_resolver';
import {sanitizeIdentifier, splitAtColon} from './util';
// group 2: "event" from "(event)"
var HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))$/g;
@@ -56,15 +38,13 @@ export class CompileAnimationEntryMetadata {
return new CompileAnimationEntryMetadata(value['name'], defs);
}
constructor(public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
constructor(
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationEntryMetadata',
'value': {
'name' : this.name,
'definitions': _arrayToJson(this.definitions)
}
'value': {'name': this.name, 'definitions': _arrayToJson(this.definitions)}
};
}
}
@@ -78,15 +58,14 @@ export class CompileAnimationStateDeclarationMetadata extends CompileAnimationSt
return new CompileAnimationStateDeclarationMetadata(value['stateNameExpr'], styles);
}
constructor(public stateNameExpr: string, public styles: CompileAnimationStyleMetadata) { super(); }
constructor(public stateNameExpr: string, public styles: CompileAnimationStyleMetadata) {
super();
}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationStateDeclarationMetadata',
'value': {
'stateNameExpr': this.stateNameExpr,
'styles': this.styles.toJson()
}
'value': {'stateNameExpr': this.stateNameExpr, 'styles': this.styles.toJson()}
};
}
}
@@ -103,17 +82,12 @@ export class CompileAnimationStateTransitionMetadata extends CompileAnimationSta
toJson(): {[key: string]: any} {
return {
'class': 'AnimationStateTransitionMetadata',
'value': {
'stateChangeExpr': this.stateChangeExpr,
'steps': this.steps.toJson()
}
'value': {'stateChangeExpr': this.stateChangeExpr, 'steps': this.steps.toJson()}
};
}
}
export abstract class CompileAnimationMetadata {
abstract toJson(): {[key: string]: any};
}
export abstract class CompileAnimationMetadata { abstract toJson(): {[key: string]: any}; }
export class CompileAnimationKeyframesSequenceMetadata extends CompileAnimationMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationKeyframesSequenceMetadata {
@@ -121,15 +95,10 @@ export class CompileAnimationKeyframesSequenceMetadata extends CompileAnimationM
return new CompileAnimationKeyframesSequenceMetadata(<CompileAnimationStyleMetadata[]>steps);
}
constructor(public steps: CompileAnimationStyleMetadata[] = []) {
super();
}
constructor(public steps: CompileAnimationStyleMetadata[] = []) { super(); }
toJson(): {[key: string]: any} {
return {
'class': 'AnimationKeyframesSequenceMetadata',
'value': _arrayToJson(this.steps)
};
return {'class': 'AnimationKeyframesSequenceMetadata', 'value': _arrayToJson(this.steps)};
}
}
@@ -142,15 +111,15 @@ export class CompileAnimationStyleMetadata extends CompileAnimationMetadata {
return new CompileAnimationStyleMetadata(offset, styles);
}
constructor(public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) { super(); }
constructor(
public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) {
super();
}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationStyleMetadata',
'value': {
'offset': this.offset,
'styles': this.styles
}
'value': {'offset': this.offset, 'styles': this.styles}
};
}
}
@@ -163,16 +132,16 @@ export class CompileAnimationAnimateMetadata extends CompileAnimationMetadata {
return new CompileAnimationAnimateMetadata(timings, styles);
}
constructor(public timings: string|number = 0,
public styles: CompileAnimationStyleMetadata|CompileAnimationKeyframesSequenceMetadata = null) { super(); }
constructor(
public timings: string|number = 0, public styles: CompileAnimationStyleMetadata|
CompileAnimationKeyframesSequenceMetadata = null) {
super();
}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationAnimateMetadata',
'value': {
'timings': this.timings,
'styles': _objToJson(this.styles)
}
'value': {'timings': this.timings, 'styles': _objToJson(this.styles)}
};
}
}
@@ -187,33 +156,23 @@ export class CompileAnimationSequenceMetadata extends CompileAnimationWithStepsM
return new CompileAnimationSequenceMetadata(steps);
}
constructor(steps: CompileAnimationMetadata[] = null) {
super(steps);
}
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
toJson(): {[key: string]: any} {
return {
'class': 'AnimationSequenceMetadata',
'value': _arrayToJson(this.steps)
};
return {'class': 'AnimationSequenceMetadata', 'value': _arrayToJson(this.steps)};
}
}
export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationGroupMetadata {
var steps = _arrayFromJson(data["value"], metadataFromJson);
var steps = _arrayFromJson(data['value'], metadataFromJson);
return new CompileAnimationGroupMetadata(steps);
}
constructor(steps: CompileAnimationMetadata[] = null) {
super(steps);
}
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
toJson(): {[key: string]: any} {
return {
'class': 'AnimationGroupMetadata',
'value': _arrayToJson(this.steps)
};
return {'class': 'AnimationGroupMetadata', 'value': _arrayToJson(this.steps)};
}
}
@@ -268,19 +227,20 @@ export class CompileDiDependencyMetadata {
token: CompileTokenMetadata;
value: any;
constructor({isAttribute, isSelf, isHost, isSkipSelf, isOptional, isValue, query, viewQuery,
token, value}: {
isAttribute?: boolean,
isSelf?: boolean,
isHost?: boolean,
isSkipSelf?: boolean,
isOptional?: boolean,
isValue?: boolean,
query?: CompileQueryMetadata,
viewQuery?: CompileQueryMetadata,
token?: CompileTokenMetadata,
value?: any
} = {}) {
constructor(
{isAttribute, isSelf, isHost, isSkipSelf, isOptional, isValue, query, viewQuery, token,
value}: {
isAttribute?: boolean,
isSelf?: boolean,
isHost?: boolean,
isSkipSelf?: boolean,
isOptional?: boolean,
isValue?: boolean,
query?: CompileQueryMetadata,
viewQuery?: CompileQueryMetadata,
token?: CompileTokenMetadata,
value?: any
} = {}) {
this.isAttribute = normalizeBool(isAttribute);
this.isSelf = normalizeBool(isSelf);
this.isHost = normalizeBool(isHost);
@@ -435,11 +395,9 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
identifierIsInstance: boolean;
private _assetCacheKey = UNDEFINED;
constructor({value, identifier, identifierIsInstance}: {
value?: any,
identifier?: CompileIdentifierMetadata,
identifierIsInstance?: boolean
}) {
constructor(
{value, identifier, identifierIsInstance}:
{value?: any, identifier?: CompileIdentifierMetadata, identifierIsInstance?: boolean}) {
this.value = value;
this.identifier = identifier;
this.identifierIsInstance = normalizeBool(identifierIsInstance);
@@ -473,11 +431,9 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
if (this._assetCacheKey === UNDEFINED) {
if (isPresent(this.identifier)) {
if (isPresent(this.identifier.moduleUrl) &&
isPresent(getUrlScheme(this.identifier.moduleUrl))) {
var uri = reflector.importUri({
'filePath': this.identifier.moduleUrl,
'name': this.identifier.name
});
isPresent(getUrlScheme(this.identifier.moduleUrl))) {
var uri = reflector.importUri(
{'filePath': this.identifier.moduleUrl, 'name': this.identifier.name});
this._assetCacheKey = `${this.identifier.name}|${uri}|${this.identifierIsInstance}`;
} else {
this._assetCacheKey = null;
@@ -493,7 +449,7 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
var rk = this.runtimeCacheKey;
var ak = this.assetCacheKey;
return (isPresent(rk) && rk == token2.runtimeCacheKey) ||
(isPresent(ak) && ak == token2.assetCacheKey);
(isPresent(ak) && ak == token2.assetCacheKey);
}
get name(): string {
@@ -647,15 +603,16 @@ export class CompileTemplateMetadata {
styleUrls: string[];
animations: CompileAnimationEntryMetadata[];
ngContentSelectors: string[];
constructor({encapsulation, template, templateUrl, styles, styleUrls, animations, ngContentSelectors}: {
encapsulation?: ViewEncapsulation,
template?: string,
templateUrl?: string,
styles?: string[],
styleUrls?: string[],
ngContentSelectors?: string[],
animations?: CompileAnimationEntryMetadata[]
} = {}) {
constructor(
{encapsulation, template, templateUrl, styles, styleUrls, animations, ngContentSelectors}: {
encapsulation?: ViewEncapsulation,
template?: string,
templateUrl?: string,
styles?: string[],
styleUrls?: string[],
ngContentSelectors?: string[],
animations?: CompileAnimationEntryMetadata[]
} = {}) {
this.encapsulation = encapsulation;
this.template = template;
this.templateUrl = templateUrl;
@@ -666,11 +623,12 @@ export class CompileTemplateMetadata {
}
static fromJson(data: {[key: string]: any}): CompileTemplateMetadata {
var animations = <CompileAnimationEntryMetadata[]>_arrayFromJson(data['animations'], metadataFromJson);
var animations =
<CompileAnimationEntryMetadata[]>_arrayFromJson(data['animations'], metadataFromJson);
return new CompileTemplateMetadata({
encapsulation: isPresent(data['encapsulation']) ?
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
data['encapsulation'],
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
data['encapsulation'],
template: data['template'],
templateUrl: data['templateUrl'],
styles: data['styles'],
@@ -682,8 +640,8 @@ export class CompileTemplateMetadata {
toJson(): {[key: string]: any} {
return {
'encapsulation':
isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) : this.encapsulation,
'encapsulation': isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) :
this.encapsulation,
'template': this.template,
'templateUrl': this.templateUrl,
'styles': this.styles,
@@ -698,25 +656,26 @@ export class CompileTemplateMetadata {
* Metadata regarding compilation of a directive.
*/
export class CompileDirectiveMetadata implements CompileMetadataWithType {
static create({type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
lifecycleHooks, providers, viewProviders, queries, viewQueries, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
exportAs?: string,
changeDetection?: ChangeDetectionStrategy,
inputs?: string[],
outputs?: string[],
host?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
viewProviders?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata
} = {}): CompileDirectiveMetadata {
static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
lifecycleHooks, providers, viewProviders, queries, viewQueries, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
exportAs?: string,
changeDetection?: ChangeDetectionStrategy,
inputs?: string[],
outputs?: string[],
host?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
viewProviders?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata
} = {}): CompileDirectiveMetadata {
var hostListeners: {[key: string]: string} = {};
var hostProperties: {[key: string]: string} = {};
var hostAttributes: {[key: string]: string} = {};
@@ -787,28 +746,29 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
viewQueries: CompileQueryMetadata[];
template: CompileTemplateMetadata;
constructor({type, isComponent, selector, exportAs, changeDetection, inputs, outputs,
hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers,
viewProviders, queries, viewQueries, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
exportAs?: string,
changeDetection?: ChangeDetectionStrategy,
inputs?: {[key: string]: string},
outputs?: {[key: string]: string},
hostListeners?: {[key: string]: string},
hostProperties?: {[key: string]: string},
hostAttributes?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
viewProviders?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata
} = {}) {
constructor(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners,
hostProperties, hostAttributes, lifecycleHooks, providers, viewProviders, queries,
viewQueries, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
exportAs?: string,
changeDetection?: ChangeDetectionStrategy,
inputs?: {[key: string]: string},
outputs?: {[key: string]: string},
hostListeners?: {[key: string]: string},
hostProperties?: {[key: string]: string},
hostAttributes?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
viewProviders?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata
} = {}) {
this.type = type;
this.isComponent = isComponent;
this.selector = selector;
@@ -836,8 +796,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
exportAs: data['exportAs'],
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
changeDetection: isPresent(data['changeDetection']) ?
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
data['changeDetection'],
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
data['changeDetection'],
inputs: data['inputs'],
outputs: data['outputs'],
hostListeners: data['hostListeners'],
@@ -881,8 +841,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
/**
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
*/
export function createHostComponentMeta(componentType: CompileTypeMetadata,
componentSelector: string): CompileDirectiveMetadata {
export function createHostComponentMeta(
componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
return CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({
@@ -891,8 +851,14 @@ export function createHostComponentMeta(componentType: CompileTypeMetadata,
moduleUrl: componentType.moduleUrl,
isHost: true
}),
template: new CompileTemplateMetadata(
{template: template, templateUrl: '', styles: [], styleUrls: [], ngContentSelectors: [], animations:[]}),
template: new CompileTemplateMetadata({
template: template,
templateUrl: '',
styles: [],
styleUrls: [],
ngContentSelectors: [],
animations: []
}),
changeDetection: ChangeDetectionStrategy.Default,
inputs: [],
outputs: [],
@@ -966,7 +932,7 @@ function _arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
return isBlank(obj) ? null : obj.map(o => _objFromJson(o, fn));
}
function _arrayToJson(obj: any[]): string | {[key: string]: any} {
function _arrayToJson(obj: any[]): string|{[key: string]: any} {
return isBlank(obj) ? null : obj.map(_objToJson);
}
@@ -976,7 +942,7 @@ function _objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {
return fn(obj);
}
function _objToJson(obj: any): string | {[key: string]: any} {
function _objToJson(obj: any): string|{[key: string]: any} {
if (isArray(obj)) return _arrayToJson(obj);
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
return obj.toJson();
+4 -14
View File
@@ -39,24 +39,14 @@ function _createCompilerConfig() {
* A set of providers that provide `RuntimeCompiler` and its dependencies to use for
* template compilation.
*/
export const COMPILER_PROVIDERS: Array<any | Type | {[k: string]: any} | any[]> =
export const COMPILER_PROVIDERS: Array<any|Type|{[k: string]: any}|any[]> =
/*@ts2dart_const*/[
Lexer,
Parser,
HtmlParser,
TemplateParser,
DirectiveNormalizer,
CompileMetadataResolver,
DEFAULT_PACKAGE_URL_PROVIDER,
StyleCompiler,
ViewCompiler,
Lexer, Parser, HtmlParser, TemplateParser, DirectiveNormalizer, CompileMetadataResolver,
DEFAULT_PACKAGE_URL_PROVIDER, StyleCompiler, ViewCompiler,
/*@ts2dart_Provider*/ {provide: CompilerConfig, useFactory: _createCompilerConfig, deps: []},
RuntimeCompiler,
/*@ts2dart_Provider*/ {provide: ComponentResolver, useExisting: RuntimeCompiler},
DomElementSchemaRegistry,
/*@ts2dart_Provider*/ {provide: ElementSchemaRegistry, useExisting: DomElementSchemaRegistry},
UrlResolver,
ViewResolver,
DirectiveResolver,
PipeResolver
UrlResolver, ViewResolver, DirectiveResolver, PipeResolver
];
+9 -7
View File
@@ -1,16 +1,18 @@
import {isBlank} from '../src/facade/lang';
import {unimplemented} from '../src/facade/exceptions';
import {Identifiers} from './identifiers';
import {CompileIdentifierMetadata} from './compile_metadata';
import {ViewEncapsulation} from '@angular/core';
import {unimplemented} from '../src/facade/exceptions';
import {isBlank} from '../src/facade/lang';
import {CompileIdentifierMetadata} from './compile_metadata';
import {Identifiers} from './identifiers';
export class CompilerConfig {
public renderTypes: RenderTypes;
public defaultEncapsulation: ViewEncapsulation;
constructor(public genDebugInfo: boolean, public logBindingUpdate: boolean,
public useJit: boolean, renderTypes: RenderTypes = null,
defaultEncapsulation: ViewEncapsulation = null) {
constructor(
public genDebugInfo: boolean, public logBindingUpdate: boolean, public useJit: boolean,
renderTypes: RenderTypes = null, defaultEncapsulation: ViewEncapsulation = null) {
if (isBlank(renderTypes)) {
renderTypes = new DefaultRenderTypes();
}
+36 -88
View File
@@ -1,65 +1,9 @@
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from '../facade/lang';
import {$$, $0, $9, $A, $AMPERSAND, $AT, $BACKSLASH, $BANG, $CARET, $COLON, $COMMA, $CR, $DQ, $EOF, $EQ, $FF, $GT, $HASH, $LBRACE, $LBRACKET, $LF, $LPAREN, $MINUS, $PERCENT, $PERIOD, $PIPE, $PLUS, $QUESTION, $RBRACE, $RBRACKET, $RPAREN, $SEMICOLON, $SLASH, $SQ, $STAR, $TILDA, $VTAB, $Z, $_, $a, $z, isWhitespace} from '@angular/compiler/src/chars';
import {BaseException} from '../facade/exceptions';
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from '../facade/lang';
import {
isWhitespace,
$EOF,
$HASH,
$TILDA,
$CARET,
$PERCENT,
$$,
$_,
$COLON,
$SQ,
$DQ,
$EQ,
$SLASH,
$BACKSLASH,
$PERIOD,
$STAR,
$PLUS,
$LPAREN,
$RPAREN,
$LBRACE,
$RBRACE,
$LBRACKET,
$RBRACKET,
$PIPE,
$COMMA,
$SEMICOLON,
$MINUS,
$BANG,
$QUESTION,
$AT,
$AMPERSAND,
$GT,
$a,
$A,
$z,
$Z,
$0,
$9,
$FF,
$CR,
$LF,
$VTAB
} from '@angular/compiler/src/chars';
export {
$EOF,
$AT,
$RBRACE,
$LBRACE,
$LBRACKET,
$RBRACKET,
$LPAREN,
$RPAREN,
$COMMA,
$COLON,
$SEMICOLON,
isWhitespace
} from '@angular/compiler/src/chars';
export {$AT, $COLON, $COMMA, $EOF, $LBRACE, $LBRACKET, $LPAREN, $RBRACE, $RBRACKET, $RPAREN, $SEMICOLON, isWhitespace} from '@angular/compiler/src/chars';
export enum CssTokenType {
EOF,
@@ -94,35 +38,37 @@ export class LexedCssResult {
constructor(public error: CssScannerError, public token: CssToken) {}
}
export function generateErrorMessage(input: string, message: string, errorValue: string,
index: number, row: number, column: number): string {
export function generateErrorMessage(
input: string, message: string, errorValue: string, index: number, row: number,
column: number): string {
return `${message} at column ${row}:${column} in expression [` +
findProblemCode(input, errorValue, index, column) + ']';
findProblemCode(input, errorValue, index, column) + ']';
}
export function findProblemCode(input: string, errorValue: string, index: number,
column: number): string {
export function findProblemCode(
input: string, errorValue: string, index: number, column: number): string {
var endOfProblemLine = index;
var current = charCode(input, index);
while (current > 0 && !isNewline(current)) {
current = charCode(input, ++endOfProblemLine);
}
var choppedString = input.substring(0, endOfProblemLine);
var pointerPadding = "";
var pointerPadding = '';
for (var i = 0; i < column; i++) {
pointerPadding += " ";
pointerPadding += ' ';
}
var pointerString = "";
var pointerString = '';
for (var i = 0; i < errorValue.length; i++) {
pointerString += "^";
pointerString += '^';
}
return choppedString + "\n" + pointerPadding + pointerString + "\n";
return choppedString + '\n' + pointerPadding + pointerString + '\n';
}
export class CssToken {
numValue: number;
constructor(public index: number, public column: number, public line: number,
public type: CssTokenType, public strValue: string) {
constructor(
public index: number, public column: number, public line: number, public type: CssTokenType,
public strValue: string) {
this.numValue = charCode(strValue, 0);
}
}
@@ -248,7 +194,7 @@ export class CssScanner {
var next = output.token;
if (!isPresent(next)) {
next = new CssToken(0, 0, 0, CssTokenType.EOF, "end of file");
next = new CssToken(0, 0, 0, CssTokenType.EOF, 'end of file');
}
var isMatchingType: any /** TODO #9100 */;
@@ -265,16 +211,17 @@ export class CssScanner {
var error: any /** TODO #9100 */ = null;
if (!isMatchingType || (isPresent(value) && value != next.strValue)) {
var errorMessage = resolveEnumToken(CssTokenType, next.type) + " does not match expected " +
resolveEnumToken(CssTokenType, type) + " value";
var errorMessage = resolveEnumToken(CssTokenType, next.type) + ' does not match expected ' +
resolveEnumToken(CssTokenType, type) + ' value';
if (isPresent(value)) {
errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
}
error = new CssScannerError(
next, generateErrorMessage(this.input, errorMessage, next.strValue, previousIndex,
previousLine, previousColumn));
next, generateErrorMessage(
this.input, errorMessage, next.strValue, previousIndex, previousLine,
previousColumn));
}
return new LexedCssResult(error, next);
@@ -354,8 +301,8 @@ export class CssScanner {
}
scanComment(): CssToken {
if (this.assertCondition(isCommentStart(this.peek, this.peekPeek),
"Expected comment start value")) {
if (this.assertCondition(
isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) {
return null;
}
@@ -392,8 +339,8 @@ export class CssScanner {
}
scanString(): CssToken {
if (this.assertCondition(isStringStart(this.peek, this.peekPeek),
"Unexpected non-string starting value")) {
if (this.assertCondition(
isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) {
return null;
}
@@ -412,7 +359,7 @@ export class CssScanner {
this.advance();
}
if (this.assertCondition(this.peek == target, "Unterminated quote")) {
if (this.assertCondition(this.peek == target, 'Unterminated quote')) {
return null;
}
this.advance();
@@ -442,8 +389,8 @@ export class CssScanner {
}
scanIdentifier(): CssToken {
if (this.assertCondition(isIdentifierStart(this.peek, this.peekPeek),
'Expected identifier starting value')) {
if (this.assertCondition(
isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) {
return null;
}
@@ -475,8 +422,9 @@ export class CssScanner {
scanCharacter(): CssToken {
var start = this.index;
var startingColumn = this.column;
if (this.assertCondition(isValidCssCharacter(this.peek, this._currentMode),
charStr(this.peek) + ' is not a valid CSS character')) {
if (this.assertCondition(
isValidCssCharacter(this.peek, this._currentMode),
charStr(this.peek) + ' is not a valid CSS character')) {
return null;
}
@@ -563,12 +511,12 @@ function isIdentifierStart(code: number, next: number): boolean {
}
return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH ||
target == $MINUS || target == $_;
target == $MINUS || target == $_;
}
function isIdentifierPart(target: number): boolean {
return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH ||
target == $MINUS || target == $_ || isDigit(target);
target == $MINUS || target == $_ || isDigit(target);
}
function isValidPseudoSelectorCharacter(code: number): boolean {
+37 -63
View File
@@ -1,38 +1,7 @@
import {
ParseSourceSpan,
ParseSourceFile,
ParseLocation,
ParseError
} from '@angular/compiler/src/parse_util';
import {$AT, $COLON, $COMMA, $EOF, $LBRACE, $LBRACKET, $LPAREN, $RBRACE, $RBRACKET, $RPAREN, $SEMICOLON, CssLexerMode, CssScanner, CssScannerError, CssToken, CssTokenType, generateErrorMessage, isNewline} from '@angular/compiler/src/css/lexer';
import {ParseError, ParseLocation, ParseSourceFile, ParseSourceSpan} from '@angular/compiler/src/parse_util';
import {
bitWiseOr,
bitWiseAnd,
NumberWrapper,
StringWrapper,
isPresent
} from '../facade/lang';
import {
CssLexerMode,
CssToken,
CssTokenType,
CssScanner,
CssScannerError,
generateErrorMessage,
$AT,
$EOF,
$RBRACE,
$LBRACE,
$LBRACKET,
$RBRACKET,
$LPAREN,
$RPAREN,
$COMMA,
$COLON,
$SEMICOLON,
isNewline
} from '@angular/compiler/src/css/lexer';
import {NumberWrapper, StringWrapper, bitWiseAnd, bitWiseOr, isPresent} from '../facade/lang';
export {CssToken} from '@angular/compiler/src/css/lexer';
@@ -60,7 +29,7 @@ const SEMICOLON_DELIM = 32;
const NEWLINE_DELIM = 64;
const RPAREN_DELIM = 128;
function mergeTokens(tokens: CssToken[], separator: string = ""): CssToken {
function mergeTokens(tokens: CssToken[], separator: string = ''): CssToken {
var mainToken = tokens[0];
var str = mainToken.strValue;
for (var i = 1; i < tokens.length; i++) {
@@ -205,8 +174,9 @@ export class CssParser {
var token = this._scan();
this._assertCondition(token.type == CssTokenType.AtKeyword,
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
this._assertCondition(
token.type == CssTokenType.AtKeyword,
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
var block: any /** TODO #9100 */, type = this._resolveBlockType(token);
switch (type) {
@@ -245,11 +215,12 @@ export class CssParser {
default:
var listOfTokens: any[] /** TODO #9100 */ = [];
this._scanner.setMode(CssLexerMode.ALL);
this._error(generateErrorMessage(
this._scanner.input,
`The CSS "at" rule "${token.strValue}" is not allowed to used here`,
token.strValue, token.index, token.line, token.column),
token);
this._error(
generateErrorMessage(
this._scanner.input,
`The CSS "at" rule "${token.strValue}" is not allowed to used here`, token.strValue,
token.index, token.line, token.column),
token);
this._collectUntilDelim(bitWiseOr([delimiters, LBRACE_DELIM, SEMICOLON_DELIM]))
.forEach((token) => { listOfTokens.push(token); });
@@ -403,7 +374,7 @@ export class CssParser {
// contains an inner selector that needs to be parsed
// in isolation
if (this._scanner.getMode() == CssLexerMode.PSEUDO_SELECTOR && isPresent(previousToken) &&
previousToken.numValue == $COLON && token.strValue == "not" &&
previousToken.numValue == $COLON && token.strValue == 'not' &&
this._scanner.peek == $LPAREN) {
selectorCssTokens.push(token);
selectorCssTokens.push(this._consume(CssTokenType.Character, '('));
@@ -453,7 +424,7 @@ export class CssParser {
this._scanner.setMode(CssLexerMode.STYLE_VALUE);
var strValue = "";
var strValue = '';
var tokens: any[] /** TODO #9100 */ = [];
var previous: CssToken;
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
@@ -493,9 +464,9 @@ export class CssParser {
this._consume(CssTokenType.Character, ';');
} else if (code != $RBRACE) {
this._error(
generateErrorMessage(this._scanner.input,
`The CSS key/value definition did not end with a semicolon`,
previous.strValue, previous.index, previous.line, previous.column),
generateErrorMessage(
this._scanner.input, `The CSS key/value definition did not end with a semicolon`,
previous.strValue, previous.index, previous.line, previous.column),
previous);
}
@@ -592,7 +563,7 @@ export class CssParser {
remainingTokens.forEach((token) => { propStr.push(token.strValue); });
}
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(" "));
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(' '));
}
// this means we've reached the end of the definition and/or block
@@ -608,10 +579,11 @@ export class CssParser {
if (parseValue) {
value = this._parseValue(delimiters);
} else {
this._error(generateErrorMessage(this._scanner.input,
`The CSS property was not paired with a style value`,
prop.strValue, prop.index, prop.line, prop.column),
prop);
this._error(
generateErrorMessage(
this._scanner.input, `The CSS property was not paired with a style value`,
prop.strValue, prop.index, prop.line, prop.column),
prop);
}
return new CssDefinitionAST(prop, value);
@@ -629,8 +601,8 @@ export class CssParser {
/** @internal */
_error(message: string, problemToken: CssToken) {
var length = problemToken.strValue.length;
var error = CssParseError.create(this._file, 0, problemToken.line, problemToken.column, length,
message);
var error = CssParseError.create(
this._file, 0, problemToken.line, problemToken.column, length, message);
this._errors.push(error);
}
}
@@ -657,7 +629,7 @@ export class CssKeyframeRuleAST extends CssBlockRuleAST {
export class CssKeyframeDefinitionAST extends CssBlockRuleAST {
public steps: any /** TODO #9100 */;
constructor(_steps: CssToken[], block: CssBlockAST) {
super(BlockType.Keyframes, block, mergeTokens(_steps, ","));
super(BlockType.Keyframes, block, mergeTokens(_steps, ','));
this.steps = _steps;
}
visit(visitor: CssASTVisitor, context?: any) {
@@ -669,10 +641,11 @@ export class CssBlockDefinitionRuleAST extends CssBlockRuleAST {
public strValue: string;
constructor(type: BlockType, public query: CssToken[], block: CssBlockAST) {
super(type, block);
this.strValue = query.map(token => token.strValue).join("");
this.strValue = query.map(token => token.strValue).join('');
var firstCssToken: CssToken = query[0];
this.name = new CssToken(firstCssToken.index, firstCssToken.column, firstCssToken.line,
CssTokenType.Identifier, this.strValue);
this.name = new CssToken(
firstCssToken.index, firstCssToken.column, firstCssToken.line, CssTokenType.Identifier,
this.strValue);
}
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssBlock(this.block, context); }
}
@@ -692,7 +665,7 @@ export class CssSelectorRuleAST extends CssBlockRuleAST {
constructor(public selectors: CssSelectorAST[], block: CssBlockAST) {
super(BlockType.Selector, block);
this.strValue = selectors.map(selector => selector.strValue).join(",");
this.strValue = selectors.map(selector => selector.strValue).join(',');
}
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelectorRule(this, context); }
@@ -707,7 +680,7 @@ export class CssSelectorAST extends CssAST {
public strValue: any /** TODO #9100 */;
constructor(public tokens: CssToken[], public isComplex: boolean = false) {
super();
this.strValue = tokens.map(token => token.strValue).join("");
this.strValue = tokens.map(token => token.strValue).join('');
}
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelector(this, context); }
}
@@ -723,12 +696,13 @@ export class CssStyleSheetAST extends CssAST {
}
export class CssParseError extends ParseError {
static create(file: ParseSourceFile, offset: number, line: number, col: number, length: number,
errMsg: string): CssParseError {
static create(
file: ParseSourceFile, offset: number, line: number, col: number, length: number,
errMsg: string): CssParseError {
var start = new ParseLocation(file, offset, line, col);
var end = new ParseLocation(file, offset, line, col + length);
var span = new ParseSourceSpan(start, end);
return new CssParseError(span, "CSS Parse Error: " + errMsg);
return new CssParseError(span, 'CSS Parse Error: ' + errMsg);
}
constructor(span: ParseSourceSpan, message: string) { super(span, message); }
@@ -1,13 +1,4 @@
import {
OnInit,
OnDestroy,
DoCheck,
OnChanges,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
} from '@angular/core';
import {OnInit, OnDestroy, DoCheck, OnChanges, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked,} from '@angular/core';
import {reflector, LifecycleHooks} from '../core_private';
import {Type} from '../src/facade/lang';
@@ -1,28 +1,15 @@
import {Injectable, ViewEncapsulation} from '@angular/core';
import {isPresent, isBlank} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {PromiseWrapper} from '../src/facade/async';
import {BaseException} from '../src/facade/exceptions';
import {isBlank, isPresent} from '../src/facade/lang';
import {
CompileTypeMetadata,
CompileDirectiveMetadata,
CompileTemplateMetadata,
} from './compile_metadata';
import {CompileTypeMetadata, CompileDirectiveMetadata, CompileTemplateMetadata,} from './compile_metadata';
import {XHR} from './xhr';
import {UrlResolver} from './url_resolver';
import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver';
import {
HtmlAstVisitor,
HtmlElementAst,
HtmlTextAst,
HtmlAttrAst,
HtmlCommentAst,
HtmlExpansionAst,
HtmlExpansionCaseAst,
htmlVisitAll
} from './html_ast';
import {HtmlAstVisitor, HtmlElementAst, HtmlTextAst, HtmlAttrAst, HtmlCommentAst, HtmlExpansionAst, HtmlExpansionCaseAst, htmlVisitAll} from './html_ast';
import {HtmlParser} from './html_parser';
import {CompilerConfig} from './config';
@@ -31,8 +18,9 @@ import {preparseElement, PreparsedElementType} from './template_preparser';
@Injectable()
export class DirectiveNormalizer {
constructor(private _xhr: XHR, private _urlResolver: UrlResolver,
private _htmlParser: HtmlParser, private _config: CompilerConfig) {}
constructor(
private _xhr: XHR, private _urlResolver: UrlResolver, private _htmlParser: HtmlParser,
private _config: CompilerConfig) {}
normalizeDirective(directive: CompileDirectiveMetadata): Promise<CompileDirectiveMetadata> {
if (!directive.isComponent) {
@@ -60,23 +48,25 @@ export class DirectiveNormalizer {
}));
}
normalizeTemplate(directiveType: CompileTypeMetadata,
template: CompileTemplateMetadata): Promise<CompileTemplateMetadata> {
normalizeTemplate(directiveType: CompileTypeMetadata, template: CompileTemplateMetadata):
Promise<CompileTemplateMetadata> {
if (isPresent(template.template)) {
return PromiseWrapper.resolve(this.normalizeLoadedTemplate(
directiveType, template, template.template, directiveType.moduleUrl));
} else if (isPresent(template.templateUrl)) {
var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl);
return this._xhr.get(sourceAbsUrl)
.then(templateContent => this.normalizeLoadedTemplate(directiveType, template,
templateContent, sourceAbsUrl));
.then(
templateContent => this.normalizeLoadedTemplate(
directiveType, template, templateContent, sourceAbsUrl));
} else {
throw new BaseException(`No template specified for component ${directiveType.name}`);
}
}
normalizeLoadedTemplate(directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata,
template: string, templateAbsUrl: string): CompileTemplateMetadata {
normalizeLoadedTemplate(
directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata, template: string,
templateAbsUrl: string): CompileTemplateMetadata {
var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name);
if (rootNodesAndErrors.errors.length > 0) {
var errorString = rootNodesAndErrors.errors.join('\n');
@@ -1,17 +1,4 @@
import {
resolveForwardRef,
Injectable,
DirectiveMetadata,
ComponentMetadata,
InputMetadata,
OutputMetadata,
HostBindingMetadata,
HostListenerMetadata,
ContentChildrenMetadata,
ViewChildrenMetadata,
ContentChildMetadata,
ViewChildMetadata,
} from '@angular/core';
import {resolveForwardRef, Injectable, DirectiveMetadata, ComponentMetadata, InputMetadata, OutputMetadata, HostBindingMetadata, HostListenerMetadata, ContentChildrenMetadata, ViewChildrenMetadata, ContentChildMetadata, ViewChildMetadata,} from '@angular/core';
import {ReflectorReader, reflector} from '../core_private';
import {Type, isPresent, stringify} from '../src/facade/lang';
@@ -58,9 +45,9 @@ export class DirectiveResolver {
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
}
private _mergeWithPropertyMetadata(dm: DirectiveMetadata,
propertyMetadata: {[key: string]: any[]},
directiveType: Type): DirectiveMetadata {
private _mergeWithPropertyMetadata(
dm: DirectiveMetadata, propertyMetadata: {[key: string]: any[]},
directiveType: Type): DirectiveMetadata {
var inputs: any[] /** TODO #9100 */ = [];
var outputs: any[] /** TODO #9100 */ = [];
var host: {[key: string]: string} = {};
@@ -117,9 +104,9 @@ export class DirectiveResolver {
return this._merge(dm, inputs, outputs, host, queries, directiveType);
}
private _merge(dm: DirectiveMetadata, inputs: string[], outputs: string[],
host: {[key: string]: string}, queries: {[key: string]: any},
directiveType: Type): DirectiveMetadata {
private _merge(
dm: DirectiveMetadata, inputs: string[], outputs: string[], host: {[key: string]: string},
queries: {[key: string]: any}, directiveType: Type): DirectiveMetadata {
var mergedInputs = isPresent(dm.inputs) ? ListWrapper.concat(dm.inputs, inputs) : inputs;
var mergedOutputs: any /** TODO #9100 */;
@@ -2,7 +2,7 @@ import {ListWrapper} from '../facade/collection';
export class AST {
visit(visitor: AstVisitor, context: any = null): any { return null; }
toString(): string { return "AST"; }
toString(): string { return 'AST'; }
}
/**
@@ -23,7 +23,7 @@ export class Quote extends AST {
super();
}
visit(visitor: AstVisitor, context: any = null): any { return visitor.visitQuote(this, context); }
toString(): string { return "Quote"; }
toString(): string { return 'Quote'; }
}
export class EmptyExpr extends AST {
@@ -163,8 +163,9 @@ export class ASTWithSource extends AST {
}
export class TemplateBinding {
constructor(public key: string, public keyIsVar: boolean, public name: string,
public expression: ASTWithSource) {}
constructor(
public key: string, public keyIsVar: boolean, public name: string,
public expression: ASTWithSource) {}
}
export interface AstVisitor {
@@ -316,8 +317,8 @@ export class AstTransformer implements AstVisitor {
}
visitConditional(ast: Conditional, context: any): AST {
return new Conditional(ast.condition.visit(this), ast.trueExp.visit(this),
ast.falseExp.visit(this));
return new Conditional(
ast.condition.visit(this), ast.trueExp.visit(this), ast.falseExp.visit(this));
}
visitPipe(ast: BindingPipe, context: any): AST {
@@ -1,7 +1,8 @@
import {Injectable} from '@angular/core';
import {SetWrapper} from '../facade/collection';
import {NumberWrapper, StringJoiner, StringWrapper, isPresent} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {NumberWrapper, StringJoiner, StringWrapper, isPresent} from '../facade/lang';
export enum TokenType {
Character,
@@ -27,8 +28,9 @@ export class Lexer {
}
export class Token {
constructor(public index: number, public type: TokenType, public numValue: number,
public strValue: string) {}
constructor(
public index: number, public type: TokenType, public numValue: number,
public strValue: string) {}
isCharacter(code: number): boolean {
return (this.type == TokenType.Character && this.numValue == code);
@@ -47,20 +49,20 @@ export class Token {
isKeyword(): boolean { return (this.type == TokenType.Keyword); }
isKeywordDeprecatedVar(): boolean {
return (this.type == TokenType.Keyword && this.strValue == "var");
return (this.type == TokenType.Keyword && this.strValue == 'var');
}
isKeywordLet(): boolean { return (this.type == TokenType.Keyword && this.strValue == "let"); }
isKeywordLet(): boolean { return (this.type == TokenType.Keyword && this.strValue == 'let'); }
isKeywordNull(): boolean { return (this.type == TokenType.Keyword && this.strValue == "null"); }
isKeywordNull(): boolean { return (this.type == TokenType.Keyword && this.strValue == 'null'); }
isKeywordUndefined(): boolean {
return (this.type == TokenType.Keyword && this.strValue == "undefined");
return (this.type == TokenType.Keyword && this.strValue == 'undefined');
}
isKeywordTrue(): boolean { return (this.type == TokenType.Keyword && this.strValue == "true"); }
isKeywordTrue(): boolean { return (this.type == TokenType.Keyword && this.strValue == 'true'); }
isKeywordFalse(): boolean { return (this.type == TokenType.Keyword && this.strValue == "false"); }
isKeywordFalse(): boolean { return (this.type == TokenType.Keyword && this.strValue == 'false'); }
toNumber(): number {
// -1 instead of NULL ok?
@@ -104,11 +106,11 @@ function newStringToken(index: number, text: string): Token {
}
function newNumberToken(index: number, n: number): Token {
return new Token(index, TokenType.Number, n, "");
return new Token(index, TokenType.Number, n, '');
}
export var EOF: Token = new Token(-1, TokenType.Character, 0, "");
export var EOF: Token = new Token(-1, TokenType.Character, 0, '');
export const $EOF = /*@ts2dart_const*/ 0;
export const $TAB = /*@ts2dart_const*/ 9;
@@ -237,8 +239,8 @@ class _Scanner {
return this.scanComplexOperator(start, StringWrapper.fromCharCode(peek), $EQ, '=');
case $BANG:
case $EQ:
return this.scanComplexOperator(start, StringWrapper.fromCharCode(peek), $EQ, '=', $EQ,
'=');
return this.scanComplexOperator(
start, StringWrapper.fromCharCode(peek), $EQ, '=', $EQ, '=');
case $AMPERSAND:
return this.scanComplexOperator(start, '&', $AMPERSAND, '&');
case $BAR:
@@ -274,8 +276,9 @@ class _Scanner {
* @param three third symbol (part of the operator when provided and matches source expression)
* @returns {Token}
*/
scanComplexOperator(start: number, one: string, twoCode: number, two: string, threeCode?: number,
three?: string): Token {
scanComplexOperator(
start: number, one: string, twoCode: number, two: string, threeCode?: number,
three?: string): Token {
this.advance();
var str: string = one;
if (this.peek == twoCode) {
@@ -406,7 +409,7 @@ export function isIdentifier(input: string): boolean {
function isIdentifierPart(code: number): boolean {
return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || ($0 <= code && code <= $9) ||
(code == $_) || (code == $$);
(code == $_) || (code == $$);
}
function isDigit(code: number): boolean {
@@ -443,29 +446,8 @@ function unescape(code: number): number {
}
var OPERATORS = SetWrapper.createFromList([
'+',
'-',
'*',
'/',
'%',
'^',
'=',
'==',
'!=',
'===',
'!==',
'<',
'>',
'<=',
'>=',
'&&',
'||',
'&',
'|',
'!',
'?',
'#',
'?.'
'+', '-', '*', '/', '%', '^', '=', '==', '!=', '===', '!==', '<',
'>', '<=', '>=', '&&', '||', '&', '|', '!', '?', '#', '?.'
]);
@@ -1,51 +1,11 @@
import {Injectable} from '@angular/core';
import {isBlank, isPresent, StringWrapper} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {ListWrapper} from '../facade/collection';
import {
Lexer,
EOF,
isIdentifier,
isQuote,
Token,
$PERIOD,
$COLON,
$SEMICOLON,
$LBRACKET,
$RBRACKET,
$COMMA,
$LBRACE,
$RBRACE,
$LPAREN,
$RPAREN,
$SLASH
} from './lexer';
import {
AST,
EmptyExpr,
ImplicitReceiver,
PropertyRead,
PropertyWrite,
SafePropertyRead,
LiteralPrimitive,
Binary,
PrefixNot,
Conditional,
BindingPipe,
Chain,
KeyedRead,
KeyedWrite,
LiteralArray,
LiteralMap,
Interpolation,
MethodCall,
SafeMethodCall,
FunctionCall,
TemplateBinding,
ASTWithSource,
AstVisitor,
Quote
} from './ast';
import {BaseException} from '../facade/exceptions';
import {StringWrapper, isBlank, isPresent} from '../facade/lang';
import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, EmptyExpr, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead, TemplateBinding} from './ast';
import {$COLON, $COMMA, $LBRACE, $LBRACKET, $LPAREN, $PERIOD, $RBRACE, $RBRACKET, $RPAREN, $SEMICOLON, $SLASH, EOF, Lexer, Token, isIdentifier, isQuote} from './lexer';
var _implicitReceiver = new ImplicitReceiver();
@@ -152,9 +112,9 @@ export class Parser {
} else if (part.trim().length > 0) {
expressions.push(part);
} else {
throw new ParseException('Blank expressions are not allowed in interpolated strings', input,
`at column ${this._findInterpolationErrorColumn(parts, i)} in`,
location);
throw new ParseException(
'Blank expressions are not allowed in interpolated strings', input,
`at column ${this._findInterpolationErrorColumn(parts, i)} in`, location);
}
}
return new SplitInterpolation(strings, expressions);
@@ -189,9 +149,9 @@ export class Parser {
private _checkNoInterpolation(input: string, location: any): void {
var parts = StringWrapper.split(input, INTERPOLATION_REGEXP);
if (parts.length > 1) {
throw new ParseException('Got interpolation ({{}}) where expression was expected', input,
`at column ${this._findInterpolationErrorColumn(parts, 1)} in`,
location);
throw new ParseException(
'Got interpolation ({{}}) where expression was expected', input,
`at column ${this._findInterpolationErrorColumn(parts, 1)} in`, location);
}
}
@@ -207,8 +167,9 @@ export class Parser {
export class _ParseAST {
index: number = 0;
constructor(public input: string, public location: any, public tokens: any[],
public parseAction: boolean) {}
constructor(
public input: string, public location: any, public tokens: any[],
public parseAction: boolean) {}
peek(offset: number): Token {
var i = this.index + offset;
@@ -284,7 +245,7 @@ export class _ParseAST {
if (this.optionalCharacter($SEMICOLON)) {
if (!this.parseAction) {
this.error("Binding expression cannot contain chained expression");
this.error('Binding expression cannot contain chained expression');
}
while (this.optionalCharacter($SEMICOLON)) {
} // read all semicolons
@@ -299,9 +260,9 @@ export class _ParseAST {
parsePipe(): AST {
var result = this.parseExpression();
if (this.optionalOperator("|")) {
if (this.optionalOperator('|')) {
if (this.parseAction) {
this.error("Cannot have a pipe in an action expression");
this.error('Cannot have a pipe in an action expression');
}
do {
@@ -311,7 +272,7 @@ export class _ParseAST {
args.push(this.parseExpression());
}
result = new BindingPipe(result, name, args);
} while (this.optionalOperator("|"));
} while (this.optionalOperator('|'));
}
return result;
@@ -445,7 +406,7 @@ export class _ParseAST {
} else if (this.optionalCharacter($LBRACKET)) {
var key = this.parsePipe();
this.expectCharacter($RBRACKET);
if (this.optionalOperator("=")) {
if (this.optionalOperator('=')) {
var value = this.parseConditional();
result = new KeyedWrite(result, key, value);
} else {
@@ -508,7 +469,7 @@ export class _ParseAST {
this.error(`Unexpected token ${this.next}`);
}
// error() throws, so we don't reach here.
throw new BaseException("Fell through all cases in parsePrimary");
throw new BaseException('Fell through all cases in parsePrimary');
}
parseExpressionList(terminator: number): any[] {
@@ -547,15 +508,15 @@ export class _ParseAST {
} else {
if (isSafe) {
if (this.optionalOperator("=")) {
this.error("The '?.' operator cannot be used in the assignment");
if (this.optionalOperator('=')) {
this.error('The \'?.\' operator cannot be used in the assignment');
} else {
return new SafePropertyRead(receiver, id);
}
} else {
if (this.optionalOperator("=")) {
if (this.optionalOperator('=')) {
if (!this.parseAction) {
this.error("Bindings cannot contain assignments");
this.error('Bindings cannot contain assignments');
}
let value = this.parseConditional();
@@ -580,7 +541,7 @@ export class _ParseAST {
parseBlockContent(): AST {
if (!this.parseAction) {
this.error("Binding expression cannot contain chained expression");
this.error('Binding expression cannot contain chained expression');
}
var exprs: any[] /** TODO #9100 */ = [];
while (this.index < this.tokens.length && !this.next.isCharacter($RBRACE)) {
@@ -645,13 +606,14 @@ export class _ParseAST {
var name: any /** TODO #9100 */ = null;
var expression: any /** TODO #9100 */ = null;
if (keyIsVar) {
if (this.optionalOperator("=")) {
if (this.optionalOperator('=')) {
name = this.expectTemplateBindingKey();
} else {
name = '\$implicit';
}
} else if (this.next !== EOF && !this.peekKeywordLet() && !this.peekDeprecatedKeywordVar() &&
!this.peekDeprecatedOperatorHash()) {
} else if (
this.next !== EOF && !this.peekKeywordLet() && !this.peekDeprecatedKeywordVar() &&
!this.peekDeprecatedOperatorHash()) {
var start = this.inputIndex;
var ast = this.parsePipe();
var source = this.input.substring(start, this.inputIndex);
+10 -8
View File
@@ -13,17 +13,18 @@ export class HtmlTextAst implements HtmlAst {
}
export class HtmlExpansionAst implements HtmlAst {
constructor(public switchValue: string, public type: string, public cases: HtmlExpansionCaseAst[],
public sourceSpan: ParseSourceSpan, public switchValueSourceSpan: ParseSourceSpan) {}
constructor(
public switchValue: string, public type: string, public cases: HtmlExpansionCaseAst[],
public sourceSpan: ParseSourceSpan, public switchValueSourceSpan: ParseSourceSpan) {}
visit(visitor: HtmlAstVisitor, context: any): any {
return visitor.visitExpansion(this, context);
}
}
export class HtmlExpansionCaseAst implements HtmlAst {
constructor(public value: string, public expression: HtmlAst[],
public sourceSpan: ParseSourceSpan, public valueSourceSpan: ParseSourceSpan,
public expSourceSpan: ParseSourceSpan) {}
constructor(
public value: string, public expression: HtmlAst[], public sourceSpan: ParseSourceSpan,
public valueSourceSpan: ParseSourceSpan, public expSourceSpan: ParseSourceSpan) {}
visit(visitor: HtmlAstVisitor, context: any): any {
return visitor.visitExpansionCase(this, context);
@@ -36,9 +37,10 @@ export class HtmlAttrAst implements HtmlAst {
}
export class HtmlElementAst implements HtmlAst {
constructor(public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
public endSourceSpan: ParseSourceSpan) {}
constructor(
public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
public endSourceSpan: ParseSourceSpan) {}
visit(visitor: HtmlAstVisitor, context: any): any { return visitor.visitElement(this, context); }
}
+25 -24
View File
@@ -1,7 +1,7 @@
import {StringWrapper, NumberWrapper, isPresent, isBlank} from './facade/lang';
import {ListWrapper} from './facade/collection';
import {ParseLocation, ParseError, ParseSourceFile, ParseSourceSpan} from './parse_util';
import {getHtmlTagDefinition, HtmlTagContentType, NAMED_ENTITIES} from './html_tags';
import {NumberWrapper, StringWrapper, isBlank, isPresent} from './facade/lang';
import {HtmlTagContentType, NAMED_ENTITIES, getHtmlTagDefinition} from './html_tags';
import {ParseError, ParseLocation, ParseSourceFile, ParseSourceSpan} from './parse_util';
export enum HtmlTokenType {
TAG_OPEN_START,
@@ -27,8 +27,8 @@ export enum HtmlTokenType {
}
export class HtmlToken {
constructor(public type: HtmlTokenType, public parts: string[],
public sourceSpan: ParseSourceSpan) {}
constructor(
public type: HtmlTokenType, public parts: string[], public sourceSpan: ParseSourceSpan) {}
}
export class HtmlTokenError extends ParseError {
@@ -41,8 +41,9 @@ export class HtmlTokenizeResult {
constructor(public tokens: HtmlToken[], public errors: HtmlTokenError[]) {}
}
export function tokenizeHtml(sourceContent: string, sourceUrl: string,
tokenizeExpansionForms: boolean = false): HtmlTokenizeResult {
export function tokenizeHtml(
sourceContent: string, sourceUrl: string,
tokenizeExpansionForms: boolean = false): HtmlTokenizeResult {
return new _HtmlTokenizer(new ParseSourceFile(sourceContent, sourceUrl), tokenizeExpansionForms)
.tokenize();
}
@@ -161,12 +162,12 @@ class _HtmlTokenizer {
} else if (this.peek === $EQ && this.tokenizeExpansionForms) {
this._consumeExpansionCaseStart();
} else if (this.peek === $RBRACE && this.isInExpansionCase() &&
this.tokenizeExpansionForms) {
} else if (
this.peek === $RBRACE && this.isInExpansionCase() && this.tokenizeExpansionForms) {
this._consumeExpansionCaseEnd();
} else if (this.peek === $RBRACE && this.isInExpansionForm() &&
this.tokenizeExpansionForms) {
} else if (
this.peek === $RBRACE && this.isInExpansionForm() && this.tokenizeExpansionForms) {
this._consumeExpansionFormEnd();
} else {
@@ -211,8 +212,8 @@ class _HtmlTokenizer {
if (isBlank(end)) {
end = this._getLocation();
}
var token = new HtmlToken(this.currentTokenType, parts,
new ParseSourceSpan(this.currentTokenStart, end));
var token = new HtmlToken(
this.currentTokenType, parts, new ParseSourceSpan(this.currentTokenStart, end));
this.tokens.push(token);
this.currentTokenStart = null;
this.currentTokenType = null;
@@ -261,8 +262,8 @@ class _HtmlTokenizer {
private _requireCharCode(charCode: number) {
var location = this._getLocation();
if (!this._attemptCharCode(charCode)) {
throw this._createError(unexpectedCharacterErrorMsg(this.peek),
this._getSpan(location, location));
throw this._createError(
unexpectedCharacterErrorMsg(this.peek), this._getSpan(location, location));
}
}
@@ -365,12 +366,12 @@ class _HtmlTokenizer {
}
}
private _consumeRawText(decodeEntities: boolean, firstCharOfEnd: number,
attemptEndRest: Function): HtmlToken {
private _consumeRawText(
decodeEntities: boolean, firstCharOfEnd: number, attemptEndRest: Function): HtmlToken {
var tagCloseStart: any /** TODO #9100 */;
var textStart = this._getLocation();
this._beginToken(decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT,
textStart);
this._beginToken(
decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT, textStart);
var parts: any[] /** TODO #9100 */ = [];
while (true) {
tagCloseStart = this._getLocation();
@@ -655,14 +656,14 @@ class _HtmlTokenizer {
private isInExpansionCase(): boolean {
return this.expansionCaseStack.length > 0 &&
this.expansionCaseStack[this.expansionCaseStack.length - 1] ===
HtmlTokenType.EXPANSION_CASE_EXP_START;
this.expansionCaseStack[this.expansionCaseStack.length - 1] ===
HtmlTokenType.EXPANSION_CASE_EXP_START;
}
private isInExpansionForm(): boolean {
return this.expansionCaseStack.length > 0 &&
this.expansionCaseStack[this.expansionCaseStack.length - 1] ===
HtmlTokenType.EXPANSION_FORM_START;
this.expansionCaseStack[this.expansionCaseStack.length - 1] ===
HtmlTokenType.EXPANSION_FORM_START;
}
}
@@ -676,7 +677,7 @@ function isWhitespace(code: number): boolean {
function isNameEnd(code: number): boolean {
return isWhitespace(code) || code === $GT || code === $SLASH || code === $SQ || code === $DQ ||
code === $EQ;
code === $EQ;
}
function isPrefixEnd(code: number): boolean {
+25 -35
View File
@@ -1,21 +1,10 @@
import {Injectable} from '@angular/core';
import {
isPresent,
isBlank,
} from '../src/facade/lang';
import {isPresent, isBlank,} from '../src/facade/lang';
import {ListWrapper} from '../src/facade/collection';
import {
HtmlAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
HtmlElementAst,
HtmlExpansionAst,
HtmlExpansionCaseAst
} from './html_ast';
import {HtmlAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, HtmlElementAst, HtmlExpansionAst, HtmlExpansionCaseAst} from './html_ast';
import {HtmlToken, HtmlTokenType, tokenizeHtml} from './html_lexer';
import {ParseError, ParseSourceSpan} from './parse_util';
@@ -35,12 +24,13 @@ export class HtmlParseTreeResult {
@Injectable()
export class HtmlParser {
parse(sourceContent: string, sourceUrl: string,
parseExpansionForms: boolean = false): HtmlParseTreeResult {
parse(sourceContent: string, sourceUrl: string, parseExpansionForms: boolean = false):
HtmlParseTreeResult {
var tokensAndErrors = tokenizeHtml(sourceContent, sourceUrl, parseExpansionForms);
var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
return new HtmlParseTreeResult(treeAndErrors.rootNodes, (<ParseError[]>tokensAndErrors.errors)
.concat(treeAndErrors.errors));
return new HtmlParseTreeResult(
treeAndErrors.rootNodes,
(<ParseError[]>tokensAndErrors.errors).concat(treeAndErrors.errors));
}
}
@@ -67,9 +57,9 @@ class TreeBuilder {
} else if (this.peek.type === HtmlTokenType.COMMENT_START) {
this._closeVoidElement();
this._consumeComment(this._advance());
} else if (this.peek.type === HtmlTokenType.TEXT ||
this.peek.type === HtmlTokenType.RAW_TEXT ||
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
} else if (
this.peek.type === HtmlTokenType.TEXT || this.peek.type === HtmlTokenType.RAW_TEXT ||
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
this._closeVoidElement();
this._consumeText(this._advance());
} else if (this.peek.type === HtmlTokenType.EXPANSION_FORM_START) {
@@ -133,8 +123,8 @@ class TreeBuilder {
this._advance();
let mainSourceSpan = new ParseSourceSpan(token.sourceSpan.start, this.peek.sourceSpan.end);
this._addToParent(new HtmlExpansionAst(switchValue.parts[0], type.parts[0], cases,
mainSourceSpan, switchValue.sourceSpan));
this._addToParent(new HtmlExpansionAst(
switchValue.parts[0], type.parts[0], cases, mainSourceSpan, switchValue.sourceSpan));
}
private _parseExpansionCase(): HtmlExpansionCaseAst {
@@ -142,8 +132,8 @@ class TreeBuilder {
// read {
if (this.peek.type !== HtmlTokenType.EXPANSION_CASE_EXP_START) {
this.errors.push(HtmlTreeError.create(null, this.peek.sourceSpan,
`Invalid expansion form. Missing '{'.,`));
this.errors.push(HtmlTreeError.create(
null, this.peek.sourceSpan, `Invalid expansion form. Missing '{'.,`));
return null;
}
@@ -165,8 +155,8 @@ class TreeBuilder {
let sourceSpan = new ParseSourceSpan(value.sourceSpan.start, end.sourceSpan.end);
let expSourceSpan = new ParseSourceSpan(start.sourceSpan.start, end.sourceSpan.end);
return new HtmlExpansionCaseAst(value.parts[0], parsedExp.rootNodes, sourceSpan,
value.sourceSpan, expSourceSpan);
return new HtmlExpansionCaseAst(
value.parts[0], parsedExp.rootNodes, sourceSpan, value.sourceSpan, expSourceSpan);
}
private _collectExpansionExpTokens(start: HtmlToken): HtmlToken[] {
@@ -280,8 +270,8 @@ class TreeBuilder {
var tagDef = getHtmlTagDefinition(el.name);
var parentEl = this._getParentElement();
if (tagDef.requireExtraParent(isPresent(parentEl) ? parentEl.name : null)) {
var newParent = new HtmlElementAst(tagDef.parentToAdd, [], [el], el.sourceSpan,
el.startSourceSpan, el.endSourceSpan);
var newParent = new HtmlElementAst(
tagDef.parentToAdd, [], [el], el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
this._addToParent(newParent);
this.elementStack.push(newParent);
this.elementStack.push(el);
@@ -300,12 +290,12 @@ class TreeBuilder {
}
if (getHtmlTagDefinition(fullName).isVoid) {
this.errors.push(
HtmlTreeError.create(fullName, endTagToken.sourceSpan,
`Void elements do not have end tags "${endTagToken.parts[1]}"`));
this.errors.push(HtmlTreeError.create(
fullName, endTagToken.sourceSpan,
`Void elements do not have end tags "${endTagToken.parts[1]}"`));
} else if (!this._popElement(fullName)) {
this.errors.push(HtmlTreeError.create(fullName, endTagToken.sourceSpan,
`Unexpected closing tag "${endTagToken.parts[1]}"`));
this.errors.push(HtmlTreeError.create(
fullName, endTagToken.sourceSpan, `Unexpected closing tag "${endTagToken.parts[1]}"`));
}
}
@@ -350,8 +340,8 @@ class TreeBuilder {
}
}
function getElementFullName(prefix: string, localName: string,
parentElement: HtmlElementAst): string {
function getElementFullName(
prefix: string, localName: string, parentElement: HtmlElementAst): string {
if (isBlank(prefix)) {
prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix;
if (isBlank(prefix) && isPresent(parentElement)) {
+15 -42
View File
@@ -1,9 +1,4 @@
import {
isPresent,
isBlank,
normalizeBool,
RegExpWrapper,
} from '../src/facade/lang';
import {isPresent, isBlank, normalizeBool, RegExpWrapper,} from '../src/facade/lang';
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
// see https://html.spec.whatwg.org/multipage/entities.json
@@ -280,16 +275,17 @@ export class HtmlTagDefinition {
public isVoid: boolean;
public ignoreFirstLf: boolean;
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType,
closedByParent, isVoid, ignoreFirstLf}: {
closedByChildren?: string[],
closedByParent?: boolean,
requiredParents?: string[],
implicitNamespacePrefix?: string,
contentType?: HtmlTagContentType,
isVoid?: boolean,
ignoreFirstLf?: boolean
} = {}) {
constructor(
{closedByChildren, requiredParents, implicitNamespacePrefix, contentType, closedByParent,
isVoid, ignoreFirstLf}: {
closedByChildren?: string[],
closedByParent?: boolean,
requiredParents?: string[],
implicitNamespacePrefix?: string,
contentType?: HtmlTagContentType,
isVoid?: boolean,
ignoreFirstLf?: boolean
} = {}) {
if (isPresent(closedByChildren) && closedByChildren.length > 0) {
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
}
@@ -341,32 +337,9 @@ var TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
'wbr': new HtmlTagDefinition({isVoid: true}),
'p': new HtmlTagDefinition({
closedByChildren: [
'address',
'article',
'aside',
'blockquote',
'div',
'dl',
'fieldset',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'header',
'hgroup',
'hr',
'main',
'nav',
'ol',
'p',
'pre',
'section',
'table',
'ul'
'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',
'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'
],
closedByParent: true
}),
+33 -44
View File
@@ -1,16 +1,6 @@
import {
HtmlAst,
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
HtmlExpansionAst,
HtmlExpansionCaseAst,
htmlVisitAll
} from '../html_ast';
import {BaseException} from '../facade/exceptions';
import {HtmlAst, HtmlAstVisitor, HtmlAttrAst, HtmlCommentAst, HtmlElementAst, HtmlExpansionAst, HtmlExpansionCaseAst, HtmlTextAst, htmlVisitAll} from '../html_ast';
/**
@@ -51,8 +41,9 @@ class _Expander implements HtmlAstVisitor {
constructor() {}
visitElement(ast: HtmlElementAst, context: any): any {
return new HtmlElementAst(ast.name, ast.attrs, htmlVisitAll(this, ast.children), ast.sourceSpan,
ast.startSourceSpan, ast.endSourceSpan);
return new HtmlElementAst(
ast.name, ast.attrs, htmlVisitAll(this, ast.children), ast.sourceSpan, ast.startSourceSpan,
ast.endSourceSpan);
}
visitAttr(ast: HtmlAttrAst, context: any): any { return ast; }
@@ -63,11 +54,11 @@ class _Expander implements HtmlAstVisitor {
visitExpansion(ast: HtmlExpansionAst, context: any): any {
this.expanded = true;
return ast.type == "plural" ? _expandPluralForm(ast) : _expandDefaultForm(ast);
return ast.type == 'plural' ? _expandPluralForm(ast) : _expandDefaultForm(ast);
}
visitExpansionCase(ast: HtmlExpansionCaseAst, context: any): any {
throw new BaseException("Should not be reached");
throw new BaseException('Should not be reached');
}
}
@@ -75,42 +66,40 @@ function _expandPluralForm(ast: HtmlExpansionAst): HtmlElementAst {
let children = ast.cases.map(c => {
let expansionResult = expandNodes(c.expression);
let i18nAttrs = expansionResult.expanded ?
[] :
[new HtmlAttrAst("i18n", `${ast.type}_${c.value}`, c.valueSourceSpan)];
[] :
[new HtmlAttrAst('i18n', `${ast.type}_${c.value}`, c.valueSourceSpan)];
return new HtmlElementAst(`template`,
[
new HtmlAttrAst("ngPluralCase", c.value, c.valueSourceSpan),
],
[
new HtmlElementAst(`li`, i18nAttrs, expansionResult.nodes,
c.sourceSpan, c.sourceSpan, c.sourceSpan)
],
c.sourceSpan, c.sourceSpan, c.sourceSpan);
return new HtmlElementAst(
`template`,
[
new HtmlAttrAst('ngPluralCase', c.value, c.valueSourceSpan),
],
[new HtmlElementAst(
`li`, i18nAttrs, expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan)],
c.sourceSpan, c.sourceSpan, c.sourceSpan);
});
let switchAttr = new HtmlAttrAst("[ngPlural]", ast.switchValue, ast.switchValueSourceSpan);
return new HtmlElementAst("ul", [switchAttr], children, ast.sourceSpan, ast.sourceSpan,
ast.sourceSpan);
let switchAttr = new HtmlAttrAst('[ngPlural]', ast.switchValue, ast.switchValueSourceSpan);
return new HtmlElementAst(
'ul', [switchAttr], children, ast.sourceSpan, ast.sourceSpan, ast.sourceSpan);
}
function _expandDefaultForm(ast: HtmlExpansionAst): HtmlElementAst {
let children = ast.cases.map(c => {
let expansionResult = expandNodes(c.expression);
let i18nAttrs = expansionResult.expanded ?
[] :
[new HtmlAttrAst("i18n", `${ast.type}_${c.value}`, c.valueSourceSpan)];
[] :
[new HtmlAttrAst('i18n', `${ast.type}_${c.value}`, c.valueSourceSpan)];
return new HtmlElementAst(`template`,
[
new HtmlAttrAst("ngSwitchWhen", c.value, c.valueSourceSpan),
],
[
new HtmlElementAst(`li`, i18nAttrs, expansionResult.nodes,
c.sourceSpan, c.sourceSpan, c.sourceSpan)
],
c.sourceSpan, c.sourceSpan, c.sourceSpan);
return new HtmlElementAst(
`template`,
[
new HtmlAttrAst('ngSwitchWhen', c.value, c.valueSourceSpan),
],
[new HtmlElementAst(
`li`, i18nAttrs, expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan)],
c.sourceSpan, c.sourceSpan, c.sourceSpan);
});
let switchAttr = new HtmlAttrAst("[ngSwitch]", ast.switchValue, ast.switchValueSourceSpan);
return new HtmlElementAst("ul", [switchAttr], children, ast.sourceSpan, ast.sourceSpan,
ast.sourceSpan);
let switchAttr = new HtmlAttrAst('[ngSwitch]', ast.switchValue, ast.switchValueSourceSpan);
return new HtmlElementAst(
'ul', [switchAttr], children, ast.sourceSpan, ast.sourceSpan, ast.sourceSpan);
}
@@ -1,36 +1,17 @@
import {HtmlParser, HtmlParseTreeResult} from "../html_parser";
import {ParseSourceSpan, ParseError} from "../parse_util";
import {
HtmlAst,
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
HtmlExpansionAst,
HtmlExpansionCaseAst,
htmlVisitAll
} from "../html_ast";
import {ListWrapper, StringMapWrapper} from "../facade/collection";
import {RegExpWrapper, NumberWrapper, isPresent} from "../facade/lang";
import {BaseException} from "../facade/exceptions";
import {Parser} from "../expression_parser/parser";
import {id} from "./message";
import {expandNodes} from "./expander";
import {
messageFromI18nAttribute,
I18nError,
I18N_ATTR_PREFIX,
I18N_ATTR,
partition,
Part,
getPhNameFromBinding,
dedupePhName,
messageFromAttribute
} from "./shared";
import {Parser} from '../expression_parser/parser';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {BaseException} from '../facade/exceptions';
import {NumberWrapper, RegExpWrapper, isPresent} from '../facade/lang';
import {HtmlAst, HtmlAstVisitor, HtmlAttrAst, HtmlCommentAst, HtmlElementAst, HtmlExpansionAst, HtmlExpansionCaseAst, HtmlTextAst, htmlVisitAll} from '../html_ast';
import {HtmlParseTreeResult, HtmlParser} from '../html_parser';
import {ParseError, ParseSourceSpan} from '../parse_util';
const _PLACEHOLDER_ELEMENT = "ph";
const _NAME_ATTR = "name";
import {expandNodes} from './expander';
import {id} from './message';
import {I18N_ATTR, I18N_ATTR_PREFIX, I18nError, Part, dedupePhName, getPhNameFromBinding, messageFromAttribute, messageFromI18nAttribute, partition} from './shared';
const _PLACEHOLDER_ELEMENT = 'ph';
const _NAME_ATTR = 'name';
let _PLACEHOLDER_EXPANDED_REGEXP = /<ph(\s)+name=("(\w)+")><\/ph>/gi;
/**
@@ -116,12 +97,13 @@ let _PLACEHOLDER_EXPANDED_REGEXP = /<ph(\s)+name=("(\w)+")><\/ph>/gi;
export class I18nHtmlParser implements HtmlParser {
errors: ParseError[];
constructor(private _htmlParser: HtmlParser, private _parser: Parser,
private _messagesContent: string, private _messages: {[key: string]: HtmlAst[]},
private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {}
constructor(
private _htmlParser: HtmlParser, private _parser: Parser, private _messagesContent: string,
private _messages: {[key: string]: HtmlAst[]}, private _implicitTags: string[],
private _implicitAttrs: {[k: string]: string[]}) {}
parse(sourceContent: string, sourceUrl: string,
parseExpansionForms: boolean = false): HtmlParseTreeResult {
parse(sourceContent: string, sourceUrl: string, parseExpansionForms: boolean = false):
HtmlParseTreeResult {
this.errors = [];
let res = this._htmlParser.parse(sourceContent, sourceUrl, true);
@@ -168,10 +150,8 @@ export class I18nHtmlParser implements HtmlParser {
let root = p.rootElement;
let children = this._recurse(p.children);
let attrs = this._i18nAttributes(root);
return [
new HtmlElementAst(root.name, attrs, children, root.sourceSpan, root.startSourceSpan,
root.endSourceSpan)
];
return [new HtmlElementAst(
root.name, attrs, children, root.sourceSpan, root.startSourceSpan, root.endSourceSpan)];
// a text node without i18n or interpolation, nothing to do
} else if (isPresent(p.rootTextNode)) {
@@ -200,14 +180,12 @@ export class I18nHtmlParser implements HtmlParser {
if (isPresent(p.rootElement)) {
let root = p.rootElement;
let attrs = this._i18nAttributes(root);
return [
new HtmlElementAst(root.name, attrs, merged, root.sourceSpan, root.startSourceSpan,
root.endSourceSpan)
];
return [new HtmlElementAst(
root.name, attrs, merged, root.sourceSpan, root.startSourceSpan, root.endSourceSpan)];
// this should never happen with a part. Parts that have root text node should not be merged.
} else if (isPresent(p.rootTextNode)) {
throw new BaseException("should not be reached");
throw new BaseException('should not be reached');
} else {
return merged;
@@ -223,24 +201,24 @@ export class I18nHtmlParser implements HtmlParser {
return t;
} else {
throw new BaseException("should not be reached");
throw new BaseException('should not be reached');
}
});
}
private _mergeElementOrInterpolation(t: HtmlElementAst, translated: HtmlAst[],
mapping: HtmlAst[]): HtmlAst {
private _mergeElementOrInterpolation(
t: HtmlElementAst, translated: HtmlAst[], mapping: HtmlAst[]): HtmlAst {
let name = this._getName(t);
let type = name[0];
let index = NumberWrapper.parseInt(name.substring(1), 10);
let originalNode = mapping[index];
if (type == "t") {
if (type == 't') {
return this._mergeTextInterpolation(t, <HtmlTextAst>originalNode);
} else if (type == "e") {
} else if (type == 'e') {
return this._mergeElement(t, <HtmlElementAst>originalNode, mapping);
} else {
throw new BaseException("should not be reached");
throw new BaseException('should not be reached');
}
}
@@ -270,12 +248,12 @@ export class I18nHtmlParser implements HtmlParser {
return new HtmlTextAst(translated, originalNode.sourceSpan);
}
private _mergeElement(t: HtmlElementAst, originalNode: HtmlElementAst,
mapping: HtmlAst[]): HtmlElementAst {
private _mergeElement(t: HtmlElementAst, originalNode: HtmlElementAst, mapping: HtmlAst[]):
HtmlElementAst {
let children = this._mergeTreesHelper(t.children, mapping);
return new HtmlElementAst(originalNode.name, this._i18nAttributes(originalNode), children,
originalNode.sourceSpan, originalNode.startSourceSpan,
originalNode.endSourceSpan);
return new HtmlElementAst(
originalNode.name, this._i18nAttributes(originalNode), children, originalNode.sourceSpan,
originalNode.startSourceSpan, originalNode.endSourceSpan);
}
private _i18nAttributes(el: HtmlElementAst): HtmlAttrAst[] {
@@ -330,14 +308,15 @@ export class I18nHtmlParser implements HtmlParser {
return this._replacePlaceholdersWithExpressions(messageSubstring, exps, attr.sourceSpan);
};
private _replacePlaceholdersWithExpressions(message: string, exps: string[],
sourceSpan: ParseSourceSpan): string {
private _replacePlaceholdersWithExpressions(
message: string, exps: string[], sourceSpan: ParseSourceSpan): string {
let expMap = this._buildExprMap(exps);
return RegExpWrapper.replaceAll(_PLACEHOLDER_EXPANDED_REGEXP, message, (match: any /** TODO #9100 */) => {
let nameWithQuotes = match[2];
let name = nameWithQuotes.substring(1, nameWithQuotes.length - 1);
return this._convertIntoExpression(name, expMap, sourceSpan);
});
return RegExpWrapper.replaceAll(
_PLACEHOLDER_EXPANDED_REGEXP, message, (match: any /** TODO #9100 */) => {
let nameWithQuotes = match[2];
let name = nameWithQuotes.substring(1, nameWithQuotes.length - 1);
return this._convertIntoExpression(name, expMap, sourceSpan);
});
}
private _buildExprMap(exps: string[]): Map<string, string> {
@@ -351,8 +330,8 @@ export class I18nHtmlParser implements HtmlParser {
return expMap;
}
private _convertIntoExpression(name: string, expMap: Map<string, string>,
sourceSpan: ParseSourceSpan) {
private _convertIntoExpression(
name: string, expMap: Map<string, string>, sourceSpan: ParseSourceSpan) {
if (expMap.has(name)) {
return `{{${expMap.get(name)}}}`;
} else {
@@ -381,5 +360,5 @@ class _CreateNodeMapping implements HtmlAstVisitor {
visitExpansionCase(ast: HtmlExpansionCaseAst, context: any): any { return null; }
visitComment(ast: HtmlCommentAst, context: any): any { return ""; }
visitComment(ast: HtmlCommentAst, context: any): any { return ''; }
}
@@ -1,4 +1,5 @@
import {isPresent, escape} from '../facade/lang';
import {escape, isPresent} from '../facade/lang';
/**
* A message extracted from a template.
@@ -15,7 +16,7 @@ export class Message {
* Computes the id of a message
*/
export function id(m: Message): string {
let meaning = isPresent(m.meaning) ? m.meaning : "";
let content = isPresent(m.content) ? m.content : "";
let meaning = isPresent(m.meaning) ? m.meaning : '';
let content = isPresent(m.content) ? m.content : '';
return escape(`$ng|${meaning}|${content}`);
}
@@ -1,19 +1,14 @@
import {HtmlParser} from "../html_parser";
import {ParseError} from "../parse_util";
import {HtmlAst, HtmlElementAst} from "../html_ast";
import {isPresent} from "../facade/lang";
import {StringMapWrapper} from "../facade/collection";
import {Parser} from "../expression_parser/parser";
import {Message, id} from "./message";
import {expandNodes} from "./expander";
import {
I18nError,
Part,
I18N_ATTR_PREFIX,
partition,
messageFromI18nAttribute,
messageFromAttribute
} from "./shared";
import {Parser} from '../expression_parser/parser';
import {StringMapWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {HtmlAst, HtmlElementAst} from '../html_ast';
import {HtmlParser} from '../html_parser';
import {ParseError} from '../parse_util';
import {expandNodes} from './expander';
import {Message, id} from './message';
import {I18N_ATTR_PREFIX, I18nError, Part, messageFromAttribute, messageFromI18nAttribute, partition} from './shared';
/**
* All messages extracted from a template.
@@ -106,8 +101,9 @@ export class MessageExtractor {
messages: Message[];
errors: ParseError[];
constructor(private _htmlParser: HtmlParser, private _parser: Parser,
private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {}
constructor(
private _htmlParser: HtmlParser, private _parser: Parser, private _implicitTags: string[],
private _implicitAttrs: {[k: string]: string[]}) {}
extract(template: string, sourceUrl: string): ExtractionResult {
this.messages = [];
+32 -39
View File
@@ -1,21 +1,12 @@
import {ParseSourceSpan, ParseError} from '../parse_util';
import {
HtmlAst,
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
HtmlExpansionAst,
HtmlExpansionCaseAst,
htmlVisitAll
} from '../html_ast';
import {isPresent, isBlank, StringWrapper} from '../facade/lang';
import {Message} from './message';
import {Parser} from '../expression_parser/parser';
import {StringWrapper, isBlank, isPresent} from '../facade/lang';
import {HtmlAst, HtmlAstVisitor, HtmlAttrAst, HtmlCommentAst, HtmlElementAst, HtmlExpansionAst, HtmlExpansionCaseAst, HtmlTextAst, htmlVisitAll} from '../html_ast';
import {ParseError, ParseSourceSpan} from '../parse_util';
export const I18N_ATTR = "i18n";
export const I18N_ATTR_PREFIX = "i18n-";
import {Message} from './message';
export const I18N_ATTR = 'i18n';
export const I18N_ATTR_PREFIX = 'i18n-';
var CUSTOM_PH_EXP = /\/\/[\s\S]*i18n[\s\S]*\([\s\S]*ph[\s\S]*=[\s\S]*"([\s\S]*?)"[\s\S]*\)/g;
/**
@@ -39,7 +30,7 @@ export function partition(nodes: HtmlAst[], errors: ParseError[], implicitTags:
while (!_isClosingComment(nodes[i])) {
temp.push(nodes[i++]);
if (i === nodes.length) {
errors.push(new I18nError(n.sourceSpan, "Missing closing 'i18n' comment."));
errors.push(new I18nError(n.sourceSpan, 'Missing closing \'i18n\' comment.'));
break;
}
}
@@ -58,8 +49,9 @@ export function partition(nodes: HtmlAst[], errors: ParseError[], implicitTags:
}
export class Part {
constructor(public rootElement: HtmlElementAst, public rootTextNode: HtmlTextAst,
public children: HtmlAst[], public i18n: string, public hasI18n: boolean) {}
constructor(
public rootElement: HtmlElementAst, public rootTextNode: HtmlTextAst,
public children: HtmlAst[], public i18n: string, public hasI18n: boolean) {}
get sourceSpan(): ParseSourceSpan {
if (isPresent(this.rootElement))
@@ -71,17 +63,17 @@ export class Part {
}
createMessage(parser: Parser): Message {
return new Message(stringifyNodes(this.children, parser), meaning(this.i18n),
description(this.i18n));
return new Message(
stringifyNodes(this.children, parser), meaning(this.i18n), description(this.i18n));
}
}
function _isOpeningComment(n: HtmlAst): boolean {
return n instanceof HtmlCommentAst && isPresent(n.value) && n.value.startsWith("i18n:");
return n instanceof HtmlCommentAst && isPresent(n.value) && n.value.startsWith('i18n:');
}
function _isClosingComment(n: HtmlAst): boolean {
return n instanceof HtmlCommentAst && isPresent(n.value) && n.value == "/i18n";
return n instanceof HtmlCommentAst && isPresent(n.value) && n.value == '/i18n';
}
function _findI18nAttr(p: HtmlElementAst): HtmlAttrAst {
@@ -90,13 +82,13 @@ function _findI18nAttr(p: HtmlElementAst): HtmlAttrAst {
}
export function meaning(i18n: string): string {
if (isBlank(i18n) || i18n == "") return null;
return i18n.split("|")[0];
if (isBlank(i18n) || i18n == '') return null;
return i18n.split('|')[0];
}
export function description(i18n: string): string {
if (isBlank(i18n) || i18n == "") return null;
let parts = i18n.split("|");
if (isBlank(i18n) || i18n == '') return null;
let parts = i18n.split('|');
return parts.length > 1 ? parts[1] : null;
}
@@ -105,32 +97,33 @@ export function description(i18n: string): string {
*
* @internal
*/
export function messageFromI18nAttribute(parser: Parser, p: HtmlElementAst,
i18nAttr: HtmlAttrAst): Message {
export function messageFromI18nAttribute(
parser: Parser, p: HtmlElementAst, i18nAttr: HtmlAttrAst): Message {
let expectedName = i18nAttr.name.substring(5);
let matching = p.attrs.filter(a => a.name == expectedName);
if (matching.length > 0) {
return messageFromAttribute(parser, matching[0], meaning(i18nAttr.value),
description(i18nAttr.value));
return messageFromAttribute(
parser, matching[0], meaning(i18nAttr.value), description(i18nAttr.value));
}
throw new I18nError(p.sourceSpan, `Missing attribute '${expectedName}'.`);
}
export function messageFromAttribute(parser: Parser, attr: HtmlAttrAst, meaning: string = null,
description: string = null): Message {
export function messageFromAttribute(
parser: Parser, attr: HtmlAttrAst, meaning: string = null,
description: string = null): Message {
let value = removeInterpolation(attr.value, attr.sourceSpan, parser);
return new Message(value, meaning, description);
}
export function removeInterpolation(value: string, source: ParseSourceSpan,
parser: Parser): string {
export function removeInterpolation(
value: string, source: ParseSourceSpan, parser: Parser): string {
try {
let parsed = parser.splitInterpolation(value, source.toString());
let usedNames = new Map<string, number>();
if (isPresent(parsed)) {
let res = "";
let res = '';
for (let i = 0; i < parsed.strings.length; ++i) {
res += parsed.strings[i];
if (i != parsed.strings.length - 1) {
@@ -166,7 +159,7 @@ export function dedupePhName(usedNames: Map<string, number>, name: string): stri
export function stringifyNodes(nodes: HtmlAst[], parser: Parser): string {
let visitor = new _StringifyVisitor(parser);
return htmlVisitAll(visitor, nodes).join("");
return htmlVisitAll(visitor, nodes).join('');
}
class _StringifyVisitor implements HtmlAstVisitor {
@@ -175,7 +168,7 @@ class _StringifyVisitor implements HtmlAstVisitor {
visitElement(ast: HtmlElementAst, context: any): any {
let name = this._index++;
let children = this._join(htmlVisitAll(this, ast.children), "");
let children = this._join(htmlVisitAll(this, ast.children), '');
return `<ph name="e${name}">${children}</ph>`;
}
@@ -191,7 +184,7 @@ class _StringifyVisitor implements HtmlAstVisitor {
}
}
visitComment(ast: HtmlCommentAst, context: any): any { return ""; }
visitComment(ast: HtmlCommentAst, context: any): any { return ''; }
visitExpansion(ast: HtmlExpansionAst, context: any): any { return null; }
@@ -1,22 +1,24 @@
import {isPresent, isBlank, RegExpWrapper} from '../facade/lang';
import {RegExpWrapper, isBlank, isPresent} from '../facade/lang';
import {HtmlAst, HtmlElementAst} from '../html_ast';
import {Message, id} from './message';
import {HtmlParser} from '../html_parser';
import {ParseSourceSpan, ParseError} from '../parse_util';
import {ParseError, ParseSourceSpan} from '../parse_util';
import {Message, id} from './message';
let _PLACEHOLDER_REGEXP = RegExpWrapper.create(`\\<ph(\\s)+name=("(\\w)+")\\/\\>`);
const _ID_ATTR = "id";
const _MSG_ELEMENT = "msg";
const _BUNDLE_ELEMENT = "message-bundle";
const _ID_ATTR = 'id';
const _MSG_ELEMENT = 'msg';
const _BUNDLE_ELEMENT = 'message-bundle';
export function serializeXmb(messages: Message[]): string {
let ms = messages.map((m) => _serializeMessage(m)).join("");
let ms = messages.map((m) => _serializeMessage(m)).join('');
return `<message-bundle>${ms}</message-bundle>`;
}
export class XmbDeserializationResult {
constructor(public content: string, public messages: {[key: string]: HtmlAst[]},
public errors: ParseError[]) {}
constructor(
public content: string, public messages: {[key: string]: HtmlAst[]},
public errors: ParseError[]) {}
}
export class XmbDeserializationError extends ParseError {
@@ -44,17 +46,17 @@ export function deserializeXmb(content: string, url: string): XmbDeserialization
_createMessages(bundleEl.children, messages, errors);
return (errors.length == 0) ?
new XmbDeserializationResult(normalizedContent, messages, []) :
new XmbDeserializationResult(null, <{[key: string]: HtmlAst[]}>{}, errors);
new XmbDeserializationResult(normalizedContent, messages, []) :
new XmbDeserializationResult(null, <{[key: string]: HtmlAst[]}>{}, errors);
}
function _checkRootElement(nodes: HtmlAst[]): boolean {
return nodes.length < 1 || !(nodes[0] instanceof HtmlElementAst) ||
(<HtmlElementAst>nodes[0]).name != _BUNDLE_ELEMENT;
(<HtmlElementAst>nodes[0]).name != _BUNDLE_ELEMENT;
}
function _createMessages(nodes: HtmlAst[], messages: {[key: string]: HtmlAst[]},
errors: ParseError[]): void {
function _createMessages(
nodes: HtmlAst[], messages: {[key: string]: HtmlAst[]}, errors: ParseError[]): void {
nodes.forEach((item) => {
if (item instanceof HtmlElementAst) {
let msg = <HtmlElementAst>item;
@@ -83,7 +85,7 @@ function _id(el: HtmlElementAst): string {
}
function _serializeMessage(m: Message): string {
let desc = isPresent(m.description) ? ` desc='${m.description}'` : "";
let desc = isPresent(m.description) ? ` desc='${m.description}'` : '';
return `<msg id='${id(m)}'${desc}>${m.content}</msg>`;
}
+13 -70
View File
@@ -1,57 +1,6 @@
import {
SimpleChange,
ChangeDetectorRef,
ChangeDetectionStrategy,
ElementRef,
ViewContainerRef,
Renderer,
RenderComponentType,
Injector,
QueryList,
ViewEncapsulation,
TemplateRef
} from '@angular/core';
import {
AppElement,
AppView,
DebugAppView,
ChangeDetectorState,
checkBinding,
DebugContext,
devModeEqual,
flattenNestedViewRenderNodes,
interpolate,
StaticNodeDebugInfo,
TemplateRef_,
uninitialized,
ValueUnwrapper,
ViewType,
ViewUtils,
castByValue,
EMPTY_ARRAY,
EMPTY_MAP,
pureProxy1,
pureProxy2,
pureProxy3,
pureProxy4,
pureProxy5,
pureProxy6,
pureProxy7,
pureProxy8,
pureProxy9,
pureProxy10,
AnimationKeyframe as AnimationKeyframe_,
AnimationStyles as AnimationStyles_,
NoOpAnimationPlayer as NoOpAnimationPlayer_,
AnimationGroupPlayer as AnimationGroupPlayer_,
AnimationSequencePlayer as AnimationSequencePlayer_,
balanceAnimationStyles as impBalanceAnimationStyles,
balanceAnimationKeyframes as impBalanceAnimationKeyframes,
clearStyles as impClearStyles,
collectAndResolveStyles as impCollectAndResolveStyles,
renderStyles as impRenderStyles,
SecurityContext
} from '../core_private';
import {ChangeDetectionStrategy, ChangeDetectorRef, ElementRef, Injector, QueryList, RenderComponentType, Renderer, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
import {AnimationGroupPlayer as AnimationGroupPlayer_, AnimationKeyframe as AnimationKeyframe_, AnimationSequencePlayer as AnimationSequencePlayer_, AnimationStyles as AnimationStyles_, AppElement, AppView, ChangeDetectorState, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NoOpAnimationPlayer as NoOpAnimationPlayer_, SecurityContext, StaticNodeDebugInfo, TemplateRef_, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes as impBalanceAnimationKeyframes, balanceAnimationStyles as impBalanceAnimationStyles, castByValue, checkBinding, clearStyles as impClearStyles, collectAndResolveStyles as impCollectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, renderStyles as impRenderStyles, uninitialized} from '../core_private';
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
import {assetUrl} from './util';
@@ -98,7 +47,7 @@ var impAnimationKeyframe = AnimationKeyframe_;
var impAnimationStyles = AnimationStyles_;
var impNoOpAnimationPlayer = NoOpAnimationPlayer_;
var ANIMATION_STYLE_UTIL_ASSET_URL = assetUrl('core','animation/animation_style_util');
var ANIMATION_STYLE_UTIL_ASSET_URL = assetUrl('core', 'animation/animation_style_util');
export class Identifiers {
static ViewUtils = new CompileIdentifierMetadata(
@@ -223,27 +172,27 @@ export class Identifiers {
});
static AnimationKeyframe = new CompileIdentifierMetadata({
name: 'AnimationKeyframe',
moduleUrl: assetUrl('core','animation/animation_keyframe'),
moduleUrl: assetUrl('core', 'animation/animation_keyframe'),
runtime: impAnimationKeyframe
});
static AnimationStyles = new CompileIdentifierMetadata({
name: 'AnimationStyles',
moduleUrl: assetUrl('core','animation/animation_styles'),
moduleUrl: assetUrl('core', 'animation/animation_styles'),
runtime: impAnimationStyles
});
static NoOpAnimationPlayer = new CompileIdentifierMetadata({
name: 'NoOpAnimationPlayer',
moduleUrl: assetUrl('core','animation/animation_player'),
moduleUrl: assetUrl('core', 'animation/animation_player'),
runtime: impNoOpAnimationPlayer
});
static AnimationGroupPlayer = new CompileIdentifierMetadata({
name: 'AnimationGroupPlayer',
moduleUrl: assetUrl('core','animation/animation_group_player'),
moduleUrl: assetUrl('core', 'animation/animation_group_player'),
runtime: impAnimationGroupPlayer
});
static AnimationSequencePlayer = new CompileIdentifierMetadata({
name: 'AnimationSequencePlayer',
moduleUrl: assetUrl('core','animation/animation_sequence_player'),
moduleUrl: assetUrl('core', 'animation/animation_sequence_player'),
runtime: impAnimationSequencePlayer
});
static balanceAnimationStyles = new CompileIdentifierMetadata({
@@ -256,16 +205,10 @@ export class Identifiers {
moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL,
runtime: impBalanceAnimationKeyframes
});
static clearStyles = new CompileIdentifierMetadata({
name: 'clearStyles',
moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL,
runtime: impClearStyles
});
static renderStyles = new CompileIdentifierMetadata({
name: 'renderStyles',
moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL,
runtime: impRenderStyles
});
static clearStyles = new CompileIdentifierMetadata(
{name: 'clearStyles', moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL, runtime: impClearStyles});
static renderStyles = new CompileIdentifierMetadata(
{name: 'renderStyles', moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL, runtime: impRenderStyles});
static collectAndResolveStyles = new CompileIdentifierMetadata({
name: 'collectAndResolveStyles',
moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL,
@@ -1,53 +1,18 @@
import {
AnimationMetadata,
AnimationEntryMetadata,
AnimationStateMetadata,
AnimationStateDeclarationMetadata,
AnimationStateTransitionMetadata,
AnimationStyleMetadata,
AnimationKeyframesSequenceMetadata,
AnimationAnimateMetadata,
AnimationWithStepsMetadata,
AnimationGroupMetadata,
AttributeMetadata,
OptionalMetadata,
ComponentMetadata,
SelfMetadata,
HostMetadata,
SkipSelfMetadata,
Provider,
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
Injectable,
Inject,
Optional,
ViewMetadata,
QueryMetadata,
resolveForwardRef,
InjectMetadata,
ViewQueryMetadata
} from '@angular/core';
import {LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from '../core_private';
import {
Type,
isBlank,
isPresent,
isArray,
stringify,
isString,
isStringMap
} from '../src/facade/lang';
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, AttributeMetadata, ComponentMetadata, HostMetadata, Inject, InjectMetadata, Injectable, Optional, OptionalMetadata, PLATFORM_DIRECTIVES, PLATFORM_PIPES, Provider, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewMetadata, ViewQueryMetadata, resolveForwardRef} from '@angular/core';
import {LIFECYCLE_HOOKS_VALUES, ReflectorReader, createProvider, isProviderLiteral, reflector} from '../core_private';
import {StringMapWrapper} from '../src/facade/collection';
import {BaseException} from '../src/facade/exceptions';
import {Type, isArray, isBlank, isPresent, isString, isStringMap, stringify} from '../src/facade/lang';
import {assertArrayOfStrings} from './assertions';
import * as cpl from './compile_metadata';
import {hasLifecycleHook} from './directive_lifecycle_reflector';
import {DirectiveResolver} from './directive_resolver';
import {PipeResolver} from './pipe_resolver';
import {ViewResolver} from './view_resolver';
import {hasLifecycleHook} from './directive_lifecycle_reflector';
import {MODULE_SUFFIX, sanitizeIdentifier, ValueTransformer, visitValue} from './util';
import {assertArrayOfStrings} from './assertions';
import {getUrlScheme} from './url_resolver';
import {createProvider, isProviderLiteral} from "../core_private";
import {MODULE_SUFFIX, ValueTransformer, sanitizeIdentifier, visitValue} from './util';
import {ViewResolver} from './view_resolver';
@Injectable()
@@ -58,11 +23,12 @@ export class CompileMetadataResolver {
private _anonymousTypeIndex = 0;
private _reflector: ReflectorReader;
constructor(private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
private _viewResolver: ViewResolver,
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[],
_reflector?: ReflectorReader) {
constructor(
private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
private _viewResolver: ViewResolver,
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[],
_reflector?: ReflectorReader) {
if (isPresent(_reflector)) {
this._reflector = _reflector;
} else {
@@ -94,7 +60,8 @@ export class CompileMetadataResolver {
var styles = this.getAnimationStyleMetadata(value.styles);
return new cpl.CompileAnimationStateDeclarationMetadata(value.stateNameExpr, styles);
} else if (value instanceof AnimationStateTransitionMetadata) {
return new cpl.CompileAnimationStateTransitionMetadata(value.stateChangeExpr, this.getAnimationMetadata(value.steps));
return new cpl.CompileAnimationStateTransitionMetadata(
value.stateChangeExpr, this.getAnimationMetadata(value.steps));
}
return null;
}
@@ -107,9 +74,12 @@ export class CompileMetadataResolver {
if (value instanceof AnimationStyleMetadata) {
return this.getAnimationStyleMetadata(value);
} else if (value instanceof AnimationKeyframesSequenceMetadata) {
return new cpl.CompileAnimationKeyframesSequenceMetadata(value.steps.map(entry => this.getAnimationStyleMetadata(entry)));
return new cpl.CompileAnimationKeyframesSequenceMetadata(
value.steps.map(entry => this.getAnimationStyleMetadata(entry)));
} else if (value instanceof AnimationAnimateMetadata) {
let animateData = <cpl.CompileAnimationStyleMetadata|cpl.CompileAnimationKeyframesSequenceMetadata>this.getAnimationMetadata(value.styles);
let animateData =
<cpl.CompileAnimationStyleMetadata|cpl.CompileAnimationKeyframesSequenceMetadata>this
.getAnimationMetadata(value.styles);
return new cpl.CompileAnimationAnimateMetadata(value.timings, animateData);
} else if (value instanceof AnimationWithStepsMetadata) {
var steps = value.steps.map(step => this.getAnimationMetadata(step));
@@ -135,9 +105,9 @@ export class CompileMetadataResolver {
var cmpMeta = <ComponentMetadata>dirMeta;
var viewMeta = this._viewResolver.resolve(directiveType);
assertArrayOfStrings('styles', viewMeta.styles);
var animations = isPresent(viewMeta.animations)
? viewMeta.animations.map(e => this.getAnimationEntryMetadata(e))
: null;
var animations = isPresent(viewMeta.animations) ?
viewMeta.animations.map(e => this.getAnimationEntryMetadata(e)) :
null;
templateMeta = new cpl.CompileTemplateMetadata({
encapsulation: viewMeta.encapsulation,
@@ -258,8 +228,8 @@ export class CompileMetadataResolver {
return pipes.map(type => this.getPipeMetadata(type));
}
getDependenciesMetadata(typeOrFunc: Type | Function,
dependencies: any[]): cpl.CompileDiDependencyMetadata[] {
getDependenciesMetadata(typeOrFunc: Type|Function, dependencies: any[]):
cpl.CompileDiDependencyMetadata[] {
let hasUnknownDeps = false;
let params = isPresent(dependencies) ? dependencies : this._reflector.parameters(typeOrFunc);
if (isBlank(params)) {
@@ -278,31 +248,30 @@ export class CompileMetadataResolver {
let viewQuery: ViewQueryMetadata = null;
var token: any /** TODO #9100 */ = null;
if (isArray(param)) {
(<any[]>param)
.forEach((paramEntry) => {
if (paramEntry instanceof HostMetadata) {
isHost = true;
} else if (paramEntry instanceof SelfMetadata) {
isSelf = true;
} else if (paramEntry instanceof SkipSelfMetadata) {
isSkipSelf = true;
} else if (paramEntry instanceof OptionalMetadata) {
isOptional = true;
} else if (paramEntry instanceof AttributeMetadata) {
isAttribute = true;
token = paramEntry.attributeName;
} else if (paramEntry instanceof QueryMetadata) {
if (paramEntry.isViewQuery) {
viewQuery = paramEntry;
} else {
query = paramEntry;
}
} else if (paramEntry instanceof InjectMetadata) {
token = paramEntry.token;
} else if (isValidType(paramEntry) && isBlank(token)) {
token = paramEntry;
}
});
(<any[]>param).forEach((paramEntry) => {
if (paramEntry instanceof HostMetadata) {
isHost = true;
} else if (paramEntry instanceof SelfMetadata) {
isSelf = true;
} else if (paramEntry instanceof SkipSelfMetadata) {
isSkipSelf = true;
} else if (paramEntry instanceof OptionalMetadata) {
isOptional = true;
} else if (paramEntry instanceof AttributeMetadata) {
isAttribute = true;
token = paramEntry.attributeName;
} else if (paramEntry instanceof QueryMetadata) {
if (paramEntry.isViewQuery) {
viewQuery = paramEntry;
} else {
query = paramEntry;
}
} else if (paramEntry instanceof InjectMetadata) {
token = paramEntry.token;
} else if (isValidType(paramEntry) && isBlank(token)) {
token = paramEntry;
}
});
} else {
token = param;
}
@@ -324,10 +293,11 @@ export class CompileMetadataResolver {
});
if (hasUnknownDeps) {
let depsTokens = dependenciesMetadata.map((dep) => {
return dep ? stringify(dep.token) : '?';
}).join(', ');
throw new BaseException(`Can't resolve all parameters for ${stringify(typeOrFunc)}: (${depsTokens}).`);
let depsTokens =
dependenciesMetadata.map((dep) => { return dep ? stringify(dep.token) : '?'; })
.join(', ');
throw new BaseException(
`Can't resolve all parameters for ${stringify(typeOrFunc)}: (${depsTokens}).`);
}
return dependenciesMetadata;
@@ -351,7 +321,7 @@ export class CompileMetadataResolver {
}
getProvidersMetadata(providers: any[]):
Array<cpl.CompileProviderMetadata | cpl.CompileTypeMetadata | any[]> {
Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> {
return providers.map((provider) => {
provider = resolveForwardRef(provider);
if (isArray(provider)) {
@@ -375,15 +345,13 @@ export class CompileMetadataResolver {
}
return new cpl.CompileProviderMetadata({
token: this.getTokenMetadata(provider.token),
useClass:
isPresent(provider.useClass) ?
this.getTypeMetadata(provider.useClass, staticTypeModuleUrl(provider.useClass)) :
null,
useClass: isPresent(provider.useClass) ?
this.getTypeMetadata(provider.useClass, staticTypeModuleUrl(provider.useClass)) :
null,
useValue: convertToCompileValue(provider.useValue),
useFactory: isPresent(provider.useFactory) ?
this.getFactoryMetadata(provider.useFactory,
staticTypeModuleUrl(provider.useFactory)) :
null,
this.getFactoryMetadata(provider.useFactory, staticTypeModuleUrl(provider.useFactory)) :
null,
useExisting: isPresent(provider.useExisting) ? this.getTokenMetadata(provider.useExisting) :
null,
deps: compileDeps,
@@ -391,24 +359,28 @@ export class CompileMetadataResolver {
});
}
getQueriesMetadata(queries: {[key: string]: QueryMetadata},
isViewQuery: boolean, directiveType: Type): cpl.CompileQueryMetadata[] {
getQueriesMetadata(
queries: {[key: string]: QueryMetadata}, isViewQuery: boolean,
directiveType: Type): cpl.CompileQueryMetadata[] {
var compileQueries: any[] /** TODO #9100 */ = [];
StringMapWrapper.forEach(queries, (query: any /** TODO #9100 */, propertyName: any /** TODO #9100 */) => {
if (query.isViewQuery === isViewQuery) {
compileQueries.push(this.getQueryMetadata(query, propertyName, directiveType));
}
});
StringMapWrapper.forEach(
queries, (query: any /** TODO #9100 */, propertyName: any /** TODO #9100 */) => {
if (query.isViewQuery === isViewQuery) {
compileQueries.push(this.getQueryMetadata(query, propertyName, directiveType));
}
});
return compileQueries;
}
getQueryMetadata(q: QueryMetadata, propertyName: string, typeOrFunc: Type | Function): cpl.CompileQueryMetadata {
getQueryMetadata(q: QueryMetadata, propertyName: string, typeOrFunc: Type|Function):
cpl.CompileQueryMetadata {
var selectors: any /** TODO #9100 */;
if (q.isVarBindingQuery) {
selectors = q.varBindings.map(varName => this.getTokenMetadata(varName));
} else {
if (!isPresent(q.selector)) {
throw new BaseException(`Can't construct a query for the property "${propertyName}" of "${stringify(typeOrFunc)}" since the query selector wasn't defined.`);
throw new BaseException(
`Can't construct a query for the property "${propertyName}" of "${stringify(typeOrFunc)}" since the query selector wasn't defined.`);
}
selectors = [this.getTokenMetadata(q.selector)];
}
@@ -444,7 +416,7 @@ function flattenPipes(view: ViewMetadata, platformPipes: any[]): Type[] {
return pipes;
}
function flattenArray(tree: any[], out: Array<Type | any[]>): void {
function flattenArray(tree: any[], out: Array<Type|any[]>): void {
for (var i = 0; i < tree.length; i++) {
var item = resolveForwardRef(tree[i]);
if (isArray(item)) {
@@ -467,8 +439,8 @@ function staticTypeModuleUrl(value: any): string {
return isStaticType(value) ? value['filePath'] : null;
}
function componentModuleUrl(reflector: ReflectorReader, type: any,
cmpMetadata: ComponentMetadata): string {
function componentModuleUrl(
reflector: ReflectorReader, type: any, cmpMetadata: ComponentMetadata): string {
if (isStaticType(type)) {
return staticTypeModuleUrl(type);
}
@@ -1,23 +1,16 @@
import {ComponentFactory} from '@angular/core';
import {
CompileDirectiveMetadata,
CompileIdentifierMetadata,
CompilePipeMetadata,
createHostComponentMeta
} from './compile_metadata';
import {BaseException} from './facade/exceptions';
import {ListWrapper} from './facade/collection';
import {StyleCompiler, StylesCompileResult} from './style_compiler';
import {ViewCompiler, ViewCompileResult} from './view_compiler/view_compiler';
import {TemplateParser} from './template_parser';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata, createHostComponentMeta} from './compile_metadata';
import {DirectiveNormalizer} from './directive_normalizer';
import {ListWrapper} from './facade/collection';
import {BaseException} from './facade/exceptions';
import {OutputEmitter} from './output/abstract_emitter';
import * as o from './output/output_ast';
import {XHR} from './xhr';
import {StyleCompiler, StylesCompileResult} from './style_compiler';
import {TemplateParser} from './template_parser';
import {assetUrl} from './util';
import {ViewCompileResult, ViewCompiler} from './view_compiler/view_compiler';
import {XHR} from './xhr';
var _COMPONENT_FACTORY_IDENTIFIER = new CompileIdentifierMetadata({
name: 'ComponentFactory',
@@ -34,15 +27,16 @@ export class StyleSheetSourceWithImports {
}
export class NormalizedComponentWithViewDirectives {
constructor(public component: CompileDirectiveMetadata,
public directives: CompileDirectiveMetadata[], public pipes: CompilePipeMetadata[]) {}
constructor(
public component: CompileDirectiveMetadata, public directives: CompileDirectiveMetadata[],
public pipes: CompilePipeMetadata[]) {}
}
export class OfflineCompiler {
constructor(private _directiveNormalizer: DirectiveNormalizer,
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
private _viewCompiler: ViewCompiler, private _outputEmitter: OutputEmitter,
private _xhr: XHR) {}
constructor(
private _directiveNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
private _outputEmitter: OutputEmitter, private _xhr: XHR) {}
normalizeDirectiveMetadata(directive: CompileDirectiveMetadata):
Promise<CompileDirectiveMetadata> {
@@ -59,8 +53,8 @@ export class OfflineCompiler {
components.forEach(componentWithDirs => {
var compMeta = <CompileDirectiveMetadata>componentWithDirs.component;
_assertComponent(compMeta);
var compViewFactoryVar = this._compileComponent(compMeta, componentWithDirs.directives,
componentWithDirs.pipes, statements);
var compViewFactoryVar = this._compileComponent(
compMeta, componentWithDirs.directives, componentWithDirs.pipes, statements);
exportedVars.push(compViewFactoryVar);
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
@@ -71,56 +65,56 @@ export class OfflineCompiler {
.set(o.importExpr(_COMPONENT_FACTORY_IDENTIFIER, [o.importType(compMeta.type)])
.instantiate(
[
o.literal(compMeta.selector),
o.variable(hostViewFactoryVar),
o.literal(compMeta.selector), o.variable(hostViewFactoryVar),
o.importExpr(compMeta.type)
],
o.importType(_COMPONENT_FACTORY_IDENTIFIER,
[o.importType(compMeta.type)], [o.TypeModifier.Const])))
o.importType(
_COMPONENT_FACTORY_IDENTIFIER, [o.importType(compMeta.type)],
[o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]));
exportedVars.push(compFactoryVar);
});
return this._codegenSourceModule(moduleUrl, statements, exportedVars);
}
loadAndCompileStylesheet(stylesheetUrl: string, shim: boolean,
suffix: string): Promise<StyleSheetSourceWithImports> {
return this._xhr.get(stylesheetUrl)
.then((cssText) => {
var compileResult = this._styleCompiler.compileStylesheet(stylesheetUrl, cssText, shim);
var importedUrls: any[] /** TODO #9100 */ = [];
compileResult.dependencies.forEach((dep) => {
importedUrls.push(dep.moduleUrl);
dep.valuePlaceholder.moduleUrl = _stylesModuleUrl(dep.moduleUrl, dep.isShimmed, suffix);
});
return new StyleSheetSourceWithImports(
this._codgenStyles(stylesheetUrl, shim, suffix, compileResult), importedUrls);
});
loadAndCompileStylesheet(stylesheetUrl: string, shim: boolean, suffix: string):
Promise<StyleSheetSourceWithImports> {
return this._xhr.get(stylesheetUrl).then((cssText) => {
var compileResult = this._styleCompiler.compileStylesheet(stylesheetUrl, cssText, shim);
var importedUrls: any[] /** TODO #9100 */ = [];
compileResult.dependencies.forEach((dep) => {
importedUrls.push(dep.moduleUrl);
dep.valuePlaceholder.moduleUrl = _stylesModuleUrl(dep.moduleUrl, dep.isShimmed, suffix);
});
return new StyleSheetSourceWithImports(
this._codgenStyles(stylesheetUrl, shim, suffix, compileResult), importedUrls);
});
}
private _compileComponent(compMeta: CompileDirectiveMetadata,
directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
targetStatements: o.Statement[]): string {
private _compileComponent(
compMeta: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], targetStatements: o.Statement[]): string {
var styleResult = this._styleCompiler.compileComponent(compMeta);
var parsedTemplate = this._templateParser.parse(compMeta, compMeta.template.template,
directives, pipes, compMeta.type.name);
var viewResult = this._viewCompiler.compileComponent(compMeta, parsedTemplate,
o.variable(styleResult.stylesVar), pipes);
ListWrapper.addAll(targetStatements,
_resolveStyleStatements(compMeta.type.moduleUrl, styleResult));
var parsedTemplate = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, compMeta.type.name);
var viewResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, o.variable(styleResult.stylesVar), pipes);
ListWrapper.addAll(
targetStatements, _resolveStyleStatements(compMeta.type.moduleUrl, styleResult));
ListWrapper.addAll(targetStatements, _resolveViewStatements(viewResult));
return viewResult.viewFactoryVar;
}
private _codgenStyles(inputUrl: string, shim: boolean, suffix: string,
stylesCompileResult: StylesCompileResult): SourceModule {
return this._codegenSourceModule(_stylesModuleUrl(inputUrl, shim, suffix),
stylesCompileResult.statements,
[stylesCompileResult.stylesVar]);
private _codgenStyles(
inputUrl: string, shim: boolean, suffix: string,
stylesCompileResult: StylesCompileResult): SourceModule {
return this._codegenSourceModule(
_stylesModuleUrl(inputUrl, shim, suffix), stylesCompileResult.statements,
[stylesCompileResult.stylesVar]);
}
private _codegenSourceModule(moduleUrl: string, statements: o.Statement[],
exportedVars: string[]): SourceModule {
private _codegenSourceModule(
moduleUrl: string, statements: o.Statement[], exportedVars: string[]): SourceModule {
return new SourceModule(
moduleUrl, this._outputEmitter.emitStatements(moduleUrl, statements, exportedVars));
}
@@ -133,8 +127,8 @@ function _resolveViewStatements(compileResult: ViewCompileResult): o.Statement[]
}
function _resolveStyleStatements(containingModuleUrl: string,
compileResult: StylesCompileResult): o.Statement[] {
function _resolveStyleStatements(
containingModuleUrl: string, compileResult: StylesCompileResult): o.Statement[] {
var containingSuffix = _splitSuffix(containingModuleUrl)[1];
compileResult.dependencies.forEach((dep) => {
dep.valuePlaceholder.moduleUrl =
@@ -1,5 +1,6 @@
import {isPresent, isBlank, isString, StringWrapper} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {StringWrapper, isBlank, isPresent, isString} from '../facade/lang';
import * as o from './output_ast';
var _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
@@ -73,13 +74,14 @@ export class EmitterVisitorContext {
if (lines[lines.length - 1].parts.length === 0) {
lines = lines.slice(0, lines.length - 1);
}
return lines.map((line) => {
if (line.parts.length > 0) {
return _createIndent(line.indent) + line.parts.join('');
} else {
return '';
}
})
return lines
.map((line) => {
if (line.parts.length > 0) {
return _createIndent(line.indent) + line.parts.join('');
} else {
return '';
}
})
.join('\n');
}
}
@@ -367,14 +369,17 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex
return null;
}
visitAllExpressions(expressions: o.Expression[], ctx: EmitterVisitorContext, separator: string,
newLine: boolean = false): void {
this.visitAllObjects((expr: any /** TODO #9100 */) => expr.visitExpression(this, ctx), expressions, ctx, separator,
newLine);
visitAllExpressions(
expressions: o.Expression[], ctx: EmitterVisitorContext, separator: string,
newLine: boolean = false): void {
this.visitAllObjects(
(expr: any /** TODO #9100 */) => expr.visitExpression(this, ctx), expressions, ctx,
separator, newLine);
}
visitAllObjects(handler: Function, expressions: any, ctx: EmitterVisitorContext,
separator: string, newLine: boolean = false): void {
visitAllObjects(
handler: Function, expressions: any, ctx: EmitterVisitorContext, separator: string,
newLine: boolean = false): void {
for (var i = 0; i < expressions.length; i++) {
if (i > 0) {
ctx.print(separator, newLine);
@@ -395,17 +400,18 @@ export function escapeSingleQuoteString(input: string, escapeDollar: boolean): a
if (isBlank(input)) {
return null;
}
var body = StringWrapper.replaceAllMapped(input, _SINGLE_QUOTE_ESCAPE_STRING_RE, (match: any /** TODO #9100 */) => {
if (match[0] == '$') {
return escapeDollar ? '\\$' : '$';
} else if (match[0] == '\n') {
return '\\n';
} else if (match[0] == '\r') {
return '\\r';
} else {
return `\\${match[0]}`;
}
});
var body = StringWrapper.replaceAllMapped(
input, _SINGLE_QUOTE_ESCAPE_STRING_RE, (match: any /** TODO #9100 */) => {
if (match[0] == '$') {
return escapeDollar ? '\\$' : '$';
} else if (match[0] == '\n') {
return '\\n';
} else if (match[0] == '\r') {
return '\\r';
} else {
return `\\${match[0]}`;
}
});
return `'${body}'`;
}
@@ -1,12 +1,8 @@
import {isPresent} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {isPresent} from '../facade/lang';
import {AbstractEmitterVisitor, CATCH_ERROR_VAR, CATCH_STACK_VAR, EmitterVisitorContext} from './abstract_emitter';
import * as o from './output_ast';
import {
EmitterVisitorContext,
AbstractEmitterVisitor,
CATCH_ERROR_VAR,
CATCH_STACK_VAR
} from './abstract_emitter';
export abstract class AbstractJsEmitterVisitor extends AbstractEmitterVisitor {
constructor() { super(false); }
@@ -130,10 +126,10 @@ export abstract class AbstractJsEmitterVisitor extends AbstractEmitterVisitor {
ctx.decIndent();
ctx.println(`} catch (${CATCH_ERROR_VAR.name}) {`);
ctx.incIndent();
var catchStmts = [
<o.Statement>CATCH_STACK_VAR.set(CATCH_ERROR_VAR.prop('stack'))
.toDeclStmt(null, [o.StmtModifier.Final])
].concat(stmt.catchStmts);
var catchStmts =
[<o.Statement>CATCH_STACK_VAR.set(CATCH_ERROR_VAR.prop('stack')).toDeclStmt(null, [
o.StmtModifier.Final
])].concat(stmt.catchStmts);
this.visitAllStatements(catchStmts, ctx);
ctx.decIndent();
ctx.println(`}`);
@@ -1,14 +1,10 @@
import {isPresent, isBlank, isArray} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {CompileIdentifierMetadata} from '../compile_metadata';
import {BaseException} from '../facade/exceptions';
import {isArray, isBlank, isPresent} from '../facade/lang';
import * as o from './output_ast';
import {
OutputEmitter,
EmitterVisitorContext,
AbstractEmitterVisitor,
CATCH_ERROR_VAR,
CATCH_STACK_VAR,
} from './abstract_emitter';
import {OutputEmitter, EmitterVisitorContext, AbstractEmitterVisitor, CATCH_ERROR_VAR, CATCH_STACK_VAR,} from './abstract_emitter';
import {ImportGenerator} from './path_util';
var _debugModuleUrl = 'asset://debug/lib';
@@ -332,8 +328,8 @@ class _DartEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisito
}, params, ctx, ',');
}
private _visitIdentifier(value: CompileIdentifierMetadata, typeParams: o.Type[],
ctx: EmitterVisitorContext): void {
private _visitIdentifier(
value: CompileIdentifierMetadata, typeParams: o.Type[], ctx: EmitterVisitorContext): void {
if (isBlank(value.name)) {
throw new BaseException(`Internal error: unknown identifier ${value}`);
}
@@ -348,7 +344,8 @@ class _DartEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisito
ctx.print(value.name);
if (isPresent(typeParams) && typeParams.length > 0) {
ctx.print(`<`);
this.visitAllObjects((type: any /** TODO #9100 */) => type.visitType(this, ctx), typeParams, ctx, ',');
this.visitAllObjects(
(type: any /** TODO #9100 */) => type.visitType(this, ctx), typeParams, ctx, ',');
ctx.print(`>`);
}
}
@@ -1,7 +1,8 @@
import {BaseException} from '../facade/exceptions';
import {isPresent, isBlank, RegExpWrapper, Math} from '../facade/lang';
import {Injectable} from '@angular/core';
import {BaseException} from '../facade/exceptions';
import {Math, RegExpWrapper, isBlank, isPresent} from '../facade/lang';
import {AssetUrl, ImportGenerator} from './path_util';
var _PATH_SEP = '/';
@@ -1,12 +1,13 @@
import {AppElement, AppView, DebugAppView} from '../../core_private';
import {isPresent} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {InstanceFactory, DynamicInstance} from './output_interpreter';
import {isPresent} from '../facade/lang';
import {DynamicInstance, InstanceFactory} from './output_interpreter';
export class InterpretiveAppViewInstanceFactory implements InstanceFactory {
createInstance(superClass: any, clazz: any, args: any[], props: Map<string, any>,
getters: Map<string, Function>, methods: Map<string, Function>): any {
createInstance(
superClass: any, clazz: any, args: any[], props: Map<string, any>,
getters: Map<string, Function>, methods: Map<string, Function>): any {
if (superClass === AppView) {
// We are always using DebugAppView as parent.
// However, in prod mode we generate a constructor call that does
@@ -21,11 +22,12 @@ export class InterpretiveAppViewInstanceFactory implements InstanceFactory {
}
class _InterpretiveAppView extends DebugAppView<any> implements DynamicInstance {
constructor(args: any[], public props: Map<string, any>, public getters: Map<string, Function>,
public methods: Map<string, Function>) {
constructor(
args: any[], public props: Map<string, any>, public getters: Map<string, Function>,
public methods: Map<string, Function>) {
super(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
}
createInternal(rootSelector: string | any): AppElement {
createInternal(rootSelector: string|any): AppElement {
var m = this.methods.get('createInternal');
if (isPresent(m)) {
return m(rootSelector);
@@ -1,15 +1,10 @@
import * as o from './output_ast';
import {
isPresent,
isBlank,
isString,
evalExpression,
RegExpWrapper,
StringWrapper
} from '../facade/lang';
import {BaseException} from '@angular/core';
import {OutputEmitter, EmitterVisitorContext} from './abstract_emitter';
import {RegExpWrapper, StringWrapper, evalExpression, isBlank, isPresent, isString} from '../facade/lang';
import {EmitterVisitorContext, OutputEmitter} from './abstract_emitter';
import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
import * as o from './output_ast';
import {ImportGenerator} from './path_util';
export class JavaScriptEmitter implements OutputEmitter {
@@ -1,5 +1,6 @@
import {isString, isPresent, isBlank} from '../facade/lang';
import {CompileIdentifierMetadata} from '../compile_metadata';
import {isBlank, isPresent, isString} from '../facade/lang';
//// Types
export enum TypeModifier {
@@ -34,8 +35,9 @@ export class BuiltinType extends Type {
}
export class ExternalType extends Type {
constructor(public value: CompileIdentifierMetadata, public typeParams: Type[] = null,
modifiers: TypeModifier[] = null) {
constructor(
public value: CompileIdentifierMetadata, public typeParams: Type[] = null,
modifiers: TypeModifier[] = null) {
super(modifiers);
}
visitType(visitor: TypeVisitor, context: any): any {
@@ -45,7 +47,7 @@ export class ExternalType extends Type {
export class ArrayType extends Type {
constructor(public of: Type, modifiers: TypeModifier[] = null) { super(modifiers); }
constructor(public of : Type, modifiers: TypeModifier[] = null) { super(modifiers); }
visitType(visitor: TypeVisitor, context: any): any {
return visitor.visitArrayType(this, context);
}
@@ -104,7 +106,7 @@ export abstract class Expression {
return new ReadKeyExpr(this, index, type);
}
callMethod(name: string | BuiltinMethod, params: Expression[]): InvokeMethodExpr {
callMethod(name: string|BuiltinMethod, params: Expression[]): InvokeMethodExpr {
return new InvokeMethodExpr(this, name, params);
}
@@ -182,7 +184,7 @@ export class ReadVarExpr extends Expression {
public name: any /** TODO #9100 */;
public builtin: BuiltinVar;
constructor(name: string | BuiltinVar, type: Type = null) {
constructor(name: string|BuiltinVar, type: Type = null) {
super(type);
if (isString(name)) {
this.name = <string>name;
@@ -219,8 +221,8 @@ export class WriteVarExpr extends Expression {
export class WriteKeyExpr extends Expression {
public value: Expression;
constructor(public receiver: Expression, public index: Expression, value: Expression,
type: Type = null) {
constructor(
public receiver: Expression, public index: Expression, value: Expression, type: Type = null) {
super(isPresent(type) ? type : value.type);
this.value = value;
}
@@ -232,8 +234,8 @@ export class WriteKeyExpr extends Expression {
export class WritePropExpr extends Expression {
public value: Expression;
constructor(public receiver: Expression, public name: string, value: Expression,
type: Type = null) {
constructor(
public receiver: Expression, public name: string, value: Expression, type: Type = null) {
super(isPresent(type) ? type : value.type);
this.value = value;
}
@@ -251,8 +253,9 @@ export enum BuiltinMethod {
export class InvokeMethodExpr extends Expression {
public name: string;
public builtin: BuiltinMethod;
constructor(public receiver: Expression, method: string | BuiltinMethod,
public args: Expression[], type: Type = null) {
constructor(
public receiver: Expression, method: string|BuiltinMethod, public args: Expression[],
type: Type = null) {
super(type);
if (isString(method)) {
this.name = <string>method;
@@ -293,8 +296,9 @@ export class LiteralExpr extends Expression {
export class ExternalExpr extends Expression {
constructor(public value: CompileIdentifierMetadata, type: Type = null,
public typeParams: Type[] = null) {
constructor(
public value: CompileIdentifierMetadata, type: Type = null,
public typeParams: Type[] = null) {
super(type);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@@ -305,8 +309,9 @@ export class ExternalExpr extends Expression {
export class ConditionalExpr extends Expression {
public trueCase: Expression;
constructor(public condition: Expression, trueCase: Expression,
public falseCase: Expression = null, type: Type = null) {
constructor(
public condition: Expression, trueCase: Expression, public falseCase: Expression = null,
type: Type = null) {
super(isPresent(type) ? type : trueCase.type);
this.trueCase = trueCase;
}
@@ -352,8 +357,8 @@ export class FunctionExpr extends Expression {
export class BinaryOperatorExpr extends Expression {
public lhs: Expression;
constructor(public operator: BinaryOperator, lhs: Expression, public rhs: Expression,
type: Type = null) {
constructor(
public operator: BinaryOperator, lhs: Expression, public rhs: Expression, type: Type = null) {
super(isPresent(type) ? type : lhs.type);
this.lhs = lhs;
}
@@ -401,7 +406,7 @@ export class LiteralArrayExpr extends Expression {
export class LiteralMapExpr extends Expression {
public valueType: Type = null;
constructor(public entries: Array<Array<string | Expression>>, type: MapType = null) {
constructor(public entries: Array<Array<string|Expression>>, type: MapType = null) {
super(type);
if (isPresent(type)) {
this.valueType = type.valueType;
@@ -460,8 +465,9 @@ export abstract class Statement {
export class DeclareVarStmt extends Statement {
public type: Type;
constructor(public name: string, public value: Expression, type: Type = null,
modifiers: StmtModifier[] = null) {
constructor(
public name: string, public value: Expression, type: Type = null,
modifiers: StmtModifier[] = null) {
super(modifiers);
this.type = isPresent(type) ? type : value.type;
}
@@ -472,8 +478,9 @@ export class DeclareVarStmt extends Statement {
}
export class DeclareFunctionStmt extends Statement {
constructor(public name: string, public params: FnParam[], public statements: Statement[],
public type: Type = null, modifiers: StmtModifier[] = null) {
constructor(
public name: string, public params: FnParam[], public statements: Statement[],
public type: Type = null, modifiers: StmtModifier[] = null) {
super(modifiers);
}
@@ -515,25 +522,28 @@ export class ClassField extends AbstractClassPart {
export class ClassMethod extends AbstractClassPart {
constructor(public name: string, public params: FnParam[], public body: Statement[],
type: Type = null, modifiers: StmtModifier[] = null) {
constructor(
public name: string, public params: FnParam[], public body: Statement[], type: Type = null,
modifiers: StmtModifier[] = null) {
super(type, modifiers);
}
}
export class ClassGetter extends AbstractClassPart {
constructor(public name: string, public body: Statement[], type: Type = null,
modifiers: StmtModifier[] = null) {
constructor(
public name: string, public body: Statement[], type: Type = null,
modifiers: StmtModifier[] = null) {
super(type, modifiers);
}
}
export class ClassStmt extends Statement {
constructor(public name: string, public parent: Expression, public fields: ClassField[],
public getters: ClassGetter[], public constructorMethod: ClassMethod,
public methods: ClassMethod[], modifiers: StmtModifier[] = null) {
constructor(
public name: string, public parent: Expression, public fields: ClassField[],
public getters: ClassGetter[], public constructorMethod: ClassMethod,
public methods: ClassMethod[], modifiers: StmtModifier[] = null) {
super(modifiers);
}
visitStatement(visitor: StatementVisitor, context: any): any {
@@ -543,8 +553,9 @@ export class ClassStmt extends Statement {
export class IfStmt extends Statement {
constructor(public condition: Expression, public trueCase: Statement[],
public falseCase: Statement[] = /*@ts2dart_const*/[]) {
constructor(
public condition: Expression, public trueCase: Statement[],
public falseCase: Statement[] = /*@ts2dart_const*/[]) {
super();
}
visitStatement(visitor: StatementVisitor, context: any): any {
@@ -594,33 +605,37 @@ export class ExpressionTransformer implements StatementVisitor, ExpressionVisito
return new WriteVarExpr(expr.name, expr.value.visitExpression(this, context));
}
visitWriteKeyExpr(expr: WriteKeyExpr, context: any): any {
return new WriteKeyExpr(expr.receiver.visitExpression(this, context),
expr.index.visitExpression(this, context),
expr.value.visitExpression(this, context));
return new WriteKeyExpr(
expr.receiver.visitExpression(this, context), expr.index.visitExpression(this, context),
expr.value.visitExpression(this, context));
}
visitWritePropExpr(expr: WritePropExpr, context: any): any {
return new WritePropExpr(expr.receiver.visitExpression(this, context), expr.name,
expr.value.visitExpression(this, context));
return new WritePropExpr(
expr.receiver.visitExpression(this, context), expr.name,
expr.value.visitExpression(this, context));
}
visitInvokeMethodExpr(ast: InvokeMethodExpr, context: any): any {
var method = isPresent(ast.builtin) ? ast.builtin : ast.name;
return new InvokeMethodExpr(ast.receiver.visitExpression(this, context), method,
this.visitAllExpressions(ast.args, context), ast.type);
return new InvokeMethodExpr(
ast.receiver.visitExpression(this, context), method,
this.visitAllExpressions(ast.args, context), ast.type);
}
visitInvokeFunctionExpr(ast: InvokeFunctionExpr, context: any): any {
return new InvokeFunctionExpr(ast.fn.visitExpression(this, context),
this.visitAllExpressions(ast.args, context), ast.type);
return new InvokeFunctionExpr(
ast.fn.visitExpression(this, context), this.visitAllExpressions(ast.args, context),
ast.type);
}
visitInstantiateExpr(ast: InstantiateExpr, context: any): any {
return new InstantiateExpr(ast.classExpr.visitExpression(this, context),
this.visitAllExpressions(ast.args, context), ast.type);
return new InstantiateExpr(
ast.classExpr.visitExpression(this, context), this.visitAllExpressions(ast.args, context),
ast.type);
}
visitLiteralExpr(ast: LiteralExpr, context: any): any { return ast; }
visitExternalExpr(ast: ExternalExpr, context: any): any { return ast; }
visitConditionalExpr(ast: ConditionalExpr, context: any): any {
return new ConditionalExpr(ast.condition.visitExpression(this, context),
ast.trueCase.visitExpression(this, context),
ast.falseCase.visitExpression(this, context));
return new ConditionalExpr(
ast.condition.visitExpression(this, context), ast.trueCase.visitExpression(this, context),
ast.falseCase.visitExpression(this, context));
}
visitNotExpr(ast: NotExpr, context: any): any {
return new NotExpr(ast.condition.visitExpression(this, context));
@@ -633,15 +648,17 @@ export class ExpressionTransformer implements StatementVisitor, ExpressionVisito
return ast;
}
visitBinaryOperatorExpr(ast: BinaryOperatorExpr, context: any): any {
return new BinaryOperatorExpr(ast.operator, ast.lhs.visitExpression(this, context),
ast.rhs.visitExpression(this, context), ast.type);
return new BinaryOperatorExpr(
ast.operator, ast.lhs.visitExpression(this, context),
ast.rhs.visitExpression(this, context), ast.type);
}
visitReadPropExpr(ast: ReadPropExpr, context: any): any {
return new ReadPropExpr(ast.receiver.visitExpression(this, context), ast.name, ast.type);
}
visitReadKeyExpr(ast: ReadKeyExpr, context: any): any {
return new ReadKeyExpr(ast.receiver.visitExpression(this, context),
ast.index.visitExpression(this, context), ast.type);
return new ReadKeyExpr(
ast.receiver.visitExpression(this, context), ast.index.visitExpression(this, context),
ast.type);
}
visitLiteralArrayExpr(ast: LiteralArrayExpr, context: any): any {
return new LiteralArrayExpr(this.visitAllExpressions(ast.entries, context));
@@ -655,8 +672,8 @@ export class ExpressionTransformer implements StatementVisitor, ExpressionVisito
}
visitDeclareVarStmt(stmt: DeclareVarStmt, context: any): any {
return new DeclareVarStmt(stmt.name, stmt.value.visitExpression(this, context), stmt.type,
stmt.modifiers);
return new DeclareVarStmt(
stmt.name, stmt.value.visitExpression(this, context), stmt.type, stmt.modifiers);
}
visitDeclareFunctionStmt(stmt: DeclareFunctionStmt, context: any): any {
// Don't descend into nested functions
@@ -673,13 +690,15 @@ export class ExpressionTransformer implements StatementVisitor, ExpressionVisito
return stmt;
}
visitIfStmt(stmt: IfStmt, context: any): any {
return new IfStmt(stmt.condition.visitExpression(this, context),
this.visitAllStatements(stmt.trueCase, context),
this.visitAllStatements(stmt.falseCase, context));
return new IfStmt(
stmt.condition.visitExpression(this, context),
this.visitAllStatements(stmt.trueCase, context),
this.visitAllStatements(stmt.falseCase, context));
}
visitTryCatchStmt(stmt: TryCatchStmt, context: any): any {
return new TryCatchStmt(this.visitAllStatements(stmt.bodyStmts, context),
this.visitAllStatements(stmt.catchStmts, context));
return new TryCatchStmt(
this.visitAllStatements(stmt.bodyStmts, context),
this.visitAllStatements(stmt.catchStmts, context));
}
visitThrowStmt(stmt: ThrowStmt, context: any): any {
return new ThrowStmt(stmt.error.visitExpression(this, context));
@@ -807,8 +826,8 @@ export class RecursiveExpressionVisitor implements StatementVisitor, ExpressionV
}
}
export function replaceVarInExpression(varName: string, newValue: Expression,
expression: Expression): Expression {
export function replaceVarInExpression(
varName: string, newValue: Expression, expression: Expression): Expression {
var transformer = new _ReplaceVariableTransformer(varName, newValue);
return expression.visitExpression(transformer, null);
}
@@ -842,8 +861,9 @@ export function importExpr(id: CompileIdentifierMetadata, typeParams: Type[] = n
return new ExternalExpr(id, null, typeParams);
}
export function importType(id: CompileIdentifierMetadata, typeParams: Type[] = null,
typeModifiers: TypeModifier[] = null): ExternalType {
export function importType(
id: CompileIdentifierMetadata, typeParams: Type[] = null,
typeModifiers: TypeModifier[] = null): ExternalType {
return isPresent(id) ? new ExternalType(id, typeParams, typeModifiers) : null;
}
@@ -855,8 +875,8 @@ export function literalArr(values: Expression[], type: Type = null): LiteralArra
return new LiteralArrayExpr(values, type);
}
export function literalMap(values: Array<Array<string | Expression>>,
type: MapType = null): LiteralMapExpr {
export function literalMap(
values: Array<Array<string|Expression>>, type: MapType = null): LiteralMapExpr {
return new LiteralMapExpr(values, type);
}
@@ -1,27 +1,28 @@
import {reflector} from '../../core_private';
import {isPresent, IS_DART, FunctionWrapper} from '../facade/lang';
import {ObservableWrapper} from '../facade/async';
import {BaseException, unimplemented} from '../facade/exceptions';
import {ListWrapper} from '../facade/collection';
import {BaseException, unimplemented} from '../facade/exceptions';
import {FunctionWrapper, IS_DART, isPresent} from '../facade/lang';
import * as o from './output_ast';
import {debugOutputAstAsDart} from './dart_emitter';
import * as o from './output_ast';
import {debugOutputAstAsTypeScript} from './ts_emitter';
export function interpretStatements(statements: o.Statement[], resultVar: string,
instanceFactory: InstanceFactory): any {
export function interpretStatements(
statements: o.Statement[], resultVar: string, instanceFactory: InstanceFactory): any {
var stmtsWithReturn = statements.concat([new o.ReturnStatement(o.variable(resultVar))]);
var ctx = new _ExecutionContext(null, null, null, null, new Map<string, any>(),
new Map<string, any>(), new Map<string, Function>(),
new Map<string, Function>(), instanceFactory);
var ctx = new _ExecutionContext(
null, null, null, null, new Map<string, any>(), new Map<string, any>(),
new Map<string, Function>(), new Map<string, Function>(), instanceFactory);
var visitor = new StatementInterpreter();
var result = visitor.visitAllStatements(stmtsWithReturn, ctx);
return isPresent(result) ? result.value : null;
}
export interface InstanceFactory {
createInstance(superClass: any, clazz: any, constructorArgs: any[], props: Map<string, any>,
getters: Map<string, Function>, methods: Map<string, Function>): DynamicInstance;
createInstance(
superClass: any, clazz: any, constructorArgs: any[], props: Map<string, any>,
getters: Map<string, Function>, methods: Map<string, Function>): DynamicInstance;
}
export abstract class DynamicInstance {
@@ -36,12 +37,13 @@ function isDynamicInstance(instance: any): any {
return instance instanceof DynamicInstance;
} else {
return isPresent(instance) && isPresent(instance.props) && isPresent(instance.getters) &&
isPresent(instance.methods);
isPresent(instance.methods);
}
}
function _executeFunctionStatements(varNames: string[], varValues: any[], statements: o.Statement[],
ctx: _ExecutionContext, visitor: StatementInterpreter): any {
function _executeFunctionStatements(
varNames: string[], varValues: any[], statements: o.Statement[], ctx: _ExecutionContext,
visitor: StatementInterpreter): any {
var childCtx = ctx.createChildWihtLocalVars();
for (var i = 0; i < varNames.length; i++) {
childCtx.vars.set(varNames[i], varValues[i]);
@@ -51,15 +53,16 @@ function _executeFunctionStatements(varNames: string[], varValues: any[], statem
}
class _ExecutionContext {
constructor(public parent: _ExecutionContext, public superClass: any, public superInstance: any,
public className: string, public vars: Map<string, any>,
public props: Map<string, any>, public getters: Map<string, Function>,
public methods: Map<string, Function>, public instanceFactory: InstanceFactory) {}
constructor(
public parent: _ExecutionContext, public superClass: any, public superInstance: any,
public className: string, public vars: Map<string, any>, public props: Map<string, any>,
public getters: Map<string, Function>, public methods: Map<string, Function>,
public instanceFactory: InstanceFactory) {}
createChildWihtLocalVars(): _ExecutionContext {
return new _ExecutionContext(this, this.superClass, this.superInstance, this.className,
new Map<string, any>(), this.props, this.getters, this.methods,
this.instanceFactory);
return new _ExecutionContext(
this, this.superClass, this.superInstance, this.className, new Map<string, any>(),
this.props, this.getters, this.methods, this.instanceFactory);
}
}
@@ -68,22 +71,24 @@ class ReturnValue {
}
class _DynamicClass {
constructor(private _classStmt: o.ClassStmt, private _ctx: _ExecutionContext,
private _visitor: StatementInterpreter) {}
constructor(
private _classStmt: o.ClassStmt, private _ctx: _ExecutionContext,
private _visitor: StatementInterpreter) {}
instantiate(args: any[]): DynamicInstance {
var props = new Map<string, any>();
var getters = new Map<string, Function>();
var methods = new Map<string, Function>();
var superClass = this._classStmt.parent.visitExpression(this._visitor, this._ctx);
var instanceCtx =
new _ExecutionContext(this._ctx, superClass, null, this._classStmt.name, this._ctx.vars,
props, getters, methods, this._ctx.instanceFactory);
var instanceCtx = new _ExecutionContext(
this._ctx, superClass, null, this._classStmt.name, this._ctx.vars, props, getters, methods,
this._ctx.instanceFactory);
this._classStmt.fields.forEach((field: o.ClassField) => { props.set(field.name, null); });
this._classStmt.getters.forEach((getter: o.ClassGetter) => {
getters.set(getter.name, () => _executeFunctionStatements([], [], getter.body, instanceCtx,
this._visitor));
getters.set(
getter.name,
() => _executeFunctionStatements([], [], getter.body, instanceCtx, this._visitor));
});
this._classStmt.methods.forEach((method: o.ClassMethod) => {
var paramNames = method.params.map(param => param.name);
@@ -91,8 +96,8 @@ class _DynamicClass {
});
var ctorParamNames = this._classStmt.constructorMethod.params.map(param => param.name);
_executeFunctionStatements(ctorParamNames, args, this._classStmt.constructorMethod.body,
instanceCtx, this._visitor);
_executeFunctionStatements(
ctorParamNames, args, this._classStmt.constructorMethod.body, instanceCtx, this._visitor);
return instanceCtx.superInstance;
}
@@ -100,7 +105,7 @@ class _DynamicClass {
}
class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
debugAst(ast: o.Expression | o.Statement | o.Type): string {
debugAst(ast: o.Expression|o.Statement|o.Type): string {
return IS_DART ? debugOutputAstAsDart(ast) : debugOutputAstAsTypeScript(ast);
}
@@ -207,8 +212,8 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
var args = this.visitAllExpressions(stmt.args, ctx);
var fnExpr = stmt.fn;
if (fnExpr instanceof o.ReadVarExpr && fnExpr.builtin === o.BuiltinVar.Super) {
ctx.superInstance = ctx.instanceFactory.createInstance(ctx.superClass, ctx.className, args,
ctx.props, ctx.getters, ctx.methods);
ctx.superInstance = ctx.instanceFactory.createInstance(
ctx.superClass, ctx.className, args, ctx.props, ctx.getters, ctx.methods);
ctx.parent.superInstance = ctx.superInstance;
return null;
} else {
@@ -352,8 +357,9 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
}
visitLiteralMapExpr(ast: o.LiteralMapExpr, ctx: _ExecutionContext): any {
var result = {};
ast.entries.forEach((entry) => (result as any /** TODO #9100 */)[<string>entry[0]] =
(<o.Expression>entry[1]).visitExpression(this, ctx));
ast.entries.forEach(
(entry) => (result as any /** TODO #9100 */)[<string>entry[0]] =
(<o.Expression>entry[1]).visitExpression(this, ctx));
return result;
}
@@ -373,39 +379,60 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
}
}
function _declareFn(varNames: string[], statements: o.Statement[], ctx: _ExecutionContext,
visitor: StatementInterpreter): Function {
function _declareFn(
varNames: string[], statements: o.Statement[], ctx: _ExecutionContext,
visitor: StatementInterpreter): Function {
switch (varNames.length) {
case 0:
return () => _executeFunctionStatements(varNames, [], statements, ctx, visitor);
case 1:
return (d0: any /** TODO #9100 */) => _executeFunctionStatements(varNames, [d0], statements, ctx, visitor);
return (d0: any /** TODO #9100 */) =>
_executeFunctionStatements(varNames, [d0], statements, ctx, visitor);
case 2:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */) => _executeFunctionStatements(varNames, [d0, d1], statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */) =>
_executeFunctionStatements(varNames, [d0, d1], statements, ctx, visitor);
case 3:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */) =>
_executeFunctionStatements(varNames, [d0, d1, d2], statements, ctx, visitor);
case 4:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */) =>
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */) =>
_executeFunctionStatements(varNames, [d0, d1, d2, d3], statements, ctx, visitor);
case 5:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */, d4: any /** TODO #9100 */) => _executeFunctionStatements(varNames, [d0, d1, d2, d3, d4],
statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */, d4: any /** TODO #9100 */) =>
_executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4], statements, ctx, visitor);
case 6:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */) => _executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5], statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */) =>
_executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5], statements, ctx, visitor);
case 7:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */, d6: any /** TODO #9100 */) => _executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6], statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */,
d6: any /** TODO #9100 */) =>
_executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6], statements, ctx, visitor);
case 8:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */, d6: any /** TODO #9100 */, d7: any /** TODO #9100 */) => _executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6, d7], statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */,
d6: any /** TODO #9100 */, d7: any /** TODO #9100 */) =>
_executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6, d7], statements, ctx, visitor);
case 9:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */, d6: any /** TODO #9100 */, d7: any /** TODO #9100 */, d8: any /** TODO #9100 */) => _executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6, d7, d8], statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */,
d6: any /** TODO #9100 */, d7: any /** TODO #9100 */, d8: any /** TODO #9100 */) =>
_executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6, d7, d8], statements, ctx, visitor);
case 10:
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */, d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */, d6: any /** TODO #9100 */, d7: any /** TODO #9100 */, d8: any /** TODO #9100 */, d9: any /** TODO #9100 */) => _executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6, d7, d8, d9], statements, ctx, visitor);
return (d0: any /** TODO #9100 */, d1: any /** TODO #9100 */, d2: any /** TODO #9100 */,
d3: any /** TODO #9100 */, d4: any /** TODO #9100 */, d5: any /** TODO #9100 */,
d6: any /** TODO #9100 */, d7: any /** TODO #9100 */, d8: any /** TODO #9100 */,
d9: any /** TODO #9100 */) =>
_executeFunctionStatements(
varNames, [d0, d1, d2, d3, d4, d5, d6, d7, d8, d9], statements, ctx, visitor);
default:
throw new BaseException(
'Declaring functions with more than 10 arguments is not supported right now');
@@ -1,14 +1,11 @@
import {
isPresent,
evalExpression,
} from '../facade/lang';
import {isPresent, evalExpression,} from '../facade/lang';
import * as o from './output_ast';
import {EmitterVisitorContext} from './abstract_emitter';
import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
import {sanitizeIdentifier} from '../util';
export function jitStatements(sourceUrl: string, statements: o.Statement[],
resultVar: string): any {
export function jitStatements(
sourceUrl: string, statements: o.Statement[], resultVar: string): any {
var converter = new JitEmitterVisitor();
var ctx = EmitterVisitorContext.createRoot([resultVar]);
converter.visitAllStatements(statements, ctx);
@@ -1,7 +1,9 @@
import {BaseException} from '../facade/exceptions';
import {isPresent, isBlank, RegExpWrapper, Math} from '../facade/lang';
import {Injectable} from '@angular/core';
import {BaseException} from '../facade/exceptions';
import {Math, RegExpWrapper, isBlank, isPresent} from '../facade/lang';
// asset:<package-name>/<realm>/<path-to-module>
var _ASSET_URL_RE = /asset:([^\/]+)\/([^\/]+)\/(.+)/g;
@@ -1,20 +1,15 @@
import * as o from './output_ast';
import {isPresent, isBlank, isArray} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {CompileIdentifierMetadata} from '../compile_metadata';
import {
OutputEmitter,
EmitterVisitorContext,
AbstractEmitterVisitor,
CATCH_ERROR_VAR,
CATCH_STACK_VAR
} from './abstract_emitter';
import {BaseException} from '../facade/exceptions';
import {isArray, isBlank, isPresent} from '../facade/lang';
import {AbstractEmitterVisitor, CATCH_ERROR_VAR, CATCH_STACK_VAR, EmitterVisitorContext, OutputEmitter} from './abstract_emitter';
import * as o from './output_ast';
import {ImportGenerator} from './path_util';
var _debugModuleUrl = 'asset://debug/lib';
export function debugOutputAstAsTypeScript(ast: o.Statement | o.Expression | o.Type |
any[]): string {
export function debugOutputAstAsTypeScript(ast: o.Statement | o.Expression | o.Type | any[]):
string {
var converter = new _TsEmitterVisitor(_debugModuleUrl);
var ctx = EmitterVisitorContext.createRoot([]);
var asts: any[];
@@ -197,10 +192,10 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
ctx.decIndent();
ctx.println(`} catch (${CATCH_ERROR_VAR.name}) {`);
ctx.incIndent();
var catchStmts = [
<o.Statement>CATCH_STACK_VAR.set(CATCH_ERROR_VAR.prop('stack'))
.toDeclStmt(null, [o.StmtModifier.Final])
].concat(stmt.catchStmts);
var catchStmts =
[<o.Statement>CATCH_STACK_VAR.set(CATCH_ERROR_VAR.prop('stack')).toDeclStmt(null, [
o.StmtModifier.Final
])].concat(stmt.catchStmts);
this.visitAllStatements(catchStmts, ctx);
ctx.decIndent();
ctx.println(`}`);
@@ -277,8 +272,8 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
}, params, ctx, ',');
}
private _visitIdentifier(value: CompileIdentifierMetadata, typeParams: o.Type[],
ctx: EmitterVisitorContext): void {
private _visitIdentifier(
value: CompileIdentifierMetadata, typeParams: o.Type[], ctx: EmitterVisitorContext): void {
if (isBlank(value.name)) {
throw new BaseException(`Internal error: unknown identifier ${value}`);
}
@@ -293,7 +288,8 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
ctx.print(value.name);
if (isPresent(typeParams) && typeParams.length > 0) {
ctx.print(`<`);
this.visitAllObjects((type: any /** TODO #9100 */) => type.visitType(this, ctx), typeParams, ctx, ',');
this.visitAllObjects(
(type: any /** TODO #9100 */) => type.visitType(this, ctx), typeParams, ctx, ',');
ctx.print(`>`);
}
}
+9 -7
View File
@@ -1,6 +1,7 @@
export class ParseLocation {
constructor(public file: ParseSourceFile, public offset: number, public line: number,
public col: number) {}
constructor(
public file: ParseSourceFile, public offset: number, public line: number,
public col: number) {}
toString(): string { return `${this.file.url}@${this.line}:${this.col}`; }
}
@@ -23,8 +24,9 @@ export enum ParseErrorLevel {
}
export abstract class ParseError {
constructor(public span: ParseSourceSpan, public msg: string,
public level: ParseErrorLevel = ParseErrorLevel.FATAL) {}
constructor(
public span: ParseSourceSpan, public msg: string,
public level: ParseErrorLevel = ParseErrorLevel.FATAL) {}
toString(): string {
var source = this.span.start.file.content;
@@ -39,7 +41,7 @@ export abstract class ParseError {
while (ctxLen < 100 && ctxStart > 0) {
ctxStart--;
ctxLen++;
if (source[ctxStart] == "\n") {
if (source[ctxStart] == '\n') {
if (++ctxLines == 3) {
break;
}
@@ -51,7 +53,7 @@ export abstract class ParseError {
while (ctxLen < 100 && ctxEnd < source.length - 1) {
ctxEnd++;
ctxLen++;
if (source[ctxEnd] == "\n") {
if (source[ctxEnd] == '\n') {
if (++ctxLines == 3) {
break;
}
@@ -59,7 +61,7 @@ export abstract class ParseError {
}
let context = source.substring(ctxStart, this.span.start.offset) + '[ERROR ->]' +
source.substring(this.span.start.offset, ctxEnd + 1);
source.substring(this.span.start.offset, ctxEnd + 1);
return `${this.msg} ("${context}"): ${this.span.start}`;
}
@@ -1,9 +1,8 @@
import {resolveForwardRef, Injectable, PipeMetadata} from '@angular/core';
import {Injectable, PipeMetadata, resolveForwardRef} from '@angular/core';
import {ReflectorReader, reflector} from '../core_private';
import {Type, isPresent, stringify} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {Type, isPresent, stringify} from '../src/facade/lang';
function _isPipeMetadata(type: any): boolean {
return type instanceof PipeMetadata;
@@ -1,24 +1,10 @@
import {isPresent, isBlank, isArray, normalizeBlank} from '../src/facade/lang';
import {ListWrapper} from '../src/facade/collection';
import {
VariableAst,
AttrAst,
DirectiveAst,
ProviderAst,
ProviderAstType,
ReferenceAst
} from './template_ast';
import {
CompileTypeMetadata,
CompileTokenMap,
CompileQueryMetadata,
CompileTokenMetadata,
CompileProviderMetadata,
CompileDirectiveMetadata,
CompileDiDependencyMetadata
} from './compile_metadata';
import {isArray, isBlank, isPresent, normalizeBlank} from '../src/facade/lang';
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMap, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata';
import {Identifiers, identifierToken} from './identifiers';
import {ParseSourceSpan, ParseError} from './parse_util';
import {ParseError, ParseSourceSpan} from './parse_util';
import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst, VariableAst} from './template_ast';
export class ProviderError extends ParseError {
constructor(message: string, span: ParseSourceSpan) { super(span, message); }
@@ -38,12 +24,11 @@ export class ProviderViewContext {
constructor(public component: CompileDirectiveMetadata, public sourceSpan: ParseSourceSpan) {
this.viewQueries = _getViewQueries(component);
this.viewProviders = new CompileTokenMap<boolean>();
_normalizeProviders(component.viewProviders, sourceSpan, this.errors)
.forEach((provider) => {
if (isBlank(this.viewProviders.get(provider.token))) {
this.viewProviders.add(provider.token, true);
}
});
_normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => {
if (isBlank(this.viewProviders.get(provider.token))) {
this.viewProviders.add(provider.token, true);
}
});
}
}
@@ -56,9 +41,10 @@ export class ProviderElementContext {
private _attrs: {[key: string]: string};
private _hasViewContainer: boolean = false;
constructor(private _viewContext: ProviderViewContext, private _parent: ProviderElementContext,
private _isViewRoot: boolean, private _directiveAsts: DirectiveAst[],
attrs: AttrAst[], refs: ReferenceAst[], private _sourceSpan: ParseSourceSpan) {
constructor(
private _viewContext: ProviderViewContext, private _parent: ProviderElementContext,
private _isViewRoot: boolean, private _directiveAsts: DirectiveAst[], attrs: AttrAst[],
refs: ReferenceAst[], private _sourceSpan: ParseSourceSpan) {
this._attrs = {};
attrs.forEach((attrAst) => this._attrs[attrAst.name] = attrAst.value);
var directivesMeta = _directiveAsts.map(directiveAst => directiveAst.directive);
@@ -97,9 +83,9 @@ export class ProviderElementContext {
var sortedProviderTypes =
this._transformedProviders.values().map(provider => provider.token.identifier);
var sortedDirectives = ListWrapper.clone(this._directiveAsts);
ListWrapper.sort(sortedDirectives,
(dir1, dir2) => sortedProviderTypes.indexOf(dir1.directive.type) -
sortedProviderTypes.indexOf(dir2.directive.type));
ListWrapper.sort(
sortedDirectives, (dir1, dir2) => sortedProviderTypes.indexOf(dir1.directive.type) -
sortedProviderTypes.indexOf(dir2.directive.type));
return sortedDirectives;
}
@@ -137,8 +123,9 @@ export class ProviderElementContext {
}
private _getOrCreateLocalProvider(requestingProviderType: ProviderAstType,
token: CompileTokenMetadata, eager: boolean): ProviderAst {
private _getOrCreateLocalProvider(
requestingProviderType: ProviderAstType, token: CompileTokenMetadata,
eager: boolean): ProviderAst {
var resolvedProvider = this._allProviders.get(token);
if (isBlank(resolvedProvider) ||
((requestingProviderType === ProviderAstType.Directive ||
@@ -194,9 +181,9 @@ export class ProviderElementContext {
return transformedProviderAst;
}
private _getLocalDependency(requestingProviderType: ProviderAstType,
dep: CompileDiDependencyMetadata,
eager: boolean = null): CompileDiDependencyMetadata {
private _getLocalDependency(
requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata,
eager: boolean = null): CompileDiDependencyMetadata {
if (dep.isAttribute) {
var attrValue = this._attrs[dep.token.value];
return new CompileDiDependencyMetadata({isValue: true, value: normalizeBlank(attrValue)});
@@ -231,8 +218,9 @@ export class ProviderElementContext {
return null;
}
private _getDependency(requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata,
eager: boolean = null): CompileDiDependencyMetadata {
private _getDependency(
requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata,
eager: boolean = null): CompileDiDependencyMetadata {
var currElement: ProviderElementContext = this;
var currEager: boolean = eager;
var result: CompileDiDependencyMetadata = null;
@@ -261,8 +249,8 @@ export class ProviderElementContext {
result = dep;
} else {
result = dep.isOptional ?
result = new CompileDiDependencyMetadata({isValue: true, value: null}) :
null;
result = new CompileDiDependencyMetadata({isValue: true, value: null}) :
null;
}
}
}
@@ -292,12 +280,13 @@ function _transformProvider(
function _transformProviderAst(
provider: ProviderAst,
{eager, providers}: {eager: boolean, providers: CompileProviderMetadata[]}): ProviderAst {
return new ProviderAst(provider.token, provider.multiProvider, provider.eager || eager, providers,
provider.providerType, provider.sourceSpan);
return new ProviderAst(
provider.token, provider.multiProvider, provider.eager || eager, providers,
provider.providerType, provider.sourceSpan);
}
function _normalizeProviders(
providers: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>,
providers: Array<CompileProviderMetadata|CompileTypeMetadata|any[]>,
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
targetProviders: CompileProviderMetadata[] = null): CompileProviderMetadata[] {
if (isBlank(targetProviders)) {
@@ -327,35 +316,37 @@ function _normalizeProviders(
}
function _resolveProvidersFromDirectives(directives: CompileDirectiveMetadata[],
sourceSpan: ParseSourceSpan,
targetErrors: ParseError[]): CompileTokenMap<ProviderAst> {
function _resolveProvidersFromDirectives(
directives: CompileDirectiveMetadata[], sourceSpan: ParseSourceSpan,
targetErrors: ParseError[]): CompileTokenMap<ProviderAst> {
var providersByToken = new CompileTokenMap<ProviderAst>();
directives.forEach((directive) => {
var dirProvider = new CompileProviderMetadata(
{token: new CompileTokenMetadata({identifier: directive.type}), useClass: directive.type});
_resolveProviders([dirProvider],
directive.isComponent ? ProviderAstType.Component : ProviderAstType.Directive,
true, sourceSpan, targetErrors, providersByToken);
_resolveProviders(
[dirProvider],
directive.isComponent ? ProviderAstType.Component : ProviderAstType.Directive, true,
sourceSpan, targetErrors, providersByToken);
});
// Note: directives need to be able to overwrite providers of a component!
var directivesWithComponentFirst =
directives.filter(dir => dir.isComponent).concat(directives.filter(dir => !dir.isComponent));
directivesWithComponentFirst.forEach((directive) => {
_resolveProviders(_normalizeProviders(directive.providers, sourceSpan, targetErrors),
ProviderAstType.PublicService, false, sourceSpan, targetErrors,
providersByToken);
_resolveProviders(_normalizeProviders(directive.viewProviders, sourceSpan, targetErrors),
ProviderAstType.PrivateService, false, sourceSpan, targetErrors,
providersByToken);
_resolveProviders(
_normalizeProviders(directive.providers, sourceSpan, targetErrors),
ProviderAstType.PublicService, false, sourceSpan, targetErrors, providersByToken);
_resolveProviders(
_normalizeProviders(directive.viewProviders, sourceSpan, targetErrors),
ProviderAstType.PrivateService, false, sourceSpan, targetErrors, providersByToken);
});
return providersByToken;
}
function _resolveProviders(providers: CompileProviderMetadata[], providerType: ProviderAstType,
eager: boolean, sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
targetProvidersByToken: CompileTokenMap<ProviderAst>) {
function _resolveProviders(
providers: CompileProviderMetadata[], providerType: ProviderAstType, eager: boolean,
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
targetProvidersByToken: CompileTokenMap<ProviderAst>) {
providers.forEach((provider) => {
var resolvedProvider = targetProvidersByToken.get(provider.token);
if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) {
@@ -364,8 +355,8 @@ function _resolveProviders(providers: CompileProviderMetadata[], providerType: P
sourceSpan));
}
if (isBlank(resolvedProvider)) {
resolvedProvider = new ProviderAst(provider.token, provider.multi, eager, [provider],
providerType, sourceSpan);
resolvedProvider = new ProviderAst(
provider.token, provider.multi, eager, [provider], providerType, sourceSpan);
targetProvidersByToken.add(provider.token, resolvedProvider);
} else {
if (!provider.multi) {
@@ -377,8 +368,8 @@ function _resolveProviders(providers: CompileProviderMetadata[], providerType: P
}
function _getViewQueries(
component: CompileDirectiveMetadata): CompileTokenMap<CompileQueryMetadata[]> {
function _getViewQueries(component: CompileDirectiveMetadata):
CompileTokenMap<CompileQueryMetadata[]> {
var viewQueries = new CompileTokenMap<CompileQueryMetadata[]>();
if (isPresent(component.viewQueries)) {
component.viewQueries.forEach((query) => _addQueryToTokenMap(viewQueries, query));
@@ -391,8 +382,8 @@ function _getViewQueries(
return viewQueries;
}
function _getContentQueries(
directives: CompileDirectiveMetadata[]): CompileTokenMap<CompileQueryMetadata[]> {
function _getContentQueries(directives: CompileDirectiveMetadata[]):
CompileTokenMap<CompileQueryMetadata[]> {
var contentQueries = new CompileTokenMap<CompileQueryMetadata[]>();
directives.forEach(directive => {
if (isPresent(directive.queries)) {
@@ -407,8 +398,8 @@ function _getContentQueries(
return contentQueries;
}
function _addQueryToTokenMap(map: CompileTokenMap<CompileQueryMetadata[]>,
query: CompileQueryMetadata) {
function _addQueryToTokenMap(
map: CompileTokenMap<CompileQueryMetadata[]>, query: CompileQueryMetadata) {
query.selectors.forEach((token: CompileTokenMetadata) => {
var entry = map.get(token);
if (isBlank(entry)) {
@@ -1,25 +1,12 @@
import {Injectable, ComponentFactory, ComponentResolver} from '@angular/core';
import {ComponentFactory, ComponentResolver, Injectable} from '@angular/core';
import {
IS_DART,
Type,
isBlank,
isString
} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {
ListWrapper,
} from '../src/facade/collection';
import {IS_DART, Type, isBlank, isString} from '../src/facade/lang';
import {ListWrapper,} from '../src/facade/collection';
import {PromiseWrapper} from '../src/facade/async';
import {
createHostComponentMeta,
CompileDirectiveMetadata,
CompilePipeMetadata,
CompileIdentifierMetadata
} from './compile_metadata';
import {
TemplateAst,
} from './template_ast';
import {createHostComponentMeta, CompileDirectiveMetadata, CompilePipeMetadata, CompileIdentifierMetadata} from './compile_metadata';
import {TemplateAst,} from './template_ast';
import {StyleCompiler, StylesCompileDependency, StylesCompileResult} from './style_compiler';
import {ViewCompiler} from './view_compiler/view_compiler';
import {TemplateParser} from './template_parser';
@@ -44,15 +31,16 @@ export class RuntimeCompiler implements ComponentResolver {
private _compiledTemplateCache = new Map<any, CompiledTemplate>();
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
constructor(private _metadataResolver: CompileMetadataResolver,
private _templateNormalizer: DirectiveNormalizer,
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
private _viewCompiler: ViewCompiler, private _xhr: XHR,
private _genConfig: CompilerConfig) {}
constructor(
private _metadataResolver: CompileMetadataResolver,
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler, private _xhr: XHR,
private _genConfig: CompilerConfig) {}
resolveComponent(component: Type|string): Promise<ComponentFactory<any>> {
if (isString(component)) {
return PromiseWrapper.reject(new BaseException(`Cannot resolve component using '${component}'.`), null);
return PromiseWrapper.reject(
new BaseException(`Cannot resolve component using '${component}'.`), null);
}
let componentType = <Type>component;
@@ -69,8 +57,9 @@ export class RuntimeCompiler implements ComponentResolver {
this._loadAndCompileComponent(hostCacheKey, hostMeta, [compMeta], [], []);
}
return this._compiledTemplateDone.get(hostCacheKey)
.then((compiledTemplate: CompiledTemplate) => new ComponentFactory(
compMeta.selector, compiledTemplate.viewFactory, componentType));
.then(
(compiledTemplate: CompiledTemplate) => new ComponentFactory(
compMeta.selector, compiledTemplate.viewFactory, componentType));
}
clearCache() {
@@ -81,29 +70,29 @@ export class RuntimeCompiler implements ComponentResolver {
}
private _loadAndCompileComponent(cacheKey: any, compMeta: CompileDirectiveMetadata,
viewDirectives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[],
compilingComponentsPath: any[]): CompiledTemplate {
private _loadAndCompileComponent(
cacheKey: any, compMeta: CompileDirectiveMetadata, viewDirectives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], compilingComponentsPath: any[]): CompiledTemplate {
var compiledTemplate = this._compiledTemplateCache.get(cacheKey);
var done = this._compiledTemplateDone.get(cacheKey);
if (isBlank(compiledTemplate)) {
compiledTemplate = new CompiledTemplate();
this._compiledTemplateCache.set(cacheKey, compiledTemplate);
done =
PromiseWrapper.all(
[<any>this._compileComponentStyles(compMeta)].concat(viewDirectives.map(
dirMeta => this._templateNormalizer.normalizeDirective(dirMeta))))
PromiseWrapper
.all([<any>this._compileComponentStyles(compMeta)].concat(viewDirectives.map(
dirMeta => this._templateNormalizer.normalizeDirective(dirMeta))))
.then((stylesAndNormalizedViewDirMetas: any[]) => {
var normalizedViewDirMetas = stylesAndNormalizedViewDirMetas.slice(1);
var styles = stylesAndNormalizedViewDirMetas[0];
var parsedTemplate =
this._templateParser.parse(compMeta, compMeta.template.template,
normalizedViewDirMetas, pipes, compMeta.type.name);
var parsedTemplate = this._templateParser.parse(
compMeta, compMeta.template.template, normalizedViewDirMetas, pipes,
compMeta.type.name);
var childPromises: any[] /** TODO #9100 */ = [];
compiledTemplate.init(this._compileComponent(compMeta, parsedTemplate, styles,
pipes, compilingComponentsPath, childPromises));
compiledTemplate.init(this._compileComponent(
compMeta, parsedTemplate, styles, pipes, compilingComponentsPath,
childPromises));
return PromiseWrapper.all(childPromises).then((_) => { return compiledTemplate; });
});
this._compiledTemplateDone.set(cacheKey, done);
@@ -111,11 +100,10 @@ export class RuntimeCompiler implements ComponentResolver {
return compiledTemplate;
}
private _compileComponent(compMeta: CompileDirectiveMetadata, parsedTemplate: TemplateAst[],
styles: string[],
pipes: CompilePipeMetadata[],
compilingComponentsPath: any[],
childPromises: Promise<any>[]): Function {
private _compileComponent(
compMeta: CompileDirectiveMetadata, parsedTemplate: TemplateAst[], styles: string[],
pipes: CompilePipeMetadata[], compilingComponentsPath: any[],
childPromises: Promise<any>[]): Function {
var compileResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate,
new ir.ExternalExpr(new CompileIdentifierMetadata({runtime: styles})), pipes);
@@ -130,9 +118,9 @@ export class RuntimeCompiler implements ComponentResolver {
var childIsRecursive = ListWrapper.contains(childCompilingComponentsPath, childCacheKey);
childCompilingComponentsPath.push(childCacheKey);
var childComp =
this._loadAndCompileComponent(dep.comp.type.runtime, dep.comp, childViewDirectives,
childViewPipes, childCompilingComponentsPath);
var childComp = this._loadAndCompileComponent(
dep.comp.type.runtime, dep.comp, childViewDirectives, childViewPipes,
childCompilingComponentsPath);
dep.factoryPlaceholder.runtime = childComp.proxyViewFactory;
dep.factoryPlaceholder.name = `viewFactory_${dep.comp.type.name}`;
if (!childIsRecursive) {
@@ -142,11 +130,13 @@ export class RuntimeCompiler implements ComponentResolver {
});
var factory: any /** TODO #9100 */;
if (IS_DART || !this._genConfig.useJit) {
factory = interpretStatements(compileResult.statements, compileResult.viewFactoryVar,
new InterpretiveAppViewInstanceFactory());
factory = interpretStatements(
compileResult.statements, compileResult.viewFactoryVar,
new InterpretiveAppViewInstanceFactory());
} else {
factory = jitStatements(`${compMeta.type.name}.template.js`, compileResult.statements,
compileResult.viewFactoryVar);
factory = jitStatements(
`${compMeta.type.name}.template.js`, compileResult.statements,
compileResult.viewFactoryVar);
}
return factory;
}
@@ -156,8 +146,8 @@ export class RuntimeCompiler implements ComponentResolver {
return this._resolveStylesCompileResult(compMeta.type.name, compileResult);
}
private _resolveStylesCompileResult(sourceUrl: string,
result: StylesCompileResult): Promise<string[]> {
private _resolveStylesCompileResult(sourceUrl: string, result: StylesCompileResult):
Promise<string[]> {
var promises = result.dependencies.map((dep) => this._loadStylesheetDep(dep));
return PromiseWrapper.all(promises)
.then((cssTexts) => {
@@ -179,8 +169,8 @@ export class RuntimeCompiler implements ComponentResolver {
dep.valuePlaceholder.name = `importedStyles${i}`;
}
if (IS_DART || !this._genConfig.useJit) {
return interpretStatements(result.statements, result.stylesVar,
new InterpretiveAppViewInstanceFactory());
return interpretStatements(
result.statements, result.stylesVar, new InterpretiveAppViewInstanceFactory());
} else {
return jitStatements(`${sourceUrl}.css.js`, result.statements, result.stylesVar);
}
@@ -202,8 +192,9 @@ class CompiledTemplate {
viewFactory: Function = null;
proxyViewFactory: Function;
constructor() {
this.proxyViewFactory = (viewUtils: any /** TODO #9100 */, childInjector: any /** TODO #9100 */, contextEl: any /** TODO #9100 */) =>
this.viewFactory(viewUtils, childInjector, contextEl);
this.proxyViewFactory =
(viewUtils: any /** TODO #9100 */, childInjector: any /** TODO #9100 */,
contextEl: any /** TODO #9100 */) => this.viewFactory(viewUtils, childInjector, contextEl);
}
init(viewFactory: Function) { this.viewFactory = viewFactory; }
@@ -1,9 +1,11 @@
import {Injectable} from '@angular/core';
import {SecurityContext} from '../../core_private';
import {isPresent} from '../facade/lang';
import {StringMapWrapper} from '../facade/collection';
import {ElementSchemaRegistry} from './element_schema_registry';
import {isPresent} from '../facade/lang';
import {SECURITY_SCHEMA} from './dom_security_schema';
import {ElementSchemaRegistry} from './element_schema_registry';
const EVENT = 'event';
const BOOLEAN = 'boolean';
@@ -238,7 +240,8 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
typeName.split(',').forEach(tag => this.schema[tag] = type);
var superType = this.schema[typeParts[1]];
if (isPresent(superType)) {
StringMapWrapper.forEach(superType, (v: any /** TODO #9100 */, k: any /** TODO #9100 */) => type[k] = v);
StringMapWrapper.forEach(
superType, (v: any /** TODO #9100 */, k: any /** TODO #9100 */) => type[k] = v);
}
properties.forEach((property: string) => {
if (property == '') {
@@ -28,25 +28,10 @@ registerContext(SecurityContext.HTML, [
registerContext(SecurityContext.STYLE, ['*|style']);
// NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
registerContext(SecurityContext.URL, [
'*|formAction',
'area|href',
'area|ping',
'audio|src',
'a|href',
'a|ping',
'blockquote|cite',
'body|background',
'del|cite',
'form|action',
'img|src',
'img|srcset',
'input|src',
'ins|cite',
'q|cite',
'source|src',
'source|srcset',
'video|poster',
'video|src',
'*|formAction', 'area|href', 'area|ping', 'audio|src', 'a|href',
'a|ping', 'blockquote|cite', 'body|background', 'del|cite', 'form|action',
'img|src', 'img|srcset', 'input|src', 'ins|cite', 'q|cite',
'source|src', 'source|srcset', 'video|poster', 'video|src',
]);
registerContext(SecurityContext.RESOURCE_URL, [
'applet|code',
+26 -29
View File
@@ -1,12 +1,6 @@
import {Map, ListWrapper} from '../src/facade/collection';
import {
isPresent,
isBlank,
RegExpWrapper,
RegExpMatcherWrapper,
StringWrapper
} from '../src/facade/lang';
import {ListWrapper, Map} from '../src/facade/collection';
import {BaseException} from '../src/facade/exceptions';
import {RegExpMatcherWrapper, RegExpWrapper, StringWrapper, isBlank, isPresent} from '../src/facade/lang';
const _EMPTY_ATTR_VALUE = /*@ts2dart_const*/ '';
@@ -36,7 +30,7 @@ export class CssSelector {
var _addResult = (res: CssSelector[], cssSel: any /** TODO #9100 */) => {
if (cssSel.notSelectors.length > 0 && isBlank(cssSel.element) &&
ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
cssSel.element = "*";
cssSel.element = '*';
}
res.push(cssSel);
};
@@ -81,7 +75,7 @@ export class CssSelector {
isElementSelector(): boolean {
return isPresent(this.element) && ListWrapper.isEmpty(this.classNames) &&
ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0;
ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0;
}
setElement(element: string = null) { this.element = element; }
@@ -174,8 +168,8 @@ export class SelectorMatcher {
* @param cssSelector A css selector
* @param callbackCtxt An opaque object that will be given to the callback of the `match` function
*/
private _addSelectable(cssSelector: CssSelector, callbackCtxt: any,
listContext: SelectorListContext) {
private _addSelectable(
cssSelector: CssSelector, callbackCtxt: any, listContext: SelectorListContext) {
var matcher: SelectorMatcher = this;
var element = cssSelector.element;
var classNames = cssSelector.classNames;
@@ -229,8 +223,8 @@ export class SelectorMatcher {
}
}
private _addTerminal(map: Map<string, SelectorContext[]>, name: string,
selectable: SelectorContext) {
private _addTerminal(
map: Map<string, SelectorContext[]>, name: string, selectable: SelectorContext) {
var terminalList = map.get(name);
if (isBlank(terminalList)) {
terminalList = [];
@@ -267,7 +261,7 @@ export class SelectorMatcher {
result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result;
result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) ||
result;
result;
if (isPresent(classNames)) {
for (var index = 0; index < classNames.length; index++) {
@@ -287,18 +281,18 @@ export class SelectorMatcher {
var terminalValuesMap = this._attrValueMap.get(attrName);
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
result = this._matchTerminal(terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector,
matchedCallback) ||
result;
result = this._matchTerminal(
terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
result;
}
result = this._matchTerminal(terminalValuesMap, attrValue, cssSelector, matchedCallback) ||
result;
result;
var partialValuesMap = this._attrValuePartialMap.get(attrName);
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
result = this._matchPartial(partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector,
matchedCallback) ||
result;
result = this._matchPartial(
partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
result;
}
result =
this._matchPartial(partialValuesMap, attrValue, cssSelector, matchedCallback) || result;
@@ -308,14 +302,15 @@ export class SelectorMatcher {
}
/** @internal */
_matchTerminal(map: Map<string, SelectorContext[]>, name: any /** TODO #9100 */, cssSelector: CssSelector,
matchedCallback: (c: CssSelector, a: any) => void): boolean {
_matchTerminal(
map: Map<string, SelectorContext[]>, name: any /** TODO #9100 */, cssSelector: CssSelector,
matchedCallback: (c: CssSelector, a: any) => void): boolean {
if (isBlank(map) || isBlank(name)) {
return false;
}
var selectables = map.get(name);
var starSelectables = map.get("*");
var starSelectables = map.get('*');
if (isPresent(starSelectables)) {
selectables = selectables.concat(starSelectables);
}
@@ -332,8 +327,9 @@ export class SelectorMatcher {
}
/** @internal */
_matchPartial(map: Map<string, SelectorMatcher>, name: any /** TODO #9100 */, cssSelector: CssSelector,
matchedCallback: any /** TODO #9100 */ /*: (c: CssSelector, a: any) => void*/): boolean {
_matchPartial(
map: Map<string, SelectorMatcher>, name: any /** TODO #9100 */, cssSelector: CssSelector,
matchedCallback: any /** TODO #9100 */ /*: (c: CssSelector, a: any) => void*/): boolean {
if (isBlank(map) || isBlank(name)) {
return false;
}
@@ -359,8 +355,9 @@ export class SelectorListContext {
export class SelectorContext {
notSelectors: CssSelector[];
constructor(public selector: CssSelector, public cbContext: any,
public listContext: SelectorListContext) {
constructor(
public selector: CssSelector, public cbContext: any,
public listContext: SelectorListContext) {
this.notSelectors = selector.notSelectors;
}
+40 -44
View File
@@ -1,12 +1,5 @@
import {ListWrapper} from '../src/facade/collection';
import {
StringWrapper,
RegExp,
RegExpWrapper,
RegExpMatcherWrapper,
isPresent,
isBlank
} from '../src/facade/lang';
import {RegExp, RegExpMatcherWrapper, RegExpWrapper, StringWrapper, isBlank, isPresent} from '../src/facade/lang';
/**
* This file is a port of shadowCSS from webcomponents.js to TypeScript.
@@ -174,8 +167,9 @@ export class ShadowCss {
**/
private _insertPolyfillDirectivesInCssText(cssText: string): string {
// Difference with webcomponents.js: does not handle comments
return StringWrapper.replaceAllMapped(cssText, _cssContentNextSelectorRe,
function(m: any /** TODO #9100 */) { return m[1] + '{'; });
return StringWrapper.replaceAllMapped(
cssText, _cssContentNextSelectorRe,
function(m: any /** TODO #9100 */) { return m[1] + '{'; });
}
/*
@@ -195,12 +189,13 @@ export class ShadowCss {
**/
private _insertPolyfillRulesInCssText(cssText: string): string {
// Difference with webcomponents.js: does not handle comments
return StringWrapper.replaceAllMapped(cssText, _cssContentRuleRe, function(m: any /** TODO #9100 */) {
var rule = m[0];
rule = StringWrapper.replace(rule, m[1], '');
rule = StringWrapper.replace(rule, m[2], '');
return m[3] + rule;
});
return StringWrapper.replaceAllMapped(
cssText, _cssContentRuleRe, function(m: any /** TODO #9100 */) {
var rule = m[0];
rule = StringWrapper.replace(rule, m[1], '');
rule = StringWrapper.replace(rule, m[2], '');
return m[3] + rule;
});
}
/* Ensure styles are scoped. Pseudo-scoping takes a rule like:
@@ -279,8 +274,8 @@ export class ShadowCss {
* scopeName.foo .bar { ... }
*/
private _convertColonHostContext(cssText: string): string {
return this._convertColonRule(cssText, _cssColonHostContextRe,
this._colonHostContextPartReplacer);
return this._convertColonRule(
cssText, _cssColonHostContextRe, this._colonHostContextPartReplacer);
}
private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
@@ -339,8 +334,8 @@ export class ShadowCss {
});
}
private _scopeSelector(selector: string, scopeSelector: string, hostSelector: string,
strict: boolean): string {
private _scopeSelector(
selector: string, scopeSelector: string, hostSelector: string, strict: boolean): string {
var r: any[] /** TODO #9100 */ = [], parts = selector.split(',');
for (var i = 0; i < parts.length; i++) {
var p = parts[i].trim();
@@ -348,8 +343,8 @@ export class ShadowCss {
var shallowPart = deepParts[0];
if (this._selectorNeedsScoping(shallowPart, scopeSelector)) {
deepParts[0] = strict && !StringWrapper.contains(shallowPart, _polyfillHostNoCombinator) ?
this._applyStrictSelectorScope(shallowPart, scopeSelector) :
this._applySelectorScope(shallowPart, scopeSelector, hostSelector);
this._applyStrictSelectorScope(shallowPart, scopeSelector) :
this._applySelectorScope(shallowPart, scopeSelector, hostSelector);
}
// replace /deep/ with a space for child selectors
r.push(deepParts.join(' '));
@@ -370,15 +365,15 @@ export class ShadowCss {
return RegExpWrapper.create('^(' + scopeSelector + ')' + _selectorReSuffix, 'm');
}
private _applySelectorScope(selector: string, scopeSelector: string,
hostSelector: string): string {
private _applySelectorScope(selector: string, scopeSelector: string, hostSelector: string):
string {
// Difference from webcomponentsjs: scopeSelector could not be an array
return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector);
}
// scope via name and [is=name]
private _applySimpleSelectorScope(selector: string, scopeSelector: string,
hostSelector: string): string {
private _applySimpleSelectorScope(selector: string, scopeSelector: string, hostSelector: string):
string {
if (isPresent(RegExpWrapper.firstMatch(_polyfillHostRe, selector))) {
var replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
selector = StringWrapper.replace(selector, _polyfillHostNoCombinator, replaceBy);
@@ -392,24 +387,26 @@ export class ShadowCss {
// e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name] /** @internal */
private _applyStrictSelectorScope(selector: string, scopeSelector: string): string {
var isRe = /\[is=([^\]]*)\]/g;
scopeSelector = StringWrapper.replaceAllMapped(scopeSelector, isRe, (m: any /** TODO #9100 */) => m[1]);
scopeSelector =
StringWrapper.replaceAllMapped(scopeSelector, isRe, (m: any /** TODO #9100 */) => m[1]);
var splits = [' ', '>', '+', '~'], scoped = selector, attrName = '[' + scopeSelector + ']';
for (var i = 0; i < splits.length; i++) {
var sep = splits[i];
var parts = scoped.split(sep);
scoped = parts.map(p => {
// remove :host since it should be unnecessary
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
if (t.length > 0 && !ListWrapper.contains(splits, t) &&
!StringWrapper.contains(t, attrName)) {
var re = /([^:]*)(:*)(.*)/g;
var m = RegExpWrapper.firstMatch(re, t);
if (isPresent(m)) {
p = m[1] + attrName + m[2] + m[3];
}
}
return p;
})
scoped = parts
.map(p => {
// remove :host since it should be unnecessary
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
if (t.length > 0 && !ListWrapper.contains(splits, t) &&
!StringWrapper.contains(t, attrName)) {
var re = /([^:]*)(:*)(.*)/g;
var m = RegExpWrapper.firstMatch(re, t);
if (isPresent(m)) {
p = m[1] + attrName + m[2] + m[3];
}
}
return p;
})
.join(sep);
}
return scoped;
@@ -430,14 +427,13 @@ var _polyfillHost = '-shadowcsshost';
// note: :host-context pre-processed to -shadowcsshostcontext.
var _polyfillHostContext = '-shadowcsscontext';
var _parenSuffix = ')(?:\\((' +
'(?:\\([^)(]*\\)|[^)(]*)+?' +
')\\))?([^,{]*)';
'(?:\\([^)(]*\\)|[^)(]*)+?' +
')\\))?([^,{]*)';
var _cssColonHostRe = RegExpWrapper.create('(' + _polyfillHost + _parenSuffix, 'im');
var _cssColonHostContextRe = RegExpWrapper.create('(' + _polyfillHostContext + _parenSuffix, 'im');
var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
var _shadowDOMSelectorsRe = [
/::shadow/g,
/::content/g,
/::shadow/g, /::content/g,
// Deprecated selectors
// TODO(vicb): see https://github.com/angular/clang-format/issues/16
// clang-format off
+23 -18
View File
@@ -1,23 +1,27 @@
import {ViewEncapsulation, Injectable} from '@angular/core';
import {CompileIdentifierMetadata, CompileDirectiveMetadata} from './compile_metadata';
import {Injectable, ViewEncapsulation} from '@angular/core';
import {isPresent} from '../src/facade/lang';
import {CompileDirectiveMetadata, CompileIdentifierMetadata} from './compile_metadata';
import * as o from './output/output_ast';
import {ShadowCss} from './shadow_css';
import {UrlResolver} from './url_resolver';
import {extractStyleUrls} from './style_url_resolver';
import {isPresent} from '../src/facade/lang';
import {UrlResolver} from './url_resolver';
const COMPONENT_VARIABLE = '%COMP%';
const HOST_ATTR = /*@ts2dart_const*/ `_nghost-${COMPONENT_VARIABLE}`;
const CONTENT_ATTR = /*@ts2dart_const*/ `_ngcontent-${COMPONENT_VARIABLE}`;
export class StylesCompileDependency {
constructor(public moduleUrl: string, public isShimmed: boolean,
public valuePlaceholder: CompileIdentifierMetadata) {}
constructor(
public moduleUrl: string, public isShimmed: boolean,
public valuePlaceholder: CompileIdentifierMetadata) {}
}
export class StylesCompileResult {
constructor(public statements: o.Statement[], public stylesVar: string,
public dependencies: StylesCompileDependency[]) {}
constructor(
public statements: o.Statement[], public stylesVar: string,
public dependencies: StylesCompileDependency[]) {}
}
@Injectable()
@@ -28,19 +32,20 @@ export class StyleCompiler {
compileComponent(comp: CompileDirectiveMetadata): StylesCompileResult {
var shim = comp.template.encapsulation === ViewEncapsulation.Emulated;
return this._compileStyles(getStylesVarName(comp), comp.template.styles,
comp.template.styleUrls, shim);
return this._compileStyles(
getStylesVarName(comp), comp.template.styles, comp.template.styleUrls, shim);
}
compileStylesheet(stylesheetUrl: string, cssText: string,
isShimmed: boolean): StylesCompileResult {
compileStylesheet(stylesheetUrl: string, cssText: string, isShimmed: boolean):
StylesCompileResult {
var styleWithImports = extractStyleUrls(this._urlResolver, stylesheetUrl, cssText);
return this._compileStyles(getStylesVarName(null), [styleWithImports.style],
styleWithImports.styleUrls, isShimmed);
return this._compileStyles(
getStylesVarName(null), [styleWithImports.style], styleWithImports.styleUrls, isShimmed);
}
private _compileStyles(stylesVar: string, plainStyles: string[], absUrls: string[],
shim: boolean): StylesCompileResult {
private _compileStyles(
stylesVar: string, plainStyles: string[], absUrls: string[],
shim: boolean): StylesCompileResult {
var styleExpressions =
plainStyles.map(plainStyle => o.literal(this._shimIfNeeded(plainStyle, shim)));
var dependencies: any[] /** TODO #9100 */ = [];
@@ -52,8 +57,8 @@ export class StyleCompiler {
// styles variable contains plain strings and arrays of other styles arrays (recursive),
// so we set its type to dynamic.
var stmt = o.variable(stylesVar)
.set(o.literalArr(styleExpressions,
new o.ArrayType(o.DYNAMIC_TYPE, [o.TypeModifier.Const])))
.set(o.literalArr(
styleExpressions, new o.ArrayType(o.DYNAMIC_TYPE, [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]);
return new StylesCompileResult([stmt], stylesVar, dependencies);
}
@@ -1,7 +1,8 @@
// Some of the code comes from WebComponents.JS
// https://github.com/webcomponents/webcomponentsjs/blob/master/src/HTMLImports/path.js
import {RegExpWrapper, StringWrapper, isPresent, isBlank} from '../src/facade/lang';
import {RegExpWrapper, StringWrapper, isBlank, isPresent} from '../src/facade/lang';
import {UrlResolver} from './url_resolver';
export class StyleWithImports {
@@ -18,18 +19,19 @@ export function isStyleUrlResolvable(url: string): boolean {
* Rewrites stylesheets by resolving and removing the @import urls that
* are either relative or don't have a `package:` scheme
*/
export function extractStyleUrls(resolver: UrlResolver, baseUrl: string,
cssText: string): StyleWithImports {
export function extractStyleUrls(
resolver: UrlResolver, baseUrl: string, cssText: string): StyleWithImports {
var foundUrls: any[] /** TODO #9100 */ = [];
var modifiedCssText = StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m: any /** TODO #9100 */) => {
var url = isPresent(m[1]) ? m[1] : m[2];
if (!isStyleUrlResolvable(url)) {
// Do not attempt to resolve non-package absolute URLs with URI scheme
return m[0];
}
foundUrls.push(resolver.resolve(baseUrl, url));
return '';
});
var modifiedCssText =
StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m: any /** TODO #9100 */) => {
var url = isPresent(m[1]) ? m[1] : m[2];
if (!isStyleUrlResolvable(url)) {
// Do not attempt to resolve non-package absolute URLs with URI scheme
return m[0];
}
foundUrls.push(resolver.resolve(baseUrl, url));
return '';
});
return new StyleWithImports(modifiedCssText, foundUrls);
}
+45 -41
View File
@@ -1,10 +1,8 @@
import {AST} from './expression_parser/ast';
import {isPresent} from '../src/facade/lang';
import {
CompileDirectiveMetadata,
CompileTokenMetadata,
CompileProviderMetadata,
} from './compile_metadata';
import {AST} from './expression_parser/ast';
import {CompileDirectiveMetadata, CompileTokenMetadata, CompileProviderMetadata,} from './compile_metadata';
import {ParseSourceSpan} from './parse_util';
import {SecurityContext} from '../core_private';
@@ -27,8 +25,8 @@ export interface TemplateAst {
* A segment of text within the template.
*/
export class TextAst implements TemplateAst {
constructor(public value: string, public ngContentIndex: number,
public sourceSpan: ParseSourceSpan) {}
constructor(
public value: string, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); }
}
@@ -36,8 +34,8 @@ export class TextAst implements TemplateAst {
* A bound expression within the text of a template.
*/
export class BoundTextAst implements TemplateAst {
constructor(public value: AST, public ngContentIndex: number,
public sourceSpan: ParseSourceSpan) {}
constructor(
public value: AST, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitBoundText(this, context);
}
@@ -55,9 +53,10 @@ export class AttrAst implements TemplateAst {
* A binding for an element property (e.g. `[property]="expression"`).
*/
export class BoundElementPropertyAst implements TemplateAst {
constructor(public name: string, public type: PropertyBindingType,
public securityContext: SecurityContext, public value: AST, public unit: string,
public sourceSpan: ParseSourceSpan) {}
constructor(
public name: string, public type: PropertyBindingType,
public securityContext: SecurityContext, public value: AST, public unit: string,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitElementProperty(this, context);
}
@@ -67,8 +66,9 @@ export class BoundElementPropertyAst implements TemplateAst {
* A binding for an element event (e.g. `(event)="handler()"`).
*/
export class BoundEventAst implements TemplateAst {
constructor(public name: string, public target: string, public handler: AST,
public sourceSpan: ParseSourceSpan) {}
constructor(
public name: string, public target: string, public handler: AST,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitEvent(this, context);
}
@@ -85,8 +85,9 @@ export class BoundEventAst implements TemplateAst {
* A reference declaration on an element (e.g. `let someName="expression"`).
*/
export class ReferenceAst implements TemplateAst {
constructor(public name: string, public value: CompileTokenMetadata,
public sourceSpan: ParseSourceSpan) {}
constructor(
public name: string, public value: CompileTokenMetadata, public sourceSpan: ParseSourceSpan) {
}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitReference(this, context);
}
@@ -106,12 +107,12 @@ export class VariableAst implements TemplateAst {
* An element declaration in a template.
*/
export class ElementAst implements TemplateAst {
constructor(public name: string, public attrs: AttrAst[],
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[],
public references: ReferenceAst[], public directives: DirectiveAst[],
public providers: ProviderAst[], public hasViewContainer: boolean,
public children: TemplateAst[], public ngContentIndex: number,
public sourceSpan: ParseSourceSpan) {}
constructor(
public name: string, public attrs: AttrAst[], public inputs: BoundElementPropertyAst[],
public outputs: BoundEventAst[], public references: ReferenceAst[],
public directives: DirectiveAst[], public providers: ProviderAst[],
public hasViewContainer: boolean, public children: TemplateAst[],
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitElement(this, context);
@@ -122,11 +123,12 @@ export class ElementAst implements TemplateAst {
* A `<template>` element included in an Angular template.
*/
export class EmbeddedTemplateAst implements TemplateAst {
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[],
public references: ReferenceAst[], public variables: VariableAst[],
public directives: DirectiveAst[], public providers: ProviderAst[],
public hasViewContainer: boolean, public children: TemplateAst[],
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
constructor(
public attrs: AttrAst[], public outputs: BoundEventAst[], public references: ReferenceAst[],
public variables: VariableAst[], public directives: DirectiveAst[],
public providers: ProviderAst[], public hasViewContainer: boolean,
public children: TemplateAst[], public ngContentIndex: number,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitEmbeddedTemplate(this, context);
@@ -137,8 +139,9 @@ export class EmbeddedTemplateAst implements TemplateAst {
* A directive property with a bound value (e.g. `*ngIf="condition").
*/
export class BoundDirectivePropertyAst implements TemplateAst {
constructor(public directiveName: string, public templateName: string, public value: AST,
public sourceSpan: ParseSourceSpan) {}
constructor(
public directiveName: string, public templateName: string, public value: AST,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitDirectiveProperty(this, context);
}
@@ -148,10 +151,10 @@ export class BoundDirectivePropertyAst implements TemplateAst {
* A directive declared on an element.
*/
export class DirectiveAst implements TemplateAst {
constructor(public directive: CompileDirectiveMetadata,
public inputs: BoundDirectivePropertyAst[],
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
public sourceSpan: ParseSourceSpan) {}
constructor(
public directive: CompileDirectiveMetadata, public inputs: BoundDirectivePropertyAst[],
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitDirective(this, context);
}
@@ -161,9 +164,10 @@ export class DirectiveAst implements TemplateAst {
* A provider declared on an element
*/
export class ProviderAst implements TemplateAst {
constructor(public token: CompileTokenMetadata, public multiProvider: boolean,
public eager: boolean, public providers: CompileProviderMetadata[],
public providerType: ProviderAstType, public sourceSpan: ParseSourceSpan) {}
constructor(
public token: CompileTokenMetadata, public multiProvider: boolean, public eager: boolean,
public providers: CompileProviderMetadata[], public providerType: ProviderAstType,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
// No visit method in the visitor for now...
@@ -183,8 +187,8 @@ export enum ProviderAstType {
* Position where content is to be projected (instance of `<ng-content>` in a template).
*/
export class NgContentAst implements TemplateAst {
constructor(public index: number, public ngContentIndex: number,
public sourceSpan: ParseSourceSpan) {}
constructor(
public index: number, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitNgContent(this, context);
}
@@ -242,8 +246,8 @@ export interface TemplateAstVisitor {
/**
* Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}.
*/
export function templateVisitAll(visitor: TemplateAstVisitor, asts: TemplateAst[],
context: any = null): any[] {
export function templateVisitAll(
visitor: TemplateAstVisitor, asts: TemplateAst[], context: any = null): any[] {
var result: any[] /** TODO #9100 */ = [];
asts.forEach(ast => {
var astResult = ast.visit(visitor, context);
+204 -232
View File
@@ -1,51 +1,18 @@
import {Injectable, Inject, OpaqueToken, Optional} from '@angular/core';
import {MAX_INTERPOLATION_VALUES, Console, SecurityContext} from '../core_private';
import {Inject, Injectable, OpaqueToken, Optional} from '@angular/core';
import {
ListWrapper,
StringMapWrapper,
SetWrapper,
} from '../src/facade/collection';
import {Console, MAX_INTERPOLATION_VALUES, SecurityContext} from '../core_private';
import {ListWrapper, StringMapWrapper, SetWrapper,} from '../src/facade/collection';
import {RegExpWrapper, isPresent, StringWrapper, isBlank, isArray} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {
AST,
Interpolation,
ASTWithSource,
TemplateBinding,
RecursiveAstVisitor,
BindingPipe
} from './expression_parser/ast';
import {AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe} from './expression_parser/ast';
import {Parser} from './expression_parser/parser';
import {
CompileDirectiveMetadata,
CompilePipeMetadata,
CompileMetadataWithType,
} from './compile_metadata';
import {CompileDirectiveMetadata, CompilePipeMetadata, CompileMetadataWithType,} from './compile_metadata';
import {HtmlParser} from './html_parser';
import {splitNsName, mergeNsAndName} from './html_tags';
import {ParseSourceSpan, ParseError, ParseLocation, ParseErrorLevel} from './parse_util';
import {
ElementAst,
BoundElementPropertyAst,
BoundEventAst,
ReferenceAst,
TemplateAst,
TemplateAstVisitor,
templateVisitAll,
TextAst,
BoundTextAst,
EmbeddedTemplateAst,
AttrAst,
NgContentAst,
PropertyBindingType,
DirectiveAst,
BoundDirectivePropertyAst,
ProviderAst,
ProviderAstType,
VariableAst
} from './template_ast';
import {ElementAst, BoundElementPropertyAst, BoundEventAst, ReferenceAst, TemplateAst, TemplateAstVisitor, templateVisitAll, TextAst, BoundTextAst, EmbeddedTemplateAst, AttrAst, NgContentAst, PropertyBindingType, DirectiveAst, BoundDirectivePropertyAst, ProviderAst, ProviderAstType, VariableAst} from './template_ast';
import {CssSelector, SelectorMatcher} from './selector';
import {ElementSchemaRegistry} from './schema/element_schema_registry';
@@ -53,16 +20,7 @@ import {preparseElement, PreparsedElementType} from './template_preparser';
import {isStyleUrlResolvable} from './style_url_resolver';
import {
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
HtmlExpansionAst,
HtmlExpansionCaseAst,
htmlVisitAll
} from './html_ast';
import {HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, HtmlExpansionAst, HtmlExpansionCaseAst, htmlVisitAll} from './html_ast';
import {splitAtColon} from './util';
import {identifierToken, Identifiers} from './identifiers';
@@ -116,13 +74,14 @@ export class TemplateParseResult {
@Injectable()
export class TemplateParser {
constructor(private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
private _htmlParser: HtmlParser, private _console: Console,
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
constructor(
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
private _htmlParser: HtmlParser, private _console: Console,
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
parse(component: CompileDirectiveMetadata, template: string,
directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
templateUrl: string): TemplateAst[] {
parse(
component: CompileDirectiveMetadata, template: string, directives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], templateUrl: string): TemplateAst[] {
var result = this.tryParse(component, template, directives, pipes, templateUrl);
var warnings = result.errors.filter(error => error.level === ParseErrorLevel.WARNING);
var errors = result.errors.filter(error => error.level === ParseErrorLevel.FATAL);
@@ -136,19 +95,19 @@ export class TemplateParser {
return result.templateAst;
}
tryParse(component: CompileDirectiveMetadata, template: string,
directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
templateUrl: string): TemplateParseResult {
tryParse(
component: CompileDirectiveMetadata, template: string, directives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], templateUrl: string): TemplateParseResult {
var htmlAstWithErrors = this._htmlParser.parse(template, templateUrl);
var errors:ParseError[] = htmlAstWithErrors.errors;
var errors: ParseError[] = htmlAstWithErrors.errors;
var result: any /** TODO #???? */;
if (htmlAstWithErrors.rootNodes.length > 0) {
var uniqDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
var uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
var providerViewContext =
new ProviderViewContext(component, htmlAstWithErrors.rootNodes[0].sourceSpan);
var parseVisitor = new TemplateParseVisitor(providerViewContext, uniqDirectives, uniqPipes,
this._exprParser, this._schemaRegistry);
new ProviderViewContext(component, htmlAstWithErrors.rootNodes[0].sourceSpan);
var parseVisitor = new TemplateParseVisitor(
providerViewContext, uniqDirectives, uniqPipes, this._exprParser, this._schemaRegistry);
result = htmlVisitAll(parseVisitor, htmlAstWithErrors.rootNodes, EMPTY_ELEMENT_CONTEXT);
errors = errors.concat(parseVisitor.errors).concat(providerViewContext.errors);
@@ -169,23 +128,20 @@ export class TemplateParser {
}
/** @internal */
_assertNoReferenceDuplicationOnTemplate(result:any[], errors:TemplateParseError[]):void {
_assertNoReferenceDuplicationOnTemplate(result: any[], errors: TemplateParseError[]): void {
const existingReferences: any[] /** TODO #???? */ = [];
result
.filter(element => !!element.references)
.forEach(element => element.references.forEach((reference: any /** TODO #???? */)=> {
const name = reference.name;
if (existingReferences.indexOf(name) < 0) {
existingReferences.push(name);
}
else {
const error = new TemplateParseError(
`Reference "#${name}" is defined several times`,
reference.sourceSpan,
ParseErrorLevel.FATAL);
errors.push(error);
}
}));
result.filter(element => !!element.references)
.forEach(element => element.references.forEach((reference: any /** TODO #???? */) => {
const name = reference.name;
if (existingReferences.indexOf(name) < 0) {
existingReferences.push(name);
} else {
const error = new TemplateParseError(
`Reference "#${name}" is defined several times`, reference.sourceSpan,
ParseErrorLevel.FATAL);
errors.push(error);
}
}));
}
}
@@ -196,22 +152,24 @@ class TemplateParseVisitor implements HtmlAstVisitor {
ngContentCount: number = 0;
pipesByName: Map<string, CompilePipeMetadata>;
constructor(public providerViewContext: ProviderViewContext,
directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) {
constructor(
public providerViewContext: ProviderViewContext, directives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], private _exprParser: Parser,
private _schemaRegistry: ElementSchemaRegistry) {
this.selectorMatcher = new SelectorMatcher();
ListWrapper.forEachWithIndex(directives,
(directive: CompileDirectiveMetadata, index: number) => {
var selector = CssSelector.parse(directive.selector);
this.selectorMatcher.addSelectables(selector, directive);
this.directivesIndex.set(directive, index);
});
ListWrapper.forEachWithIndex(
directives, (directive: CompileDirectiveMetadata, index: number) => {
var selector = CssSelector.parse(directive.selector);
this.selectorMatcher.addSelectables(selector, directive);
this.directivesIndex.set(directive, index);
});
this.pipesByName = new Map<string, CompilePipeMetadata>();
pipes.forEach(pipe => this.pipesByName.set(pipe.name, pipe));
}
private _reportError(message: string, sourceSpan: ParseSourceSpan,
level: ParseErrorLevel = ParseErrorLevel.FATAL) {
private _reportError(
message: string, sourceSpan: ParseSourceSpan,
level: ParseErrorLevel = ParseErrorLevel.FATAL) {
this.errors.push(new TemplateParseError(message, sourceSpan, level));
}
@@ -340,9 +298,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var isTemplateElement = lcElName == TEMPLATE_ELEMENT;
element.attrs.forEach(attr => {
var hasBinding =
this._parseAttr(isTemplateElement, attr, matchableAttrs, elementOrDirectiveProps, animationProps, events,
elementOrDirectiveRefs, elementVars);
var hasBinding = this._parseAttr(
isTemplateElement, attr, matchableAttrs, elementOrDirectiveProps, animationProps, events,
elementOrDirectiveRefs, elementVars);
var hasTemplateBinding = this._parseInlineTemplateBinding(
attr, templateMatchableAttrs, templateElementOrDirectiveProps, templateElementVars);
if (!hasBinding && !hasTemplateBinding) {
@@ -358,24 +316,26 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var elementCssSelector = createElementCssSelector(nodeName, matchableAttrs);
var directiveMetas = this._parseDirectives(this.selectorMatcher, elementCssSelector);
var references: ReferenceAst[] = [];
var directiveAsts = this._createDirectiveAsts(isTemplateElement, element.name, directiveMetas,
elementOrDirectiveProps, elementOrDirectiveRefs,
element.sourceSpan, references);
var directiveAsts = this._createDirectiveAsts(
isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps,
elementOrDirectiveRefs, element.sourceSpan, references);
var elementProps: BoundElementPropertyAst[] =
this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directiveAsts).concat(animationProps);
this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directiveAsts)
.concat(animationProps);
var isViewRoot = parent.isTemplateElement || hasInlineTemplates;
var providerContext =
new ProviderElementContext(this.providerViewContext, parent.providerContext, isViewRoot,
directiveAsts, attrs, references, element.sourceSpan);
var providerContext = new ProviderElementContext(
this.providerViewContext, parent.providerContext, isViewRoot, directiveAsts, attrs,
references, element.sourceSpan);
var children = htmlVisitAll(
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
ElementContext.create(isTemplateElement, directiveAsts,
isTemplateElement ? parent.providerContext : providerContext));
ElementContext.create(
isTemplateElement, directiveAsts,
isTemplateElement ? parent.providerContext : providerContext));
providerContext.afterElement();
// Override the actual selector when the `ngProjectAs` attribute is provided
var projectionSelector = isPresent(preparsedElement.projectAs) ?
CssSelector.parse(preparsedElement.projectAs)[0] :
elementCssSelector;
CssSelector.parse(preparsedElement.projectAs)[0] :
elementCssSelector;
var ngContentIndex = parent.findNgContentIndex(projectionSelector);
var parsedElement: any /** TODO #???? */;
@@ -390,8 +350,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
} else if (isTemplateElement) {
this._assertAllEventsPublishedByDirectives(directiveAsts, events);
this._assertNoComponentsNorElementBindingsOnTemplate(directiveAsts, elementProps,
element.sourceSpan);
this._assertNoComponentsNorElementBindingsOnTemplate(
directiveAsts, elementProps, element.sourceSpan);
parsedElement = new EmbeddedTemplateAst(
attrs, events, references, elementVars, providerContext.transformedDirectiveAsts,
@@ -410,9 +370,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
if (hasInlineTemplates) {
var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
var templateDirectiveMetas = this._parseDirectives(this.selectorMatcher, templateCssSelector);
var templateDirectiveAsts =
this._createDirectiveAsts(true, element.name, templateDirectiveMetas,
templateElementOrDirectiveProps, [], element.sourceSpan, []);
var templateDirectiveAsts = this._createDirectiveAsts(
true, element.name, templateDirectiveMetas, templateElementOrDirectiveProps, [],
element.sourceSpan, []);
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
element.name, templateElementOrDirectiveProps, templateDirectiveAsts);
this._assertNoComponentsNorElementBindingsOnTemplate(
@@ -422,18 +382,18 @@ class TemplateParseVisitor implements HtmlAstVisitor {
templateDirectiveAsts, [], [], element.sourceSpan);
templateProviderContext.afterElement();
parsedElement = new EmbeddedTemplateAst([], [], [], templateElementVars,
templateProviderContext.transformedDirectiveAsts,
templateProviderContext.transformProviders,
templateProviderContext.transformedHasViewContainer,
[parsedElement], ngContentIndex, element.sourceSpan);
parsedElement = new EmbeddedTemplateAst(
[], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts,
templateProviderContext.transformProviders,
templateProviderContext.transformedHasViewContainer, [parsedElement], ngContentIndex,
element.sourceSpan);
}
return parsedElement;
}
private _parseInlineTemplateBinding(attr: HtmlAttrAst, targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[],
targetVars: VariableAst[]): boolean {
private _parseInlineTemplateBinding(
attr: HtmlAttrAst, targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[], targetVars: VariableAst[]): boolean {
var templateBindingsSource: any /** TODO #???? */ = null;
if (attr.name == TEMPLATE_ATTR) {
templateBindingsSource = attr.value;
@@ -448,8 +408,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
if (binding.keyIsVar) {
targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan));
} else if (isPresent(binding.expression)) {
this._parsePropertyAst(binding.key, binding.expression, attr.sourceSpan,
targetMatchableAttrs, targetProps);
this._parsePropertyAst(
binding.key, binding.expression, attr.sourceSpan, targetMatchableAttrs, targetProps);
} else {
targetMatchableAttrs.push([binding.key, '']);
this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps);
@@ -460,12 +420,11 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return false;
}
private _parseAttr(isTemplateElement: boolean, attr: HtmlAttrAst,
targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[],
targetAnimationProps: BoundElementPropertyAst[],
targetEvents: BoundEventAst[],
targetRefs: ElementOrDirectiveRef[], targetVars: VariableAst[]): boolean {
private _parseAttr(
isTemplateElement: boolean, attr: HtmlAttrAst, targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[],
targetAnimationProps: BoundElementPropertyAst[], targetEvents: BoundEventAst[],
targetRefs: ElementOrDirectiveRef[], targetVars: VariableAst[]): boolean {
var attrName = this._normalizeAttributeName(attr.name);
var attrValue = attr.value;
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
@@ -473,18 +432,20 @@ class TemplateParseVisitor implements HtmlAstVisitor {
if (isPresent(bindParts)) {
hasBinding = true;
if (isPresent(bindParts[1])) { // match: bind-prop
this._parseProperty(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetProps);
this._parseProperty(
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
} else if (isPresent(bindParts[2])) { // match: var-name / var-name="iden"
var identifier = bindParts[8];
if (isTemplateElement) {
this._reportError(`"var-" on <template> elements is deprecated. Use "let-" instead!`,
attr.sourceSpan, ParseErrorLevel.WARNING);
this._reportError(
`"var-" on <template> elements is deprecated. Use "let-" instead!`, attr.sourceSpan,
ParseErrorLevel.WARNING);
this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars);
} else {
this._reportError(`"var-" on non <template> elements is deprecated. Use "ref-" instead!`,
attr.sourceSpan, ParseErrorLevel.WARNING);
this._reportError(
`"var-" on non <template> elements is deprecated. Use "ref-" instead!`,
attr.sourceSpan, ParseErrorLevel.WARNING);
this._parseReference(identifier, attrValue, attr.sourceSpan, targetRefs);
}
@@ -501,35 +462,35 @@ class TemplateParseVisitor implements HtmlAstVisitor {
this._parseReference(identifier, attrValue, attr.sourceSpan, targetRefs);
} else if (isPresent(bindParts[5])) { // match: on-event
this._parseEvent(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetEvents);
this._parseEvent(
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} else if (isPresent(bindParts[6])) { // match: bindon-prop
this._parseProperty(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetProps);
this._parseAssignmentEvent(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetEvents);
this._parseProperty(
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
this._parseAssignmentEvent(
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} else if (isPresent(bindParts[7])) { // match: animate-name
this._parseAnimation(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetAnimationProps);
this._parseAnimation(
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetAnimationProps);
} else if (isPresent(bindParts[9])) { // match: [(expr)]
this._parseProperty(bindParts[9], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetProps);
this._parseAssignmentEvent(bindParts[9], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetEvents);
this._parseProperty(
bindParts[9], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
this._parseAssignmentEvent(
bindParts[9], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} else if (isPresent(bindParts[10])) { // match: [expr]
this._parseProperty(bindParts[10], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetProps);
this._parseProperty(
bindParts[10], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
} else if (isPresent(bindParts[11])) { // match: (event)
this._parseEvent(bindParts[11], attrValue, attr.sourceSpan, targetMatchableAttrs,
targetEvents);
this._parseEvent(
bindParts[11], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
}
} else {
hasBinding = this._parsePropertyInterpolation(attrName, attrValue, attr.sourceSpan,
targetMatchableAttrs, targetProps);
hasBinding = this._parsePropertyInterpolation(
attrName, attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
}
if (!hasBinding) {
this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps);
@@ -541,9 +502,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName;
}
private _parseVariable(identifier: string, value: string, sourceSpan: ParseSourceSpan,
targetVars: VariableAst[]) {
private _parseVariable(
identifier: string, value: string, sourceSpan: ParseSourceSpan, targetVars: VariableAst[]) {
if (identifier.indexOf('-') > -1) {
this._reportError(`"-" is not allowed in variable names`, sourceSpan);
}
@@ -551,8 +511,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
targetVars.push(new VariableAst(identifier, value, sourceSpan));
}
private _parseReference(identifier: string, value: string, sourceSpan: ParseSourceSpan,
targetRefs: ElementOrDirectiveRef[]) {
private _parseReference(
identifier: string, value: string, sourceSpan: ParseSourceSpan,
targetRefs: ElementOrDirectiveRef[]) {
if (identifier.indexOf('-') > -1) {
this._reportError(`"-" is not allowed in reference names`, sourceSpan);
}
@@ -560,24 +521,26 @@ class TemplateParseVisitor implements HtmlAstVisitor {
targetRefs.push(new ElementOrDirectiveRef(identifier, value, sourceSpan));
}
private _parseProperty(name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[]) {
this._parsePropertyAst(name, this._parseBinding(expression, sourceSpan), sourceSpan,
targetMatchableAttrs, targetProps);
private _parseProperty(
name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
this._parsePropertyAst(
name, this._parseBinding(expression, sourceSpan), sourceSpan, targetMatchableAttrs,
targetProps);
}
private _parseAnimation(name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][],
targetAnimationProps: BoundElementPropertyAst[]) {
private _parseAnimation(
name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetAnimationProps: BoundElementPropertyAst[]) {
var ast = this._parseBinding(expression, sourceSpan);
targetMatchableAttrs.push([name, ast.source]);
targetAnimationProps.push(new BoundElementPropertyAst(name, PropertyBindingType.Animation, SecurityContext.NONE, ast, null, sourceSpan));
targetAnimationProps.push(new BoundElementPropertyAst(
name, PropertyBindingType.Animation, SecurityContext.NONE, ast, null, sourceSpan));
}
private _parsePropertyInterpolation(name: string, value: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[]): boolean {
private _parsePropertyInterpolation(
name: string, value: string, sourceSpan: ParseSourceSpan, targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[]): boolean {
var expr = this._parseInterpolation(value, sourceSpan);
if (isPresent(expr)) {
this._parsePropertyAst(name, expr, sourceSpan, targetMatchableAttrs, targetProps);
@@ -586,21 +549,23 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return false;
}
private _parsePropertyAst(name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[]) {
private _parsePropertyAst(
name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
targetMatchableAttrs.push([name, ast.source]);
targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan));
}
private _parseAssignmentEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
this._parseEvent(`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs,
targetEvents);
private _parseAssignmentEvent(
name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
this._parseEvent(
`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs, targetEvents);
}
private _parseEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
private _parseEvent(
name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
// long format: 'target: eventName'
var parts = splitAtColon(name, [null, name]);
var target = parts[0];
@@ -612,14 +577,15 @@ class TemplateParseVisitor implements HtmlAstVisitor {
// so don't add the event name to the matchableAttrs
}
private _parseLiteralAttr(name: string, value: string, sourceSpan: ParseSourceSpan,
targetProps: BoundElementOrDirectiveProperty[]) {
private _parseLiteralAttr(
name: string, value: string, sourceSpan: ParseSourceSpan,
targetProps: BoundElementOrDirectiveProperty[]) {
targetProps.push(new BoundElementOrDirectiveProperty(
name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan));
}
private _parseDirectives(selectorMatcher: SelectorMatcher,
elementCssSelector: CssSelector): CompileDirectiveMetadata[] {
private _parseDirectives(selectorMatcher: SelectorMatcher, elementCssSelector: CssSelector):
CompileDirectiveMetadata[] {
// Need to sort the directives so that we get consistent results throughout,
// as selectorMatcher uses Maps inside.
// Also dedupe directives as they might match more than one time!
@@ -630,12 +596,10 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return directives.filter(dir => isPresent(dir));
}
private _createDirectiveAsts(isTemplateElement: boolean, elementName: string,
directives: CompileDirectiveMetadata[],
props: BoundElementOrDirectiveProperty[],
elementOrDirectiveRefs: ElementOrDirectiveRef[],
sourceSpan: ParseSourceSpan,
targetReferences: ReferenceAst[]): DirectiveAst[] {
private _createDirectiveAsts(
isTemplateElement: boolean, elementName: string, directives: CompileDirectiveMetadata[],
props: BoundElementOrDirectiveProperty[], elementOrDirectiveRefs: ElementOrDirectiveRef[],
sourceSpan: ParseSourceSpan, targetReferences: ReferenceAst[]): DirectiveAst[] {
var matchedReferences = new Set<string>();
var component: CompileDirectiveMetadata = null;
var directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
@@ -645,26 +609,27 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var hostProperties: BoundElementPropertyAst[] = [];
var hostEvents: BoundEventAst[] = [];
var directiveProperties: BoundDirectivePropertyAst[] = [];
this._createDirectiveHostPropertyAsts(elementName, directive.hostProperties, sourceSpan,
hostProperties);
this._createDirectiveHostPropertyAsts(
elementName, directive.hostProperties, sourceSpan, hostProperties);
this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents);
this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties);
elementOrDirectiveRefs.forEach((elOrDirRef) => {
if ((elOrDirRef.value.length === 0 && directive.isComponent) ||
(directive.exportAs == elOrDirRef.value)) {
targetReferences.push(new ReferenceAst(elOrDirRef.name, identifierToken(directive.type),
elOrDirRef.sourceSpan));
targetReferences.push(new ReferenceAst(
elOrDirRef.name, identifierToken(directive.type), elOrDirRef.sourceSpan));
matchedReferences.add(elOrDirRef.name);
}
});
return new DirectiveAst(directive, directiveProperties, hostProperties, hostEvents,
sourceSpan);
return new DirectiveAst(
directive, directiveProperties, hostProperties, hostEvents, sourceSpan);
});
elementOrDirectiveRefs.forEach((elOrDirRef) => {
if (elOrDirRef.value.length > 0) {
if (!SetWrapper.has(matchedReferences, elOrDirRef.name)) {
this._reportError(`There is no directive with "exportAs" set to "${elOrDirRef.value}"`,
elOrDirRef.sourceSpan);
this._reportError(
`There is no directive with "exportAs" set to "${elOrDirRef.value}"`,
elOrDirRef.sourceSpan);
};
} else if (isBlank(component)) {
var refToken: any /** TODO #???? */ = null;
@@ -677,9 +642,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return directiveAsts;
}
private _createDirectiveHostPropertyAsts(elementName: string, hostProps: {[key: string]: string},
sourceSpan: ParseSourceSpan,
targetPropertyAsts: BoundElementPropertyAst[]) {
private _createDirectiveHostPropertyAsts(
elementName: string, hostProps: {[key: string]: string}, sourceSpan: ParseSourceSpan,
targetPropertyAsts: BoundElementPropertyAst[]) {
if (isPresent(hostProps)) {
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
var exprAst = this._parseBinding(expression, sourceSpan);
@@ -689,9 +654,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}
}
private _createDirectiveHostEventAsts(hostListeners: {[key: string]: string},
sourceSpan: ParseSourceSpan,
targetEventAsts: BoundEventAst[]) {
private _createDirectiveHostEventAsts(
hostListeners: {[key: string]: string}, sourceSpan: ParseSourceSpan,
targetEventAsts: BoundEventAst[]) {
if (isPresent(hostListeners)) {
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
@@ -699,9 +664,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}
}
private _createDirectivePropertyAsts(directiveProperties: {[key: string]: string},
boundProps: BoundElementOrDirectiveProperty[],
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
private _createDirectivePropertyAsts(
directiveProperties: {[key: string]: string}, boundProps: BoundElementOrDirectiveProperty[],
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
if (isPresent(directiveProperties)) {
var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>();
boundProps.forEach(boundProp => {
@@ -724,8 +689,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}
}
private _createElementPropertyAsts(elementName: string, props: BoundElementOrDirectiveProperty[],
directives: DirectiveAst[]): BoundElementPropertyAst[] {
private _createElementPropertyAsts(
elementName: string, props: BoundElementOrDirectiveProperty[],
directives: DirectiveAst[]): BoundElementPropertyAst[] {
var boundElementProps: BoundElementPropertyAst[] = [];
var boundDirectivePropsIndex = new Map<string, BoundDirectivePropertyAst>();
directives.forEach((directive: DirectiveAst) => {
@@ -735,15 +701,16 @@ class TemplateParseVisitor implements HtmlAstVisitor {
});
props.forEach((prop: BoundElementOrDirectiveProperty) => {
if (!prop.isLiteral && isBlank(boundDirectivePropsIndex.get(prop.name))) {
boundElementProps.push(this._createElementPropertyAst(elementName, prop.name,
prop.expression, prop.sourceSpan));
boundElementProps.push(this._createElementPropertyAst(
elementName, prop.name, prop.expression, prop.sourceSpan));
}
});
return boundElementProps;
}
private _createElementPropertyAst(elementName: string, name: string, ast: AST,
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
private _createElementPropertyAst(
elementName: string, name: string, ast: AST,
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
var unit: any /** TODO #???? */ = null;
var bindingType: any /** TODO #???? */;
var boundPropertyName: string;
@@ -755,8 +722,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
bindingType = PropertyBindingType.Property;
if (!this._schemaRegistry.hasProperty(elementName, boundPropertyName)) {
this._reportError(
`Can't bind to '${boundPropertyName}' since it isn't a known native property`,
sourceSpan);
`Can't bind to '${boundPropertyName}' since it isn't a known native property`,
sourceSpan);
}
} else {
if (parts[0] == ATTRIBUTE_PREFIX) {
@@ -794,8 +761,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}
}
return new BoundElementPropertyAst(boundPropertyName, bindingType, securityContext, ast, unit,
sourceSpan);
return new BoundElementPropertyAst(
boundPropertyName, bindingType, securityContext, ast, unit, sourceSpan);
}
@@ -817,13 +784,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}
}
private _assertNoComponentsNorElementBindingsOnTemplate(directives: DirectiveAst[],
elementProps: BoundElementPropertyAst[],
sourceSpan: ParseSourceSpan) {
private _assertNoComponentsNorElementBindingsOnTemplate(
directives: DirectiveAst[], elementProps: BoundElementPropertyAst[],
sourceSpan: ParseSourceSpan) {
var componentTypeNames: string[] = this._findComponentDirectiveNames(directives);
if (componentTypeNames.length > 0) {
this._reportError(`Components on an embedded template: ${componentTypeNames.join(',')}`,
sourceSpan);
this._reportError(
`Components on an embedded template: ${componentTypeNames.join(',')}`, sourceSpan);
}
elementProps.forEach(prop => {
this._reportError(
@@ -832,12 +799,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
});
}
private _assertAllEventsPublishedByDirectives(directives: DirectiveAst[],
events: BoundEventAst[]) {
private _assertAllEventsPublishedByDirectives(
directives: DirectiveAst[], events: BoundEventAst[]) {
var allDirectiveEvents = new Set<string>();
directives.forEach(directive => {
StringMapWrapper.forEach(directive.directive.outputs,
(eventName: string, _: any /** TODO #???? */) => { allDirectiveEvents.add(eventName); });
StringMapWrapper.forEach(
directive.directive.outputs,
(eventName: string, _: any /** TODO #???? */) => { allDirectiveEvents.add(eventName); });
});
events.forEach(event => {
if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) {
@@ -865,8 +833,9 @@ class NonBindableVisitor implements HtmlAstVisitor {
var selector = createElementCssSelector(ast.name, attrNameAndValues);
var ngContentIndex = parent.findNgContentIndex(selector);
var children = htmlVisitAll(this, ast.children, EMPTY_ELEMENT_CONTEXT);
return new ElementAst(ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], [], false,
children, ngContentIndex, ast.sourceSpan);
return new ElementAst(
ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], [], false, children,
ngContentIndex, ast.sourceSpan);
}
visitComment(ast: HtmlCommentAst, context: any): any { return null; }
visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
@@ -881,8 +850,9 @@ class NonBindableVisitor implements HtmlAstVisitor {
}
class BoundElementOrDirectiveProperty {
constructor(public name: string, public expression: AST, public isLiteral: boolean,
public sourceSpan: ParseSourceSpan) {}
constructor(
public name: string, public expression: AST, public isLiteral: boolean,
public sourceSpan: ParseSourceSpan) {}
}
class ElementOrDirectiveRef {
@@ -894,8 +864,9 @@ export function splitClasses(classAttrValue: string): string[] {
}
class ElementContext {
static create(isTemplateElement: boolean, directives: DirectiveAst[],
providerContext: ProviderElementContext): ElementContext {
static create(
isTemplateElement: boolean, directives: DirectiveAst[],
providerContext: ProviderElementContext): ElementContext {
var matcher = new SelectorMatcher();
var wildcardNgContentIndex: any /** TODO #???? */ = null;
var component = directives.find(directive => directive.directive.isComponent);
@@ -912,9 +883,9 @@ class ElementContext {
}
return new ElementContext(isTemplateElement, matcher, wildcardNgContentIndex, providerContext);
}
constructor(public isTemplateElement: boolean, private _ngContentIndexMatcher: SelectorMatcher,
private _wildcardNgContentIndex: number,
public providerContext: ProviderElementContext) {}
constructor(
public isTemplateElement: boolean, private _ngContentIndexMatcher: SelectorMatcher,
private _wildcardNgContentIndex: number, public providerContext: ProviderElementContext) {}
findNgContentIndex(selector: CssSelector): number {
var ngContentIndices: any[] /** TODO #???? */ = [];
@@ -966,8 +937,9 @@ function removeDuplicates(items: CompileMetadataWithType[]): CompileMetadataWith
let res: any[] /** TODO #???? */ = [];
items.forEach(item => {
let hasMatch =
res.filter(r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
r.type.runtime == item.type.runtime)
res.filter(
r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
r.type.runtime == item.type.runtime)
.length > 0;
if (!hasMatch) {
res.push(item);
@@ -60,8 +60,9 @@ export enum PreparsedElementType {
}
export class PreparsedElement {
constructor(public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
public nonBindable: boolean, public projectAs: string) {}
constructor(
public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
public nonBindable: boolean, public projectAs: string) {}
}
+32 -35
View File
@@ -1,10 +1,6 @@
import {Injectable, Inject, PACKAGE_ROOT_URL} from '@angular/core';
import {
StringWrapper,
isPresent,
isBlank,
RegExpWrapper,
} from '../src/facade/lang';
import {Inject, Injectable, PACKAGE_ROOT_URL} from '@angular/core';
import {StringWrapper, isPresent, isBlank, RegExpWrapper,} from '../src/facade/lang';
const _ASSET_SCHEME = 'asset:';
@@ -25,7 +21,7 @@ export function createOfflineCompileUrlResolver(): UrlResolver {
*/
export var DEFAULT_PACKAGE_URL_PROVIDER = {
provide: PACKAGE_ROOT_URL,
useValue: "/"
useValue: '/'
};
/**
@@ -59,7 +55,7 @@ export class UrlResolver {
var resolvedParts = _split(resolvedUrl);
var prefix = this._packagePrefix;
if (isPresent(prefix) && isPresent(resolvedParts) &&
resolvedParts[_ComponentIndex.Scheme] == "package") {
resolvedParts[_ComponentIndex.Scheme] == 'package') {
var path = resolvedParts[_ComponentIndex.Path];
if (this._packagePrefix === _ASSET_SCHEME) {
var pathSegements = path.split(/\//);
@@ -79,7 +75,7 @@ export class UrlResolver {
*/
export function getUrlScheme(url: string): string {
var match = _split(url);
return (match && match[_ComponentIndex.Scheme]) || "";
return (match && match[_ComponentIndex.Scheme]) || '';
}
// The code below is adapted from Traceur:
@@ -102,9 +98,9 @@ export function getUrlScheme(url: string): string {
* @param opt_fragment The URI-encoded fragment identifier.
* @return The fully combined URI.
*/
function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_domain?: string,
opt_port?: string, opt_path?: string, opt_queryData?: string,
opt_fragment?: string): string {
function _buildFromEncodedParts(
opt_scheme?: string, opt_userInfo?: string, opt_domain?: string, opt_port?: string,
opt_path?: string, opt_queryData?: string, opt_fragment?: string): string {
var out: any[] /** TODO #9100 */ = [];
if (isPresent(opt_scheme)) {
@@ -202,24 +198,24 @@ function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_
* @type {!RegExp}
* @internal
*/
var _splitRe =
RegExpWrapper.create('^' +
'(?:' +
'([^:/?#.]+)' + // scheme - ignore special characters
// used by other URL parts such as :,
// ?, /, #, and .
':)?' +
'(?://' +
'(?:([^/?#]*)@)?' + // userInfo
'([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
// digits, dashes, dots, percent
// escapes, and unicode characters.
'(?::([0-9]+))?' + // port
')?' +
'([^?#]+)?' + // path
'(?:\\?([^#]*))?' + // query
'(?:#(.*))?' + // fragment
'$');
var _splitRe = RegExpWrapper.create(
'^' +
'(?:' +
'([^:/?#.]+)' + // scheme - ignore special characters
// used by other URL parts such as :,
// ?, /, #, and .
':)?' +
'(?://' +
'(?:([^/?#]*)@)?' + // userInfo
'([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
// digits, dashes, dots, percent
// escapes, and unicode characters.
'(?::([0-9]+))?' + // port
')?' +
'([^?#]+)?' + // path
'(?:\\?([^#]*))?' + // query
'(?:#(.*))?' + // fragment
'$');
/**
* The index of each URI component in the return value of goog.uri.utils.split.
@@ -250,7 +246,7 @@ enum _ComponentIndex {
* on the browser's regular expression implementation. Never null, since
* arbitrary strings may still look like path names.
*/
function _split(uri: string): Array<string | any> {
function _split(uri: string): Array<string|any> {
return RegExpWrapper.firstMatch(_splitRe, uri);
}
@@ -308,9 +304,10 @@ function _joinAndCanonicalizePath(parts: any[]): string {
path = isBlank(path) ? '' : _removeDotSegments(path);
parts[_ComponentIndex.Path] = path;
return _buildFromEncodedParts(parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo],
parts[_ComponentIndex.Domain], parts[_ComponentIndex.Port], path,
parts[_ComponentIndex.QueryData], parts[_ComponentIndex.Fragment]);
return _buildFromEncodedParts(
parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], parts[_ComponentIndex.Domain],
parts[_ComponentIndex.Port], path, parts[_ComponentIndex.QueryData],
parts[_ComponentIndex.Fragment]);
}
/**
+8 -15
View File
@@ -1,13 +1,5 @@
import {
IS_DART,
StringWrapper,
Math,
isBlank,
isArray,
isStrictStringMap,
isPrimitive
} from './facade/lang';
import {StringMapWrapper} from './facade/collection';
import {IS_DART, Math, StringWrapper, isArray, isBlank, isPrimitive, isStrictStringMap} from './facade/lang';
export var MODULE_SUFFIX = IS_DART ? '.dart' : '';
@@ -15,13 +7,13 @@ var CAMEL_CASE_REGEXP = /([A-Z])/g;
var DASH_CASE_REGEXP = /-([a-z])/g;
export function camelCaseToDashCase(input: string): string {
return StringWrapper.replaceAllMapped(input, CAMEL_CASE_REGEXP,
(m: any /** TODO #9100 */) => { return '-' + m[1].toLowerCase(); });
return StringWrapper.replaceAllMapped(
input, CAMEL_CASE_REGEXP, (m: any /** TODO #9100 */) => { return '-' + m[1].toLowerCase(); });
}
export function dashCaseToCamelCase(input: string): string {
return StringWrapper.replaceAllMapped(input, DASH_CASE_REGEXP,
(m: any /** TODO #9100 */) => { return m[1].toUpperCase(); });
return StringWrapper.replaceAllMapped(
input, DASH_CASE_REGEXP, (m: any /** TODO #9100 */) => { return m[1].toUpperCase(); });
}
export function splitAtColon(input: string, defaultValues: string[]): string[] {
@@ -62,8 +54,9 @@ export class ValueTransformer implements ValueVisitor {
}
visitStringMap(map: {[key: string]: any}, context: any): any {
var result = {};
StringMapWrapper.forEach(map,
(value: any /** TODO #9100 */, key: any /** TODO #9100 */) => { (result as any /** TODO #9100 */)[key] = visitValue(value, this, context); });
StringMapWrapper.forEach(map, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
(result as any /** TODO #9100 */)[key] = visitValue(value, this, context);
});
return result;
}
visitPrimitive(value: any, context: any): any { return value; }
@@ -1,6 +1,7 @@
import {CompileNode} from './compile_element';
import {TemplateAst} from '../template_ast';
import {CompileNode} from './compile_element';
export class CompileBinding {
constructor(public node: CompileNode, public sourceAst: TemplateAst) {}
}
@@ -1,29 +1,24 @@
import {BaseException} from '@angular/core';
import {isPresent, isBlank} from '../facade/lang';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import * as o from '../output/output_ast';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, identifierToken} from '../identifiers';
import {InjectMethodVars} from './constants';
import * as o from '../output/output_ast';
import {ProviderAst, ProviderAstType, ReferenceAst, TemplateAst} from '../template_ast';
import {CompileView} from './compile_view';
import {TemplateAst, ProviderAst, ProviderAstType, ReferenceAst} from '../template_ast';
import {
CompileTokenMap,
CompileDirectiveMetadata,
CompileTokenMetadata,
CompileQueryMetadata,
CompileProviderMetadata,
CompileDiDependencyMetadata,
CompileIdentifierMetadata,
} from '../compile_metadata';
import {InjectMethodVars} from './constants';
import {CompileTokenMap, CompileDirectiveMetadata, CompileTokenMetadata, CompileQueryMetadata, CompileProviderMetadata, CompileDiDependencyMetadata, CompileIdentifierMetadata,} from '../compile_metadata';
import {getPropertyInView, createDiTokenExpression, injectFromViewParentInjector} from './util';
import {CompileQuery, createQueryList, addQueryToTokenMap} from './compile_query';
import {CompileMethod} from './compile_method';
import {ValueTransformer, visitValue} from '../util';
export class CompileNode {
constructor(public parent: CompileElement, public view: CompileView, public nodeIndex: number,
public renderNode: o.Expression, public sourceAst: TemplateAst) {}
constructor(
public parent: CompileElement, public view: CompileView, public nodeIndex: number,
public renderNode: o.Expression, public sourceAst: TemplateAst) {}
isNull(): boolean { return isBlank(this.renderNode); }
@@ -51,12 +46,12 @@ export class CompileElement extends CompileNode {
public directiveInstances: o.Expression[];
public referenceTokens: {[key: string]: CompileTokenMetadata};
constructor(parent: CompileElement, view: CompileView, nodeIndex: number,
renderNode: o.Expression, sourceAst: TemplateAst,
public component: CompileDirectiveMetadata,
private _directives: CompileDirectiveMetadata[],
private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean,
public hasEmbeddedView: boolean, references: ReferenceAst[]) {
constructor(
parent: CompileElement, view: CompileView, nodeIndex: number, renderNode: o.Expression,
sourceAst: TemplateAst, public component: CompileDirectiveMetadata,
private _directives: CompileDirectiveMetadata[],
private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean,
public hasEmbeddedView: boolean, references: ReferenceAst[]) {
super(parent, view, nodeIndex, renderNode, sourceAst);
this.referenceTokens = {};
references.forEach(ref => this.referenceTokens[ref.name] = ref.value);
@@ -75,17 +70,14 @@ export class CompileElement extends CompileNode {
var fieldName = `_appEl_${this.nodeIndex}`;
var parentNodeIndex = this.isRootElement() ? null : this.parent.nodeIndex;
// private is fine here as no child view will reference an AppElement
this.view.fields.push(new o.ClassField(fieldName, o.importType(Identifiers.AppElement),
[o.StmtModifier.Private]));
var statement = o.THIS_EXPR.prop(fieldName)
.set(o.importExpr(Identifiers.AppElement)
.instantiate([
o.literal(this.nodeIndex),
o.literal(parentNodeIndex),
o.THIS_EXPR,
this.renderNode
]))
.toStmt();
this.view.fields.push(new o.ClassField(
fieldName, o.importType(Identifiers.AppElement), [o.StmtModifier.Private]));
var statement =
o.THIS_EXPR.prop(fieldName)
.set(o.importExpr(Identifiers.AppElement).instantiate([
o.literal(this.nodeIndex), o.literal(parentNodeIndex), o.THIS_EXPR, this.renderNode
]))
.toStmt();
this.view.createMethod.addStmt(statement);
this.appElement = o.THIS_EXPR.prop(fieldName);
this._instances.add(identifierToken(Identifiers.AppElement), this.appElement);
@@ -103,27 +95,27 @@ export class CompileElement extends CompileNode {
setEmbeddedView(embeddedView: CompileView) {
this.embeddedView = embeddedView;
if (isPresent(embeddedView)) {
var createTemplateRefExpr =
o.importExpr(Identifiers.TemplateRef_)
.instantiate([this.appElement, this.embeddedView.viewFactory]);
var createTemplateRefExpr = o.importExpr(Identifiers.TemplateRef_).instantiate([
this.appElement, this.embeddedView.viewFactory
]);
var provider = new CompileProviderMetadata(
{token: identifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
// Add TemplateRef as first provider as it does not have deps on other providers
this._resolvedProvidersArray.unshift(new ProviderAst(provider.token, false, true, [provider],
ProviderAstType.Builtin,
this.sourceAst.sourceSpan));
this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.Builtin,
this.sourceAst.sourceSpan));
}
}
beforeChildren(): void {
if (this.hasViewContainer) {
this._instances.add(identifierToken(Identifiers.ViewContainerRef),
this.appElement.prop('vcRef'));
this._instances.add(
identifierToken(Identifiers.ViewContainerRef), this.appElement.prop('vcRef'));
}
this._resolvedProviders = new CompileTokenMap<ProviderAst>();
this._resolvedProvidersArray.forEach(provider =>
this._resolvedProviders.add(provider.token, provider));
this._resolvedProvidersArray.forEach(
provider => this._resolvedProviders.add(provider.token, provider));
// create all the provider instances, some in the view constructor,
// some as getters. We rely on the fact that they are already sorted topologically.
@@ -147,9 +139,9 @@ export class CompileElement extends CompileNode {
}
});
var propName = `_${resolvedProvider.token.name}_${this.nodeIndex}_${this._instances.size}`;
var instance =
createProviderProperty(propName, resolvedProvider, providerValueExpressions,
resolvedProvider.multiProvider, resolvedProvider.eager, this);
var instance = createProviderProperty(
propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider,
resolvedProvider.eager, this);
this._instances.add(resolvedProvider.token, instance);
});
@@ -167,19 +159,21 @@ export class CompileElement extends CompileNode {
queriesWithReads,
queriesForProvider.map(query => new _QueryWithRead(query, resolvedProvider.token)));
});
StringMapWrapper.forEach(this.referenceTokens, (_: any /** TODO #9100 */, varName: any /** TODO #9100 */) => {
var token = this.referenceTokens[varName];
var varValue: any /** TODO #9100 */;
if (isPresent(token)) {
varValue = this._instances.get(token);
} else {
varValue = this.renderNode;
}
this.view.locals.set(varName, varValue);
var varToken = new CompileTokenMetadata({value: varName});
ListWrapper.addAll(queriesWithReads, this._getQueriesFor(varToken)
.map(query => new _QueryWithRead(query, varToken)));
});
StringMapWrapper.forEach(
this.referenceTokens, (_: any /** TODO #9100 */, varName: any /** TODO #9100 */) => {
var token = this.referenceTokens[varName];
var varValue: any /** TODO #9100 */;
if (isPresent(token)) {
varValue = this._instances.get(token);
} else {
varValue = this.renderNode;
}
this.view.locals.set(varName, varValue);
var varToken = new CompileTokenMetadata({value: varName});
ListWrapper.addAll(
queriesWithReads,
this._getQueriesFor(varToken).map(query => new _QueryWithRead(query, varToken)));
});
queriesWithReads.forEach((queryWithRead) => {
var value: o.Expression;
if (isPresent(queryWithRead.read.identifier)) {
@@ -200,14 +194,15 @@ export class CompileElement extends CompileNode {
});
if (isPresent(this.component)) {
var componentConstructorViewQueryList =
isPresent(this.component) ? o.literalArr(this._componentConstructorViewQueryLists) :
o.NULL_EXPR;
var componentConstructorViewQueryList = isPresent(this.component) ?
o.literalArr(this._componentConstructorViewQueryLists) :
o.NULL_EXPR;
var compExpr = isPresent(this.getComponent()) ? this.getComponent() : o.NULL_EXPR;
this.view.createMethod.addStmt(
this.appElement.callMethod(
'initComponent',
[compExpr, componentConstructorViewQueryList, this._compViewExpr])
this.appElement
.callMethod(
'initComponent',
[compExpr, componentConstructorViewQueryList, this._compViewExpr])
.toStmt());
}
}
@@ -229,9 +224,9 @@ export class CompileElement extends CompileNode {
});
this._queries.values().forEach(
(queries) =>
queries.forEach((query) => query.afterChildren(this.view.createMethod,
this.view.updateContentQueriesMethod)));
(queries) => queries.forEach(
(query) =>
query.afterChildren(this.view.createMethod, this.view.updateContentQueriesMethod)));
}
addContentNode(ngContentIndex: number, nodeExpr: o.Expression) {
@@ -256,8 +251,8 @@ export class CompileElement extends CompileNode {
while (!currentEl.isNull()) {
queries = currentEl._queries.get(token);
if (isPresent(queries)) {
ListWrapper.addAll(result,
queries.filter((query) => query.meta.descendants || distance <= 1));
ListWrapper.addAll(
result, queries.filter((query) => query.meta.descendants || distance <= 1));
}
if (currentEl._directives.length > 0) {
distance++;
@@ -271,8 +266,8 @@ export class CompileElement extends CompileNode {
return result;
}
private _addQuery(queryMeta: CompileQueryMetadata,
directiveInstance: o.Expression): CompileQuery {
private _addQuery(queryMeta: CompileQueryMetadata, directiveInstance: o.Expression):
CompileQuery {
var propName = `_query_${queryMeta.selectors[0].name}_${this.nodeIndex}_${this._queryCount++}`;
var queryList = createQueryList(queryMeta, directiveInstance, propName, this.view);
var query = new CompileQuery(queryMeta, queryList, directiveInstance, this.view);
@@ -280,8 +275,8 @@ export class CompileElement extends CompileNode {
return query;
}
private _getLocalDependency(requestingProviderType: ProviderAstType,
dep: CompileDiDependencyMetadata): o.Expression {
private _getLocalDependency(
requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata): o.Expression {
var result: any /** TODO #9100 */ = null;
// constructor content query
if (isBlank(result) && isPresent(dep.query)) {
@@ -316,8 +311,8 @@ export class CompileElement extends CompileNode {
return result;
}
private _getDependency(requestingProviderType: ProviderAstType,
dep: CompileDiDependencyMetadata): o.Expression {
private _getDependency(requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata):
o.Expression {
var currElement: CompileElement = this;
var result: any /** TODO #9100 */ = null;
if (dep.isValue) {
@@ -329,8 +324,8 @@ export class CompileElement extends CompileNode {
// check parent elements
while (isBlank(result) && !currElement.parent.isNull()) {
currElement = currElement.parent;
result = currElement._getLocalDependency(ProviderAstType.PublicService,
new CompileDiDependencyMetadata({token: dep.token}));
result = currElement._getLocalDependency(
ProviderAstType.PublicService, new CompileDiDependencyMetadata({token: dep.token}));
}
if (isBlank(result)) {
@@ -343,9 +338,9 @@ export class CompileElement extends CompileNode {
}
}
function createInjectInternalCondition(nodeIndex: number, childNodeCount: number,
provider: ProviderAst,
providerExpr: o.Expression): o.Statement {
function createInjectInternalCondition(
nodeIndex: number, childNodeCount: number, provider: ProviderAst,
providerExpr: o.Expression): o.Statement {
var indexCondition: any /** TODO #9100 */;
if (childNodeCount > 0) {
indexCondition = o.literal(nodeIndex)
@@ -360,9 +355,9 @@ function createInjectInternalCondition(nodeIndex: number, childNodeCount: number
[new o.ReturnStatement(providerExpr)]);
}
function createProviderProperty(propName: string, provider: ProviderAst,
providerValueExpressions: o.Expression[], isMulti: boolean,
isEager: boolean, compileElement: CompileElement): o.Expression {
function createProviderProperty(
propName: string, provider: ProviderAst, providerValueExpressions: o.Expression[],
isMulti: boolean, isEager: boolean, compileElement: CompileElement): o.Expression {
var view = compileElement.view;
var resolvedProviderValueExpr: any /** TODO #9100 */;
var type: any /** TODO #9100 */;
@@ -385,9 +380,9 @@ function createProviderProperty(propName: string, provider: ProviderAst,
var getter = new CompileMethod(view);
getter.resetDebugInfo(compileElement.nodeIndex, compileElement.sourceAst);
// Note: Equals is important for JS so that it also checks the undefined case!
getter.addStmt(
new o.IfStmt(o.THIS_EXPR.prop(internalField).isBlank(),
[o.THIS_EXPR.prop(internalField).set(resolvedProviderValueExpr).toStmt()]));
getter.addStmt(new o.IfStmt(
o.THIS_EXPR.prop(internalField).isBlank(),
[o.THIS_EXPR.prop(internalField).set(resolvedProviderValueExpr).toStmt()]));
getter.addStmt(new o.ReturnStatement(o.THIS_EXPR.prop(internalField)));
view.getters.push(new o.ClassGetter(propName, getter.finish(), type));
}
@@ -411,8 +406,9 @@ class _ValueOutputAstTransformer extends ValueTransformer {
}
visitStringMap(map: {[key: string]: any}, context: any): o.Expression {
var entries: any[] /** TODO #9100 */ = [];
StringMapWrapper.forEach(
map, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => { entries.push([key, visitValue(value, this, context)]); });
StringMapWrapper.forEach(map, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
entries.push([key, visitValue(value, this, context)]);
});
return o.literalMap(entries);
}
visitPrimitive(value: any, context: any): o.Expression { return o.literal(value); }
@@ -1,6 +1,5 @@
import {isPresent} from '../facade/lang';
import {ListWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import * as o from '../output/output_ast';
import {TemplateAst} from '../template_ast';
@@ -1,10 +1,11 @@
import {isBlank, isPresent} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import * as o from '../output/output_ast';
import {CompileView} from './compile_view';
import {CompilePipeMetadata} from '../compile_metadata';
import {BaseException} from '../facade/exceptions';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, identifierToken} from '../identifiers';
import {injectFromViewParentInjector, createPureProxy, getPropertyInView} from './util';
import * as o from '../output/output_ast';
import {CompileView} from './compile_view';
import {createPureProxy, getPropertyInView, injectFromViewParentInjector} from './util';
class _PurePipeProxy {
constructor(public view: CompileView, public instance: o.ReadPropExpr, public argCount: number) {}
@@ -55,9 +56,10 @@ export class CompilePipe {
this._purePipeProxies.forEach((purePipeProxy) => {
var pipeInstanceSeenFromPureProxy =
getPropertyInView(this.instance, purePipeProxy.view, this.view);
createPureProxy(pipeInstanceSeenFromPureProxy.prop('transform')
.callMethod(o.BuiltinMethod.bind, [pipeInstanceSeenFromPureProxy]),
purePipeProxy.argCount, purePipeProxy.instance, purePipeProxy.view);
createPureProxy(
pipeInstanceSeenFromPureProxy.prop('transform')
.callMethod(o.BuiltinMethod.bind, [pipeInstanceSeenFromPureProxy]),
purePipeProxy.argCount, purePipeProxy.instance, purePipeProxy.view);
});
}
@@ -1,25 +1,24 @@
import {isPresent, isBlank} from '../facade/lang';
import {ListWrapper} from '../facade/collection';
import * as o from '../output/output_ast';
import {Identifiers} from '../identifiers';
import {CompileQueryMetadata, CompileTokenMap} from '../compile_metadata';
import {ListWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers} from '../identifiers';
import * as o from '../output/output_ast';
import {CompileView} from './compile_view';
import {CompileElement} from './compile_element';
import {CompileMethod} from './compile_method';
import {CompileView} from './compile_view';
import {getPropertyInView} from './util';
class ViewQueryValues {
constructor(public view: CompileView, public values: Array<o.Expression | ViewQueryValues>) {}
constructor(public view: CompileView, public values: Array<o.Expression|ViewQueryValues>) {}
}
export class CompileQuery {
private _values: ViewQueryValues;
constructor(public meta: CompileQueryMetadata, public queryList: o.Expression,
public ownerDirectiveExpression: o.Expression, public view: CompileView) {
constructor(
public meta: CompileQueryMetadata, public queryList: o.Expression,
public ownerDirectiveExpression: o.Expression, public view: CompileView) {
this._values = new ViewQueryValues(view, []);
}
@@ -83,28 +82,30 @@ export class CompileQuery {
function createQueryValues(viewValues: ViewQueryValues): o.Expression[] {
return ListWrapper.flatten(viewValues.values.map((entry) => {
if (entry instanceof ViewQueryValues) {
return mapNestedViews(entry.view.declarationElement.appElement, entry.view,
createQueryValues(entry));
return mapNestedViews(
entry.view.declarationElement.appElement, entry.view, createQueryValues(entry));
} else {
return <o.Expression>entry;
}
}));
}
function mapNestedViews(declarationAppElement: o.Expression, view: CompileView,
expressions: o.Expression[]): o.Expression {
function mapNestedViews(
declarationAppElement: o.Expression, view: CompileView,
expressions: o.Expression[]): o.Expression {
var adjustedExpressions: o.Expression[] = expressions.map((expr) => {
return o.replaceVarInExpression(o.THIS_EXPR.name, o.variable('nestedView'), expr);
});
return declarationAppElement.callMethod('mapNestedViews', [
o.variable(view.className),
o.fn([new o.FnParam('nestedView', view.classType)],
[new o.ReturnStatement(o.literalArr(adjustedExpressions))])
o.variable(view.className), o.fn(
[new o.FnParam('nestedView', view.classType)],
[new o.ReturnStatement(o.literalArr(adjustedExpressions))])
]);
}
export function createQueryList(query: CompileQueryMetadata, directiveInstance: o.Expression,
propertyName: string, compileView: CompileView): o.Expression {
export function createQueryList(
query: CompileQueryMetadata, directiveInstance: o.Expression, propertyName: string,
compileView: CompileView): o.Expression {
compileView.fields.push(new o.ClassField(propertyName, o.importType(Identifiers.QueryList)));
var expr = o.THIS_EXPR.prop(propertyName);
compileView.createMethod.addStmt(o.THIS_EXPR.prop(propertyName)
@@ -1,33 +1,20 @@
import {ViewType} from '../../core_private';
import {isPresent, isBlank} from '../facade/lang';
import {CompiledAnimation} from '../animation/animation_compiler';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata, CompileTokenMap} from '../compile_metadata';
import {CompilerConfig} from '../config';
import {ListWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers} from '../identifiers';
import * as o from '../output/output_ast';
import {EventHandlerVars} from './constants';
import {CompileQuery, createQueryList, addQueryToTokenMap} from './compile_query';
import {NameResolver} from './expression_converter';
import {CompileBinding} from './compile_binding';
import {CompileElement, CompileNode} from './compile_element';
import {CompileMethod} from './compile_method';
import {CompilePipe} from './compile_pipe';
import {
CompileDirectiveMetadata,
CompilePipeMetadata,
CompileIdentifierMetadata,
CompileTokenMap
} from '../compile_metadata';
import {
getViewFactoryName,
injectFromViewParentInjector,
createDiTokenExpression,
getPropertyInView,
createPureProxy
} from './util';
import {CompilerConfig} from '../config';
import {CompileBinding} from './compile_binding';
import {Identifiers} from '../identifiers';
import {CompiledAnimation} from '../animation/animation_compiler';
import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query';
import {EventHandlerVars} from './constants';
import {NameResolver} from './expression_converter';
import {createDiTokenExpression, createPureProxy, getPropertyInView, getViewFactoryName, injectFromViewParentInjector} from './util';
export class CompileView implements NameResolver {
public viewType: ViewType;
@@ -73,12 +60,11 @@ export class CompileView implements NameResolver {
public componentContext: o.Expression;
constructor(public component: CompileDirectiveMetadata, public genConfig: CompilerConfig,
public pipeMetas: CompilePipeMetadata[],
public styles: o.Expression,
animations: CompiledAnimation[],
public viewIndex: number, public declarationElement: CompileElement,
public templateVariableBindings: string[][]) {
constructor(
public component: CompileDirectiveMetadata, public genConfig: CompilerConfig,
public pipeMetas: CompilePipeMetadata[], public styles: o.Expression,
animations: CompiledAnimation[], public viewIndex: number,
public declarationElement: CompileElement, public templateVariableBindings: string[][]) {
animations.forEach(entry => this.animations.set(entry.name, entry));
this.createMethod = new CompileMethod(this);
this.injectorGetMethod = new CompileMethod(this);
@@ -167,19 +153,21 @@ export class CompileView implements NameResolver {
proxyParams.push(new o.FnParam(paramName));
proxyReturnEntries.push(o.variable(paramName));
}
createPureProxy(o.fn(proxyParams, [new o.ReturnStatement(o.literalArr(proxyReturnEntries))],
new o.ArrayType(o.DYNAMIC_TYPE)),
values.length, proxyExpr, this);
createPureProxy(
o.fn(
proxyParams, [new o.ReturnStatement(o.literalArr(proxyReturnEntries))],
new o.ArrayType(o.DYNAMIC_TYPE)),
values.length, proxyExpr, this);
return proxyExpr.callFn(values);
}
createLiteralMap(entries: Array<Array<string | o.Expression>>): o.Expression {
createLiteralMap(entries: Array<Array<string|o.Expression>>): o.Expression {
if (entries.length === 0) {
return o.importExpr(Identifiers.EMPTY_MAP);
}
var proxyExpr = o.THIS_EXPR.prop(`_map_${this.literalMapCount++}`);
var proxyParams: o.FnParam[] = [];
var proxyReturnEntries: Array<Array<string | o.Expression>> = [];
var proxyReturnEntries: Array<Array<string|o.Expression>> = [];
var values: o.Expression[] = [];
for (var i = 0; i < entries.length; i++) {
var paramName = `p${i}`;
@@ -187,9 +175,11 @@ export class CompileView implements NameResolver {
proxyReturnEntries.push([entries[i][0], o.variable(paramName)]);
values.push(<o.Expression>entries[i][1]);
}
createPureProxy(o.fn(proxyParams, [new o.ReturnStatement(o.literalMap(proxyReturnEntries))],
new o.MapType(o.DYNAMIC_TYPE)),
entries.length, proxyExpr, this);
createPureProxy(
o.fn(
proxyParams, [new o.ReturnStatement(o.literalMap(proxyReturnEntries))],
new o.MapType(o.DYNAMIC_TYPE)),
entries.length, proxyExpr, this);
return proxyExpr.callFn(values);
}
@@ -1,10 +1,10 @@
import {ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
import {ChangeDetectorState, ViewType} from '../../core_private';
import {isBlank, resolveEnumToken} from '../facade/lang';
import {ChangeDetectorState, ViewType} from '../../core_private';
import {CompileIdentifierMetadata} from '../compile_metadata';
import * as o from '../output/output_ast';
import {isBlank, resolveEnumToken} from '../facade/lang';
import {Identifiers} from '../identifiers';
import * as o from '../output/output_ast';
function _enumExpression(classIdentifier: CompileIdentifierMetadata, value: any): o.Expression {
if (isBlank(value)) return o.NULL_EXPR;
@@ -1,17 +1,14 @@
import {isBlank, isPresent, StringWrapper} from '../facade/lang';
import {CompileDirectiveMetadata} from '../compile_metadata';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {EventHandlerVars, ViewProperties} from './constants';
import {StringWrapper, isBlank, isPresent} from '../facade/lang';
import * as o from '../output/output_ast';
import {BoundEventAst, DirectiveAst} from '../template_ast';
import {CompileBinding} from './compile_binding';
import {CompileElement} from './compile_element';
import {CompileMethod} from './compile_method';
import {BoundEventAst, DirectiveAst} from '../template_ast';
import {CompileDirectiveMetadata} from '../compile_metadata';
import {EventHandlerVars, ViewProperties} from './constants';
import {convertCdStatementToIr} from './expression_converter';
import {CompileBinding} from './compile_binding';
export class CompileEventListener {
private _method: CompileMethod;
@@ -20,30 +17,33 @@ export class CompileEventListener {
private _eventParam: o.FnParam;
private _actionResultExprs: o.Expression[] = [];
static getOrCreate(compileElement: CompileElement, eventTarget: string, eventName: string,
targetEventListeners: CompileEventListener[]): CompileEventListener {
var listener = targetEventListeners.find(listener => listener.eventTarget == eventTarget &&
listener.eventName == eventName);
static getOrCreate(
compileElement: CompileElement, eventTarget: string, eventName: string,
targetEventListeners: CompileEventListener[]): CompileEventListener {
var listener = targetEventListeners.find(
listener => listener.eventTarget == eventTarget && listener.eventName == eventName);
if (isBlank(listener)) {
listener = new CompileEventListener(compileElement, eventTarget, eventName,
targetEventListeners.length);
listener = new CompileEventListener(
compileElement, eventTarget, eventName, targetEventListeners.length);
targetEventListeners.push(listener);
}
return listener;
}
constructor(public compileElement: CompileElement, public eventTarget: string,
public eventName: string, listenerIndex: number) {
constructor(
public compileElement: CompileElement, public eventTarget: string, public eventName: string,
listenerIndex: number) {
this._method = new CompileMethod(compileElement.view);
this._methodName =
`_handle_${santitizeEventName(eventName)}_${compileElement.nodeIndex}_${listenerIndex}`;
this._eventParam =
new o.FnParam(EventHandlerVars.event.name,
o.importType(this.compileElement.view.genConfig.renderTypes.renderEvent));
this._eventParam = new o.FnParam(
EventHandlerVars.event.name,
o.importType(this.compileElement.view.genConfig.renderTypes.renderEvent));
}
addAction(hostEvent: BoundEventAst, directive: CompileDirectiveMetadata,
directiveInstance: o.Expression) {
addAction(
hostEvent: BoundEventAst, directive: CompileDirectiveMetadata,
directiveInstance: o.Expression) {
if (isPresent(directive) && directive.isComponent) {
this._hasComponentHostListener = true;
}
@@ -70,8 +70,8 @@ export class CompileEventListener {
finishMethod() {
var markPathToRootStart = this._hasComponentHostListener ?
this.compileElement.appElement.prop('componentView') :
o.THIS_EXPR;
this.compileElement.appElement.prop('componentView') :
o.THIS_EXPR;
var resultExpr: o.Expression = o.literal(true);
this._actionResultExprs.forEach((expr) => { resultExpr = resultExpr.and(expr); });
var stmts =
@@ -109,27 +109,29 @@ export class CompileEventListener {
'eventHandler',
[o.THIS_EXPR.prop(this._methodName).callMethod(o.BuiltinMethod.bind, [o.THIS_EXPR])]);
this.compileElement.view.createMethod.addStmt(
subscription.set(directiveInstance.prop(observablePropName)
.callMethod(o.BuiltinMethod.SubscribeObservable, [eventListener]))
subscription
.set(directiveInstance.prop(observablePropName)
.callMethod(o.BuiltinMethod.SubscribeObservable, [eventListener]))
.toDeclStmt(null, [o.StmtModifier.Final]));
}
}
export function collectEventListeners(hostEvents: BoundEventAst[], dirs: DirectiveAst[],
compileElement: CompileElement): CompileEventListener[] {
export function collectEventListeners(
hostEvents: BoundEventAst[], dirs: DirectiveAst[],
compileElement: CompileElement): CompileEventListener[] {
var eventListeners: CompileEventListener[] = [];
hostEvents.forEach((hostEvent) => {
compileElement.view.bindings.push(new CompileBinding(compileElement, hostEvent));
var listener = CompileEventListener.getOrCreate(compileElement, hostEvent.target,
hostEvent.name, eventListeners);
var listener = CompileEventListener.getOrCreate(
compileElement, hostEvent.target, hostEvent.name, eventListeners);
listener.addAction(hostEvent, null, null);
});
ListWrapper.forEachWithIndex(dirs, (directiveAst, i) => {
var directiveInstance = compileElement.directiveInstances[i];
directiveAst.hostEvents.forEach((hostEvent) => {
compileElement.view.bindings.push(new CompileBinding(compileElement, hostEvent));
var listener = CompileEventListener.getOrCreate(compileElement, hostEvent.target,
hostEvent.name, eventListeners);
var listener = CompileEventListener.getOrCreate(
compileElement, hostEvent.target, hostEvent.name, eventListeners);
listener.addAction(hostEvent, directiveAst.directive, directiveInstance);
});
});
@@ -137,13 +139,16 @@ export function collectEventListeners(hostEvents: BoundEventAst[], dirs: Directi
return eventListeners;
}
export function bindDirectiveOutputs(directiveAst: DirectiveAst, directiveInstance: o.Expression,
eventListeners: CompileEventListener[]) {
StringMapWrapper.forEach(directiveAst.directive.outputs, (eventName: any /** TODO #9100 */, observablePropName: any /** TODO #9100 */) => {
eventListeners.filter(listener => listener.eventName == eventName)
.forEach(
(listener) => { listener.listenToDirective(directiveInstance, observablePropName); });
});
export function bindDirectiveOutputs(
directiveAst: DirectiveAst, directiveInstance: o.Expression,
eventListeners: CompileEventListener[]) {
StringMapWrapper.forEach(
directiveAst.directive.outputs,
(eventName: any /** TODO #9100 */, observablePropName: any /** TODO #9100 */) => {
eventListeners.filter(listener => listener.eventName == eventName).forEach((listener) => {
listener.listenToDirective(directiveInstance, observablePropName);
});
});
}
export function bindRenderOutputs(eventListeners: CompileEventListener[]) {
@@ -1,9 +1,8 @@
import {BaseException} from '../facade/exceptions';
import {isBlank, isPresent, isArray} from '../facade/lang';
import * as cdAst from '../expression_parser/ast';
import * as o from '../output/output_ast';
import {BaseException} from '../facade/exceptions';
import {isArray, isBlank, isPresent} from '../facade/lang';
import {Identifiers} from '../identifiers';
import * as o from '../output/output_ast';
var IMPLICIT_RECEIVER = o.variable('#implicit');
@@ -11,7 +10,7 @@ export interface NameResolver {
callPipe(name: string, input: o.Expression, args: o.Expression[]): o.Expression;
getLocal(name: string): o.Expression;
createLiteralArray(values: o.Expression[]): o.Expression;
createLiteralMap(values: Array<Array<string | o.Expression>>): o.Expression;
createLiteralMap(values: Array<Array<string|o.Expression>>): o.Expression;
}
export class ExpressionWithWrappedValueInfo {
@@ -26,8 +25,8 @@ export function convertCdExpressionToIr(
return new ExpressionWithWrappedValueInfo(irAst, visitor.needsValueUnwrapper);
}
export function convertCdStatementToIr(nameResolver: NameResolver, implicitReceiver: o.Expression,
stmt: cdAst.AST): o.Statement[] {
export function convertCdStatementToIr(
nameResolver: NameResolver, implicitReceiver: o.Expression, stmt: cdAst.AST): o.Statement[] {
var visitor = new _AstToIrVisitor(nameResolver, implicitReceiver, null);
var statements: any[] /** TODO #9100 */ = [];
flattenStatements(stmt.visit(visitor, _Mode.Statement), statements);
@@ -51,7 +50,7 @@ function ensureExpressionMode(mode: _Mode, ast: cdAst.AST) {
}
}
function convertToStatementIfNeeded(mode: _Mode, expr: o.Expression): o.Expression | o.Statement {
function convertToStatementIfNeeded(mode: _Mode, expr: o.Expression): o.Expression|o.Statement {
if (mode === _Mode.Statement) {
return expr.toStmt();
} else {
@@ -62,8 +61,9 @@ function convertToStatementIfNeeded(mode: _Mode, expr: o.Expression): o.Expressi
class _AstToIrVisitor implements cdAst.AstVisitor {
public needsValueUnwrapper: boolean = false;
constructor(private _nameResolver: NameResolver, private _implicitReceiver: o.Expression,
private _valueUnwrapper: o.ReadVarExpr) {}
constructor(
private _nameResolver: NameResolver, private _implicitReceiver: o.Expression,
private _valueUnwrapper: o.ReadVarExpr) {}
visitBinary(ast: cdAst.Binary, mode: _Mode): any {
var op: any /** TODO #9100 */;
@@ -118,8 +118,9 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
}
return convertToStatementIfNeeded(
mode, new o.BinaryOperatorExpr(op, ast.left.visit(this, _Mode.Expression),
ast.right.visit(this, _Mode.Expression)));
mode,
new o.BinaryOperatorExpr(
op, ast.left.visit(this, _Mode.Expression), ast.right.visit(this, _Mode.Expression)));
}
visitChain(ast: cdAst.Chain, mode: _Mode): any {
ensureStatementMode(mode, ast);
@@ -128,8 +129,9 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
visitConditional(ast: cdAst.Conditional, mode: _Mode): any {
var value: o.Expression = ast.condition.visit(this, _Mode.Expression);
return convertToStatementIfNeeded(
mode, value.conditional(ast.trueExp.visit(this, _Mode.Expression),
ast.falseExp.visit(this, _Mode.Expression)));
mode,
value.conditional(
ast.trueExp.visit(this, _Mode.Expression), ast.falseExp.visit(this, _Mode.Expression)));
}
visitPipe(ast: cdAst.BindingPipe, mode: _Mode): any {
var input = ast.exp.visit(this, _Mode.Expression);
@@ -139,8 +141,9 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
return convertToStatementIfNeeded(mode, this._valueUnwrapper.callMethod('unwrap', [value]));
}
visitFunctionCall(ast: cdAst.FunctionCall, mode: _Mode): any {
return convertToStatementIfNeeded(mode, ast.target.visit(this, _Mode.Expression)
.callFn(this.visitAll(ast.args, _Mode.Expression)));
return convertToStatementIfNeeded(
mode,
ast.target.visit(this, _Mode.Expression).callFn(this.visitAll(ast.args, _Mode.Expression)));
}
visitImplicitReceiver(ast: cdAst.ImplicitReceiver, mode: _Mode): any {
ensureExpressionMode(mode, ast);
@@ -1,10 +1,11 @@
import {LifecycleHooks} from '../../core_private';
import * as o from '../output/output_ast';
import {DetectChangesVars, ChangeDetectorStateEnum} from './constants';
import {CompileDirectiveMetadata, CompilePipeMetadata} from '../compile_metadata';
import * as o from '../output/output_ast';
import {DirectiveAst} from '../template_ast';
import {CompileElement} from './compile_element';
import {CompileView} from './compile_view';
import {ChangeDetectorStateEnum, DetectChangesVars} from './constants';
@@ -23,9 +24,9 @@ export function bindDirectiveDetectChangesLifecycleCallbacks(
[directiveInstance.callMethod('ngOnChanges', [DetectChangesVars.changes]).toStmt()]));
}
if (lifecycleHooks.indexOf(LifecycleHooks.OnInit) !== -1) {
detectChangesInInputsMethod.addStmt(
new o.IfStmt(STATE_IS_NEVER_CHECKED.and(NOT_THROW_ON_CHANGES),
[directiveInstance.callMethod('ngOnInit', []).toStmt()]));
detectChangesInInputsMethod.addStmt(new o.IfStmt(
STATE_IS_NEVER_CHECKED.and(NOT_THROW_ON_CHANGES),
[directiveInstance.callMethod('ngOnInit', []).toStmt()]));
}
if (lifecycleHooks.indexOf(LifecycleHooks.DoCheck) !== -1) {
detectChangesInInputsMethod.addStmt(new o.IfStmt(
@@ -33,14 +34,14 @@ export function bindDirectiveDetectChangesLifecycleCallbacks(
}
}
export function bindDirectiveAfterContentLifecycleCallbacks(directiveMeta: CompileDirectiveMetadata,
directiveInstance: o.Expression,
compileElement: CompileElement) {
export function bindDirectiveAfterContentLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) {
var view = compileElement.view;
var lifecycleHooks = directiveMeta.lifecycleHooks;
var afterContentLifecycleCallbacksMethod = view.afterContentLifecycleCallbacksMethod;
afterContentLifecycleCallbacksMethod.resetDebugInfo(compileElement.nodeIndex,
compileElement.sourceAst);
afterContentLifecycleCallbacksMethod.resetDebugInfo(
compileElement.nodeIndex, compileElement.sourceAst);
if (lifecycleHooks.indexOf(LifecycleHooks.AfterContentInit) !== -1) {
afterContentLifecycleCallbacksMethod.addStmt(new o.IfStmt(
STATE_IS_NEVER_CHECKED, [directiveInstance.callMethod('ngAfterContentInit', []).toStmt()]));
@@ -51,14 +52,14 @@ export function bindDirectiveAfterContentLifecycleCallbacks(directiveMeta: Compi
}
}
export function bindDirectiveAfterViewLifecycleCallbacks(directiveMeta: CompileDirectiveMetadata,
directiveInstance: o.Expression,
compileElement: CompileElement) {
export function bindDirectiveAfterViewLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) {
var view = compileElement.view;
var lifecycleHooks = directiveMeta.lifecycleHooks;
var afterViewLifecycleCallbacksMethod = view.afterViewLifecycleCallbacksMethod;
afterViewLifecycleCallbacksMethod.resetDebugInfo(compileElement.nodeIndex,
compileElement.sourceAst);
afterViewLifecycleCallbacksMethod.resetDebugInfo(
compileElement.nodeIndex, compileElement.sourceAst);
if (lifecycleHooks.indexOf(LifecycleHooks.AfterViewInit) !== -1) {
afterViewLifecycleCallbacksMethod.addStmt(new o.IfStmt(
STATE_IS_NEVER_CHECKED, [directiveInstance.callMethod('ngAfterViewInit', []).toStmt()]));
@@ -69,9 +70,9 @@ export function bindDirectiveAfterViewLifecycleCallbacks(directiveMeta: CompileD
}
}
export function bindDirectiveDestroyLifecycleCallbacks(directiveMeta: CompileDirectiveMetadata,
directiveInstance: o.Expression,
compileElement: CompileElement) {
export function bindDirectiveDestroyLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) {
var onDestroyMethod = compileElement.view.destroyMethod;
onDestroyMethod.resetDebugInfo(compileElement.nodeIndex, compileElement.sourceAst);
if (directiveMeta.lifecycleHooks.indexOf(LifecycleHooks.OnDestroy) !== -1) {
@@ -79,8 +80,8 @@ export function bindDirectiveDestroyLifecycleCallbacks(directiveMeta: CompileDir
}
}
export function bindPipeDestroyLifecycleCallbacks(pipeMeta: CompilePipeMetadata,
pipeInstance: o.Expression, view: CompileView) {
export function bindPipeDestroyLifecycleCallbacks(
pipeMeta: CompilePipeMetadata, pipeInstance: o.Expression, view: CompileView) {
var onDestroyMethod = view.destroyMethod;
if (pipeMeta.lifecycleHooks.indexOf(LifecycleHooks.OnDestroy) !== -1) {
onDestroyMethod.addStmt(pipeInstance.callMethod('ngOnDestroy', []).toStmt());
@@ -1,18 +1,12 @@
import {EMPTY_STATE as EMPTY_ANIMATION_STATE, LifecycleHooks, isDefaultChangeDetectionStrategy, SecurityContext} from '../../core_private';
import {isBlank, isPresent} from '../facade/lang';
import {EMPTY_STATE as EMPTY_ANIMATION_STATE, LifecycleHooks, SecurityContext, isDefaultChangeDetectionStrategy} from '../../core_private';
import * as cdAst from '../expression_parser/ast';
import * as o from '../output/output_ast';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers} from '../identifiers';
import * as o from '../output/output_ast';
import {DetectChangesVars, ViewProperties} from './constants';
import {
BoundTextAst,
BoundElementPropertyAst,
DirectiveAst,
PropertyBindingType,
} from '../template_ast';
import {BoundTextAst, BoundElementPropertyAst, DirectiveAst, PropertyBindingType,} from '../template_ast';
import {CompileView} from './compile_view';
import {CompileElement, CompileNode} from './compile_element';
@@ -34,9 +28,10 @@ function createCurrValueExpr(exprIndex: number): o.ReadVarExpr {
return o.variable(`currVal_${exprIndex}`); // fix syntax highlighting: `
}
function bind(view: CompileView, currValExpr: o.ReadVarExpr, fieldExpr: o.ReadPropExpr,
parsedExpression: cdAst.AST, context: o.Expression, actions: o.Statement[],
method: CompileMethod) {
function bind(
view: CompileView, currValExpr: o.ReadVarExpr, fieldExpr: o.ReadPropExpr,
parsedExpression: cdAst.AST, context: o.Expression, actions: o.Statement[],
method: CompileMethod) {
var checkExpression =
convertCdExpressionToIr(view, context, parsedExpression, DetectChangesVars.valUnwrapper);
if (isBlank(checkExpression.expression)) {
@@ -56,9 +51,9 @@ function bind(view: CompileView, currValExpr: o.ReadVarExpr, fieldExpr: o.ReadPr
method.addStmt(
currValExpr.set(checkExpression.expression).toDeclStmt(null, [o.StmtModifier.Final]));
var condition: o.Expression =
o.importExpr(Identifiers.checkBinding)
.callFn([DetectChangesVars.throwOnChange, fieldExpr, currValExpr]);
var condition: o.Expression = o.importExpr(Identifiers.checkBinding).callFn([
DetectChangesVars.throwOnChange, fieldExpr, currValExpr
]);
if (checkExpression.needsValueUnwrapper) {
condition = DetectChangesVars.valUnwrapper.prop('hasWrappedValue').or(condition);
}
@@ -67,25 +62,24 @@ function bind(view: CompileView, currValExpr: o.ReadVarExpr, fieldExpr: o.ReadPr
actions.concat([<o.Statement>o.THIS_EXPR.prop(fieldExpr.name).set(currValExpr).toStmt()])));
}
export function bindRenderText(boundText: BoundTextAst, compileNode: CompileNode,
view: CompileView) {
export function bindRenderText(
boundText: BoundTextAst, compileNode: CompileNode, view: CompileView) {
var bindingIndex = view.bindings.length;
view.bindings.push(new CompileBinding(compileNode, boundText));
var currValExpr = createCurrValueExpr(bindingIndex);
var valueField = createBindFieldExpr(bindingIndex);
view.detectChangesRenderPropertiesMethod.resetDebugInfo(compileNode.nodeIndex, boundText);
bind(view, currValExpr, valueField, boundText.value, view.componentContext,
[
o.THIS_EXPR.prop('renderer')
.callMethod('setText', [compileNode.renderNode, currValExpr])
.toStmt()
],
view.detectChangesRenderPropertiesMethod);
bind(
view, currValExpr, valueField, boundText.value, view.componentContext,
[o.THIS_EXPR.prop('renderer')
.callMethod('setText', [compileNode.renderNode, currValExpr])
.toStmt()],
view.detectChangesRenderPropertiesMethod);
}
function bindAndWriteToRenderer(boundProps: BoundElementPropertyAst[], context: o.Expression,
compileElement: CompileElement) {
function bindAndWriteToRenderer(
boundProps: BoundElementPropertyAst[], context: o.Expression, compileElement: CompileElement) {
var view = compileElement.view;
var renderNode = compileElement.renderNode;
boundProps.forEach((boundProp) => {
@@ -105,24 +99,24 @@ function bindAndWriteToRenderer(boundProps: BoundElementPropertyAst[], context:
}
updateStmts.push(
o.THIS_EXPR.prop('renderer')
.callMethod('setElementProperty', [renderNode, o.literal(boundProp.name), renderValue])
.toStmt()
);
.callMethod(
'setElementProperty', [renderNode, o.literal(boundProp.name), renderValue])
.toStmt());
break;
case PropertyBindingType.Attribute:
renderValue = renderValue.isBlank().conditional(o.NULL_EXPR, renderValue.callMethod('toString', []));
renderValue =
renderValue.isBlank().conditional(o.NULL_EXPR, renderValue.callMethod('toString', []));
updateStmts.push(
o.THIS_EXPR.prop('renderer')
.callMethod('setElementAttribute', [renderNode, o.literal(boundProp.name), renderValue])
.toStmt()
);
.callMethod(
'setElementAttribute', [renderNode, o.literal(boundProp.name), renderValue])
.toStmt());
break;
case PropertyBindingType.Class:
updateStmts.push(
o.THIS_EXPR.prop('renderer')
.callMethod('setElementClass', [renderNode, o.literal(boundProp.name), renderValue])
.toStmt()
);
.toStmt());
break;
case PropertyBindingType.Style:
var strValue: o.Expression = renderValue.callMethod('toString', []);
@@ -133,14 +127,14 @@ function bindAndWriteToRenderer(boundProps: BoundElementPropertyAst[], context:
updateStmts.push(
o.THIS_EXPR.prop('renderer')
.callMethod('setElementStyle', [renderNode, o.literal(boundProp.name), renderValue])
.toStmt()
);
.toStmt());
break;
case PropertyBindingType.Animation:
var animationName = boundProp.name;
var animation = view.componentView.animations.get(animationName);
if (!isPresent(animation)) {
throw new BaseException(`Internal Error: couldn't find an animation entry for ${boundProp.name}`);
throw new BaseException(
`Internal Error: couldn't find an animation entry for ${boundProp.name}`);
}
// it's important to normalize the void value as `void` explicitly
@@ -150,45 +144,36 @@ function bindAndWriteToRenderer(boundProps: BoundElementPropertyAst[], context:
// void => ...
var oldRenderVar = o.variable('oldRenderVar');
updateStmts.push(oldRenderVar.set(oldRenderValue).toDeclStmt());
updateStmts.push(
new o.IfStmt(oldRenderVar.equals(o.importExpr(Identifiers.uninitialized)), [
oldRenderVar.set(emptyStateValue).toStmt()
]));
updateStmts.push(new o.IfStmt(
oldRenderVar.equals(o.importExpr(Identifiers.uninitialized)),
[oldRenderVar.set(emptyStateValue).toStmt()]));
// ... => void
var newRenderVar = o.variable('newRenderVar');
updateStmts.push(newRenderVar.set(renderValue).toDeclStmt());
updateStmts.push(
new o.IfStmt(newRenderVar.equals(o.importExpr(Identifiers.uninitialized)), [
newRenderVar.set(emptyStateValue).toStmt()
]));
updateStmts.push(new o.IfStmt(
newRenderVar.equals(o.importExpr(Identifiers.uninitialized)),
[newRenderVar.set(emptyStateValue).toStmt()]));
updateStmts.push(
animation.fnVariable.callFn([
o.THIS_EXPR,
renderNode,
oldRenderVar,
newRenderVar
]).toStmt());
animation.fnVariable.callFn([o.THIS_EXPR, renderNode, oldRenderVar, newRenderVar])
.toStmt());
view.detachMethod.addStmt(
animation.fnVariable.callFn([
o.THIS_EXPR,
renderNode,
oldRenderValue,
emptyStateValue
]).toStmt());
animation.fnVariable.callFn([o.THIS_EXPR, renderNode, oldRenderValue, emptyStateValue])
.toStmt());
break;
}
bind(view, currValExpr, fieldExpr, boundProp.value, context, updateStmts,
view.detectChangesRenderPropertiesMethod);
bind(
view, currValExpr, fieldExpr, boundProp.value, context, updateStmts,
view.detectChangesRenderPropertiesMethod);
});
}
function sanitizedValue(boundProp: BoundElementPropertyAst,
renderValue: o.Expression): o.Expression {
function sanitizedValue(
boundProp: BoundElementPropertyAst, renderValue: o.Expression): o.Expression {
let enumValue: string;
switch (boundProp.securityContext) {
case SecurityContext.NONE:
@@ -216,18 +201,19 @@ function sanitizedValue(boundProp: BoundElementPropertyAst,
return ctx.callMethod('sanitize', args);
}
export function bindRenderInputs(boundProps: BoundElementPropertyAst[],
compileElement: CompileElement): void {
export function bindRenderInputs(
boundProps: BoundElementPropertyAst[], compileElement: CompileElement): void {
bindAndWriteToRenderer(boundProps, compileElement.view.componentContext, compileElement);
}
export function bindDirectiveHostProps(directiveAst: DirectiveAst, directiveInstance: o.Expression,
compileElement: CompileElement): void {
export function bindDirectiveHostProps(
directiveAst: DirectiveAst, directiveInstance: o.Expression,
compileElement: CompileElement): void {
bindAndWriteToRenderer(directiveAst.hostProperties, directiveInstance, compileElement);
}
export function bindDirectiveInputs(directiveAst: DirectiveAst, directiveInstance: o.Expression,
compileElement: CompileElement) {
export function bindDirectiveInputs(
directiveAst: DirectiveAst, directiveInstance: o.Expression, compileElement: CompileElement) {
if (directiveAst.inputs.length === 0) {
return;
}
@@ -238,7 +224,7 @@ export function bindDirectiveInputs(directiveAst: DirectiveAst, directiveInstanc
var lifecycleHooks = directiveAst.directive.lifecycleHooks;
var calcChangesMap = lifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1;
var isOnPushComp = directiveAst.directive.isComponent &&
!isDefaultChangeDetectionStrategy(directiveAst.directive.changeDetection);
!isDefaultChangeDetectionStrategy(directiveAst.directive.changeDetection);
if (calcChangesMap) {
detectChangesInInputsMethod.addStmt(DetectChangesVars.changes.set(o.NULL_EXPR).toStmt());
}
@@ -254,11 +240,11 @@ export function bindDirectiveInputs(directiveAst: DirectiveAst, directiveInstanc
var statements: o.Statement[] =
[directiveInstance.prop(input.directiveName).set(currValExpr).toStmt()];
if (calcChangesMap) {
statements.push(new o.IfStmt(DetectChangesVars.changes.identical(o.NULL_EXPR), [
DetectChangesVars.changes.set(o.literalMap([], new o.MapType(
o.importType(Identifiers.SimpleChange))))
.toStmt()
]));
statements.push(new o.IfStmt(
DetectChangesVars.changes.identical(o.NULL_EXPR),
[DetectChangesVars.changes
.set(o.literalMap([], new o.MapType(o.importType(Identifiers.SimpleChange))))
.toStmt()]));
statements.push(
DetectChangesVars.changes.key(o.literal(input.directiveName))
.set(o.importExpr(Identifiers.SimpleChange).instantiate([fieldExpr, currValExpr]))
@@ -271,26 +257,25 @@ export function bindDirectiveInputs(directiveAst: DirectiveAst, directiveInstanc
statements.push(
logBindingUpdateStmt(compileElement.renderNode, input.directiveName, currValExpr));
}
bind(view, currValExpr, fieldExpr, input.value, view.componentContext, statements,
detectChangesInInputsMethod);
bind(
view, currValExpr, fieldExpr, input.value, view.componentContext, statements,
detectChangesInInputsMethod);
});
if (isOnPushComp) {
detectChangesInInputsMethod.addStmt(new o.IfStmt(DetectChangesVars.changed, [
compileElement.appElement.prop('componentView')
.callMethod('markAsCheckOnce', [])
.toStmt()
compileElement.appElement.prop('componentView').callMethod('markAsCheckOnce', []).toStmt()
]));
}
}
function logBindingUpdateStmt(renderNode: o.Expression, propName: string,
value: o.Expression): o.Statement {
function logBindingUpdateStmt(
renderNode: o.Expression, propName: string, value: o.Expression): o.Statement {
return o.THIS_EXPR.prop('renderer')
.callMethod('setBindingDebugInfo',
[
renderNode,
o.literal(`ng-reflect-${camelCaseToDashCase(propName)}`),
value.isBlank().conditional(o.NULL_EXPR, value.callMethod('toString', []))
])
.callMethod(
'setBindingDebugInfo',
[
renderNode, o.literal(`ng-reflect-${camelCaseToDashCase(propName)}`),
value.isBlank().conditional(o.NULL_EXPR, value.callMethod('toString', []))
])
.toStmt();
}
@@ -1,16 +1,13 @@
import {isPresent, isBlank} from '../facade/lang';
import {BaseException} from '../facade/exceptions';
import {isBlank, isPresent} from '../facade/lang';
import * as o from '../output/output_ast';
import {
CompileTokenMetadata,
CompileDirectiveMetadata,
} from '../compile_metadata';
import {CompileTokenMetadata, CompileDirectiveMetadata,} from '../compile_metadata';
import {CompileView} from './compile_view';
import {Identifiers} from '../identifiers';
export function getPropertyInView(property: o.Expression, callingView: CompileView,
definedView: CompileView): o.Expression {
export function getPropertyInView(
property: o.Expression, callingView: CompileView, definedView: CompileView): o.Expression {
if (callingView === definedView) {
return property;
} else {
@@ -36,8 +33,8 @@ export function getPropertyInView(property: o.Expression, callingView: CompileVi
}
}
export function injectFromViewParentInjector(token: CompileTokenMetadata,
optional: boolean): o.Expression {
export function injectFromViewParentInjector(
token: CompileTokenMetadata, optional: boolean): o.Expression {
var args = [createDiTokenExpression(token)];
if (optional) {
args.push(o.NULL_EXPR);
@@ -45,8 +42,8 @@ export function injectFromViewParentInjector(token: CompileTokenMetadata,
return o.THIS_EXPR.prop('parentInjector').callMethod('get', args);
}
export function getViewFactoryName(component: CompileDirectiveMetadata,
embeddedTemplateIndex: number): string {
export function getViewFactoryName(
component: CompileDirectiveMetadata, embeddedTemplateIndex: number): string {
return `viewFactory_${component.type.name}${embeddedTemplateIndex}`;
}
@@ -85,8 +82,8 @@ export function createFlatArray(expressions: o.Expression[]): o.Expression {
return result;
}
export function createPureProxy(fn: o.Expression, argCount: number, pureProxyProp: o.ReadPropExpr,
view: CompileView) {
export function createPureProxy(
fn: o.Expression, argCount: number, pureProxyProp: o.ReadPropExpr, view: CompileView) {
view.fields.push(new o.ClassField(pureProxyProp.name, null));
var pureProxyId =
argCount < Identifiers.pureProxies.length ? Identifiers.pureProxies[argCount] : null;
@@ -1,37 +1,8 @@
import {
ListWrapper,
} from '../facade/collection';
import {
TemplateAst,
TemplateAstVisitor,
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
ReferenceAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
BoundTextAst,
TextAst,
DirectiveAst,
BoundDirectivePropertyAst,
templateVisitAll,
} from '../template_ast';
import {
bindRenderText,
bindRenderInputs,
bindDirectiveInputs,
bindDirectiveHostProps
} from './property_binder';
import {ListWrapper,} from '../facade/collection';
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, ReferenceAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll,} from '../template_ast';
import {bindRenderText, bindRenderInputs, bindDirectiveInputs, bindDirectiveHostProps} from './property_binder';
import {bindRenderOutputs, collectEventListeners, bindDirectiveOutputs} from './event_binder';
import {
bindDirectiveAfterContentLifecycleCallbacks,
bindDirectiveAfterViewLifecycleCallbacks,
bindDirectiveDestroyLifecycleCallbacks,
bindPipeDestroyLifecycleCallbacks,
bindDirectiveDetectChangesLifecycleCallbacks
} from './lifecycle_binder';
import {bindDirectiveAfterContentLifecycleCallbacks, bindDirectiveAfterViewLifecycleCallbacks, bindDirectiveDestroyLifecycleCallbacks, bindPipeDestroyLifecycleCallbacks, bindDirectiveDetectChangesLifecycleCallbacks} from './lifecycle_binder';
import {CompileView} from './compile_view';
import {CompileElement, CompileNode} from './compile_element';
@@ -77,12 +48,12 @@ class ViewBinderVisitor implements TemplateAstVisitor {
// so that children are notified before parents
ListWrapper.forEachWithIndex(ast.directives, (directiveAst, index) => {
var directiveInstance = compileElement.directiveInstances[index];
bindDirectiveAfterContentLifecycleCallbacks(directiveAst.directive, directiveInstance,
compileElement);
bindDirectiveAfterViewLifecycleCallbacks(directiveAst.directive, directiveInstance,
compileElement);
bindDirectiveDestroyLifecycleCallbacks(directiveAst.directive, directiveInstance,
compileElement);
bindDirectiveAfterContentLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
bindDirectiveAfterViewLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
bindDirectiveDestroyLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
});
return null;
}
@@ -95,12 +66,12 @@ class ViewBinderVisitor implements TemplateAstVisitor {
bindDirectiveInputs(directiveAst, directiveInstance, compileElement);
bindDirectiveDetectChangesLifecycleCallbacks(directiveAst, directiveInstance, compileElement);
bindDirectiveOutputs(directiveAst, directiveInstance, eventListeners);
bindDirectiveAfterContentLifecycleCallbacks(directiveAst.directive, directiveInstance,
compileElement);
bindDirectiveAfterViewLifecycleCallbacks(directiveAst.directive, directiveInstance,
compileElement);
bindDirectiveDestroyLifecycleCallbacks(directiveAst.directive, directiveInstance,
compileElement);
bindDirectiveAfterContentLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
bindDirectiveAfterViewLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
bindDirectiveDestroyLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
});
bindView(compileElement.embeddedView, ast.children);
return null;
@@ -1,49 +1,20 @@
import {ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
import {isDefaultChangeDetectionStrategy, ViewType} from '../../core_private';
import {isPresent, StringWrapper} from '../facade/lang';
import {ListWrapper, StringMapWrapper, SetWrapper} from '../facade/collection';
import * as o from '../output/output_ast';
import {ViewType, isDefaultChangeDetectionStrategy} from '../../core_private';
import {ListWrapper, SetWrapper, StringMapWrapper} from '../facade/collection';
import {StringWrapper, isPresent} from '../facade/lang';
import {Identifiers, identifierToken} from '../identifiers';
import {
ViewConstructorVars,
InjectMethodVars,
DetectChangesVars,
ViewTypeEnum,
ViewEncapsulationEnum,
ChangeDetectionStrategyEnum,
ViewProperties
} from './constants';
import * as o from '../output/output_ast';
import {CompileView} from './compile_view';
import {CompileElement, CompileNode} from './compile_element';
import {CompileView} from './compile_view';
import {ChangeDetectionStrategyEnum, DetectChangesVars, InjectMethodVars, ViewConstructorVars, ViewEncapsulationEnum, ViewProperties, ViewTypeEnum} from './constants';
import {
TemplateAst,
TemplateAstVisitor,
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
ReferenceAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
BoundTextAst,
TextAst,
DirectiveAst,
BoundDirectivePropertyAst,
templateVisitAll,
} from '../template_ast';
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, ReferenceAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll,} from '../template_ast';
import {getViewFactoryName, createFlatArray, createDiTokenExpression} from './util';
import {
CompileIdentifierMetadata,
CompileDirectiveMetadata,
CompileTokenMetadata
} from '../compile_metadata';
import {CompileIdentifierMetadata, CompileDirectiveMetadata, CompileTokenMetadata} from '../compile_metadata';
import {AnimationCompiler} from '../animation/animation_compiler';
@@ -55,16 +26,18 @@ var parentRenderNodeVar = o.variable('parentRenderNode');
var rootSelectorVar = o.variable('rootSelector');
export class ViewCompileDependency {
constructor(public comp: CompileDirectiveMetadata,
public factoryPlaceholder: CompileIdentifierMetadata) {}
constructor(
public comp: CompileDirectiveMetadata, public factoryPlaceholder: CompileIdentifierMetadata) {
}
}
export function buildView(view: CompileView, template: TemplateAst[],
targetDependencies: ViewCompileDependency[]): number {
export function buildView(
view: CompileView, template: TemplateAst[],
targetDependencies: ViewCompileDependency[]): number {
var builderVisitor = new ViewBuilderVisitor(view, targetDependencies);
templateVisitAll(builderVisitor, template, view.declarationElement.isNull() ?
view.declarationElement :
view.declarationElement.parent);
templateVisitAll(
builderVisitor, template,
view.declarationElement.isNull() ? view.declarationElement : view.declarationElement.parent);
return builderVisitor.nestedViewCount;
}
@@ -87,8 +60,8 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
private _isRootNode(parent: CompileElement): boolean { return parent.view !== this.view; }
private _addRootNodeAndProject(node: CompileNode, ngContentIndex: number,
parent: CompileElement) {
private _addRootNodeAndProject(
node: CompileNode, ngContentIndex: number, parent: CompileElement) {
var vcAppEl =
(node instanceof CompileElement && node.hasViewContainer) ? node.appElement : null;
if (this._isRootNode(parent)) {
@@ -111,9 +84,9 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
}
} else {
return isPresent(parent.component) &&
parent.component.template.encapsulation !== ViewEncapsulation.Native ?
o.NULL_EXPR :
parent.renderNode;
parent.component.template.encapsulation !== ViewEncapsulation.Native ?
o.NULL_EXPR :
parent.renderNode;
}
}
@@ -123,8 +96,9 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
visitText(ast: TextAst, parent: CompileElement): any {
return this._visitText(ast, ast.value, ast.ngContentIndex, parent);
}
private _visitText(ast: TemplateAst, value: string, ngContentIndex: number,
parent: CompileElement): o.Expression {
private _visitText(
ast: TemplateAst, value: string, ngContentIndex: number,
parent: CompileElement): o.Expression {
var fieldName = `_text_${this.view.nodes.length}`;
this.view.fields.push(
new o.ClassField(fieldName, o.importType(this.view.genConfig.renderTypes.renderText)));
@@ -135,8 +109,7 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
.set(ViewProperties.renderer.callMethod(
'createText',
[
this._getParentRenderNode(parent),
o.literal(value),
this._getParentRenderNode(parent), o.literal(value),
this.view.createMethod.resetDebugInfoExpr(this.view.nodes.length, ast)
]))
.toStmt();
@@ -156,13 +129,13 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
new o.ArrayType(o.importType(this.view.genConfig.renderTypes.renderNode)));
if (parentRenderNode !== o.NULL_EXPR) {
this.view.createMethod.addStmt(
ViewProperties.renderer.callMethod(
'projectNodes',
[
parentRenderNode,
o.importExpr(Identifiers.flattenNestedViewRenderNodes)
.callFn([nodesExpression])
])
ViewProperties.renderer
.callMethod(
'projectNodes',
[
parentRenderNode,
o.importExpr(Identifiers.flattenNestedViewRenderNodes).callFn([nodesExpression])
])
.toStmt());
} else if (this._isRootNode(parent)) {
if (this.view.viewType !== ViewType.COMPONENT) {
@@ -204,14 +177,14 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
var attrName = attrNameAndValues[i][0];
var attrValue = attrNameAndValues[i][1];
this.view.createMethod.addStmt(
ViewProperties.renderer.callMethod(
'setElementAttribute',
[renderNode, o.literal(attrName), o.literal(attrValue)])
ViewProperties.renderer
.callMethod(
'setElementAttribute', [renderNode, o.literal(attrName), o.literal(attrValue)])
.toStmt());
}
var compileElement =
new CompileElement(parent, this.view, nodeIndex, renderNode, ast, component, directives,
ast.providers, ast.hasViewContainer, false, ast.references);
var compileElement = new CompileElement(
parent, this.view, nodeIndex, renderNode, ast, component, directives, ast.providers,
ast.hasViewContainer, false, ast.references);
this.view.nodes.push(compileElement);
var compViewExpr: o.ReadVarExpr = null;
if (isPresent(component)) {
@@ -220,13 +193,12 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
this.targetDependencies.push(new ViewCompileDependency(component, nestedComponentIdentifier));
compViewExpr = o.variable(`compView_${nodeIndex}`); // fix highlighting: `
compileElement.setComponentView(compViewExpr);
this.view.createMethod.addStmt(compViewExpr.set(o.importExpr(nestedComponentIdentifier)
.callFn([
ViewProperties.viewUtils,
compileElement.injector,
compileElement.appElement
]))
.toDeclStmt());
this.view.createMethod.addStmt(
compViewExpr
.set(o.importExpr(nestedComponentIdentifier).callFn([
ViewProperties.viewUtils, compileElement.injector, compileElement.appElement
]))
.toDeclStmt());
}
compileElement.beforeChildren();
this._addRootNodeAndProject(compileElement, ast.ngContentIndex, parent);
@@ -242,8 +214,9 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
compileElement.contentNodesByNgContentIndex.map(nodes => createFlatArray(nodes)));
}
this.view.createMethod.addStmt(
compViewExpr.callMethod('create',
[compileElement.getComponent(), codeGenContentNodes, o.NULL_EXPR])
compViewExpr
.callMethod(
'create', [compileElement.getComponent(), codeGenContentNodes, o.NULL_EXPR])
.toStmt());
}
return null;
@@ -269,17 +242,18 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
var directives = ast.directives.map(directiveAst => directiveAst.directive);
var compileElement =
new CompileElement(parent, this.view, nodeIndex, renderNode, ast, null, directives,
ast.providers, ast.hasViewContainer, true, ast.references);
var compileElement = new CompileElement(
parent, this.view, nodeIndex, renderNode, ast, null, directives, ast.providers,
ast.hasViewContainer, true, ast.references);
this.view.nodes.push(compileElement);
var compiledAnimations = this._animationCompiler.compileComponent(this.view.component);
this.nestedViewCount++;
var embeddedView = new CompileView(
this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR, compiledAnimations,
this.view.viewIndex + this.nestedViewCount, compileElement, templateVariableBindings);
this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR,
compiledAnimations, this.view.viewIndex + this.nestedViewCount, compileElement,
templateVariableBindings);
this.nestedViewCount += buildView(embeddedView, ast.children, this.targetDependencies);
compileElement.beforeChildren();
@@ -301,15 +275,20 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
visitElementProperty(ast: BoundElementPropertyAst, context: any): any { return null; }
}
function _mergeHtmlAndDirectiveAttrs(declaredHtmlAttrs: {[key: string]: string},
directives: CompileDirectiveMetadata[]): string[][] {
function _mergeHtmlAndDirectiveAttrs(
declaredHtmlAttrs: {[key: string]: string},
directives: CompileDirectiveMetadata[]): string[][] {
var result: {[key: string]: string} = {};
StringMapWrapper.forEach(declaredHtmlAttrs, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => { result[key] = value; });
StringMapWrapper.forEach(
declaredHtmlAttrs,
(value: any /** TODO #9100 */, key: any /** TODO #9100 */) => { result[key] = value; });
directives.forEach(directiveMeta => {
StringMapWrapper.forEach(directiveMeta.hostAttributes, (value: any /** TODO #9100 */, name: any /** TODO #9100 */) => {
var prevValue = result[name];
result[name] = isPresent(prevValue) ? mergeAttributeValue(name, prevValue, value) : value;
});
StringMapWrapper.forEach(
directiveMeta.hostAttributes,
(value: any /** TODO #9100 */, name: any /** TODO #9100 */) => {
var prevValue = result[name];
result[name] = isPresent(prevValue) ? mergeAttributeValue(name, prevValue, value) : value;
});
});
return mapToKeyValueArray(result);
}
@@ -330,7 +309,9 @@ function mergeAttributeValue(attrName: string, attrValue1: string, attrValue2: s
function mapToKeyValueArray(data: {[key: string]: string}): string[][] {
var entryArray: any[] /** TODO #9100 */ = [];
StringMapWrapper.forEach(data, (value: any /** TODO #9100 */, name: any /** TODO #9100 */) => { entryArray.push([name, value]); });
StringMapWrapper.forEach(data, (value: any /** TODO #9100 */, name: any /** TODO #9100 */) => {
entryArray.push([name, value]);
});
// We need to sort to get a defined output order
// for tests and for caching generated artifacts...
ListWrapper.sort(entryArray, (entry1, entry2) => StringWrapper.compare(entry1[0], entry2[0]));
@@ -346,9 +327,10 @@ function createViewTopLevelStmts(view: CompileView, targetStatements: o.Statemen
`nodeDebugInfos_${view.component.type.name}${view.viewIndex}`); // fix highlighting: `
targetStatements.push(
(<o.ReadVarExpr>nodeDebugInfosVar)
.set(o.literalArr(view.nodes.map(createStaticNodeDebugInfo),
new o.ArrayType(new o.ExternalType(Identifiers.StaticNodeDebugInfo),
[o.TypeModifier.Const])))
.set(o.literalArr(
view.nodes.map(createStaticNodeDebugInfo),
new o.ArrayType(
new o.ExternalType(Identifiers.StaticNodeDebugInfo), [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]));
}
@@ -375,10 +357,12 @@ function createStaticNodeDebugInfo(node: CompileNode): o.Expression {
if (isPresent(compileElement.component)) {
componentToken = createDiTokenExpression(identifierToken(compileElement.component.type));
}
StringMapWrapper.forEach(compileElement.referenceTokens, (token: any /** TODO #9100 */, varName: any /** TODO #9100 */) => {
varTokenEntries.push(
[varName, isPresent(token) ? createDiTokenExpression(token) : o.NULL_EXPR]);
});
StringMapWrapper.forEach(
compileElement.referenceTokens,
(token: any /** TODO #9100 */, varName: any /** TODO #9100 */) => {
varTokenEntries.push(
[varName, isPresent(token) ? createDiTokenExpression(token) : o.NULL_EXPR]);
});
}
return o.importExpr(Identifiers.StaticNodeDebugInfo)
.instantiate(
@@ -390,31 +374,30 @@ function createStaticNodeDebugInfo(node: CompileNode): o.Expression {
o.importType(Identifiers.StaticNodeDebugInfo, null, [o.TypeModifier.Const]));
}
function createViewClass(view: CompileView, renderCompTypeVar: o.ReadVarExpr,
nodeDebugInfosVar: o.Expression): o.ClassStmt {
function createViewClass(
view: CompileView, renderCompTypeVar: o.ReadVarExpr,
nodeDebugInfosVar: o.Expression): o.ClassStmt {
var viewConstructorArgs = [
new o.FnParam(ViewConstructorVars.viewUtils.name, o.importType(Identifiers.ViewUtils)),
new o.FnParam(ViewConstructorVars.parentInjector.name, o.importType(Identifiers.Injector)),
new o.FnParam(ViewConstructorVars.declarationEl.name, o.importType(Identifiers.AppElement))
];
var superConstructorArgs = [
o.variable(view.className),
renderCompTypeVar,
ViewTypeEnum.fromValue(view.viewType),
ViewConstructorVars.viewUtils,
ViewConstructorVars.parentInjector,
o.variable(view.className), renderCompTypeVar, ViewTypeEnum.fromValue(view.viewType),
ViewConstructorVars.viewUtils, ViewConstructorVars.parentInjector,
ViewConstructorVars.declarationEl,
ChangeDetectionStrategyEnum.fromValue(getChangeDetectionMode(view))
];
if (view.genConfig.genDebugInfo) {
superConstructorArgs.push(nodeDebugInfosVar);
}
var viewConstructor = new o.ClassMethod(null, viewConstructorArgs,
[o.SUPER_EXPR.callFn(superConstructorArgs).toStmt()]);
var viewConstructor = new o.ClassMethod(
null, viewConstructorArgs, [o.SUPER_EXPR.callFn(superConstructorArgs).toStmt()]);
var viewMethods = [
new o.ClassMethod('createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)],
generateCreateMethod(view), o.importType(Identifiers.AppElement)),
new o.ClassMethod(
'createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)],
generateCreateMethod(view), o.importType(Identifiers.AppElement)),
new o.ClassMethod(
'injectorGetInternal',
[
@@ -425,22 +408,22 @@ function createViewClass(view: CompileView, renderCompTypeVar: o.ReadVarExpr,
],
addReturnValuefNotEmpty(view.injectorGetMethod.finish(), InjectMethodVars.notFoundResult),
o.DYNAMIC_TYPE),
new o.ClassMethod('detectChangesInternal',
[new o.FnParam(DetectChangesVars.throwOnChange.name, o.BOOL_TYPE)],
generateDetectChangesMethod(view)),
new o.ClassMethod(
'detectChangesInternal', [new o.FnParam(DetectChangesVars.throwOnChange.name, o.BOOL_TYPE)],
generateDetectChangesMethod(view)),
new o.ClassMethod('dirtyParentQueriesInternal', [], view.dirtyParentQueriesMethod.finish()),
new o.ClassMethod('destroyInternal', [], view.destroyMethod.finish()),
new o.ClassMethod('detachInternal', [], view.detachMethod.finish())
].concat(view.eventHandlerMethods);
var superClass = view.genConfig.genDebugInfo ? Identifiers.DebugAppView : Identifiers.AppView;
var viewClass = new o.ClassStmt(view.className, o.importExpr(superClass, [getContextType(view)]),
view.fields, view.getters, viewConstructor,
viewMethods.filter((method) => method.body.length > 0));
var viewClass = new o.ClassStmt(
view.className, o.importExpr(superClass, [getContextType(view)]), view.fields, view.getters,
viewConstructor, viewMethods.filter((method) => method.body.length > 0));
return viewClass;
}
function createViewFactory(view: CompileView, viewClass: o.ClassStmt,
renderCompTypeVar: o.ReadVarExpr): o.Statement {
function createViewFactory(
view: CompileView, viewClass: o.ClassStmt, renderCompTypeVar: o.ReadVarExpr): o.Statement {
var viewFactoryArgs = [
new o.FnParam(ViewConstructorVars.viewUtils.name, o.importType(Identifiers.ViewUtils)),
new o.FnParam(ViewConstructorVars.parentInjector.name, o.importType(Identifiers.Injector)),
@@ -455,29 +438,24 @@ function createViewFactory(view: CompileView, viewClass: o.ClassStmt,
templateUrlInfo = view.component.template.templateUrl;
}
if (view.viewIndex === 0) {
initRenderCompTypeStmts = [
new o.IfStmt(renderCompTypeVar.identical(o.NULL_EXPR),
[
renderCompTypeVar.set(ViewConstructorVars
.viewUtils.callMethod('createRenderComponentType',
[
o.literal(templateUrlInfo),
o.literal(view.component
.template.ngContentSelectors.length),
ViewEncapsulationEnum
.fromValue(view.component.template.encapsulation),
view.styles
]))
.toStmt()
])
];
initRenderCompTypeStmts = [new o.IfStmt(renderCompTypeVar.identical(o.NULL_EXPR), [
renderCompTypeVar
.set(ViewConstructorVars.viewUtils.callMethod(
'createRenderComponentType',
[
o.literal(templateUrlInfo),
o.literal(view.component.template.ngContentSelectors.length),
ViewEncapsulationEnum.fromValue(view.component.template.encapsulation), view.styles
]))
.toStmt()
])];
}
return o.fn(viewFactoryArgs, initRenderCompTypeStmts.concat([
new o.ReturnStatement(o.variable(viewClass.name)
.instantiate(viewClass.constructorMethod.params.map(
(param) => o.variable(param.name))))
]),
o.importType(Identifiers.AppView, [getContextType(view)]))
return o
.fn(viewFactoryArgs, initRenderCompTypeStmts.concat([new o.ReturnStatement(
o.variable(viewClass.name)
.instantiate(viewClass.constructorMethod.params.map(
(param) => o.variable(param.name))))]),
o.importType(Identifiers.AppView, [getContextType(view)]))
.toDeclStmt(view.viewFactory.name, [o.StmtModifier.Final]);
}
@@ -487,10 +465,10 @@ function generateCreateMethod(view: CompileView): o.Statement[] {
if (view.viewType === ViewType.COMPONENT) {
parentRenderNodeExpr = ViewProperties.renderer.callMethod(
'createViewRoot', [o.THIS_EXPR.prop('declarationAppElement').prop('nativeElement')]);
parentRenderNodeStmts = [
parentRenderNodeVar.set(parentRenderNodeExpr)
.toDeclStmt(o.importType(view.genConfig.renderTypes.renderNode), [o.StmtModifier.Final])
];
parentRenderNodeStmts =
[parentRenderNodeVar.set(parentRenderNodeExpr)
.toDeclStmt(
o.importType(view.genConfig.renderTypes.renderNode), [o.StmtModifier.Final])];
}
var resultExpr: o.Expression;
if (view.viewType === ViewType.HOST) {
@@ -498,18 +476,18 @@ function generateCreateMethod(view: CompileView): o.Statement[] {
} else {
resultExpr = o.NULL_EXPR;
}
return parentRenderNodeStmts.concat(view.createMethod.finish())
.concat([
o.THIS_EXPR.callMethod('init',
[
createFlatArray(view.rootNodesOrAppElements),
o.literalArr(view.nodes.map(node => node.renderNode)),
o.literalArr(view.disposables),
o.literalArr(view.subscriptions)
])
.toStmt(),
new o.ReturnStatement(resultExpr)
]);
return parentRenderNodeStmts.concat(view.createMethod.finish()).concat([
o.THIS_EXPR
.callMethod(
'init',
[
createFlatArray(view.rootNodesOrAppElements),
o.literalArr(view.nodes.map(node => node.renderNode)), o.literalArr(view.disposables),
o.literalArr(view.subscriptions)
])
.toStmt(),
new o.ReturnStatement(resultExpr)
]);
}
function generateDetectChangesMethod(view: CompileView): o.Statement[] {
@@ -574,8 +552,8 @@ function getChangeDetectionMode(view: CompileView): ChangeDetectionStrategy {
var mode: ChangeDetectionStrategy;
if (view.viewType === ViewType.COMPONENT) {
mode = isDefaultChangeDetectionStrategy(view.component.changeDetection) ?
ChangeDetectionStrategy.CheckAlways :
ChangeDetectionStrategy.CheckOnce;
ChangeDetectionStrategy.CheckAlways :
ChangeDetectionStrategy.CheckOnce;
} else {
mode = ChangeDetectionStrategy.CheckAlways;
}
@@ -1,18 +1,20 @@
import {Injectable} from '@angular/core';
import * as o from '../output/output_ast';
import {CompileElement} from './compile_element';
import {CompileView} from './compile_view';
import {buildView, finishView, ViewCompileDependency} from './view_builder';
import {bindView} from './view_binder';
import {CompileDirectiveMetadata, CompilePipeMetadata} from '../compile_metadata';
import {TemplateAst} from '../template_ast';
import {CompilerConfig} from '../config';
import {AnimationCompiler} from '../animation/animation_compiler';
import {CompileDirectiveMetadata, CompilePipeMetadata} from '../compile_metadata';
import {CompilerConfig} from '../config';
import * as o from '../output/output_ast';
import {TemplateAst} from '../template_ast';
import {CompileElement} from './compile_element';
import {CompileView} from './compile_view';
import {bindView} from './view_binder';
import {ViewCompileDependency, buildView, finishView} from './view_builder';
export class ViewCompileResult {
constructor(public statements: o.Statement[], public viewFactoryVar: string,
public dependencies: ViewCompileDependency[]) {}
constructor(
public statements: o.Statement[], public viewFactoryVar: string,
public dependencies: ViewCompileDependency[]) {}
}
@Injectable()
@@ -20,8 +22,9 @@ export class ViewCompiler {
private _animationCompiler = new AnimationCompiler();
constructor(private _genConfig: CompilerConfig) {}
compileComponent(component: CompileDirectiveMetadata, template: TemplateAst[],
styles: o.Expression, pipes: CompilePipeMetadata[]): ViewCompileResult {
compileComponent(
component: CompileDirectiveMetadata, template: TemplateAst[], styles: o.Expression,
pipes: CompilePipeMetadata[]): ViewCompileResult {
var dependencies: any[] /** TODO #9100 */ = [];
var compiledAnimations = this._animationCompiler.compileComponent(component);
var statements: any[] /** TODO #9100 */ = [];
@@ -29,8 +32,9 @@ export class ViewCompiler {
statements.push(entry.statesMapStatement);
statements.push(entry.fnStatement);
});
var view = new CompileView(component, this._genConfig, pipes, styles, compiledAnimations, 0,
CompileElement.createNull(), []);
var view = new CompileView(
component, this._genConfig, pipes, styles, compiledAnimations, 0,
CompileElement.createNull(), []);
buildView(view, template, dependencies);
// Need to separate binding from creation to be able to refer to
// variables that have been declared after usage.
@@ -1,8 +1,4 @@
import {
Injectable,
ViewMetadata,
ComponentMetadata,
} from '@angular/core';
import {Injectable, ViewMetadata, ComponentMetadata,} from '@angular/core';
import {ReflectorReader, reflector} from '../core_private';
@@ -67,9 +63,8 @@ export class ViewResolver {
});
}
} else {
throw new BaseException(
`Could not compile '${stringify(component)}' because it is not a component.`);
throw new BaseException(
`Could not compile '${stringify(component)}' because it is not a component.`);
}
}
}