diff --git a/src/parser/tokenizer.ts b/src/parser/tokenizer.ts index cd9b866df..a5de274aa 100644 --- a/src/parser/tokenizer.ts +++ b/src/parser/tokenizer.ts @@ -207,6 +207,14 @@ export class Tokenizer { const value = this.readQuoted() || this.readRange() if (value) return value + if (this.peek() === '[') { + this.p++ + const prop = this.readQuoted() + if (!prop) return + this.readTo(']') + return new PropertyAccessToken(prop, [], this.p) + } + const variable = this.readWord() if (!variable.size()) return diff --git a/src/render/expression.ts b/src/render/expression.ts index ffe8ff3e5..2f897709b 100644 --- a/src/render/expression.ts +++ b/src/render/expression.ts @@ -42,7 +42,7 @@ export class Expression { export function evalToken (token: Token | undefined, ctx: Context): any { assert(ctx, () => 'unable to evaluate: context not defined') if (TypeGuards.isPropertyAccessToken(token)) { - const variable = token.variable.getText() + const variable = token.getVariableAsText() const props: string[] = token.props.map(prop => evalToken(prop, ctx)) return ctx.get([variable, ...props]) } diff --git a/src/tokens/property-access-token.ts b/src/tokens/property-access-token.ts index 79512c25e..8da3c9236 100644 --- a/src/tokens/property-access-token.ts +++ b/src/tokens/property-access-token.ts @@ -2,13 +2,22 @@ import { Token } from './token' import { WordToken } from './word-token' import { QuotedToken } from './quoted-token' import { TokenKind } from '../parser/token-kind' +import { parseStringLiteral } from '../parser/parse-string-literal' export class PropertyAccessToken extends Token { constructor ( - public variable: WordToken, + public variable: WordToken | QuotedToken, public props: (WordToken | QuotedToken | PropertyAccessToken)[], end: number ) { super(TokenKind.PropertyAccess, variable.input, variable.begin, end, variable.file) } + + getVariableAsText() { + if (this.variable instanceof WordToken) { + return this.variable.getText() + } else { + return parseStringLiteral(this.variable.getText()) + } + } } diff --git a/test/e2e/issues.ts b/test/e2e/issues.ts index 972bb1a5f..3a8987f04 100644 --- a/test/e2e/issues.ts +++ b/test/e2e/issues.ts @@ -18,4 +18,9 @@ describe('Issues', function () { const html = await engine.parseAndRender(template) expect(html).to.equal('foo') }) + it('#259 complex property access with braces is not supported', async () => { + const engine = new Liquid() + const html = engine.parseAndRenderSync('{{ ["complex key"] }}', { 'complex key': 'foo' }) + expect(html).to.equal('foo') + }) })