refactor(compiler): separate Interpolation, SimpleExpression & CompoundExpression types
This commit is contained in:
parent
d491a022a7
commit
d900c13efb
@ -232,7 +232,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "attr",
|
"name": "attr",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "c",
|
"content": "c",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -315,7 +315,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "attr",
|
"name": "attr",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "&#a;",
|
"content": "&#a;",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -398,7 +398,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "attr",
|
"name": "attr",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "ÿ",
|
"content": "ÿ",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -481,7 +481,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "attr",
|
"name": "attr",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "&#xg;",
|
"content": "&#xg;",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -1183,7 +1183,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "",
|
"content": "",
|
||||||
"isEmpty": true,
|
"isEmpty": true,
|
||||||
@ -1218,7 +1218,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "",
|
"content": "",
|
||||||
"isEmpty": true,
|
"isEmpty": true,
|
||||||
@ -2359,7 +2359,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -2449,7 +2449,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -2539,7 +2539,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -2629,7 +2629,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -2736,7 +2736,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -2843,7 +2843,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -2950,7 +2950,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -3057,7 +3057,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -3164,7 +3164,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -3271,7 +3271,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -3378,7 +3378,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "abc",
|
"content": "abc",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -3884,8 +3884,8 @@ Object {
|
|||||||
Object {
|
Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"content": Object {
|
||||||
"content": "a < b",
|
"content": "a < b",
|
||||||
"isInterpolation": true,
|
|
||||||
"isStatic": false,
|
"isStatic": false,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -3902,6 +3902,21 @@ Object {
|
|||||||
},
|
},
|
||||||
"type": 4,
|
"type": 4,
|
||||||
},
|
},
|
||||||
|
"loc": Object {
|
||||||
|
"end": Object {
|
||||||
|
"column": 20,
|
||||||
|
"line": 1,
|
||||||
|
"offset": 19,
|
||||||
|
},
|
||||||
|
"source": "{{a < b}}",
|
||||||
|
"start": Object {
|
||||||
|
"column": 11,
|
||||||
|
"line": 1,
|
||||||
|
"offset": 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": 5,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"codegenNode": undefined,
|
"codegenNode": undefined,
|
||||||
"isSelfClosing": false,
|
"isSelfClosing": false,
|
||||||
@ -4133,7 +4148,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "/",
|
"content": "/",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -4240,7 +4255,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -4330,7 +4345,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -4666,7 +4681,7 @@ class=\\"bar\\"></div>",
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "foo",
|
"content": "foo",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -4701,7 +4716,7 @@ class=\\"bar\\"></div>",
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "class",
|
"name": "class",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar",
|
"content": "bar",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -4810,7 +4825,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "foo",
|
"content": "foo",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -4845,7 +4860,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "class",
|
"name": "class",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar",
|
"content": "bar",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -5476,7 +5491,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "a\\"bc",
|
"name": "a\\"bc",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "",
|
"content": "",
|
||||||
"isEmpty": true,
|
"isEmpty": true,
|
||||||
@ -5583,7 +5598,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "a'bc",
|
"name": "a'bc",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "",
|
"content": "",
|
||||||
"isEmpty": true,
|
"isEmpty": true,
|
||||||
@ -5690,7 +5705,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "a<bc",
|
"name": "a<bc",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "",
|
"content": "",
|
||||||
"isEmpty": true,
|
"isEmpty": true,
|
||||||
@ -5797,7 +5812,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar\\"",
|
"content": "bar\\"",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -5904,7 +5919,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar'",
|
"content": "bar'",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -6011,7 +6026,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar<div",
|
"content": "bar<div",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -6118,7 +6133,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar=baz",
|
"content": "bar=baz",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -6225,7 +6240,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar\`",
|
"content": "bar\`",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -6332,7 +6347,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "=",
|
"name": "=",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -6422,7 +6437,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "=foo",
|
"name": "=foo",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": Object {
|
"value": Object {
|
||||||
"content": "bar",
|
"content": "bar",
|
||||||
"isEmpty": false,
|
"isEmpty": false,
|
||||||
@ -6594,7 +6609,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "a",
|
"name": "a",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
@ -6612,7 +6627,7 @@ Object {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"name": "b",
|
"name": "b",
|
||||||
"type": 5,
|
"type": 6,
|
||||||
"value": undefined,
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -6960,8 +6975,8 @@ Object {
|
|||||||
Object {
|
Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"content": Object {
|
||||||
"content": "'</div>'",
|
"content": "'</div>'",
|
||||||
"isInterpolation": true,
|
|
||||||
"isStatic": false,
|
"isStatic": false,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -6978,6 +6993,21 @@ Object {
|
|||||||
},
|
},
|
||||||
"type": 4,
|
"type": 4,
|
||||||
},
|
},
|
||||||
|
"loc": Object {
|
||||||
|
"end": Object {
|
||||||
|
"column": 23,
|
||||||
|
"line": 1,
|
||||||
|
"offset": 22,
|
||||||
|
},
|
||||||
|
"source": "{{'</div>'}}",
|
||||||
|
"start": Object {
|
||||||
|
"column": 11,
|
||||||
|
"line": 1,
|
||||||
|
"offset": 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": 5,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"codegenNode": undefined,
|
"codegenNode": undefined,
|
||||||
"isSelfClosing": false,
|
"isSelfClosing": false,
|
||||||
@ -7317,9 +7347,9 @@ exports[`compiler: parse Errors X_MISSING_INTERPOLATION_END {{}} 1`] = `
|
|||||||
Object {
|
Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"content": Object {
|
||||||
"content": "",
|
"content": "",
|
||||||
"isInterpolation": true,
|
"isStatic": false,
|
||||||
"isStatic": true,
|
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
"column": 3,
|
"column": 3,
|
||||||
@ -7335,6 +7365,21 @@ Object {
|
|||||||
},
|
},
|
||||||
"type": 4,
|
"type": 4,
|
||||||
},
|
},
|
||||||
|
"loc": Object {
|
||||||
|
"end": Object {
|
||||||
|
"column": 5,
|
||||||
|
"line": 1,
|
||||||
|
"offset": 4,
|
||||||
|
},
|
||||||
|
"source": "{{}}",
|
||||||
|
"start": Object {
|
||||||
|
"column": 1,
|
||||||
|
"line": 1,
|
||||||
|
"offset": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": 5,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"hoists": Array [],
|
"hoists": Array [],
|
||||||
"imports": Array [],
|
"imports": Array [],
|
||||||
@ -7458,7 +7503,6 @@ Object {
|
|||||||
Object {
|
Object {
|
||||||
"arg": Object {
|
"arg": Object {
|
||||||
"content": "class",
|
"content": "class",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": true,
|
"isStatic": true,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7477,7 +7521,6 @@ Object {
|
|||||||
},
|
},
|
||||||
"exp": Object {
|
"exp": Object {
|
||||||
"content": "{ some: condition }",
|
"content": "{ some: condition }",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": false,
|
"isStatic": false,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7509,7 +7552,7 @@ Object {
|
|||||||
},
|
},
|
||||||
"modifiers": Array [],
|
"modifiers": Array [],
|
||||||
"name": "bind",
|
"name": "bind",
|
||||||
"type": 6,
|
"type": 7,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"tag": "div",
|
"tag": "div",
|
||||||
@ -7538,7 +7581,6 @@ Object {
|
|||||||
Object {
|
Object {
|
||||||
"arg": Object {
|
"arg": Object {
|
||||||
"content": "style",
|
"content": "style",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": true,
|
"isStatic": true,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7557,7 +7599,6 @@ Object {
|
|||||||
},
|
},
|
||||||
"exp": Object {
|
"exp": Object {
|
||||||
"content": "{ color: 'red' }",
|
"content": "{ color: 'red' }",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": false,
|
"isStatic": false,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7589,7 +7630,7 @@ Object {
|
|||||||
},
|
},
|
||||||
"modifiers": Array [],
|
"modifiers": Array [],
|
||||||
"name": "bind",
|
"name": "bind",
|
||||||
"type": 6,
|
"type": 7,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"tag": "p",
|
"tag": "p",
|
||||||
@ -7645,7 +7686,6 @@ Object {
|
|||||||
Object {
|
Object {
|
||||||
"arg": Object {
|
"arg": Object {
|
||||||
"content": "style",
|
"content": "style",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": true,
|
"isStatic": true,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7664,7 +7704,6 @@ Object {
|
|||||||
},
|
},
|
||||||
"exp": Object {
|
"exp": Object {
|
||||||
"content": "{ color: 'red' }",
|
"content": "{ color: 'red' }",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": false,
|
"isStatic": false,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7696,7 +7735,7 @@ Object {
|
|||||||
},
|
},
|
||||||
"modifiers": Array [],
|
"modifiers": Array [],
|
||||||
"name": "bind",
|
"name": "bind",
|
||||||
"type": 6,
|
"type": 7,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"tag": "p",
|
"tag": "p",
|
||||||
@ -7744,7 +7783,6 @@ Object {
|
|||||||
Object {
|
Object {
|
||||||
"arg": Object {
|
"arg": Object {
|
||||||
"content": "class",
|
"content": "class",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": true,
|
"isStatic": true,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7763,7 +7801,6 @@ Object {
|
|||||||
},
|
},
|
||||||
"exp": Object {
|
"exp": Object {
|
||||||
"content": "{ some: condition }",
|
"content": "{ some: condition }",
|
||||||
"isInterpolation": false,
|
|
||||||
"isStatic": false,
|
"isStatic": false,
|
||||||
"loc": Object {
|
"loc": Object {
|
||||||
"end": Object {
|
"end": Object {
|
||||||
@ -7795,7 +7832,7 @@ Object {
|
|||||||
},
|
},
|
||||||
"modifiers": Array [],
|
"modifiers": Array [],
|
||||||
"name": "bind",
|
"name": "bind",
|
||||||
"type": 6,
|
"type": 7,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"tag": "div",
|
"tag": "div",
|
||||||
|
@ -3,14 +3,16 @@ import {
|
|||||||
NodeTypes,
|
NodeTypes,
|
||||||
RootNode,
|
RootNode,
|
||||||
SourceLocation,
|
SourceLocation,
|
||||||
createExpression,
|
createSimpleExpression,
|
||||||
Namespaces,
|
Namespaces,
|
||||||
ElementTypes,
|
ElementTypes,
|
||||||
CallExpression,
|
CallExpression,
|
||||||
createObjectExpression,
|
createObjectExpression,
|
||||||
createObjectProperty,
|
createObjectProperty,
|
||||||
createArrayExpression,
|
createArrayExpression,
|
||||||
ElementNode
|
ElementNode,
|
||||||
|
createCompoundExpression,
|
||||||
|
createInterpolation
|
||||||
} from '../src'
|
} from '../src'
|
||||||
import {
|
import {
|
||||||
CREATE_VNODE,
|
CREATE_VNODE,
|
||||||
@ -93,12 +95,12 @@ describe('compiler: codegen', () => {
|
|||||||
test('hoists', () => {
|
test('hoists', () => {
|
||||||
const root = createRoot({
|
const root = createRoot({
|
||||||
hoists: [
|
hoists: [
|
||||||
createExpression(`hello`, false, mockLoc),
|
createSimpleExpression(`hello`, false, mockLoc),
|
||||||
createObjectExpression(
|
createObjectExpression(
|
||||||
[
|
[
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
createExpression(`id`, true, mockLoc),
|
createSimpleExpression(`id`, true, mockLoc),
|
||||||
createExpression(`foo`, true, mockLoc),
|
createSimpleExpression(`foo`, true, mockLoc),
|
||||||
mockLoc
|
mockLoc
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -138,7 +140,7 @@ describe('compiler: codegen', () => {
|
|||||||
test('interpolation', () => {
|
test('interpolation', () => {
|
||||||
const { code } = generate(
|
const { code } = generate(
|
||||||
createRoot({
|
createRoot({
|
||||||
children: [createExpression(`hello`, false, mockLoc, true)]
|
children: [createInterpolation(`hello`, mockLoc)]
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
expect(code).toMatch(`return _${TO_STRING}(hello)`)
|
expect(code).toMatch(`return _${TO_STRING}(hello)`)
|
||||||
@ -171,7 +173,7 @@ describe('compiler: codegen', () => {
|
|||||||
isEmpty: false,
|
isEmpty: false,
|
||||||
loc: mockLoc
|
loc: mockLoc
|
||||||
},
|
},
|
||||||
createExpression(`hello`, false, mockLoc, true),
|
createInterpolation(`hello`, mockLoc),
|
||||||
{
|
{
|
||||||
type: NodeTypes.COMMENT,
|
type: NodeTypes.COMMENT,
|
||||||
content: 'foo',
|
content: 'foo',
|
||||||
@ -199,7 +201,7 @@ describe('compiler: codegen', () => {
|
|||||||
isEmpty: false,
|
isEmpty: false,
|
||||||
loc: mockLoc
|
loc: mockLoc
|
||||||
},
|
},
|
||||||
createExpression(`hello`, false, mockLoc, true),
|
createInterpolation(`hello`, mockLoc),
|
||||||
{
|
{
|
||||||
type: NodeTypes.COMMENT,
|
type: NodeTypes.COMMENT,
|
||||||
content: 'foo',
|
content: 'foo',
|
||||||
@ -224,14 +226,13 @@ describe('compiler: codegen', () => {
|
|||||||
const { code } = generate(
|
const { code } = generate(
|
||||||
createRoot({
|
createRoot({
|
||||||
children: [
|
children: [
|
||||||
{
|
createInterpolation(
|
||||||
type: NodeTypes.EXPRESSION,
|
createCompoundExpression(
|
||||||
content: 'foo',
|
[`_ctx.`, createSimpleExpression(`foo`, false, mockLoc)],
|
||||||
isStatic: false,
|
mockLoc
|
||||||
isInterpolation: true,
|
),
|
||||||
loc: mockLoc,
|
mockLoc
|
||||||
children: [`_ctx.`, createExpression(`foo`, false, mockLoc)]
|
)
|
||||||
}
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -249,7 +250,7 @@ describe('compiler: codegen', () => {
|
|||||||
branches: [
|
branches: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.IF_BRANCH,
|
type: NodeTypes.IF_BRANCH,
|
||||||
condition: createExpression('foo', false, mockLoc),
|
condition: createSimpleExpression('foo', false, mockLoc),
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -262,9 +263,9 @@ describe('compiler: codegen', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: NodeTypes.IF_BRANCH,
|
type: NodeTypes.IF_BRANCH,
|
||||||
condition: createExpression('a + b', false, mockLoc),
|
condition: createSimpleExpression('a + b', false, mockLoc),
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
children: [createExpression(`bye`, false, mockLoc, true)]
|
children: [createInterpolation(`bye`, mockLoc)]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: NodeTypes.IF_BRANCH,
|
type: NodeTypes.IF_BRANCH,
|
||||||
@ -302,7 +303,7 @@ describe('compiler: codegen', () => {
|
|||||||
branches: [
|
branches: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.IF_BRANCH,
|
type: NodeTypes.IF_BRANCH,
|
||||||
condition: createExpression('foo', false, mockLoc),
|
condition: createSimpleExpression('foo', false, mockLoc),
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -315,9 +316,9 @@ describe('compiler: codegen', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: NodeTypes.IF_BRANCH,
|
type: NodeTypes.IF_BRANCH,
|
||||||
condition: createExpression('a + b', false, mockLoc),
|
condition: createSimpleExpression('a + b', false, mockLoc),
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
children: [createExpression(`bye`, false, mockLoc, true)]
|
children: [createInterpolation(`bye`, mockLoc)]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -340,11 +341,11 @@ describe('compiler: codegen', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.FOR,
|
type: NodeTypes.FOR,
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
source: createExpression(`list`, false, mockLoc),
|
source: createSimpleExpression(`list`, false, mockLoc),
|
||||||
valueAlias: createExpression(`v`, false, mockLoc),
|
valueAlias: createSimpleExpression(`v`, false, mockLoc),
|
||||||
keyAlias: createExpression(`k`, false, mockLoc),
|
keyAlias: createSimpleExpression(`k`, false, mockLoc),
|
||||||
objectIndexAlias: createExpression(`i`, false, mockLoc),
|
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc),
|
||||||
children: [createExpression(`v`, false, mockLoc, true)]
|
children: [createInterpolation(`v`, mockLoc)]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -364,11 +365,11 @@ describe('compiler: codegen', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.FOR,
|
type: NodeTypes.FOR,
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
source: createExpression(`list`, false, mockLoc),
|
source: createSimpleExpression(`list`, false, mockLoc),
|
||||||
valueAlias: createExpression(`v`, false, mockLoc),
|
valueAlias: createSimpleExpression(`v`, false, mockLoc),
|
||||||
keyAlias: createExpression(`k`, false, mockLoc),
|
keyAlias: createSimpleExpression(`k`, false, mockLoc),
|
||||||
objectIndexAlias: createExpression(`i`, false, mockLoc),
|
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc),
|
||||||
children: [createExpression(`v`, false, mockLoc, true)]
|
children: [createInterpolation(`v`, mockLoc)]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
@ -391,11 +392,11 @@ describe('compiler: codegen', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.FOR,
|
type: NodeTypes.FOR,
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
source: createExpression(`list`, false, mockLoc),
|
source: createSimpleExpression(`list`, false, mockLoc),
|
||||||
valueAlias: undefined,
|
valueAlias: undefined,
|
||||||
keyAlias: createExpression(`k`, false, mockLoc),
|
keyAlias: createSimpleExpression(`k`, false, mockLoc),
|
||||||
objectIndexAlias: createExpression(`i`, false, mockLoc),
|
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc),
|
||||||
children: [createExpression(`v`, false, mockLoc, true)]
|
children: [createInterpolation(`v`, mockLoc)]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -415,11 +416,11 @@ describe('compiler: codegen', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.FOR,
|
type: NodeTypes.FOR,
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
source: createExpression(`list`, false, mockLoc),
|
source: createSimpleExpression(`list`, false, mockLoc),
|
||||||
valueAlias: createExpression(`v`, false, mockLoc),
|
valueAlias: createSimpleExpression(`v`, false, mockLoc),
|
||||||
keyAlias: undefined,
|
keyAlias: undefined,
|
||||||
objectIndexAlias: createExpression(`i`, false, mockLoc),
|
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc),
|
||||||
children: [createExpression(`v`, false, mockLoc, true)]
|
children: [createInterpolation(`v`, mockLoc)]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -439,11 +440,11 @@ describe('compiler: codegen', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.FOR,
|
type: NodeTypes.FOR,
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
source: createExpression(`list`, false, mockLoc),
|
source: createSimpleExpression(`list`, false, mockLoc),
|
||||||
valueAlias: undefined,
|
valueAlias: undefined,
|
||||||
keyAlias: undefined,
|
keyAlias: undefined,
|
||||||
objectIndexAlias: createExpression(`i`, false, mockLoc),
|
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc),
|
||||||
children: [createExpression(`v`, false, mockLoc, true)]
|
children: [createInterpolation(`v`, mockLoc)]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -488,29 +489,26 @@ describe('compiler: codegen', () => {
|
|||||||
createObjectExpression(
|
createObjectExpression(
|
||||||
[
|
[
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
createExpression(`id`, true, mockLoc),
|
createSimpleExpression(`id`, true, mockLoc),
|
||||||
createExpression(`foo`, true, mockLoc),
|
createSimpleExpression(`foo`, true, mockLoc),
|
||||||
mockLoc
|
mockLoc
|
||||||
),
|
),
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
createExpression(`prop`, false, mockLoc),
|
createSimpleExpression(`prop`, false, mockLoc),
|
||||||
createExpression(`bar`, false, mockLoc),
|
createSimpleExpression(`bar`, false, mockLoc),
|
||||||
mockLoc
|
mockLoc
|
||||||
),
|
),
|
||||||
// compound expression as computed key
|
// compound expression as computed key
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
content: ``,
|
|
||||||
loc: mockLoc,
|
loc: mockLoc,
|
||||||
isStatic: false,
|
|
||||||
isInterpolation: false,
|
|
||||||
children: [
|
children: [
|
||||||
`foo + `,
|
`foo + `,
|
||||||
createExpression(`bar`, false, mockLoc)
|
createSimpleExpression(`bar`, false, mockLoc)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
createExpression(`bar`, false, mockLoc),
|
createSimpleExpression(`bar`, false, mockLoc),
|
||||||
mockLoc
|
mockLoc
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -524,8 +522,8 @@ describe('compiler: codegen', () => {
|
|||||||
[
|
[
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
// should quote the key!
|
// should quote the key!
|
||||||
createExpression(`some-key`, true, mockLoc),
|
createSimpleExpression(`some-key`, true, mockLoc),
|
||||||
createExpression(`foo`, true, mockLoc),
|
createSimpleExpression(`foo`, true, mockLoc),
|
||||||
mockLoc
|
mockLoc
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -4,12 +4,12 @@ import {
|
|||||||
CommentNode,
|
CommentNode,
|
||||||
ElementNode,
|
ElementNode,
|
||||||
ElementTypes,
|
ElementTypes,
|
||||||
ExpressionNode,
|
|
||||||
Namespaces,
|
Namespaces,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
Position,
|
Position,
|
||||||
TextNode,
|
TextNode,
|
||||||
AttributeNode
|
AttributeNode,
|
||||||
|
InterpolationNode
|
||||||
} from '../src/ast'
|
} from '../src/ast'
|
||||||
|
|
||||||
describe('compiler: parse', () => {
|
describe('compiler: parse', () => {
|
||||||
@ -290,82 +290,118 @@ describe('compiler: parse', () => {
|
|||||||
describe('Interpolation', () => {
|
describe('Interpolation', () => {
|
||||||
test('simple interpolation', () => {
|
test('simple interpolation', () => {
|
||||||
const ast = parse('{{message}}')
|
const ast = parse('{{message}}')
|
||||||
const interpolation = ast.children[0] as ExpressionNode
|
const interpolation = ast.children[0] as InterpolationNode
|
||||||
|
|
||||||
expect(interpolation).toStrictEqual({
|
expect(interpolation).toStrictEqual({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
content: 'message',
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `message`,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: true,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 2, line: 1, column: 3 },
|
start: { offset: 2, line: 1, column: 3 },
|
||||||
end: { offset: 9, line: 1, column: 10 },
|
end: { offset: 9, line: 1, column: 10 },
|
||||||
source: 'message'
|
source: `message`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loc: {
|
||||||
|
start: { offset: 0, line: 1, column: 1 },
|
||||||
|
end: { offset: 11, line: 1, column: 12 },
|
||||||
|
source: '{{message}}'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it can have tag-like notation', () => {
|
test('it can have tag-like notation', () => {
|
||||||
const ast = parse('{{ a<b }}')
|
const ast = parse('{{ a<b }}')
|
||||||
const interpolation = ast.children[0] as ExpressionNode
|
const interpolation = ast.children[0] as InterpolationNode
|
||||||
|
|
||||||
expect(interpolation).toStrictEqual({
|
expect(interpolation).toStrictEqual({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
content: 'a<b',
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `a<b`,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: true,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 3, line: 1, column: 4 },
|
start: { offset: 3, line: 1, column: 4 },
|
||||||
end: { offset: 6, line: 1, column: 7 },
|
end: { offset: 6, line: 1, column: 7 },
|
||||||
source: 'a<b'
|
source: 'a<b'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loc: {
|
||||||
|
start: { offset: 0, line: 1, column: 1 },
|
||||||
|
end: { offset: 9, line: 1, column: 10 },
|
||||||
|
source: '{{ a<b }}'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it can have tag-like notation (2)', () => {
|
test('it can have tag-like notation (2)', () => {
|
||||||
const ast = parse('{{ a<b }}{{ c>d }}')
|
const ast = parse('{{ a<b }}{{ c>d }}')
|
||||||
const interpolation1 = ast.children[0] as ExpressionNode
|
const interpolation1 = ast.children[0] as InterpolationNode
|
||||||
const interpolation2 = ast.children[1] as ExpressionNode
|
const interpolation2 = ast.children[1] as InterpolationNode
|
||||||
|
|
||||||
expect(interpolation1).toStrictEqual({
|
expect(interpolation1).toStrictEqual({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
content: 'a<b',
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `a<b`,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: true,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 3, line: 1, column: 4 },
|
start: { offset: 3, line: 1, column: 4 },
|
||||||
end: { offset: 6, line: 1, column: 7 },
|
end: { offset: 6, line: 1, column: 7 },
|
||||||
source: 'a<b'
|
source: 'a<b'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loc: {
|
||||||
|
start: { offset: 0, line: 1, column: 1 },
|
||||||
|
end: { offset: 9, line: 1, column: 10 },
|
||||||
|
source: '{{ a<b }}'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(interpolation2).toStrictEqual({
|
expect(interpolation2).toStrictEqual({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
content: 'c>d',
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: true,
|
content: 'c>d',
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 12, line: 1, column: 13 },
|
start: { offset: 12, line: 1, column: 13 },
|
||||||
end: { offset: 15, line: 1, column: 16 },
|
end: { offset: 15, line: 1, column: 16 },
|
||||||
source: 'c>d'
|
source: 'c>d'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loc: {
|
||||||
|
start: { offset: 9, line: 1, column: 10 },
|
||||||
|
end: { offset: 18, line: 1, column: 19 },
|
||||||
|
source: '{{ c>d }}'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it can have tag-like notation (3)', () => {
|
test('it can have tag-like notation (3)', () => {
|
||||||
const ast = parse('<div>{{ "</div>" }}</div>')
|
const ast = parse('<div>{{ "</div>" }}</div>')
|
||||||
const element = ast.children[0] as ElementNode
|
const element = ast.children[0] as ElementNode
|
||||||
const interpolation = element.children[0] as ExpressionNode
|
const interpolation = element.children[0] as InterpolationNode
|
||||||
|
|
||||||
expect(interpolation).toStrictEqual({
|
expect(interpolation).toStrictEqual({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
content: '"</div>"',
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: true,
|
content: '"</div>"',
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 16, line: 1, column: 17 },
|
end: { offset: 16, line: 1, column: 17 },
|
||||||
source: '"</div>"'
|
source: '"</div>"'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loc: {
|
||||||
|
start: { offset: 5, line: 1, column: 6 },
|
||||||
|
end: { offset: 19, line: 1, column: 20 },
|
||||||
|
source: '{{ "</div>" }}'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -889,10 +925,9 @@ describe('compiler: parse', () => {
|
|||||||
arg: undefined,
|
arg: undefined,
|
||||||
modifiers: [],
|
modifiers: [],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'a',
|
content: 'a',
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 11, line: 1, column: 12 },
|
start: { offset: 11, line: 1, column: 12 },
|
||||||
end: { offset: 12, line: 1, column: 13 },
|
end: { offset: 12, line: 1, column: 13 },
|
||||||
@ -915,10 +950,10 @@ describe('compiler: parse', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: 'on',
|
name: 'on',
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'click',
|
content: 'click',
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
source: 'click',
|
source: 'click',
|
||||||
start: {
|
start: {
|
||||||
@ -987,10 +1022,10 @@ describe('compiler: parse', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: 'on',
|
name: 'on',
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'click',
|
content: 'click',
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
source: 'click',
|
source: 'click',
|
||||||
start: {
|
start: {
|
||||||
@ -1023,10 +1058,10 @@ describe('compiler: parse', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: 'bind',
|
name: 'bind',
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'a',
|
content: 'a',
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
start: {
|
start: {
|
||||||
@ -1043,10 +1078,10 @@ describe('compiler: parse', () => {
|
|||||||
},
|
},
|
||||||
modifiers: [],
|
modifiers: [],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 9, line: 1, column: 10 },
|
end: { offset: 9, line: 1, column: 10 },
|
||||||
@ -1069,10 +1104,10 @@ describe('compiler: parse', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: 'bind',
|
name: 'bind',
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'a',
|
content: 'a',
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
start: {
|
start: {
|
||||||
@ -1089,10 +1124,10 @@ describe('compiler: parse', () => {
|
|||||||
},
|
},
|
||||||
modifiers: ['sync'],
|
modifiers: ['sync'],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 13, line: 1, column: 14 },
|
start: { offset: 13, line: 1, column: 14 },
|
||||||
end: { offset: 14, line: 1, column: 15 },
|
end: { offset: 14, line: 1, column: 15 },
|
||||||
@ -1115,10 +1150,10 @@ describe('compiler: parse', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: 'on',
|
name: 'on',
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'a',
|
content: 'a',
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
start: {
|
start: {
|
||||||
@ -1135,10 +1170,10 @@ describe('compiler: parse', () => {
|
|||||||
},
|
},
|
||||||
modifiers: [],
|
modifiers: [],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 9, line: 1, column: 10 },
|
end: { offset: 9, line: 1, column: 10 },
|
||||||
@ -1161,10 +1196,10 @@ describe('compiler: parse', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: 'on',
|
name: 'on',
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'a',
|
content: 'a',
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
source: 'a',
|
source: 'a',
|
||||||
start: {
|
start: {
|
||||||
@ -1181,10 +1216,10 @@ describe('compiler: parse', () => {
|
|||||||
},
|
},
|
||||||
modifiers: ['enter'],
|
modifiers: ['enter'],
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: 'b',
|
content: 'b',
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: false,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 14, line: 1, column: 15 },
|
start: { offset: 14, line: 1, column: 15 },
|
||||||
end: { offset: 15, line: 1, column: 16 },
|
end: { offset: 15, line: 1, column: 16 },
|
||||||
@ -1313,20 +1348,27 @@ foo
|
|||||||
offset += foo.loc.source.length
|
offset += foo.loc.source.length
|
||||||
expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
|
expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
|
||||||
|
|
||||||
|
expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
|
||||||
|
const barInner = (bar as InterpolationNode).content
|
||||||
offset += 3
|
offset += 3
|
||||||
expect(bar.loc.start).toEqual({ line: 2, column: 8, offset })
|
expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
|
||||||
offset += bar.loc.source.length
|
offset += barInner.loc.source.length
|
||||||
expect(bar.loc.end).toEqual({ line: 2, column: 11, offset })
|
expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
|
||||||
offset += 3
|
offset += 3
|
||||||
|
expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
|
||||||
|
|
||||||
expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
|
expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
|
||||||
offset += but.loc.source.length
|
offset += but.loc.source.length
|
||||||
expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
|
expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
|
||||||
|
|
||||||
|
expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
|
||||||
|
const bazInner = (baz as InterpolationNode).content
|
||||||
offset += 3
|
offset += 3
|
||||||
expect(baz.loc.start).toEqual({ line: 2, column: 22, offset })
|
expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
|
||||||
offset += baz.loc.source.length
|
offset += bazInner.loc.source.length
|
||||||
expect(baz.loc.end).toEqual({ line: 2, column: 25, offset })
|
expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
|
||||||
|
offset += 3
|
||||||
|
expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('namedCharacterReferences option', () => {
|
describe('namedCharacterReferences option', () => {
|
||||||
|
@ -52,12 +52,12 @@ function createStaticObjectMatcher(obj: any) {
|
|||||||
properties: Object.keys(obj).map(key => ({
|
properties: Object.keys(obj).map(key => ({
|
||||||
type: NodeTypes.JS_PROPERTY,
|
type: NodeTypes.JS_PROPERTY,
|
||||||
key: {
|
key: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: key,
|
content: key,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: obj[key],
|
content: obj[key],
|
||||||
isStatic: true
|
isStatic: true
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ describe('compiler: element transform', () => {
|
|||||||
expect(node.arguments).toMatchObject([
|
expect(node.arguments).toMatchObject([
|
||||||
`"div"`,
|
`"div"`,
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `_hoisted_1`
|
content: `_hoisted_1`
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@ -106,7 +106,7 @@ describe('compiler: element transform', () => {
|
|||||||
expect(node.arguments).toMatchObject([
|
expect(node.arguments).toMatchObject([
|
||||||
`"div"`,
|
`"div"`,
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `_hoisted_1`
|
content: `_hoisted_1`
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
@ -148,7 +148,7 @@ describe('compiler: element transform', () => {
|
|||||||
expect(node.callee).toBe(`_${CREATE_VNODE}`)
|
expect(node.callee).toBe(`_${CREATE_VNODE}`)
|
||||||
// should directly use `obj` in props position
|
// should directly use `obj` in props position
|
||||||
expect(node.arguments[1]).toMatchObject({
|
expect(node.arguments[1]).toMatchObject({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `obj`
|
content: `obj`
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -167,7 +167,7 @@ describe('compiler: element transform', () => {
|
|||||||
id: 'foo'
|
id: 'foo'
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `obj`
|
content: `obj`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -185,7 +185,7 @@ describe('compiler: element transform', () => {
|
|||||||
callee: `_${MERGE_PROPS}`,
|
callee: `_${MERGE_PROPS}`,
|
||||||
arguments: [
|
arguments: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `obj`
|
content: `obj`
|
||||||
},
|
},
|
||||||
createStaticObjectMatcher({
|
createStaticObjectMatcher({
|
||||||
@ -209,7 +209,7 @@ describe('compiler: element transform', () => {
|
|||||||
id: 'foo'
|
id: 'foo'
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `obj`
|
content: `obj`
|
||||||
},
|
},
|
||||||
createStaticObjectMatcher({
|
createStaticObjectMatcher({
|
||||||
@ -237,7 +237,7 @@ describe('compiler: element transform', () => {
|
|||||||
callee: `_${TO_HANDLERS}`,
|
callee: `_${TO_HANDLERS}`,
|
||||||
arguments: [
|
arguments: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `obj`
|
content: `obj`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -267,13 +267,13 @@ describe('compiler: element transform', () => {
|
|||||||
callee: `_${TO_HANDLERS}`,
|
callee: `_${TO_HANDLERS}`,
|
||||||
arguments: [
|
arguments: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `handlers`
|
content: `handlers`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `obj`
|
content: `obj`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -363,14 +363,13 @@ describe('compiler: element transform', () => {
|
|||||||
`_directive_foo`,
|
`_directive_foo`,
|
||||||
// exp
|
// exp
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `hello`,
|
content: `hello`,
|
||||||
isStatic: false,
|
isStatic: false
|
||||||
isInterpolation: false
|
|
||||||
},
|
},
|
||||||
// arg
|
// arg
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `bar`,
|
content: `bar`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
}
|
}
|
||||||
@ -408,7 +407,7 @@ describe('compiler: element transform', () => {
|
|||||||
`_directive_bar`,
|
`_directive_bar`,
|
||||||
// exp
|
// exp
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `x`
|
content: `x`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -419,14 +418,13 @@ describe('compiler: element transform', () => {
|
|||||||
`_directive_baz`,
|
`_directive_baz`,
|
||||||
// exp
|
// exp
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `y`,
|
content: `y`,
|
||||||
isStatic: false,
|
isStatic: false
|
||||||
isInterpolation: false
|
|
||||||
},
|
},
|
||||||
// arg
|
// arg
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `arg`,
|
content: `arg`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
},
|
},
|
||||||
@ -437,12 +435,12 @@ describe('compiler: element transform', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.JS_PROPERTY,
|
type: NodeTypes.JS_PROPERTY,
|
||||||
key: {
|
key: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `mod`,
|
content: `mod`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `true`,
|
content: `true`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
@ -450,12 +448,12 @@ describe('compiler: element transform', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.JS_PROPERTY,
|
type: NodeTypes.JS_PROPERTY,
|
||||||
key: {
|
key: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `mad`,
|
content: `mad`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `true`,
|
content: `true`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
@ -484,7 +482,7 @@ describe('compiler: element transform', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.JS_PROPERTY,
|
type: NodeTypes.JS_PROPERTY,
|
||||||
key: {
|
key: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `onClick`,
|
content: `onClick`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
@ -492,12 +490,12 @@ describe('compiler: element transform', () => {
|
|||||||
type: NodeTypes.JS_ARRAY_EXPRESSION,
|
type: NodeTypes.JS_ARRAY_EXPRESSION,
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `a`,
|
content: `a`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `b`,
|
content: `b`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
@ -524,7 +522,7 @@ describe('compiler: element transform', () => {
|
|||||||
{
|
{
|
||||||
type: NodeTypes.JS_PROPERTY,
|
type: NodeTypes.JS_PROPERTY,
|
||||||
key: {
|
key: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `style`,
|
content: `style`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
@ -532,12 +530,12 @@ describe('compiler: element transform', () => {
|
|||||||
type: NodeTypes.JS_ARRAY_EXPRESSION,
|
type: NodeTypes.JS_ARRAY_EXPRESSION,
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `_hoisted_1`,
|
content: `_hoisted_1`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `{ color: 'red' }`,
|
content: `{ color: 'red' }`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
parse,
|
parse,
|
||||||
transform,
|
transform,
|
||||||
ExpressionNode,
|
|
||||||
ElementNode,
|
ElementNode,
|
||||||
DirectiveNode,
|
DirectiveNode,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
ForNode,
|
ForNode,
|
||||||
CompilerOptions,
|
CompilerOptions,
|
||||||
IfNode
|
IfNode,
|
||||||
|
InterpolationNode
|
||||||
} from '../../src'
|
} from '../../src'
|
||||||
import { transformIf } from '../../src/transforms/vIf'
|
import { transformIf } from '../../src/transforms/vIf'
|
||||||
import { transformFor } from '../../src/transforms/vFor'
|
import { transformFor } from '../../src/transforms/vFor'
|
||||||
@ -28,28 +28,58 @@ function parseWithExpressionTransform(
|
|||||||
|
|
||||||
describe('compiler: expression transform', () => {
|
describe('compiler: expression transform', () => {
|
||||||
test('interpolation (root)', () => {
|
test('interpolation (root)', () => {
|
||||||
const node = parseWithExpressionTransform(`{{ foo }}`) as ExpressionNode
|
const node = parseWithExpressionTransform(`{{ foo }}`) as InterpolationNode
|
||||||
expect(node.children).toBeUndefined()
|
expect(node.content).toMatchObject({
|
||||||
expect(node.content).toBe(`_ctx.foo`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.foo`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('interpolation (children)', () => {
|
test('interpolation (children)', () => {
|
||||||
const el = parseWithExpressionTransform(
|
const el = parseWithExpressionTransform(
|
||||||
`<div>{{ foo }}</div>`
|
`<div>{{ foo }}</div>`
|
||||||
) as ElementNode
|
) as ElementNode
|
||||||
const node = el.children[0] as ExpressionNode
|
const node = el.children[0] as InterpolationNode
|
||||||
expect(node.children).toBeUndefined()
|
expect(node.content).toMatchObject({
|
||||||
expect(node.content).toBe(`_ctx.foo`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.foo`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('interpolation (complex)', () => {
|
||||||
|
const el = parseWithExpressionTransform(
|
||||||
|
`<div>{{ foo + bar(baz.qux) }}</div>`
|
||||||
|
) as ElementNode
|
||||||
|
const node = el.children[0] as InterpolationNode
|
||||||
|
expect(node.content).toMatchObject({
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
|
{ content: `_ctx.foo` },
|
||||||
|
` + `,
|
||||||
|
{ content: `_ctx.bar` },
|
||||||
|
`(`,
|
||||||
|
{ content: `_ctx.baz` },
|
||||||
|
`.`,
|
||||||
|
{ content: `qux` },
|
||||||
|
`)`
|
||||||
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('directive value', () => {
|
test('directive value', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`<div v-foo:arg="baz"/>`
|
`<div v-foo:arg="baz"/>`
|
||||||
) as ElementNode
|
) as ElementNode
|
||||||
expect((node.props[0] as DirectiveNode).arg!.children).toBeUndefined()
|
const arg = (node.props[0] as DirectiveNode).arg!
|
||||||
|
expect(arg).toMatchObject({
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `arg`
|
||||||
|
})
|
||||||
const exp = (node.props[0] as DirectiveNode).exp!
|
const exp = (node.props[0] as DirectiveNode).exp!
|
||||||
expect(exp.children).toBeUndefined()
|
expect(exp).toMatchObject({
|
||||||
expect(exp.content).toBe(`_ctx.baz`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.baz`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('dynamic directive arg', () => {
|
test('dynamic directive arg', () => {
|
||||||
@ -57,19 +87,25 @@ describe('compiler: expression transform', () => {
|
|||||||
`<div v-foo:[arg]="baz"/>`
|
`<div v-foo:[arg]="baz"/>`
|
||||||
) as ElementNode
|
) as ElementNode
|
||||||
const arg = (node.props[0] as DirectiveNode).arg!
|
const arg = (node.props[0] as DirectiveNode).arg!
|
||||||
|
expect(arg).toMatchObject({
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.arg`
|
||||||
|
})
|
||||||
const exp = (node.props[0] as DirectiveNode).exp!
|
const exp = (node.props[0] as DirectiveNode).exp!
|
||||||
expect(arg.children).toBeUndefined()
|
expect(exp).toMatchObject({
|
||||||
expect(arg.content).toBe(`_ctx.arg`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
expect(exp.children).toBeUndefined()
|
content: `_ctx.baz`
|
||||||
expect(exp.content).toBe(`_ctx.baz`)
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix complex expressions', () => {
|
test('should prefix complex expressions', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ foo(baz + 1, { key: kuz }) }}`
|
`{{ foo(baz + 1, { key: kuz }) }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
// should parse into compound expression
|
// should parse into compound expression
|
||||||
expect(node.children).toMatchObject([
|
expect(node.content).toMatchObject({
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
{
|
{
|
||||||
content: `_ctx.foo`,
|
content: `_ctx.foo`,
|
||||||
loc: {
|
loc: {
|
||||||
@ -121,21 +157,43 @@ describe('compiler: expression transform', () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
` })`
|
` })`
|
||||||
])
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix v-if condition', () => {
|
test('should prefix v-if condition', () => {
|
||||||
const node = parseWithExpressionTransform(`<div v-if="ok"/>`) as IfNode
|
const node = parseWithExpressionTransform(`<div v-if="ok"/>`) as IfNode
|
||||||
expect(node.branches[0].condition!.children).toBeUndefined()
|
expect(node.branches[0].condition).toMatchObject({
|
||||||
expect(node.branches[0].condition!.content).toBe(`_ctx.ok`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.ok`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix v-for source', () => {
|
test('should prefix v-for source', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`<div v-for="i in list"/>`
|
`<div v-for="i in list"/>`
|
||||||
) as ForNode
|
) as ForNode
|
||||||
expect(node.source.children).toBeUndefined()
|
expect(node.source).toMatchObject({
|
||||||
expect(node.source.content).toBe(`_ctx.list`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.list`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should prefix v-for source w/ complex expression', () => {
|
||||||
|
const node = parseWithExpressionTransform(
|
||||||
|
`<div v-for="i in list.concat([foo])"/>`
|
||||||
|
) as ForNode
|
||||||
|
expect(node.source).toMatchObject({
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
|
{ content: `_ctx.list` },
|
||||||
|
`.`,
|
||||||
|
{ content: `concat` },
|
||||||
|
`([`,
|
||||||
|
{ content: `_ctx.foo` },
|
||||||
|
`])`
|
||||||
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix v-for alias', () => {
|
test('should not prefix v-for alias', () => {
|
||||||
@ -143,16 +201,14 @@ describe('compiler: expression transform', () => {
|
|||||||
`<div v-for="i in list">{{ i }}{{ j }}</div>`
|
`<div v-for="i in list">{{ i }}{{ j }}</div>`
|
||||||
) as ForNode
|
) as ForNode
|
||||||
const div = node.children[0] as ElementNode
|
const div = node.children[0] as ElementNode
|
||||||
|
expect((div.children[0] as InterpolationNode).content).toMatchObject({
|
||||||
const i = div.children[0] as ExpressionNode
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
expect(i.type).toBe(NodeTypes.EXPRESSION)
|
content: `i`
|
||||||
expect(i.content).toBe(`i`)
|
})
|
||||||
expect(i.children).toBeUndefined()
|
expect((div.children[1] as InterpolationNode).content).toMatchObject({
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
const j = div.children[1] as ExpressionNode
|
content: `_ctx.j`
|
||||||
expect(j.type).toBe(NodeTypes.EXPRESSION)
|
})
|
||||||
expect(j.children).toBeUndefined()
|
|
||||||
expect(j.content).toBe(`_ctx.j`)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix v-for aliases (multiple)', () => {
|
test('should not prefix v-for aliases (multiple)', () => {
|
||||||
@ -160,32 +216,30 @@ describe('compiler: expression transform', () => {
|
|||||||
`<div v-for="(i, j, k) in list">{{ i + j + k }}{{ l }}</div>`
|
`<div v-for="(i, j, k) in list">{{ i + j + k }}{{ l }}</div>`
|
||||||
) as ForNode
|
) as ForNode
|
||||||
const div = node.children[0] as ElementNode
|
const div = node.children[0] as ElementNode
|
||||||
|
expect((div.children[0] as InterpolationNode).content).toMatchObject({
|
||||||
const exp = div.children[0] as ExpressionNode
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
expect(exp.type).toBe(NodeTypes.EXPRESSION)
|
children: [
|
||||||
// parsed for better source-map support
|
|
||||||
expect(exp.children).toMatchObject([
|
|
||||||
{ content: `i` },
|
{ content: `i` },
|
||||||
` + `,
|
` + `,
|
||||||
{ content: `j` },
|
{ content: `j` },
|
||||||
` + `,
|
` + `,
|
||||||
{ content: `k` }
|
{ content: `k` }
|
||||||
])
|
]
|
||||||
|
})
|
||||||
const l = div.children[1] as ExpressionNode
|
expect((div.children[1] as InterpolationNode).content).toMatchObject({
|
||||||
expect(l.type).toBe(NodeTypes.EXPRESSION)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
expect(l.children).toBeUndefined()
|
content: `_ctx.l`
|
||||||
expect(l.content).toBe(`_ctx.l`)
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix id outside of v-for', () => {
|
test('should prefix id outside of v-for', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`<div><div v-for="i in list" />{{ i }}</div>`
|
`<div><div v-for="i in list" />{{ i }}</div>`
|
||||||
) as ElementNode
|
) as ElementNode
|
||||||
const exp = node.children[1] as ExpressionNode
|
expect((node.children[1] as InterpolationNode).content).toMatchObject({
|
||||||
expect(exp.type).toBe(NodeTypes.EXPRESSION)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
expect(exp.children).toBeUndefined()
|
content: `_ctx.i`
|
||||||
expect(exp.content).toBe(`_ctx.i`)
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('nested v-for', () => {
|
test('nested v-for', () => {
|
||||||
@ -197,123 +251,130 @@ describe('compiler: expression transform', () => {
|
|||||||
const outerDiv = node.children[0] as ElementNode
|
const outerDiv = node.children[0] as ElementNode
|
||||||
const innerFor = outerDiv.children[0] as ForNode
|
const innerFor = outerDiv.children[0] as ForNode
|
||||||
const innerExp = (innerFor.children[0] as ElementNode)
|
const innerExp = (innerFor.children[0] as ElementNode)
|
||||||
.children[0] as ExpressionNode
|
.children[0] as InterpolationNode
|
||||||
expect(innerExp.type).toBe(NodeTypes.EXPRESSION)
|
expect(innerExp.content).toMatchObject({
|
||||||
expect(innerExp.children).toMatchObject([
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
{ content: 'i' },
|
children: [{ content: 'i' }, ` + `, { content: `_ctx.j` }]
|
||||||
` + `,
|
})
|
||||||
{ content: `_ctx.j` }
|
|
||||||
])
|
|
||||||
|
|
||||||
// when an inner v-for shadows a variable of an outer v-for and exit,
|
// when an inner v-for shadows a variable of an outer v-for and exit,
|
||||||
// it should not cause the outer v-for's alias to be removed from known ids
|
// it should not cause the outer v-for's alias to be removed from known ids
|
||||||
const outerExp = outerDiv.children[1] as ExpressionNode
|
const outerExp = outerDiv.children[1] as InterpolationNode
|
||||||
expect(outerExp.type).toBe(NodeTypes.EXPRESSION)
|
expect(outerExp.content).toMatchObject({
|
||||||
expect(outerExp.content).toBe(`i`)
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
expect(outerExp.children).toBeUndefined()
|
content: `i`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix whitelisted globals', () => {
|
test('should not prefix whitelisted globals', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ Math.max(1, 2) }}`
|
`{{ Math.max(1, 2) }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.type).toBe(NodeTypes.EXPRESSION)
|
expect(node.content).toMatchObject({
|
||||||
expect(node.children).toMatchObject([
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
{ content: `Math` },
|
children: [{ content: `Math` }, `.`, { content: `max` }, `(1, 2)`]
|
||||||
`.`,
|
})
|
||||||
{ content: `max` },
|
|
||||||
`(1, 2)`
|
|
||||||
])
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix id of a function declaration', () => {
|
test('should not prefix id of a function declaration', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ function foo() { return bar } }}`
|
`{{ function foo() { return bar } }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.type).toBe(NodeTypes.EXPRESSION)
|
expect(node.content).toMatchObject({
|
||||||
expect(node.children).toMatchObject([
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
`function `,
|
`function `,
|
||||||
{ content: `foo` },
|
{ content: `foo` },
|
||||||
`() { return `,
|
`() { return `,
|
||||||
{ content: `_ctx.bar` },
|
{ content: `_ctx.bar` },
|
||||||
` }`
|
` }`
|
||||||
])
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix params of a function expression', () => {
|
test('should not prefix params of a function expression', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ foo => foo + bar }}`
|
`{{ foo => foo + bar }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.type).toBe(NodeTypes.EXPRESSION)
|
expect(node.content).toMatchObject({
|
||||||
expect(node.children).toMatchObject([
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
{ content: `foo` },
|
{ content: `foo` },
|
||||||
` => `,
|
` => `,
|
||||||
{ content: `foo` },
|
{ content: `foo` },
|
||||||
` + `,
|
` + `,
|
||||||
{ content: `_ctx.bar` }
|
{ content: `_ctx.bar` }
|
||||||
])
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix an object property key', () => {
|
test('should not prefix an object property key', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ { foo: bar } }}`
|
`{{ { foo: bar } }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.type).toBe(NodeTypes.EXPRESSION)
|
expect(node.content).toMatchObject({
|
||||||
expect(node.children).toMatchObject([
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
`{ foo: `,
|
children: [`{ foo: `, { content: `_ctx.bar` }, ` }`]
|
||||||
{ content: `_ctx.bar` },
|
})
|
||||||
` }`
|
|
||||||
])
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix a computed object property key', () => {
|
test('should prefix a computed object property key', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ { [foo]: bar } }}`
|
`{{ { [foo]: bar } }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.type).toBe(NodeTypes.EXPRESSION)
|
expect(node.content).toMatchObject({
|
||||||
expect(node.children).toMatchObject([
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
`{ [`,
|
`{ [`,
|
||||||
{ content: `_ctx.foo` },
|
{ content: `_ctx.foo` },
|
||||||
`]: `,
|
`]: `,
|
||||||
{ content: `_ctx.bar` },
|
{ content: `_ctx.bar` },
|
||||||
` }`
|
` }`
|
||||||
])
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix object property shorthand value', () => {
|
test('should prefix object property shorthand value', () => {
|
||||||
const node = parseWithExpressionTransform(`{{ { foo } }}`) as ExpressionNode
|
const node = parseWithExpressionTransform(
|
||||||
expect(node.children).toMatchObject([
|
`{{ { foo } }}`
|
||||||
`{ foo: `,
|
) as InterpolationNode
|
||||||
{ content: `_ctx.foo` },
|
expect(node.content).toMatchObject({
|
||||||
` }`
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
])
|
children: [`{ foo: `, { content: `_ctx.foo` }, ` }`]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not prefix id in a member expression', () => {
|
test('should not prefix id in a member expression', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ foo.bar.baz }}`
|
`{{ foo.bar.baz }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.children).toMatchObject([
|
expect(node.content).toMatchObject({
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
{ content: `_ctx.foo` },
|
{ content: `_ctx.foo` },
|
||||||
`.`,
|
`.`,
|
||||||
{ content: `bar` },
|
{ content: `bar` },
|
||||||
`.`,
|
`.`,
|
||||||
{ content: `baz` }
|
{ content: `baz` }
|
||||||
])
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should prefix computed id in a member expression', () => {
|
test('should prefix computed id in a member expression', () => {
|
||||||
const node = parseWithExpressionTransform(
|
const node = parseWithExpressionTransform(
|
||||||
`{{ foo[bar][baz] }}`
|
`{{ foo[bar][baz] }}`
|
||||||
) as ExpressionNode
|
) as InterpolationNode
|
||||||
expect(node.children).toMatchObject([
|
expect(node.content).toMatchObject({
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
{ content: `_ctx.foo` },
|
{ content: `_ctx.foo` },
|
||||||
`[`,
|
`[`,
|
||||||
{ content: `_ctx.bar` },
|
{ content: `_ctx.bar` },
|
||||||
`][`,
|
`][`,
|
||||||
{ content: '_ctx.baz' },
|
{ content: '_ctx.baz' },
|
||||||
`]`
|
`]`
|
||||||
])
|
]
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should handle parse error', () => {
|
test('should handle parse error', () => {
|
||||||
|
@ -31,7 +31,7 @@ describe('compiler: style transform', () => {
|
|||||||
)
|
)
|
||||||
expect(root.hoists).toMatchObject([
|
expect(root.hoists).toMatchObject([
|
||||||
{
|
{
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `{"color":"red"}`,
|
content: `{"color":"red"}`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
@ -40,12 +40,12 @@ describe('compiler: style transform', () => {
|
|||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: `bind`,
|
name: `bind`,
|
||||||
arg: {
|
arg: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `style`,
|
content: `style`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
exp: {
|
exp: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `_hoisted_1`,
|
content: `_hoisted_1`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
@ -64,12 +64,12 @@ describe('compiler: style transform', () => {
|
|||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
key: {
|
key: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `style`,
|
content: `style`,
|
||||||
isStatic: true
|
isStatic: true
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `_hoisted_1`,
|
content: `_hoisted_1`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
} from '../../src'
|
} from '../../src'
|
||||||
import { transformBind } from '../../src/transforms/vBind'
|
import { transformBind } from '../../src/transforms/vBind'
|
||||||
import { transformElement } from '../../src/transforms/transformElement'
|
import { transformElement } from '../../src/transforms/transformElement'
|
||||||
|
import { CAMELIZE } from '../../src/runtimeConstants'
|
||||||
|
import { transformExpression } from '../../src/transforms/transformExpression'
|
||||||
|
|
||||||
function parseWithVBind(
|
function parseWithVBind(
|
||||||
template: string,
|
template: string,
|
||||||
@ -15,7 +17,10 @@ function parseWithVBind(
|
|||||||
): ElementNode {
|
): ElementNode {
|
||||||
const ast = parse(template)
|
const ast = parse(template)
|
||||||
transform(ast, {
|
transform(ast, {
|
||||||
nodeTransforms: [transformElement],
|
nodeTransforms: [
|
||||||
|
...(options.prefixIdentifiers ? [transformExpression] : []),
|
||||||
|
transformElement
|
||||||
|
],
|
||||||
directiveTransforms: {
|
directiveTransforms: {
|
||||||
bind: transformBind
|
bind: transformBind
|
||||||
},
|
},
|
||||||
@ -117,4 +122,42 @@ describe('compiler: transform v-bind', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('.camel modifier w/ dynamic arg', () => {
|
||||||
|
const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`)
|
||||||
|
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
||||||
|
expect(props.properties[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `_${CAMELIZE}(foo)`,
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `id`,
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('.camel modifier w/ dynamic arg + prefixIdentifiers', () => {
|
||||||
|
const node = parseWithVBind(`<div v-bind:[foo(bar)].camel="id"/>`, {
|
||||||
|
prefixIdentifiers: true
|
||||||
|
})
|
||||||
|
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
||||||
|
expect(props.properties[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
children: [
|
||||||
|
`${CAMELIZE}(`,
|
||||||
|
{ content: `_ctx.foo` },
|
||||||
|
`(`,
|
||||||
|
{ content: `_ctx.bar` },
|
||||||
|
`)`,
|
||||||
|
`)`
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `_ctx.id`,
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { parse } from '../../src/parse'
|
import { parse } from '../../src/parse'
|
||||||
import { transform } from '../../src/transform'
|
import { transform } from '../../src/transform'
|
||||||
import { transformFor } from '../../src/transforms/vFor'
|
import { transformFor } from '../../src/transforms/vFor'
|
||||||
import { ForNode, NodeTypes } from '../../src/ast'
|
import { ForNode, NodeTypes, SimpleExpressionNode } from '../../src/ast'
|
||||||
import { ErrorCodes } from '../../src/errors'
|
import { ErrorCodes } from '../../src/errors'
|
||||||
import { CompilerOptions } from '../../src'
|
import { CompilerOptions } from '../../src'
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias).toBeUndefined()
|
expect(forNode.keyAlias).toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('index')
|
expect(forNode.valueAlias!.content).toBe('index')
|
||||||
expect(forNode.source.content).toBe('5')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('5')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('value', () => {
|
test('value', () => {
|
||||||
@ -32,7 +32,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias).toBeUndefined()
|
expect(forNode.keyAlias).toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('item')
|
expect(forNode.valueAlias!.content).toBe('item')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('object de-structured value', () => {
|
test('object de-structured value', () => {
|
||||||
@ -42,7 +42,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias).toBeUndefined()
|
expect(forNode.keyAlias).toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('{ id, value }')
|
expect(forNode.valueAlias!.content).toBe('{ id, value }')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('array de-structured value', () => {
|
test('array de-structured value', () => {
|
||||||
@ -52,7 +52,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias).toBeUndefined()
|
expect(forNode.keyAlias).toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('[ id, value ]')
|
expect(forNode.valueAlias!.content).toBe('[ id, value ]')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('value and key', () => {
|
test('value and key', () => {
|
||||||
@ -63,7 +63,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias!.content).toBe('key')
|
expect(forNode.keyAlias!.content).toBe('key')
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('item')
|
expect(forNode.valueAlias!.content).toBe('item')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('value, key and index', () => {
|
test('value, key and index', () => {
|
||||||
@ -75,7 +75,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias!.content).toBe('index')
|
expect(forNode.objectIndexAlias!.content).toBe('index')
|
||||||
expect(forNode.valueAlias!.content).toBe('value')
|
expect(forNode.valueAlias!.content).toBe('value')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('skipped key', () => {
|
test('skipped key', () => {
|
||||||
@ -86,7 +86,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias!.content).toBe('index')
|
expect(forNode.objectIndexAlias!.content).toBe('index')
|
||||||
expect(forNode.valueAlias!.content).toBe('value')
|
expect(forNode.valueAlias!.content).toBe('value')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('skipped value and key', () => {
|
test('skipped value and key', () => {
|
||||||
@ -95,7 +95,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias!.content).toBe('index')
|
expect(forNode.objectIndexAlias!.content).toBe('index')
|
||||||
expect(forNode.valueAlias).toBeUndefined()
|
expect(forNode.valueAlias).toBeUndefined()
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unbracketed value', () => {
|
test('unbracketed value', () => {
|
||||||
@ -103,7 +103,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias).toBeUndefined()
|
expect(forNode.keyAlias).toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('item')
|
expect(forNode.valueAlias!.content).toBe('item')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unbracketed value and key', () => {
|
test('unbracketed value and key', () => {
|
||||||
@ -112,7 +112,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.keyAlias!.content).toBe('key')
|
expect(forNode.keyAlias!.content).toBe('key')
|
||||||
expect(forNode.objectIndexAlias).toBeUndefined()
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
||||||
expect(forNode.valueAlias!.content).toBe('item')
|
expect(forNode.valueAlias!.content).toBe('item')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unbracketed value, key and index', () => {
|
test('unbracketed value, key and index', () => {
|
||||||
@ -124,7 +124,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias!.content).toBe('index')
|
expect(forNode.objectIndexAlias!.content).toBe('index')
|
||||||
expect(forNode.valueAlias!.content).toBe('value')
|
expect(forNode.valueAlias!.content).toBe('value')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unbracketed skipped key', () => {
|
test('unbracketed skipped key', () => {
|
||||||
@ -135,7 +135,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias!.content).toBe('index')
|
expect(forNode.objectIndexAlias!.content).toBe('index')
|
||||||
expect(forNode.valueAlias!.content).toBe('value')
|
expect(forNode.valueAlias!.content).toBe('value')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unbracketed skipped value and key', () => {
|
test('unbracketed skipped value and key', () => {
|
||||||
@ -144,7 +144,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
||||||
expect(forNode.objectIndexAlias!.content).toBe('index')
|
expect(forNode.objectIndexAlias!.content).toBe('index')
|
||||||
expect(forNode.valueAlias).toBeUndefined()
|
expect(forNode.valueAlias).toBeUndefined()
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('missing expression', () => {
|
test('missing expression', () => {
|
||||||
@ -223,7 +223,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const itemsOffset = source.indexOf('items')
|
const itemsOffset = source.indexOf('items')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
||||||
expect(forNode.source.loc.start.line).toBe(1)
|
expect(forNode.source.loc.start.line).toBe(1)
|
||||||
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
||||||
@ -248,7 +248,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const itemsOffset = source.indexOf('items')
|
const itemsOffset = source.indexOf('items')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
||||||
expect(forNode.source.loc.start.line).toBe(1)
|
expect(forNode.source.loc.start.line).toBe(1)
|
||||||
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
||||||
@ -273,7 +273,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const itemsOffset = source.indexOf('items')
|
const itemsOffset = source.indexOf('items')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
||||||
expect(forNode.source.loc.start.line).toBe(1)
|
expect(forNode.source.loc.start.line).toBe(1)
|
||||||
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
||||||
@ -318,7 +318,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const itemsOffset = source.indexOf('items')
|
const itemsOffset = source.indexOf('items')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
||||||
expect(forNode.source.loc.start.line).toBe(1)
|
expect(forNode.source.loc.start.line).toBe(1)
|
||||||
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
||||||
@ -353,7 +353,7 @@ describe('compiler: transform v-for', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const itemsOffset = source.indexOf('items')
|
const itemsOffset = source.indexOf('items')
|
||||||
expect(forNode.source.content).toBe('items')
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
||||||
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
expect(forNode.source.loc.start.offset).toBe(itemsOffset)
|
||||||
expect(forNode.source.loc.start.line).toBe(1)
|
expect(forNode.source.loc.start.line).toBe(1)
|
||||||
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
expect(forNode.source.loc.start.column).toBe(itemsOffset + 1)
|
||||||
|
@ -6,7 +6,8 @@ import {
|
|||||||
NodeTypes,
|
NodeTypes,
|
||||||
ElementNode,
|
ElementNode,
|
||||||
TextNode,
|
TextNode,
|
||||||
CommentNode
|
CommentNode,
|
||||||
|
SimpleExpressionNode
|
||||||
} from '../../src/ast'
|
} from '../../src/ast'
|
||||||
import { ErrorCodes } from '../../src/errors'
|
import { ErrorCodes } from '../../src/errors'
|
||||||
import { CompilerOptions } from '../../src'
|
import { CompilerOptions } from '../../src'
|
||||||
@ -30,7 +31,9 @@ describe('compiler: transform v-if', () => {
|
|||||||
const node = parseWithIfTransform(`<div v-if="ok"/>`)
|
const node = parseWithIfTransform(`<div v-if="ok"/>`)
|
||||||
expect(node.type).toBe(NodeTypes.IF)
|
expect(node.type).toBe(NodeTypes.IF)
|
||||||
expect(node.branches.length).toBe(1)
|
expect(node.branches.length).toBe(1)
|
||||||
expect(node.branches[0].condition!.content).toBe(`ok`)
|
expect((node.branches[0].condition as SimpleExpressionNode).content).toBe(
|
||||||
|
`ok`
|
||||||
|
)
|
||||||
expect(node.branches[0].children.length).toBe(1)
|
expect(node.branches[0].children.length).toBe(1)
|
||||||
expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
|
expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
|
||||||
@ -42,7 +45,9 @@ describe('compiler: transform v-if', () => {
|
|||||||
)
|
)
|
||||||
expect(node.type).toBe(NodeTypes.IF)
|
expect(node.type).toBe(NodeTypes.IF)
|
||||||
expect(node.branches.length).toBe(1)
|
expect(node.branches.length).toBe(1)
|
||||||
expect(node.branches[0].condition!.content).toBe(`ok`)
|
expect((node.branches[0].condition as SimpleExpressionNode).content).toBe(
|
||||||
|
`ok`
|
||||||
|
)
|
||||||
expect(node.branches[0].children.length).toBe(3)
|
expect(node.branches[0].children.length).toBe(3)
|
||||||
expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
|
expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
|
||||||
@ -58,7 +63,7 @@ describe('compiler: transform v-if', () => {
|
|||||||
expect(node.branches.length).toBe(2)
|
expect(node.branches.length).toBe(2)
|
||||||
|
|
||||||
const b1 = node.branches[0]
|
const b1 = node.branches[0]
|
||||||
expect(b1.condition!.content).toBe(`ok`)
|
expect((b1.condition as SimpleExpressionNode).content).toBe(`ok`)
|
||||||
expect(b1.children.length).toBe(1)
|
expect(b1.children.length).toBe(1)
|
||||||
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
||||||
@ -76,13 +81,13 @@ describe('compiler: transform v-if', () => {
|
|||||||
expect(node.branches.length).toBe(2)
|
expect(node.branches.length).toBe(2)
|
||||||
|
|
||||||
const b1 = node.branches[0]
|
const b1 = node.branches[0]
|
||||||
expect(b1.condition!.content).toBe(`ok`)
|
expect((b1.condition as SimpleExpressionNode).content).toBe(`ok`)
|
||||||
expect(b1.children.length).toBe(1)
|
expect(b1.children.length).toBe(1)
|
||||||
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
||||||
|
|
||||||
const b2 = node.branches[1]
|
const b2 = node.branches[1]
|
||||||
expect(b2.condition!.content).toBe(`orNot`)
|
expect((b2.condition as SimpleExpressionNode).content).toBe(`orNot`)
|
||||||
expect(b2.children.length).toBe(1)
|
expect(b2.children.length).toBe(1)
|
||||||
expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((b2.children[0] as ElementNode).tag).toBe(`p`)
|
expect((b2.children[0] as ElementNode).tag).toBe(`p`)
|
||||||
@ -96,13 +101,13 @@ describe('compiler: transform v-if', () => {
|
|||||||
expect(node.branches.length).toBe(3)
|
expect(node.branches.length).toBe(3)
|
||||||
|
|
||||||
const b1 = node.branches[0]
|
const b1 = node.branches[0]
|
||||||
expect(b1.condition!.content).toBe(`ok`)
|
expect((b1.condition as SimpleExpressionNode).content).toBe(`ok`)
|
||||||
expect(b1.children.length).toBe(1)
|
expect(b1.children.length).toBe(1)
|
||||||
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
||||||
|
|
||||||
const b2 = node.branches[1]
|
const b2 = node.branches[1]
|
||||||
expect(b2.condition!.content).toBe(`orNot`)
|
expect((b2.condition as SimpleExpressionNode).content).toBe(`orNot`)
|
||||||
expect(b2.children.length).toBe(1)
|
expect(b2.children.length).toBe(1)
|
||||||
expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((b2.children[0] as ElementNode).tag).toBe(`p`)
|
expect((b2.children[0] as ElementNode).tag).toBe(`p`)
|
||||||
@ -126,13 +131,13 @@ describe('compiler: transform v-if', () => {
|
|||||||
expect(node.branches.length).toBe(3)
|
expect(node.branches.length).toBe(3)
|
||||||
|
|
||||||
const b1 = node.branches[0]
|
const b1 = node.branches[0]
|
||||||
expect(b1.condition!.content).toBe(`ok`)
|
expect((b1.condition as SimpleExpressionNode).content).toBe(`ok`)
|
||||||
expect(b1.children.length).toBe(1)
|
expect(b1.children.length).toBe(1)
|
||||||
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
expect((b1.children[0] as ElementNode).tag).toBe(`div`)
|
||||||
|
|
||||||
const b2 = node.branches[1]
|
const b2 = node.branches[1]
|
||||||
expect(b2.condition!.content).toBe(`orNot`)
|
expect((b2.condition as SimpleExpressionNode).content).toBe(`orNot`)
|
||||||
expect(b2.children.length).toBe(2)
|
expect(b2.children.length).toBe(2)
|
||||||
expect(b2.children[0].type).toBe(NodeTypes.COMMENT)
|
expect(b2.children[0].type).toBe(NodeTypes.COMMENT)
|
||||||
expect((b2.children[0] as CommentNode).content).toBe(`foo`)
|
expect((b2.children[0] as CommentNode).content).toBe(`foo`)
|
||||||
|
@ -4,7 +4,8 @@ import {
|
|||||||
ElementNode,
|
ElementNode,
|
||||||
ObjectExpression,
|
ObjectExpression,
|
||||||
CompilerOptions,
|
CompilerOptions,
|
||||||
ErrorCodes
|
ErrorCodes,
|
||||||
|
NodeTypes
|
||||||
} from '../../src'
|
} from '../../src'
|
||||||
import { transformOn } from '../../src/transforms/vOn'
|
import { transformOn } from '../../src/transforms/vOn'
|
||||||
import { transformElement } from '../../src/transforms/transformElement'
|
import { transformElement } from '../../src/transforms/transformElement'
|
||||||
@ -76,10 +77,11 @@ describe('compiler: transform v-on', () => {
|
|||||||
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
||||||
expect(props.properties[0]).toMatchObject({
|
expect(props.properties[0]).toMatchObject({
|
||||||
key: {
|
key: {
|
||||||
isStatic: false,
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
children: [`"on" + `, { content: `event` }]
|
children: [`"on" + (`, { content: `event` }, `)`]
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `handler`,
|
content: `handler`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
@ -93,10 +95,36 @@ describe('compiler: transform v-on', () => {
|
|||||||
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
||||||
expect(props.properties[0]).toMatchObject({
|
expect(props.properties[0]).toMatchObject({
|
||||||
key: {
|
key: {
|
||||||
isStatic: false,
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
children: [`"on" + `, { content: `_ctx.event` }]
|
children: [`"on" + (`, { content: `_ctx.event` }, `)`]
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `_ctx.handler`,
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dynamic arg with complex exp prefixing', () => {
|
||||||
|
const node = parseWithVOn(`<div v-on:[event(foo)]="handler"/>`, {
|
||||||
|
prefixIdentifiers: true
|
||||||
|
})
|
||||||
|
const props = node.codegenNode!.arguments[1] as ObjectExpression
|
||||||
|
expect(props.properties[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
children: [
|
||||||
|
`"on" + (`,
|
||||||
|
{ content: `_ctx.event` },
|
||||||
|
`(`,
|
||||||
|
{ content: `_ctx.foo` },
|
||||||
|
`)`,
|
||||||
|
`)`
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: `_ctx.handler`,
|
content: `_ctx.handler`,
|
||||||
isStatic: false
|
isStatic: false
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { isString } from '@vue/shared'
|
||||||
|
|
||||||
// Vue template is a platform-agnostic superset of HTML (syntax only).
|
// Vue template is a platform-agnostic superset of HTML (syntax only).
|
||||||
// More namespaces like SVG and MathML are declared by platform specific
|
// More namespaces like SVG and MathML are declared by platform specific
|
||||||
// compilers.
|
// compilers.
|
||||||
@ -12,7 +14,8 @@ export const enum NodeTypes {
|
|||||||
ELEMENT,
|
ELEMENT,
|
||||||
TEXT,
|
TEXT,
|
||||||
COMMENT,
|
COMMENT,
|
||||||
EXPRESSION,
|
SIMPLE_EXPRESSION,
|
||||||
|
INTERPOLATION,
|
||||||
ATTRIBUTE,
|
ATTRIBUTE,
|
||||||
DIRECTIVE,
|
DIRECTIVE,
|
||||||
// containers
|
// containers
|
||||||
@ -55,9 +58,11 @@ export interface Position {
|
|||||||
|
|
||||||
export type ParentNode = RootNode | ElementNode | IfBranchNode | ForNode
|
export type ParentNode = RootNode | ElementNode | IfBranchNode | ForNode
|
||||||
|
|
||||||
|
export type ExpressionNode = SimpleExpressionNode | CompoundExpressionNode
|
||||||
|
|
||||||
export type ChildNode =
|
export type ChildNode =
|
||||||
| ElementNode
|
| ElementNode
|
||||||
| ExpressionNode
|
| InterpolationNode
|
||||||
| TextNode
|
| TextNode
|
||||||
| CommentNode
|
| CommentNode
|
||||||
| IfNode
|
| IfNode
|
||||||
@ -107,12 +112,21 @@ export interface DirectiveNode extends Node {
|
|||||||
modifiers: string[]
|
modifiers: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExpressionNode extends Node {
|
export interface SimpleExpressionNode extends Node {
|
||||||
type: NodeTypes.EXPRESSION
|
type: NodeTypes.SIMPLE_EXPRESSION
|
||||||
content: string
|
content: string
|
||||||
isStatic: boolean
|
isStatic: boolean
|
||||||
isInterpolation: boolean
|
}
|
||||||
children?: (ExpressionNode | string)[]
|
|
||||||
|
export interface InterpolationNode extends Node {
|
||||||
|
type: NodeTypes.INTERPOLATION
|
||||||
|
content: ExpressionNode
|
||||||
|
}
|
||||||
|
|
||||||
|
// always dynamic
|
||||||
|
export interface CompoundExpressionNode extends Node {
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION
|
||||||
|
children: (SimpleExpressionNode | string)[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IfNode extends Node {
|
export interface IfNode extends Node {
|
||||||
@ -129,9 +143,9 @@ export interface IfBranchNode extends Node {
|
|||||||
export interface ForNode extends Node {
|
export interface ForNode extends Node {
|
||||||
type: NodeTypes.FOR
|
type: NodeTypes.FOR
|
||||||
source: ExpressionNode
|
source: ExpressionNode
|
||||||
valueAlias: ExpressionNode | undefined
|
valueAlias: SimpleExpressionNode | undefined
|
||||||
keyAlias: ExpressionNode | undefined
|
keyAlias: SimpleExpressionNode | undefined
|
||||||
objectIndexAlias: ExpressionNode | undefined
|
objectIndexAlias: SimpleExpressionNode | undefined
|
||||||
children: ChildNode[]
|
children: ChildNode[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +204,7 @@ export function createObjectExpression(
|
|||||||
|
|
||||||
export function createObjectProperty(
|
export function createObjectProperty(
|
||||||
key: ExpressionNode,
|
key: ExpressionNode,
|
||||||
value: ExpressionNode,
|
value: JSChildNode,
|
||||||
loc: SourceLocation
|
loc: SourceLocation
|
||||||
): Property {
|
): Property {
|
||||||
return {
|
return {
|
||||||
@ -201,18 +215,40 @@ export function createObjectProperty(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createExpression(
|
export function createSimpleExpression(
|
||||||
content: string,
|
content: string,
|
||||||
isStatic: boolean,
|
isStatic: boolean,
|
||||||
loc: SourceLocation,
|
loc: SourceLocation
|
||||||
isInterpolation = false
|
): SimpleExpressionNode {
|
||||||
): ExpressionNode {
|
|
||||||
return {
|
return {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
loc,
|
loc,
|
||||||
content,
|
content,
|
||||||
isStatic,
|
isStatic
|
||||||
isInterpolation
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createInterpolation(
|
||||||
|
content: string | CompoundExpressionNode,
|
||||||
|
loc: SourceLocation
|
||||||
|
): InterpolationNode {
|
||||||
|
return {
|
||||||
|
type: NodeTypes.INTERPOLATION,
|
||||||
|
loc,
|
||||||
|
content: isString(content)
|
||||||
|
? createSimpleExpression(content, false, loc)
|
||||||
|
: content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createCompoundExpression(
|
||||||
|
children: CompoundExpressionNode['children'],
|
||||||
|
loc: SourceLocation
|
||||||
|
): CompoundExpressionNode {
|
||||||
|
return {
|
||||||
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
||||||
|
loc,
|
||||||
|
children
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,10 @@ import {
|
|||||||
ObjectExpression,
|
ObjectExpression,
|
||||||
IfBranchNode,
|
IfBranchNode,
|
||||||
SourceLocation,
|
SourceLocation,
|
||||||
Position
|
Position,
|
||||||
|
InterpolationNode,
|
||||||
|
CompoundExpressionNode,
|
||||||
|
SimpleExpressionNode
|
||||||
} from './ast'
|
} from './ast'
|
||||||
import { SourceMapGenerator, RawSourceMap } from 'source-map'
|
import { SourceMapGenerator, RawSourceMap } from 'source-map'
|
||||||
import {
|
import {
|
||||||
@ -110,11 +113,7 @@ function createCodegenContext(
|
|||||||
if (!__BROWSER__ && context.map) {
|
if (!__BROWSER__ && context.map) {
|
||||||
if (node) {
|
if (node) {
|
||||||
let name
|
let name
|
||||||
if (
|
if (node.type === NodeTypes.SIMPLE_EXPRESSION && !node.isStatic) {
|
||||||
node.type === NodeTypes.EXPRESSION &&
|
|
||||||
!node.children &&
|
|
||||||
!node.isStatic
|
|
||||||
) {
|
|
||||||
const content = node.content.replace(/^_ctx\./, '')
|
const content = node.content.replace(/^_ctx\./, '')
|
||||||
if (content !== node.content && isSimpleIdentifier(content)) {
|
if (content !== node.content && isSimpleIdentifier(content)) {
|
||||||
name = content
|
name = content
|
||||||
@ -263,7 +262,7 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) {
|
|||||||
|
|
||||||
// This will generate a single vnode call if:
|
// This will generate a single vnode call if:
|
||||||
// - The target position explicitly allows a single node (root, if, for)
|
// - The target position explicitly allows a single node (root, if, for)
|
||||||
// - The list has length === 1, AND The only child is a text or expression.
|
// - The list has length === 1, AND The only child is a text, expression or comment.
|
||||||
function genChildren(
|
function genChildren(
|
||||||
children: ChildNode[],
|
children: ChildNode[],
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
@ -277,7 +276,8 @@ function genChildren(
|
|||||||
children.length === 1 &&
|
children.length === 1 &&
|
||||||
(allowSingle ||
|
(allowSingle ||
|
||||||
child.type === NodeTypes.TEXT ||
|
child.type === NodeTypes.TEXT ||
|
||||||
child.type == NodeTypes.EXPRESSION)
|
child.type === NodeTypes.INTERPOLATION ||
|
||||||
|
child.type === NodeTypes.COMMENT)
|
||||||
) {
|
) {
|
||||||
genNode(child, context)
|
genNode(child, context)
|
||||||
} else {
|
} else {
|
||||||
@ -331,9 +331,15 @@ function genNode(node: CodegenNode, context: CodegenContext) {
|
|||||||
case NodeTypes.TEXT:
|
case NodeTypes.TEXT:
|
||||||
genText(node, context)
|
genText(node, context)
|
||||||
break
|
break
|
||||||
case NodeTypes.EXPRESSION:
|
case NodeTypes.SIMPLE_EXPRESSION:
|
||||||
genExpression(node, context)
|
genExpression(node, context)
|
||||||
break
|
break
|
||||||
|
case NodeTypes.INTERPOLATION:
|
||||||
|
genInterpolation(node, context)
|
||||||
|
break
|
||||||
|
case NodeTypes.COMPOUND_EXPRESSION:
|
||||||
|
genCompoundExpression(node, context)
|
||||||
|
break
|
||||||
case NodeTypes.COMMENT:
|
case NodeTypes.COMMENT:
|
||||||
genComment(node, context)
|
genComment(node, context)
|
||||||
break
|
break
|
||||||
@ -369,24 +375,37 @@ function genElement(node: ElementNode, context: CodegenContext) {
|
|||||||
genCallExpression(node.codegenNode!, context, false)
|
genCallExpression(node.codegenNode!, context, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function genText(node: TextNode | ExpressionNode, context: CodegenContext) {
|
function genText(
|
||||||
|
node: TextNode | SimpleExpressionNode,
|
||||||
|
context: CodegenContext
|
||||||
|
) {
|
||||||
context.push(JSON.stringify(node.content), node)
|
context.push(JSON.stringify(node.content), node)
|
||||||
}
|
}
|
||||||
|
|
||||||
function genExpression(node: ExpressionNode, context: CodegenContext) {
|
function genExpression(node: SimpleExpressionNode, context: CodegenContext) {
|
||||||
|
const { content, isStatic } = node
|
||||||
|
context.push(isStatic ? JSON.stringify(content) : content, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
function genInterpolation(node: InterpolationNode, context: CodegenContext) {
|
||||||
const { push, helper } = context
|
const { push, helper } = context
|
||||||
const { content, children, isStatic, isInterpolation } = node
|
|
||||||
if (isInterpolation) {
|
|
||||||
push(`${helper(TO_STRING)}(`)
|
push(`${helper(TO_STRING)}(`)
|
||||||
}
|
genNode(node.content, context)
|
||||||
if (children) {
|
|
||||||
genCompoundExpression(node, context)
|
|
||||||
} else {
|
|
||||||
push(isStatic ? JSON.stringify(content) : content, node)
|
|
||||||
}
|
|
||||||
if (isInterpolation) {
|
|
||||||
push(`)`)
|
push(`)`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function genCompoundExpression(
|
||||||
|
node: CompoundExpressionNode,
|
||||||
|
context: CodegenContext
|
||||||
|
) {
|
||||||
|
for (let i = 0; i < node.children!.length; i++) {
|
||||||
|
const child = node.children![i]
|
||||||
|
if (isString(child)) {
|
||||||
|
context.push(child)
|
||||||
|
} else {
|
||||||
|
genExpression(child, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function genExpressionAsPropertyKey(
|
function genExpressionAsPropertyKey(
|
||||||
@ -394,28 +413,18 @@ function genExpressionAsPropertyKey(
|
|||||||
context: CodegenContext
|
context: CodegenContext
|
||||||
) {
|
) {
|
||||||
const { push } = context
|
const { push } = context
|
||||||
const { content, children, isStatic } = node
|
if (node.type === NodeTypes.COMPOUND_EXPRESSION) {
|
||||||
if (children) {
|
|
||||||
push(`[`)
|
push(`[`)
|
||||||
genCompoundExpression(node, context)
|
genCompoundExpression(node, context)
|
||||||
push(`]`)
|
push(`]`)
|
||||||
} else if (isStatic) {
|
} else if (node.isStatic) {
|
||||||
// only quote keys if necessary
|
// only quote keys if necessary
|
||||||
const text = isSimpleIdentifier(content) ? content : JSON.stringify(content)
|
const text = isSimpleIdentifier(node.content)
|
||||||
|
? node.content
|
||||||
|
: JSON.stringify(node.content)
|
||||||
push(text, node)
|
push(text, node)
|
||||||
} else {
|
} else {
|
||||||
push(`[${content}]`, node)
|
push(`[${node.content}]`, node)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function genCompoundExpression(node: ExpressionNode, context: CodegenContext) {
|
|
||||||
for (let i = 0; i < node.children!.length; i++) {
|
|
||||||
const child = node.children![i]
|
|
||||||
if (isString(child)) {
|
|
||||||
context.push(child)
|
|
||||||
} else {
|
|
||||||
genExpression(child, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,10 +454,14 @@ function genIfBranch(
|
|||||||
if (condition) {
|
if (condition) {
|
||||||
// v-if or v-else-if
|
// v-if or v-else-if
|
||||||
const { push, indent, deindent, newline } = context
|
const { push, indent, deindent, newline } = context
|
||||||
|
if (condition.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||||
const needsQuote = !isSimpleIdentifier(condition.content)
|
const needsQuote = !isSimpleIdentifier(condition.content)
|
||||||
needsQuote && push(`(`)
|
needsQuote && push(`(`)
|
||||||
genExpression(condition, context)
|
genExpression(condition, context)
|
||||||
needsQuote && push(`)`)
|
needsQuote && push(`)`)
|
||||||
|
} else {
|
||||||
|
genCompoundExpression(condition, context)
|
||||||
|
}
|
||||||
indent()
|
indent()
|
||||||
context.indentLevel++
|
context.indentLevel++
|
||||||
push(`? `)
|
push(`? `)
|
||||||
@ -473,7 +486,7 @@ function genFor(node: ForNode, context: CodegenContext) {
|
|||||||
const { push, helper, indent, deindent } = context
|
const { push, helper, indent, deindent } = context
|
||||||
const { source, keyAlias, valueAlias, objectIndexAlias, children } = node
|
const { source, keyAlias, valueAlias, objectIndexAlias, children } = node
|
||||||
push(`${helper(RENDER_LIST)}(`, node, true)
|
push(`${helper(RENDER_LIST)}(`, node, true)
|
||||||
genExpression(source, context)
|
genNode(source, context)
|
||||||
push(`, (`)
|
push(`, (`)
|
||||||
if (valueAlias) {
|
if (valueAlias) {
|
||||||
genExpression(valueAlias, context)
|
genExpression(valueAlias, context)
|
||||||
|
@ -128,7 +128,8 @@ export const errorMessages: { [code: number]: string } = {
|
|||||||
[ErrorCodes.X_MISSING_INTERPOLATION_END]:
|
[ErrorCodes.X_MISSING_INTERPOLATION_END]:
|
||||||
'Interpolation end sign was not found.',
|
'Interpolation end sign was not found.',
|
||||||
[ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END]:
|
[ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END]:
|
||||||
'End bracket for dynamic directive argument was not found.',
|
'End bracket for dynamic directive argument was not found. ' +
|
||||||
|
'Note that dynamic directive argument connot contain spaces.',
|
||||||
|
|
||||||
// transform errors
|
// transform errors
|
||||||
[ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF]: `v-else-if has no adjacent v-if`,
|
[ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF]: `v-else-if has no adjacent v-if`,
|
||||||
|
@ -23,7 +23,8 @@ import {
|
|||||||
RootNode,
|
RootNode,
|
||||||
SourceLocation,
|
SourceLocation,
|
||||||
TextNode,
|
TextNode,
|
||||||
ChildNode
|
ChildNode,
|
||||||
|
InterpolationNode
|
||||||
} from './ast'
|
} from './ast'
|
||||||
|
|
||||||
export interface ParserOptions {
|
export interface ParserOptions {
|
||||||
@ -122,7 +123,7 @@ function parseChildren(
|
|||||||
while (!isEnd(context, mode, ancestors)) {
|
while (!isEnd(context, mode, ancestors)) {
|
||||||
__DEV__ && assert(context.source.length > 0)
|
__DEV__ && assert(context.source.length > 0)
|
||||||
const s = context.source
|
const s = context.source
|
||||||
let node: any = null
|
let node: ChildNode | ChildNode[] | undefined = undefined
|
||||||
|
|
||||||
if (startsWith(s, context.options.delimiters[0])) {
|
if (startsWith(s, context.options.delimiters[0])) {
|
||||||
// '{{'
|
// '{{'
|
||||||
@ -529,10 +530,9 @@ function parseAttribute(
|
|||||||
}
|
}
|
||||||
|
|
||||||
arg = {
|
arg = {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content,
|
content,
|
||||||
isStatic,
|
isStatic,
|
||||||
isInterpolation: false,
|
|
||||||
loc
|
loc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -555,10 +555,9 @@ function parseAttribute(
|
|||||||
? 'on'
|
? 'on'
|
||||||
: 'slot'),
|
: 'slot'),
|
||||||
exp: value && {
|
exp: value && {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
content: value.content,
|
content: value.content,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: false,
|
|
||||||
loc: value.loc
|
loc: value.loc
|
||||||
},
|
},
|
||||||
arg,
|
arg,
|
||||||
@ -633,7 +632,7 @@ function parseAttributeValue(
|
|||||||
function parseInterpolation(
|
function parseInterpolation(
|
||||||
context: ParserContext,
|
context: ParserContext,
|
||||||
mode: TextModes
|
mode: TextModes
|
||||||
): ExpressionNode | undefined {
|
): InterpolationNode | undefined {
|
||||||
const [open, close] = context.options.delimiters
|
const [open, close] = context.options.delimiters
|
||||||
__DEV__ && assert(startsWith(context.source, open))
|
__DEV__ && assert(startsWith(context.source, open))
|
||||||
|
|
||||||
@ -643,28 +642,32 @@ function parseInterpolation(
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceBy(context, open.length)
|
|
||||||
const start = getCursor(context)
|
const start = getCursor(context)
|
||||||
const end = getCursor(context)
|
advanceBy(context, open.length)
|
||||||
|
const innerStart = getCursor(context)
|
||||||
|
const innerEnd = getCursor(context)
|
||||||
const rawContentLength = closeIndex - open.length
|
const rawContentLength = closeIndex - open.length
|
||||||
const rawContent = context.source.slice(0, rawContentLength)
|
const rawContent = context.source.slice(0, rawContentLength)
|
||||||
const preTrimContent = parseTextData(context, rawContentLength, mode)
|
const preTrimContent = parseTextData(context, rawContentLength, mode)
|
||||||
const content = preTrimContent.trim()
|
const content = preTrimContent.trim()
|
||||||
const startOffset = preTrimContent.indexOf(content)
|
const startOffset = preTrimContent.indexOf(content)
|
||||||
if (startOffset > 0) {
|
if (startOffset > 0) {
|
||||||
advancePositionWithMutation(start, rawContent, startOffset)
|
advancePositionWithMutation(innerStart, rawContent, startOffset)
|
||||||
}
|
}
|
||||||
const endOffset =
|
const endOffset =
|
||||||
rawContentLength - (preTrimContent.length - content.length - startOffset)
|
rawContentLength - (preTrimContent.length - content.length - startOffset)
|
||||||
advancePositionWithMutation(end, rawContent, endOffset)
|
advancePositionWithMutation(innerEnd, rawContent, endOffset)
|
||||||
advanceBy(context, close.length)
|
advanceBy(context, close.length)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
isStatic: false,
|
||||||
content,
|
content,
|
||||||
loc: getSelection(context, start, end),
|
loc: getSelection(context, innerStart, innerEnd)
|
||||||
isStatic: content === '',
|
},
|
||||||
isInterpolation: true
|
loc: getSelection(context, start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,3 +13,4 @@ export const RENDER_LIST = `renderList`
|
|||||||
export const TO_STRING = `toString`
|
export const TO_STRING = `toString`
|
||||||
export const MERGE_PROPS = `mergeProps`
|
export const MERGE_PROPS = `mergeProps`
|
||||||
export const TO_HANDLERS = `toHandlers`
|
export const TO_HANDLERS = `toHandlers`
|
||||||
|
export const CAMELIZE = `camelize`
|
||||||
|
@ -7,8 +7,9 @@ import {
|
|||||||
DirectiveNode,
|
DirectiveNode,
|
||||||
Property,
|
Property,
|
||||||
ExpressionNode,
|
ExpressionNode,
|
||||||
createExpression,
|
createSimpleExpression,
|
||||||
JSChildNode
|
JSChildNode,
|
||||||
|
SimpleExpressionNode
|
||||||
} from './ast'
|
} from './ast'
|
||||||
import { isString, isArray } from '@vue/shared'
|
import { isString, isArray } from '@vue/shared'
|
||||||
import { CompilerError, defaultOnError } from './errors'
|
import { CompilerError, defaultOnError } from './errors'
|
||||||
@ -63,8 +64,8 @@ export interface TransformContext extends Required<TransformOptions> {
|
|||||||
replaceNode(node: ChildNode): void
|
replaceNode(node: ChildNode): void
|
||||||
removeNode(node?: ChildNode): void
|
removeNode(node?: ChildNode): void
|
||||||
onNodeRemoved: () => void
|
onNodeRemoved: () => void
|
||||||
addIdentifier(exp: ExpressionNode): void
|
addIdentifier(exp: SimpleExpressionNode): void
|
||||||
removeIdentifier(exp: ExpressionNode): void
|
removeIdentifier(exp: SimpleExpressionNode): void
|
||||||
hoist(exp: JSChildNode): ExpressionNode
|
hoist(exp: JSChildNode): ExpressionNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ function createTransformContext(
|
|||||||
},
|
},
|
||||||
hoist(exp) {
|
hoist(exp) {
|
||||||
context.hoists.push(exp)
|
context.hoists.push(exp)
|
||||||
return createExpression(
|
return createSimpleExpression(
|
||||||
`_hoisted_${context.hoists.length}`,
|
`_hoisted_${context.hoists.length}`,
|
||||||
false,
|
false,
|
||||||
exp.loc
|
exp.loc
|
||||||
@ -205,11 +206,9 @@ export function traverseNode(node: ChildNode, context: TransformContext) {
|
|||||||
// comment nodes with `createVNode`
|
// comment nodes with `createVNode`
|
||||||
context.helper(COMMENT)
|
context.helper(COMMENT)
|
||||||
break
|
break
|
||||||
case NodeTypes.EXPRESSION:
|
case NodeTypes.INTERPOLATION:
|
||||||
// no need to traverse, but we need to inject toString helper
|
// no need to traverse, but we need to inject toString helper
|
||||||
if (node.isInterpolation) {
|
|
||||||
context.helper(TO_STRING)
|
context.helper(TO_STRING)
|
||||||
}
|
|
||||||
break
|
break
|
||||||
|
|
||||||
// for container types, further traverse downwards
|
// for container types, further traverse downwards
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
createCallExpression,
|
createCallExpression,
|
||||||
createArrayExpression,
|
createArrayExpression,
|
||||||
createObjectProperty,
|
createObjectProperty,
|
||||||
createExpression,
|
createSimpleExpression,
|
||||||
createObjectExpression,
|
createObjectExpression,
|
||||||
Property
|
Property
|
||||||
} from '../ast'
|
} from '../ast'
|
||||||
@ -122,8 +122,12 @@ function buildProps(
|
|||||||
const { loc, name, value } = prop
|
const { loc, name, value } = prop
|
||||||
properties.push(
|
properties.push(
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
createExpression(name, true, getInnerRange(loc, 0, name.length)),
|
createSimpleExpression(
|
||||||
createExpression(
|
name,
|
||||||
|
true,
|
||||||
|
getInnerRange(loc, 0, name.length)
|
||||||
|
),
|
||||||
|
createSimpleExpression(
|
||||||
value ? value.content : '',
|
value ? value.content : '',
|
||||||
true,
|
true,
|
||||||
value ? value.loc : loc
|
value ? value.loc : loc
|
||||||
@ -236,8 +240,8 @@ function dedupeProperties(properties: Property[]): Property[] {
|
|||||||
const deduped: Property[] = []
|
const deduped: Property[] = []
|
||||||
for (let i = 0; i < properties.length; i++) {
|
for (let i = 0; i < properties.length; i++) {
|
||||||
const prop = properties[i]
|
const prop = properties[i]
|
||||||
// dynamic key named are always allowed
|
// dynamic keys are always allowed
|
||||||
if (!prop.key.isStatic) {
|
if (prop.key.type === NodeTypes.COMPOUND_EXPRESSION || !prop.key.isStatic) {
|
||||||
deduped.push(prop)
|
deduped.push(prop)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -273,16 +277,7 @@ function mergeAsArray(existing: Property, incoming: Property) {
|
|||||||
// :class="expression" class="string"
|
// :class="expression" class="string"
|
||||||
// -> class: expression + "string"
|
// -> class: expression + "string"
|
||||||
function mergeClasses(existing: Property, incoming: Property) {
|
function mergeClasses(existing: Property, incoming: Property) {
|
||||||
const e = existing.value as ExpressionNode
|
// TODO
|
||||||
const children =
|
|
||||||
e.children ||
|
|
||||||
(e.children = [
|
|
||||||
{
|
|
||||||
...e,
|
|
||||||
children: undefined
|
|
||||||
}
|
|
||||||
])
|
|
||||||
children.push(` + " " + `, incoming.value as ExpressionNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDirectiveArgs(
|
function createDirectiveArgs(
|
||||||
@ -305,8 +300,8 @@ function createDirectiveArgs(
|
|||||||
createObjectExpression(
|
createObjectExpression(
|
||||||
dir.modifiers.map(modifier =>
|
dir.modifiers.map(modifier =>
|
||||||
createObjectProperty(
|
createObjectProperty(
|
||||||
createExpression(modifier, true, loc),
|
createSimpleExpression(modifier, true, loc),
|
||||||
createExpression(`true`, false, loc),
|
createSimpleExpression(`true`, false, loc),
|
||||||
loc
|
loc
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -11,26 +11,39 @@
|
|||||||
import { parseScript } from 'meriyah'
|
import { parseScript } from 'meriyah'
|
||||||
import { walk } from 'estree-walker'
|
import { walk } from 'estree-walker'
|
||||||
import { NodeTransform, TransformContext } from '../transform'
|
import { NodeTransform, TransformContext } from '../transform'
|
||||||
import { NodeTypes, createExpression, ExpressionNode } from '../ast'
|
import {
|
||||||
|
NodeTypes,
|
||||||
|
createSimpleExpression,
|
||||||
|
ExpressionNode,
|
||||||
|
SimpleExpressionNode,
|
||||||
|
CompoundExpressionNode,
|
||||||
|
createCompoundExpression
|
||||||
|
} from '../ast'
|
||||||
import { Node, Function, Identifier, Property } from 'estree'
|
import { Node, Function, Identifier, Property } from 'estree'
|
||||||
import { advancePositionWithClone } from '../utils'
|
import { advancePositionWithClone } from '../utils'
|
||||||
|
|
||||||
export const transformExpression: NodeTransform = (node, context) => {
|
export const transformExpression: NodeTransform = (node, context) => {
|
||||||
if (node.type === NodeTypes.EXPRESSION && !node.isStatic) {
|
if (node.type === NodeTypes.INTERPOLATION) {
|
||||||
processExpression(node, context)
|
node.content = processExpression(
|
||||||
|
node.content as SimpleExpressionNode,
|
||||||
|
context
|
||||||
|
)
|
||||||
} else if (node.type === NodeTypes.ELEMENT) {
|
} else if (node.type === NodeTypes.ELEMENT) {
|
||||||
// handle directives on element
|
// handle directives on element
|
||||||
for (let i = 0; i < node.props.length; i++) {
|
for (let i = 0; i < node.props.length; i++) {
|
||||||
const prop = node.props[i]
|
const prop = node.props[i]
|
||||||
if (prop.type === NodeTypes.DIRECTIVE) {
|
if (prop.type === NodeTypes.DIRECTIVE) {
|
||||||
if (prop.exp) {
|
const exp = prop.exp as SimpleExpressionNode | undefined
|
||||||
processExpression(prop.exp, context)
|
const arg = prop.arg as SimpleExpressionNode | undefined
|
||||||
|
if (exp) {
|
||||||
|
prop.exp = processExpression(exp, context)
|
||||||
}
|
}
|
||||||
if (prop.arg && !prop.arg.isStatic) {
|
if (arg && !arg.isStatic) {
|
||||||
if (prop.name === 'class') {
|
if (prop.name === 'class') {
|
||||||
// TODO special expression optimization for classes
|
// TODO special expression optimization for classes
|
||||||
processExpression(prop.arg, context)
|
prop.arg = processExpression(arg, context)
|
||||||
} else {
|
} else {
|
||||||
processExpression(prop.arg, context)
|
prop.arg = processExpression(arg, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,32 +73,33 @@ interface PrefixMeta {
|
|||||||
// always be used with a leading !__BROWSER__ check so that it can be
|
// always be used with a leading !__BROWSER__ check so that it can be
|
||||||
// tree-shaken from the browser build.
|
// tree-shaken from the browser build.
|
||||||
export function processExpression(
|
export function processExpression(
|
||||||
node: ExpressionNode,
|
node: SimpleExpressionNode,
|
||||||
context: TransformContext
|
context: TransformContext
|
||||||
) {
|
): ExpressionNode {
|
||||||
if (!context.prefixIdentifiers) {
|
if (!context.prefixIdentifiers) {
|
||||||
return
|
return node
|
||||||
}
|
}
|
||||||
// lazy require dependencies so that they don't end up in rollup's dep graph
|
|
||||||
// and thus can be tree-shaken in browser builds.
|
|
||||||
const parseScript =
|
|
||||||
_parseScript || (_parseScript = require('meriyah').parseScript)
|
|
||||||
const walk = _walk || (_walk = require('estree-walker').walk)
|
|
||||||
|
|
||||||
// fast path if expression is a simple identifier.
|
// fast path if expression is a simple identifier.
|
||||||
if (simpleIdRE.test(node.content)) {
|
if (simpleIdRE.test(node.content)) {
|
||||||
if (!context.identifiers[node.content]) {
|
if (!context.identifiers[node.content]) {
|
||||||
node.content = `_ctx.${node.content}`
|
node.content = `_ctx.${node.content}`
|
||||||
}
|
}
|
||||||
return
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lazy require dependencies so that they don't end up in rollup's dep graph
|
||||||
|
// and thus can be tree-shaken in browser builds.
|
||||||
|
const parseScript =
|
||||||
|
_parseScript || (_parseScript = require('meriyah').parseScript)
|
||||||
|
const walk = _walk || (_walk = require('estree-walker').walk)
|
||||||
|
|
||||||
let ast
|
let ast
|
||||||
try {
|
try {
|
||||||
ast = parseScript(`(${node.content})`, { ranges: true }) as any
|
ast = parseScript(`(${node.content})`, { ranges: true }) as any
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
context.onError(e)
|
context.onError(e)
|
||||||
return
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
const ids: (Identifier & PrefixMeta)[] = []
|
const ids: (Identifier & PrefixMeta)[] = []
|
||||||
@ -145,7 +159,7 @@ export function processExpression(
|
|||||||
// an ExpressionNode has the `.children` property, it will be used instead of
|
// an ExpressionNode has the `.children` property, it will be used instead of
|
||||||
// `.content`.
|
// `.content`.
|
||||||
const full = node.content
|
const full = node.content
|
||||||
const children: ExpressionNode['children'] = []
|
const children: CompoundExpressionNode['children'] = []
|
||||||
ids.sort((a, b) => a.start - b.start)
|
ids.sort((a, b) => a.start - b.start)
|
||||||
ids.forEach((id, i) => {
|
ids.forEach((id, i) => {
|
||||||
const last = ids[i - 1] as any
|
const last = ids[i - 1] as any
|
||||||
@ -155,7 +169,7 @@ export function processExpression(
|
|||||||
}
|
}
|
||||||
const source = full.slice(id.start - 1, id.end - 1)
|
const source = full.slice(id.start - 1, id.end - 1)
|
||||||
children.push(
|
children.push(
|
||||||
createExpression(id.name, false, {
|
createSimpleExpression(id.name, false, {
|
||||||
source,
|
source,
|
||||||
start: advancePositionWithClone(node.loc.start, source, id.start - 1),
|
start: advancePositionWithClone(node.loc.start, source, id.start - 1),
|
||||||
end: advancePositionWithClone(node.loc.start, source, id.end - 1)
|
end: advancePositionWithClone(node.loc.start, source, id.end - 1)
|
||||||
@ -167,10 +181,9 @@ export function processExpression(
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (children.length) {
|
if (children.length) {
|
||||||
// mark it empty so that it's more noticeable in case another transform or
|
return createCompoundExpression(children, node.loc)
|
||||||
// codegen forget to handle `.children` first.
|
} else {
|
||||||
node.content = __DEV__ ? `[[REMOVED]]` : ``
|
return node
|
||||||
node.children = children
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NodeTransform } from '../transform'
|
import { NodeTransform } from '../transform'
|
||||||
import { NodeTypes, createExpression } from '../ast'
|
import { NodeTypes, createSimpleExpression } from '../ast'
|
||||||
|
|
||||||
// Parse inline CSS strings for static style attributes into an object.
|
// Parse inline CSS strings for static style attributes into an object.
|
||||||
// This is a NodeTransform since it works on the static `style` attribute and
|
// This is a NodeTransform since it works on the static `style` attribute and
|
||||||
@ -13,11 +13,11 @@ export const transformStyle: NodeTransform = (node, context) => {
|
|||||||
if (p.type === NodeTypes.ATTRIBUTE && p.name === 'style' && p.value) {
|
if (p.type === NodeTypes.ATTRIBUTE && p.name === 'style' && p.value) {
|
||||||
// replace p with an expression node
|
// replace p with an expression node
|
||||||
const parsed = JSON.stringify(parseInlineCSS(p.value.content))
|
const parsed = JSON.stringify(parseInlineCSS(p.value.content))
|
||||||
const exp = context.hoist(createExpression(parsed, false, p.loc))
|
const exp = context.hoist(createSimpleExpression(parsed, false, p.loc))
|
||||||
node.props[i] = {
|
node.props[i] = {
|
||||||
type: NodeTypes.DIRECTIVE,
|
type: NodeTypes.DIRECTIVE,
|
||||||
name: `bind`,
|
name: `bind`,
|
||||||
arg: createExpression(`style`, true, p.loc),
|
arg: createSimpleExpression(`style`, true, p.loc),
|
||||||
exp,
|
exp,
|
||||||
modifiers: [],
|
modifiers: [],
|
||||||
loc: p.loc
|
loc: p.loc
|
||||||
|
@ -1,27 +1,36 @@
|
|||||||
import { DirectiveTransform } from '../transform'
|
import { DirectiveTransform } from '../transform'
|
||||||
import { createObjectProperty, createExpression } from '../ast'
|
import { createObjectProperty, createSimpleExpression, NodeTypes } from '../ast'
|
||||||
import { createCompilerError, ErrorCodes } from '../errors'
|
import { createCompilerError, ErrorCodes } from '../errors'
|
||||||
import { camelize } from '@vue/shared'
|
import { camelize } from '@vue/shared'
|
||||||
|
import { CAMELIZE } from '../runtimeConstants'
|
||||||
|
|
||||||
// v-bind without arg is handled directly in ./element.ts due to it affecting
|
// v-bind without arg is handled directly in ./element.ts due to it affecting
|
||||||
// codegen for the entire props object. This transform here is only for v-bind
|
// codegen for the entire props object. This transform here is only for v-bind
|
||||||
// *with* args.
|
// *with* args.
|
||||||
export const transformBind: DirectiveTransform = (
|
export const transformBind: DirectiveTransform = (dir, context) => {
|
||||||
{ exp, arg, modifiers, loc },
|
const { exp, modifiers, loc } = dir
|
||||||
context
|
const arg = dir.arg!
|
||||||
) => {
|
|
||||||
if (!exp) {
|
if (!exp) {
|
||||||
context.onError(createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc))
|
context.onError(createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc))
|
||||||
}
|
}
|
||||||
// .prop is no longer necessary due to new patch behavior
|
// .prop is no longer necessary due to new patch behavior
|
||||||
// .sync is replced by v-model:arg
|
// .sync is replced by v-model:arg
|
||||||
if (modifiers.includes('camel')) {
|
if (modifiers.includes('camel')) {
|
||||||
arg!.content = camelize(arg!.content)
|
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||||
|
if (arg.isStatic) {
|
||||||
|
arg.content = camelize(arg.content)
|
||||||
|
} else {
|
||||||
|
arg.content = `${context.helper(CAMELIZE)}(${arg.content})`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arg.children.unshift(`${context.helper(CAMELIZE)}(`)
|
||||||
|
arg.children.push(`)`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
props: createObjectProperty(
|
props: createObjectProperty(
|
||||||
arg!,
|
arg!,
|
||||||
exp || createExpression('', true, loc),
|
exp || createSimpleExpression('', true, loc),
|
||||||
loc
|
loc
|
||||||
),
|
),
|
||||||
needRuntime: false
|
needRuntime: false
|
||||||
|
@ -5,8 +5,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
ExpressionNode,
|
ExpressionNode,
|
||||||
createExpression,
|
createSimpleExpression,
|
||||||
SourceLocation
|
SourceLocation,
|
||||||
|
SimpleExpressionNode
|
||||||
} from '../ast'
|
} from '../ast'
|
||||||
import { createCompilerError, ErrorCodes } from '../errors'
|
import { createCompilerError, ErrorCodes } from '../errors'
|
||||||
import { getInnerRange } from '../utils'
|
import { getInnerRange } from '../utils'
|
||||||
@ -17,7 +18,12 @@ export const transformFor = createStructuralDirectiveTransform(
|
|||||||
'for',
|
'for',
|
||||||
(node, dir, context) => {
|
(node, dir, context) => {
|
||||||
if (dir.exp) {
|
if (dir.exp) {
|
||||||
const parseResult = parseForExpression(dir.exp, context)
|
const parseResult = parseForExpression(
|
||||||
|
// can only be simple expression because vFor transform is applied
|
||||||
|
// before expression transform.
|
||||||
|
dir.exp as SimpleExpressionNode,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
if (parseResult) {
|
if (parseResult) {
|
||||||
context.helper(RENDER_LIST)
|
context.helper(RENDER_LIST)
|
||||||
@ -66,29 +72,33 @@ const stripParensRE = /^\(|\)$/g
|
|||||||
|
|
||||||
interface ForParseResult {
|
interface ForParseResult {
|
||||||
source: ExpressionNode
|
source: ExpressionNode
|
||||||
value: ExpressionNode | undefined
|
value: SimpleExpressionNode | undefined
|
||||||
key: ExpressionNode | undefined
|
key: SimpleExpressionNode | undefined
|
||||||
index: ExpressionNode | undefined
|
index: SimpleExpressionNode | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseForExpression(
|
function parseForExpression(
|
||||||
input: ExpressionNode,
|
input: SimpleExpressionNode,
|
||||||
context: TransformContext
|
context: TransformContext
|
||||||
): ForParseResult | null {
|
): ForParseResult | null {
|
||||||
const loc = input.loc
|
const loc = input.loc
|
||||||
const source = input.content
|
const exp = input.content
|
||||||
const inMatch = source.match(forAliasRE)
|
const inMatch = exp.match(forAliasRE)
|
||||||
if (!inMatch) return null
|
if (!inMatch) return null
|
||||||
|
|
||||||
const [, LHS, RHS] = inMatch
|
const [, LHS, RHS] = inMatch
|
||||||
const result: ForParseResult = {
|
|
||||||
source: createAliasExpression(
|
let source: ExpressionNode = createAliasExpression(
|
||||||
loc,
|
loc,
|
||||||
RHS.trim(),
|
RHS.trim(),
|
||||||
source.indexOf(RHS, LHS.length),
|
exp.indexOf(RHS, LHS.length)
|
||||||
context,
|
)
|
||||||
context.prefixIdentifiers
|
if (!__BROWSER__ && context.prefixIdentifiers) {
|
||||||
),
|
source = processExpression(source, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: ForParseResult = {
|
||||||
|
source,
|
||||||
value: undefined,
|
value: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
index: undefined
|
index: undefined
|
||||||
@ -106,11 +116,8 @@ function parseForExpression(
|
|||||||
const keyContent = iteratorMatch[1].trim()
|
const keyContent = iteratorMatch[1].trim()
|
||||||
let keyOffset: number | undefined
|
let keyOffset: number | undefined
|
||||||
if (keyContent) {
|
if (keyContent) {
|
||||||
keyOffset = source.indexOf(
|
keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length)
|
||||||
keyContent,
|
result.key = createAliasExpression(loc, keyContent, keyOffset)
|
||||||
trimmedOffset + valueContent.length
|
|
||||||
)
|
|
||||||
result.key = createAliasExpression(loc, keyContent, keyOffset, context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iteratorMatch[2]) {
|
if (iteratorMatch[2]) {
|
||||||
@ -120,25 +127,19 @@ function parseForExpression(
|
|||||||
result.index = createAliasExpression(
|
result.index = createAliasExpression(
|
||||||
loc,
|
loc,
|
||||||
indexContent,
|
indexContent,
|
||||||
source.indexOf(
|
exp.indexOf(
|
||||||
indexContent,
|
indexContent,
|
||||||
result.key
|
result.key
|
||||||
? keyOffset! + keyContent.length
|
? keyOffset! + keyContent.length
|
||||||
: trimmedOffset + valueContent.length
|
: trimmedOffset + valueContent.length
|
||||||
),
|
)
|
||||||
context
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueContent) {
|
if (valueContent) {
|
||||||
result.value = createAliasExpression(
|
result.value = createAliasExpression(loc, valueContent, trimmedOffset)
|
||||||
loc,
|
|
||||||
valueContent,
|
|
||||||
trimmedOffset,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -147,17 +148,11 @@ function parseForExpression(
|
|||||||
function createAliasExpression(
|
function createAliasExpression(
|
||||||
range: SourceLocation,
|
range: SourceLocation,
|
||||||
content: string,
|
content: string,
|
||||||
offset: number,
|
offset: number
|
||||||
context: TransformContext,
|
): SimpleExpressionNode {
|
||||||
process: boolean = false
|
return createSimpleExpression(
|
||||||
): ExpressionNode {
|
|
||||||
const exp = createExpression(
|
|
||||||
content,
|
content,
|
||||||
false,
|
false,
|
||||||
getInnerRange(range, offset, content.length)
|
getInnerRange(range, offset, content.length)
|
||||||
)
|
)
|
||||||
if (!__BROWSER__ && process) {
|
|
||||||
processExpression(exp, context)
|
|
||||||
}
|
|
||||||
return exp
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ import {
|
|||||||
ElementTypes,
|
ElementTypes,
|
||||||
ElementNode,
|
ElementNode,
|
||||||
DirectiveNode,
|
DirectiveNode,
|
||||||
IfBranchNode
|
IfBranchNode,
|
||||||
|
SimpleExpressionNode
|
||||||
} from '../ast'
|
} from '../ast'
|
||||||
import { createCompilerError, ErrorCodes } from '../errors'
|
import { createCompilerError, ErrorCodes } from '../errors'
|
||||||
import { processExpression } from './transformExpression'
|
import { processExpression } from './transformExpression'
|
||||||
@ -16,7 +17,9 @@ export const transformIf = createStructuralDirectiveTransform(
|
|||||||
/^(if|else|else-if)$/,
|
/^(if|else|else-if)$/,
|
||||||
(node, dir, context) => {
|
(node, dir, context) => {
|
||||||
if (!__BROWSER__ && context.prefixIdentifiers && dir.exp) {
|
if (!__BROWSER__ && context.prefixIdentifiers && dir.exp) {
|
||||||
processExpression(dir.exp, context)
|
// dir.exp can only be simple expression because vIf transform is applied
|
||||||
|
// before expression transform.
|
||||||
|
processExpression(dir.exp as SimpleExpressionNode, context)
|
||||||
}
|
}
|
||||||
if (dir.name === 'if') {
|
if (dir.name === 'if') {
|
||||||
context.replaceNode({
|
context.replaceNode({
|
||||||
|
@ -1,37 +1,46 @@
|
|||||||
import { DirectiveTransform } from '../transform'
|
import { DirectiveTransform } from '../transform'
|
||||||
import { createObjectProperty, createExpression, ExpressionNode } from '../ast'
|
import {
|
||||||
|
createObjectProperty,
|
||||||
|
createSimpleExpression,
|
||||||
|
ExpressionNode,
|
||||||
|
NodeTypes,
|
||||||
|
createCompoundExpression
|
||||||
|
} from '../ast'
|
||||||
import { capitalize } from '@vue/shared'
|
import { capitalize } from '@vue/shared'
|
||||||
import { createCompilerError, ErrorCodes } from '../errors'
|
import { createCompilerError, ErrorCodes } from '../errors'
|
||||||
|
|
||||||
// v-on without arg is handled directly in ./element.ts due to it affecting
|
// v-on without arg is handled directly in ./element.ts due to it affecting
|
||||||
// codegen for the entire props object. This transform here is only for v-on
|
// codegen for the entire props object. This transform here is only for v-on
|
||||||
// *with* args.
|
// *with* args.
|
||||||
export const transformOn: DirectiveTransform = (
|
export const transformOn: DirectiveTransform = (dir, context) => {
|
||||||
{ arg, exp, loc, modifiers },
|
const { exp, loc, modifiers } = dir
|
||||||
context
|
const arg = dir.arg!
|
||||||
) => {
|
|
||||||
if (!exp && !modifiers.length) {
|
if (!exp && !modifiers.length) {
|
||||||
context.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc))
|
context.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc))
|
||||||
}
|
}
|
||||||
const { content, isStatic, loc: argLoc } = arg!
|
|
||||||
let eventName: ExpressionNode
|
let eventName: ExpressionNode
|
||||||
if (isStatic) {
|
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||||
// static arg
|
if (arg.isStatic) {
|
||||||
eventName = createExpression(`on${capitalize(content)}`, true, argLoc)
|
eventName = createSimpleExpression(
|
||||||
|
`on${capitalize(arg.content)}`,
|
||||||
|
true,
|
||||||
|
arg.loc
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// dynamic arg. turn it into a compound expression.
|
eventName = createCompoundExpression([`"on" + (`, arg, `)`], arg.loc)
|
||||||
eventName = arg!
|
}
|
||||||
;(
|
} else {
|
||||||
eventName.children ||
|
// already a compound epxression.
|
||||||
(eventName.children = [{ ...eventName, children: undefined }])
|
eventName = arg
|
||||||
).unshift(`"on" + `)
|
eventName.children.unshift(`"on" + (`)
|
||||||
|
eventName.children.push(`)`)
|
||||||
}
|
}
|
||||||
// TODO .once modifier handling since it is platform agnostic
|
// TODO .once modifier handling since it is platform agnostic
|
||||||
// other modifiers are handled in compiler-dom
|
// other modifiers are handled in compiler-dom
|
||||||
return {
|
return {
|
||||||
props: createObjectProperty(
|
props: createObjectProperty(
|
||||||
eventName,
|
eventName,
|
||||||
exp || createExpression(`() => {}`, false, loc),
|
exp || createSimpleExpression(`() => {}`, false, loc),
|
||||||
loc
|
loc
|
||||||
),
|
),
|
||||||
needRuntime: false
|
needRuntime: false
|
||||||
|
@ -4,8 +4,8 @@ import {
|
|||||||
ElementNode,
|
ElementNode,
|
||||||
TextNode,
|
TextNode,
|
||||||
ErrorCodes,
|
ErrorCodes,
|
||||||
ExpressionNode,
|
ElementTypes,
|
||||||
ElementTypes
|
InterpolationNode
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
import {
|
import {
|
||||||
parserOptionsMinimal as parserOptions,
|
parserOptionsMinimal as parserOptions,
|
||||||
@ -109,18 +109,25 @@ describe('DOM parser', () => {
|
|||||||
test('HTML entities in interpolation should be translated for backward compatibility.', () => {
|
test('HTML entities in interpolation should be translated for backward compatibility.', () => {
|
||||||
const ast = parse('<div>{{ a < b }}</div>', parserOptions)
|
const ast = parse('<div>{{ a < b }}</div>', parserOptions)
|
||||||
const element = ast.children[0] as ElementNode
|
const element = ast.children[0] as ElementNode
|
||||||
const interpolation = element.children[0] as ExpressionNode
|
const interpolation = element.children[0] as InterpolationNode
|
||||||
|
|
||||||
expect(interpolation).toStrictEqual({
|
expect(interpolation).toStrictEqual({
|
||||||
type: NodeTypes.EXPRESSION,
|
type: NodeTypes.INTERPOLATION,
|
||||||
content: 'a < b',
|
content: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: `a < b`,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
isInterpolation: true,
|
|
||||||
loc: {
|
loc: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 16, line: 1, column: 17 },
|
end: { offset: 16, line: 1, column: 17 },
|
||||||
source: 'a < b'
|
source: 'a < b'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loc: {
|
||||||
|
start: { offset: 5, line: 1, column: 6 },
|
||||||
|
end: { offset: 19, line: 1, column: 20 },
|
||||||
|
source: '{{ a < b }}'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -42,6 +42,7 @@ export { resolveComponent, resolveDirective } from './helpers/resolveAssets'
|
|||||||
export { renderList } from './helpers/renderList'
|
export { renderList } from './helpers/renderList'
|
||||||
export { toString } from './helpers/toString'
|
export { toString } from './helpers/toString'
|
||||||
export { toHandlers } from './helpers/toHandlers'
|
export { toHandlers } from './helpers/toHandlers'
|
||||||
|
export { capitalize, camelize } from '@vue/shared'
|
||||||
|
|
||||||
// Internal, for integration with runtime compiler
|
// Internal, for integration with runtime compiler
|
||||||
export { registerRuntimeCompiler } from './component'
|
export { registerRuntimeCompiler } from './component'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user