From eab3f62f25133ae857fb1357701913588ead9115 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 29 Mar 2017 16:19:27 -0400 Subject: [PATCH 1/4] try to parse expressions as javascript before interpreting them as an identifier (#424) --- src/parse/read/expression.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/parse/read/expression.js b/src/parse/read/expression.js index 110b6af4efee..904b1c5229ff 100644 --- a/src/parse/read/expression.js +++ b/src/parse/read/expression.js @@ -3,16 +3,6 @@ import { parseExpressionAt } from 'acorn'; export default function readExpression ( parser ) { const start = parser.index; - const name = parser.readUntil( /\s*}}/ ); - if ( name && /^[a-z]+$/.test( name ) ) { - return { - type: 'Identifier', - start, - end: start + name.length, - name - }; - } - parser.index = start; try { @@ -21,6 +11,15 @@ export default function readExpression ( parser ) { return node; } catch ( err ) { + const name = parser.readUntil( /\s*}}/ ); + if ( name && /^[a-z]+$/.test( name ) ) { + return { + type: 'Identifier', + start, + end: start + name.length, + name + }; + } parser.acornError( err ); } } From 343a0055069fe97000e757795231a210837781dc Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 29 Mar 2017 16:57:11 -0400 Subject: [PATCH 2/4] add unit test for #424 --- .../attribute-prefer-expression/_config.js | 19 +++++++++++++++++++ .../attribute-prefer-expression/main.html | 2 ++ 2 files changed, 21 insertions(+) create mode 100644 test/generator/samples/attribute-prefer-expression/_config.js create mode 100644 test/generator/samples/attribute-prefer-expression/main.html diff --git a/test/generator/samples/attribute-prefer-expression/_config.js b/test/generator/samples/attribute-prefer-expression/_config.js new file mode 100644 index 000000000000..ef88c5afa536 --- /dev/null +++ b/test/generator/samples/attribute-prefer-expression/_config.js @@ -0,0 +1,19 @@ +export default { + 'skip-ssr': true, + + data: { + foo: false + }, + + test ( assert, component, target ) { + const inputs = target.querySelectorAll( 'input' ); + + assert.ok( inputs[0].checked ); + assert.ok( !inputs[1].checked ); + + component.set( { foo: true } ); + + assert.ok( !inputs[0].checked ); + assert.ok( inputs[1].checked ); + } +}; diff --git a/test/generator/samples/attribute-prefer-expression/main.html b/test/generator/samples/attribute-prefer-expression/main.html new file mode 100644 index 000000000000..c69a83993d8f --- /dev/null +++ b/test/generator/samples/attribute-prefer-expression/main.html @@ -0,0 +1,2 @@ + + From 6c754c2a3d4f357e7d5eca599402bc01c1617781 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 2 Apr 2017 09:25:32 -0400 Subject: [PATCH 3/4] special case literals --- src/parse/read/expression.js | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/parse/read/expression.js b/src/parse/read/expression.js index 904b1c5229ff..e896f647cd8d 100644 --- a/src/parse/read/expression.js +++ b/src/parse/read/expression.js @@ -1,8 +1,36 @@ import { parseExpressionAt } from 'acorn'; +const literals = { + true: true, + false: false, + null: null +}; + export default function readExpression ( parser ) { const start = parser.index; + const name = parser.readUntil( /\s*}}/ ); + if ( name && /^[a-z]+$/.test( name ) ) { + const end = start + name.length; + + if ( name in literals ) { + return { + type: 'Literal', + start, + end, + value: literals[ name ], + raw: name + }; + } + + return { + type: 'Identifier', + start, + end: start + name.length, + name + }; + } + parser.index = start; try { @@ -11,15 +39,6 @@ export default function readExpression ( parser ) { return node; } catch ( err ) { - const name = parser.readUntil( /\s*}}/ ); - if ( name && /^[a-z]+$/.test( name ) ) { - return { - type: 'Identifier', - start, - end: start + name.length, - name - }; - } parser.acornError( err ); } } From 6e0d0b1a124ac72a627113a73bf3ba4995f49bf5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 2 Apr 2017 09:48:14 -0400 Subject: [PATCH 4/4] use a map to avoid false positives --- src/parse/read/expression.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/parse/read/expression.js b/src/parse/read/expression.js index e896f647cd8d..7aa34b9bdcee 100644 --- a/src/parse/read/expression.js +++ b/src/parse/read/expression.js @@ -1,10 +1,10 @@ import { parseExpressionAt } from 'acorn'; -const literals = { - true: true, - false: false, - null: null -}; +const literals = new Map([ + [ 'true', true ], + [ 'false', false ], + [ 'null', null ] +]); export default function readExpression ( parser ) { const start = parser.index; @@ -13,12 +13,12 @@ export default function readExpression ( parser ) { if ( name && /^[a-z]+$/.test( name ) ) { const end = start + name.length; - if ( name in literals ) { + if ( literals.has( name ) ) { return { type: 'Literal', start, end, - value: literals[ name ], + value: literals.get( name ), raw: name }; }