diff --git a/modules/angular2/docs/cheatsheet/built-in-directives.md b/modules/angular2/docs/cheatsheet/built-in-directives.md index a908f79c34..68b8941c4e 100644 --- a/modules/angular2/docs/cheatsheet/built-in-directives.md +++ b/modules/angular2/docs/cheatsheet/built-in-directives.md @@ -14,7 +14,7 @@ Removes or recreates a portion of the DOM tree based on the showSection expressi @cheatsheetItem syntax: -`
  • `|`*ngFor` +`
  • `|`*ngFor` description: Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list. diff --git a/modules/angular2/docs/core/01_templates.md b/modules/angular2/docs/core/01_templates.md index c308419eab..121d62d155 100644 --- a/modules/angular2/docs/core/01_templates.md +++ b/modules/angular2/docs/core/01_templates.md @@ -433,7 +433,7 @@ Finally, we can move the `ngFor` keyword to the left hand side and prefix it wit ``` ``` diff --git a/modules/angular2/docs/core/10_view.md b/modules/angular2/docs/core/10_view.md index 888a484287..613fa283eb 100644 --- a/modules/angular2/docs/core/10_view.md +++ b/modules/angular2/docs/core/10_view.md @@ -94,7 +94,7 @@ Let's start with a View such as: ``` ``` diff --git a/modules/angular2/examples/core/pipes/ts/slice_pipe/slice_pipe_example.ts b/modules/angular2/examples/core/pipes/ts/slice_pipe/slice_pipe_example.ts index 325cf6ab61..d796c3d89f 100644 --- a/modules/angular2/examples/core/pipes/ts/slice_pipe/slice_pipe_example.ts +++ b/modules/angular2/examples/core/pipes/ts/slice_pipe/slice_pipe_example.ts @@ -22,7 +22,7 @@ export class SlicePipeStringExample { @Component({ selector: 'slice-list-example', template: `
    -
  • {{i}}
  • +
  • {{i}}
  • ` }) export class SlicePipeListExample { diff --git a/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts b/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts index a3875b7879..bdf26a5b5c 100644 --- a/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts +++ b/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts @@ -36,7 +36,7 @@ class MyCmp implements OnDeactivate {

    Log:

    -

    {{ logItem }}

    +

    {{ logItem }}

    `, directives: [ROUTER_DIRECTIVES] diff --git a/modules/angular2/http.ts b/modules/angular2/http.ts index 9b003f2fca..1776a4a6d8 100644 --- a/modules/angular2/http.ts +++ b/modules/angular2/http.ts @@ -56,7 +56,7 @@ export {URLSearchParams} from './src/http/url_search_params'; *
    *

    People

    * @@ -194,7 +194,7 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS; *
    *

    People

    * diff --git a/modules/angular2/src/common/directives/ng_for.ts b/modules/angular2/src/common/directives/ng_for.ts index 11694b584d..2212c57473 100644 --- a/modules/angular2/src/common/directives/ng_for.ts +++ b/modules/angular2/src/common/directives/ng_for.ts @@ -58,7 +58,7 @@ import {BaseException} from "../../facade/exceptions"; * * ### Syntax * - * - `
  • ...
  • ` + * - `
  • ...
  • ` * - `
  • ...
  • ` * - `` * diff --git a/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts b/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts index 408b5a6be4..408b336454 100644 --- a/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts +++ b/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts @@ -96,7 +96,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor { * * ``` * * ``` */ diff --git a/modules/angular2/src/compiler/expression_parser/lexer.ts b/modules/angular2/src/compiler/expression_parser/lexer.ts index 790b48455e..a15dab113c 100644 --- a/modules/angular2/src/compiler/expression_parser/lexer.ts +++ b/modules/angular2/src/compiler/expression_parser/lexer.ts @@ -46,7 +46,11 @@ export class Token { isKeyword(): boolean { return (this.type == TokenType.Keyword); } - isKeywordVar(): boolean { return (this.type == TokenType.Keyword && this.strValue == "var"); } + isKeywordDeprecatedVar(): boolean { + return (this.type == TokenType.Keyword && this.strValue == "var"); + } + + isKeywordLet(): boolean { return (this.type == TokenType.Keyword && this.strValue == "let"); } isKeywordNull(): boolean { return (this.type == TokenType.Keyword && this.strValue == "null"); } @@ -464,4 +468,4 @@ var OPERATORS = SetWrapper.createFromList([ var KEYWORDS = - SetWrapper.createFromList(['var', 'null', 'undefined', 'true', 'false', 'if', 'else']); + SetWrapper.createFromList(['var', 'let', 'null', 'undefined', 'true', 'false', 'if', 'else']); diff --git a/modules/angular2/src/compiler/expression_parser/parser.ts b/modules/angular2/src/compiler/expression_parser/parser.ts index cff564e814..4ff6ff1f6f 100644 --- a/modules/angular2/src/compiler/expression_parser/parser.ts +++ b/modules/angular2/src/compiler/expression_parser/parser.ts @@ -62,6 +62,10 @@ export class SplitInterpolation { constructor(public strings: string[], public expressions: string[]) {} } +export class TemplateBindingParseResult { + constructor(public templateBindings: TemplateBinding[], public warnings: string[]) {} +} + @Injectable() export class Parser { constructor(/** @internal */ @@ -112,7 +116,7 @@ export class Parser { return new Quote(prefix, uninterpretedExpression, location); } - parseTemplateBindings(input: string, location: any): TemplateBinding[] { + parseTemplateBindings(input: string, location: any): TemplateBindingParseResult { var tokens = this._lexer.tokenize(input); return new _ParseAST(input, location, tokens, false).parseTemplateBindings(); } @@ -228,16 +232,11 @@ export class _ParseAST { } } - optionalKeywordVar(): boolean { - if (this.peekKeywordVar()) { - this.advance(); - return true; - } else { - return false; - } - } + peekKeywordLet(): boolean { return this.next.isKeywordLet(); } - peekKeywordVar(): boolean { return this.next.isKeywordVar() || this.next.isOperator('#'); } + peekDeprecatedKeywordVar(): boolean { return this.next.isKeywordDeprecatedVar(); } + + peekDeprecatedOperatorHash(): boolean { return this.next.isOperator('#'); } expectCharacter(code: number) { if (this.optionalCharacter(code)) return; @@ -617,11 +616,23 @@ export class _ParseAST { return result.toString(); } - parseTemplateBindings(): any[] { - var bindings = []; + parseTemplateBindings(): TemplateBindingParseResult { + var bindings: TemplateBinding[] = []; var prefix = null; + var warnings: string[] = []; while (this.index < this.tokens.length) { - var keyIsVar: boolean = this.optionalKeywordVar(); + var keyIsVar: boolean = this.peekKeywordLet(); + if (!keyIsVar && this.peekDeprecatedKeywordVar()) { + keyIsVar = true; + warnings.push(`"var" inside of expressions is deprecated. Use "let" instead!`); + } + if (!keyIsVar && this.peekDeprecatedOperatorHash()) { + keyIsVar = true; + warnings.push(`"#" inside of expressions is deprecated. Use "let" instead!`); + } + if (keyIsVar) { + this.advance(); + } var key = this.expectTemplateBindingKey(); if (!keyIsVar) { if (prefix == null) { @@ -639,7 +650,8 @@ export class _ParseAST { } else { name = '\$implicit'; } - } else if (this.next !== EOF && !this.peekKeywordVar()) { + } 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); @@ -650,7 +662,7 @@ export class _ParseAST { this.optionalCharacter($COMMA); } } - return bindings; + return new TemplateBindingParseResult(bindings, warnings); } error(message: string, index: number = null) { diff --git a/modules/angular2/src/compiler/parse_util.ts b/modules/angular2/src/compiler/parse_util.ts index a1070f2e68..f842d3c36c 100644 --- a/modules/angular2/src/compiler/parse_util.ts +++ b/modules/angular2/src/compiler/parse_util.ts @@ -17,8 +17,14 @@ export class ParseSourceSpan { } } +export enum ParseErrorLevel { + WARNING, + FATAL +} + export abstract class ParseError { - constructor(public span: ParseSourceSpan, public msg: string) {} + constructor(public span: ParseSourceSpan, public msg: string, + public level: ParseErrorLevel = ParseErrorLevel.FATAL) {} toString(): string { var source = this.span.start.file.content; diff --git a/modules/angular2/src/compiler/provider_parser.ts b/modules/angular2/src/compiler/provider_parser.ts index ff618cc07d..a32e1259f7 100644 --- a/modules/angular2/src/compiler/provider_parser.ts +++ b/modules/angular2/src/compiler/provider_parser.ts @@ -6,7 +6,7 @@ import { NgContentAst, EmbeddedTemplateAst, ElementAst, - VariableAst, + ReferenceAst, BoundEventAst, BoundElementPropertyAst, AttrAst, @@ -69,7 +69,7 @@ export class ProviderElementContext { constructor(private _viewContext: ProviderViewContext, private _parent: ProviderElementContext, private _isViewRoot: boolean, private _directiveAsts: DirectiveAst[], - attrs: AttrAst[], vars: VariableAst[], private _sourceSpan: ParseSourceSpan) { + 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); @@ -79,9 +79,8 @@ export class ProviderElementContext { var queriedTokens = new CompileTokenMap(); this._allProviders.values().forEach( (provider) => { this._addQueryReadsTo(provider.token, queriedTokens); }); - vars.forEach((varAst) => { - var varToken = new CompileTokenMetadata({value: varAst.name}); - this._addQueryReadsTo(varToken, queriedTokens); + refs.forEach((refAst) => { + this._addQueryReadsTo(new CompileTokenMetadata({value: refAst.name}), queriedTokens); }); if (isPresent(queriedTokens.get(identifierToken(Identifiers.ViewContainerRef)))) { this._hasViewContainer = true; diff --git a/modules/angular2/src/compiler/runtime_compiler.ts b/modules/angular2/src/compiler/runtime_compiler.ts index d7c98f3060..706d961ab8 100644 --- a/modules/angular2/src/compiler/runtime_compiler.ts +++ b/modules/angular2/src/compiler/runtime_compiler.ts @@ -30,7 +30,6 @@ import { NgContentAst, EmbeddedTemplateAst, ElementAst, - VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, diff --git a/modules/angular2/src/compiler/template_ast.ts b/modules/angular2/src/compiler/template_ast.ts index f328131649..a0c00ecf8e 100644 --- a/modules/angular2/src/compiler/template_ast.ts +++ b/modules/angular2/src/compiler/template_ast.ts @@ -82,7 +82,18 @@ export class BoundEventAst implements TemplateAst { } /** - * A variable declaration on an element (e.g. `#var="expression"`). + * 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) {} + visit(visitor: TemplateAstVisitor, context: any): any { + return visitor.visitReference(this, context); + } +} + +/** + * A variable declaration on a