Skip to content

Commit

Permalink
expression parser #2 (#207)
Browse files Browse the repository at this point in the history
* test(expression-parser): initial tests for ForOfStatement

* feat(kernel): add decoratable interface to support strongly typed decorators

* chore(tslint): disable no-this-assignment and interface-name rules

* fix(kernel): fix decorated interface

* feat(binding): add @connectable decorator back in (strongly typed)

refactor(binding): cleanup/shuffle some interfaces accordingly

* chore(ast): update typings for connectable binding

* fix(binding): wrap updatetarget/updatesource so vCurrent BBs work again

* feat(all): implement InterpolationBinding

* fix(expression-parser): fix differentation for caching of expressions/interpolations

* fix(iterator-binding): correctly compile and render ForOfStatement

refactor(template-compiler): cleanup/inline instruction classes

* feat(unparser): implement interpolation unparsing

* perf(expression-parser): remove unreachable branch

* test(expression-parser): add interpolation tests

* test(expression-parser): explicitly verify precedence

* chore(all): turn off emitDecoratorMetadata in jit and runtime to make sure we don't use it
  • Loading branch information
fkleuver authored and EisenbergEffect committed Oct 7, 2018
1 parent eff5bb7 commit f67a414
Show file tree
Hide file tree
Showing 39 changed files with 1,023 additions and 806 deletions.
70 changes: 59 additions & 11 deletions packages/debug/src/binding/unparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,17 +226,55 @@ export class Unparser implements AST.IVisitor<void> {
}
}

public visitArrayBindingPattern(expr: AST.ArrayBindingPattern): string { throw new Error('visitArrayBindingPattern'); }
public visitArrayBindingPattern(expr: AST.ArrayBindingPattern): void {
const elements = expr.elements;
this.text += '[';
for (let i = 0, length = elements.length; i < length; ++i) {
if (i !== 0) {
this.text += ',';
}
elements[i].accept(this);
}
this.text += ']';
}

public visitObjectBindingPattern(expr: AST.ObjectBindingPattern): string { throw new Error('visitObjectBindingPattern'); }
public visitObjectBindingPattern(expr: AST.ObjectBindingPattern): void {
const keys = expr.keys;
const values = expr.values;
this.text += '{';
for (let i = 0, length = keys.length; i < length; ++i) {
if (i !== 0) {
this.text += ',';
}
this.text += `'${keys[i]}':`;
values[i].accept(this);
}
this.text += '}';
}

public visitBindingIdentifier(expr: AST.BindingIdentifier): string { throw new Error('visitBindingIdentifier'); }
public visitBindingIdentifier(expr: AST.BindingIdentifier): void {
this.text += expr.name;
}

public visitHtmlLiteral(expr: AST.HtmlLiteral): string { throw new Error('visitHtmlLiteral'); }
public visitHtmlLiteral(expr: AST.HtmlLiteral): void { throw new Error('visitHtmlLiteral'); }

public visitForOfStatement(expr: AST.ForOfStatement): string { throw new Error('visitForOfStatement'); }
public visitForOfStatement(expr: AST.ForOfStatement): void {
expr.declaration.accept(this);
this.text += ' of ';
expr.iterable.accept(this);
}

public visitInterpolation(expr: AST.Interpolation): string { throw new Error('visitInterpolation'); }
public visitInterpolation(expr: AST.Interpolation): void {
const { parts, expressions } = expr;
const length = expressions.length;
this.text += '${';
this.text += parts[0];
for (let i = 0; i < length; i++) {
expressions[i].accept(this);
this.text += parts[i + 1];
}
this.text += '}';
}

private writeArgs(args: ReadonlyArray<AST.IExpression>): void {
this.text += '(';
Expand Down Expand Up @@ -332,17 +370,27 @@ export class Serializer implements AST.IVisitor<string> {
return `{"type":"BindingBehavior","name":"${expr.name}","expression":${expr.expression.accept(this)},"args":${this.serializeExpressions(expr.args)}}`;
}

public visitArrayBindingPattern(expr: AST.ArrayBindingPattern): string { throw new Error('visitArrayBindingPattern'); }
public visitArrayBindingPattern(expr: AST.ArrayBindingPattern): string {
return `{"type":"ArrayBindingPattern","elements":${this.serializeExpressions(expr.elements)}}`;
}

public visitObjectBindingPattern(expr: AST.ObjectBindingPattern): string { throw new Error('visitObjectBindingPattern'); }
public visitObjectBindingPattern(expr: AST.ObjectBindingPattern): string {
return `{"type":"ObjectBindingPattern","keys":${serializePrimitives(expr.keys)},"values":${this.serializeExpressions(expr.values)}}`;
}

public visitBindingIdentifier(expr: AST.BindingIdentifier): string { throw new Error('visitBindingIdentifier'); }
public visitBindingIdentifier(expr: AST.BindingIdentifier): string {
return `{"type":"BindingIdentifier","name":"${expr.name}"}`;
}

public visitHtmlLiteral(expr: AST.HtmlLiteral): string { throw new Error('visitHtmlLiteral'); }

public visitForOfStatement(expr: AST.ForOfStatement): string { throw new Error('visitForOfStatement'); }
public visitForOfStatement(expr: AST.ForOfStatement): string {
return `{"type":"ForOfStatement","declaration":${expr.declaration.accept(this)},"iterable":${expr.iterable.accept(this)}}`;
}

public visitInterpolation(expr: AST.Interpolation): string { throw new Error('visitInterpolation'); }
public visitInterpolation(expr: AST.Interpolation): string {
return `{"type":"Interpolation","cooked":${serializePrimitives(expr.parts)},"expressions":${this.serializeExpressions(expr.expressions)}}`;
}

// tslint:disable-next-line:no-any
private serializeExpressions(args: ReadonlyArray<AST.IExpression>): string {
Expand Down
6 changes: 3 additions & 3 deletions packages/jit/src/binding-command.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// tslint:disable:interface-name
import { Constructable, IContainer, Registration, Writable } from '@aurelia/kernel';
import { BindingType, IExpressionParser, IResourceKind, IResourceType, ITemplateSource, TargetedInstruction } from '@aurelia/runtime';
import {
Expand All @@ -12,7 +11,8 @@ import {
SetPropertyInstruction,
ToViewBindingInstruction,
TriggerBindingInstruction,
TwoWayBindingInstruction
TwoWayBindingInstruction,
IteratorBindingInstruction
} from '.';

export interface IBindingCommandSource {
Expand Down Expand Up @@ -190,7 +190,7 @@ export class ForBindingCommand implements IBindingCommand {
instructions: []
};
return new HydrateTemplateController(src, 'repeat', [
new ToViewBindingInstruction(this.parser.parse($symbol.rawValue, BindingType.ForCommand), 'items'),
new IteratorBindingInstruction(this.parser.parse($symbol.rawValue, BindingType.ForCommand), 'items'),
new SetPropertyInstruction('item', 'local')
// tslint:disable-next-line:align
], false);
Expand Down
3 changes: 0 additions & 3 deletions packages/jit/src/expression-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,9 +597,6 @@ function parseInterpolation(state: ParserState): Interpolation {
default:
result += String.fromCharCode(state.currentChar);
}
if (state.index >= length) {
break;
}
nextChar(state);
}
if (expressions.length) {
Expand Down
Loading

0 comments on commit f67a414

Please sign in to comment.