fix: fix source map by fixing advancePositionWithMutation
This commit is contained in:
		
							parent
							
								
									ff2313e43a
								
							
						
					
					
						commit
						6c8f226a79
					
				| @ -20,7 +20,7 @@ exports[`compiler: codegen comment 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return createVNode(Comment, 0, \\"foo\\") | ||||
|     return _createVNode(_Comment, 0, \\"foo\\") | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -29,7 +29,7 @@ exports[`compiler: codegen compound expression 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return toString(_ctx.foo) | ||||
|     return _toString(_ctx.foo) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -38,16 +38,30 @@ exports[`compiler: codegen forNode 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return renderList(list, (v, k, i) => toString(v)) | ||||
|     return _renderList(list, (v, k, i) => { | ||||
|       return _toString(v) | ||||
|     }) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| 
 | ||||
| exports[`compiler: codegen forNode w/ prefixIdentifiers: true 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   const _ctx = this | ||||
|   return renderList(list, (v, k, i) => { | ||||
|     return toString(v) | ||||
|   }) | ||||
| }" | ||||
| `; | ||||
| 
 | ||||
| exports[`compiler: codegen forNode w/ skipped key alias 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return renderList(list, (v, __key, i) => toString(v)) | ||||
|     return _renderList(list, (v, __key, i) => { | ||||
|       return _toString(v) | ||||
|     }) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -56,7 +70,9 @@ exports[`compiler: codegen forNode w/ skipped value alias 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return renderList(list, (__value, k, i) => toString(v)) | ||||
|     return _renderList(list, (__value, k, i) => { | ||||
|       return _toString(v) | ||||
|     }) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -65,7 +81,9 @@ exports[`compiler: codegen forNode w/ skipped value and key aliases 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return renderList(list, (__value, __key, i) => toString(v)) | ||||
|     return _renderList(list, (__value, __key, i) => { | ||||
|       return _toString(v) | ||||
|     }) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -74,12 +92,21 @@ exports[`compiler: codegen function mode preamble 1`] = ` | ||||
| "const _Vue = Vue | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     const { helperOne, helperTwo } = _Vue | ||||
|     const { helperOne: _helperOne, helperTwo: _helperTwo } = _Vue | ||||
|     return null | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| 
 | ||||
| exports[`compiler: codegen function mode preamble w/ prefixIdentifiers: true 1`] = ` | ||||
| "const { helperOne, helperTwo } = Vue | ||||
| 
 | ||||
| return function render() { | ||||
|   const _ctx = this | ||||
|   return null | ||||
| }" | ||||
| `; | ||||
| 
 | ||||
| exports[`compiler: codegen hoists 1`] = ` | ||||
| "const _hoisted_1 = hello | ||||
| const _hoisted_2 = { id: \\"foo\\" } | ||||
| @ -98,8 +125,8 @@ return function render() { | ||||
|     return foo | ||||
|       ? \\"foo\\" | ||||
|       : (a + b) | ||||
|         ? toString(bye) | ||||
|         : createVNode(Comment, 0, \\"foo\\") | ||||
|         ? _toString(bye) | ||||
|         : _createVNode(_Comment, 0, \\"foo\\") | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -111,7 +138,7 @@ return function render() { | ||||
|     return foo | ||||
|       ? \\"foo\\" | ||||
|       : (a + b) | ||||
|         ? toString(bye) | ||||
|         ? _toString(bye) | ||||
|         : null | ||||
|   } | ||||
| }" | ||||
| @ -121,7 +148,7 @@ exports[`compiler: codegen interpolation 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     return toString(hello) | ||||
|     return _toString(hello) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -171,9 +198,21 @@ return function render() { | ||||
|   with (this) { | ||||
|     return [ | ||||
|       \\"foo\\", | ||||
|       toString(hello), | ||||
|       createVNode(Comment, 0, \\"foo\\") | ||||
|       _toString(hello), | ||||
|       _createVNode(_Comment, 0, \\"foo\\") | ||||
|     ] | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| 
 | ||||
| exports[`compiler: codegen text + comment + interpolation w/ prefixIdentifiers: true 1`] = ` | ||||
| " | ||||
| return function render() { | ||||
|   const _ctx = this | ||||
|   return [ | ||||
|     \\"foo\\", | ||||
|     toString(hello), | ||||
|     createVNode(Comment, 0, \\"foo\\") | ||||
|   ] | ||||
| }" | ||||
| `; | ||||
|  | ||||
| @ -0,0 +1,22 @@ | ||||
| // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
| 
 | ||||
| exports[`function mode 1`] = ` | ||||
| "const _Vue = Vue | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     const { createVNode: _createVNode, toString: _toString, renderList: _renderList } = _Vue | ||||
|     return _createVNode(\\"div\\", { | ||||
|       id: \\"foo\\", | ||||
|       class: bar | ||||
|     }, [ | ||||
|       _toString(world), | ||||
|       ok | ||||
|         ? _createVNode(\\"div\\", 0, \\"yes\\") | ||||
|         : \\"no\\", | ||||
|       _renderList(list, (i, j) => { | ||||
|         return _createVNode(\\"div\\", 0, [_createVNode(\\"span\\", 0, _toString(i + j))]) | ||||
|       }) | ||||
|     ]) | ||||
|   } | ||||
| }" | ||||
| `; | ||||
| @ -7481,15 +7481,15 @@ Object { | ||||
|             "isStatic": false, | ||||
|             "loc": Object { | ||||
|               "end": Object { | ||||
|                 "column": 34, | ||||
|                 "column": 33, | ||||
|                 "line": 1, | ||||
|                 "offset": 33, | ||||
|                 "offset": 32, | ||||
|               }, | ||||
|               "source": "\\"{ some: condition }\\"", | ||||
|               "start": Object { | ||||
|                 "column": 13, | ||||
|                 "column": 14, | ||||
|                 "line": 1, | ||||
|                 "offset": 12, | ||||
|                 "offset": 13, | ||||
|               }, | ||||
|             }, | ||||
|             "type": 4, | ||||
| @ -7561,15 +7561,15 @@ Object { | ||||
|             "isStatic": false, | ||||
|             "loc": Object { | ||||
|               "end": Object { | ||||
|                 "column": 35, | ||||
|                 "column": 34, | ||||
|                 "line": 2, | ||||
|                 "offset": 71, | ||||
|                 "offset": 70, | ||||
|               }, | ||||
|               "source": "\\"{ color: 'red' }\\"", | ||||
|               "start": Object { | ||||
|                 "column": 17, | ||||
|                 "column": 18, | ||||
|                 "line": 2, | ||||
|                 "offset": 53, | ||||
|                 "offset": 54, | ||||
|               }, | ||||
|             }, | ||||
|             "type": 4, | ||||
| @ -7629,13 +7629,13 @@ Object { | ||||
|           "isSelfClosing": true, | ||||
|           "loc": Object { | ||||
|             "end": Object { | ||||
|               "column": 38, | ||||
|               "column": 39, | ||||
|               "line": 2, | ||||
|               "offset": 73, | ||||
|             }, | ||||
|             "source": "<p v-bind:style=\\"{ color: 'red' }\\"/>", | ||||
|             "start": Object { | ||||
|               "column": 2, | ||||
|               "column": 3, | ||||
|               "line": 2, | ||||
|               "offset": 37, | ||||
|             }, | ||||
| @ -7649,13 +7649,13 @@ Object { | ||||
|                 "isStatic": true, | ||||
|                 "loc": Object { | ||||
|                   "end": Object { | ||||
|                     "column": 17, | ||||
|                     "column": 18, | ||||
|                     "line": 2, | ||||
|                     "offset": 52, | ||||
|                   }, | ||||
|                   "source": "style", | ||||
|                   "start": Object { | ||||
|                     "column": 12, | ||||
|                     "column": 13, | ||||
|                     "line": 2, | ||||
|                     "offset": 47, | ||||
|                   }, | ||||
| @ -7670,26 +7670,26 @@ Object { | ||||
|                   "end": Object { | ||||
|                     "column": 36, | ||||
|                     "line": 2, | ||||
|                     "offset": 71, | ||||
|                     "offset": 70, | ||||
|                   }, | ||||
|                   "source": "\\"{ color: 'red' }\\"", | ||||
|                   "start": Object { | ||||
|                     "column": 18, | ||||
|                     "column": 20, | ||||
|                     "line": 2, | ||||
|                     "offset": 53, | ||||
|                     "offset": 54, | ||||
|                   }, | ||||
|                 }, | ||||
|                 "type": 4, | ||||
|               }, | ||||
|               "loc": Object { | ||||
|                 "end": Object { | ||||
|                   "column": 36, | ||||
|                   "column": 37, | ||||
|                   "line": 2, | ||||
|                   "offset": 71, | ||||
|                 }, | ||||
|                 "source": "v-bind:style=\\"{ color: 'red' }\\"", | ||||
|                 "start": Object { | ||||
|                   "column": 5, | ||||
|                   "column": 6, | ||||
|                   "line": 2, | ||||
|                   "offset": 40, | ||||
|                 }, | ||||
| @ -7707,13 +7707,13 @@ Object { | ||||
|           "content": " a comment with <html> inside it ", | ||||
|           "loc": Object { | ||||
|             "end": Object { | ||||
|               "column": 42, | ||||
|               "column": 43, | ||||
|               "line": 3, | ||||
|               "offset": 116, | ||||
|             }, | ||||
|             "source": "<!-- a comment with <html> inside it -->", | ||||
|             "start": Object { | ||||
|               "column": 2, | ||||
|               "column": 3, | ||||
|               "line": 3, | ||||
|               "offset": 76, | ||||
|             }, | ||||
| @ -7767,15 +7767,15 @@ Object { | ||||
|             "isStatic": false, | ||||
|             "loc": Object { | ||||
|               "end": Object { | ||||
|                 "column": 34, | ||||
|                 "column": 33, | ||||
|                 "line": 1, | ||||
|                 "offset": 33, | ||||
|                 "offset": 32, | ||||
|               }, | ||||
|               "source": "\\"{ some: condition }\\"", | ||||
|               "start": Object { | ||||
|                 "column": 13, | ||||
|                 "column": 14, | ||||
|                 "line": 1, | ||||
|                 "offset": 12, | ||||
|                 "offset": 13, | ||||
|               }, | ||||
|             }, | ||||
|             "type": 4, | ||||
|  | ||||
| @ -12,7 +12,12 @@ import { | ||||
|   createArrayExpression, | ||||
|   ElementNode | ||||
| } from '../src' | ||||
| import { CREATE_VNODE, COMMENT, TO_STRING } from '../src/runtimeConstants' | ||||
| import { | ||||
|   CREATE_VNODE, | ||||
|   COMMENT, | ||||
|   TO_STRING, | ||||
|   RENDER_LIST | ||||
| } from '../src/runtimeConstants' | ||||
| 
 | ||||
| const mockLoc: SourceLocation = { | ||||
|   source: ``, | ||||
| @ -56,7 +61,22 @@ describe('compiler: codegen', () => { | ||||
|     }) | ||||
|     const { code } = generate(root, { mode: 'function' }) | ||||
|     expect(code).toMatch(`const _Vue = Vue`) | ||||
|     expect(code).toMatch(`const { helperOne, helperTwo } = _Vue`) | ||||
|     expect(code).toMatch( | ||||
|       `const { helperOne: _helperOne, helperTwo: _helperTwo } = _Vue` | ||||
|     ) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
|   test('function mode preamble w/ prefixIdentifiers: true', () => { | ||||
|     const root = createRoot({ | ||||
|       imports: [`helperOne`, `helperTwo`] | ||||
|     }) | ||||
|     const { code } = generate(root, { | ||||
|       mode: 'function', | ||||
|       prefixIdentifiers: true | ||||
|     }) | ||||
|     expect(code).not.toMatch(`const _Vue = Vue`) | ||||
|     expect(code).toMatch(`const { helperOne, helperTwo } = Vue`) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -121,7 +141,7 @@ describe('compiler: codegen', () => { | ||||
|         children: [createExpression(`hello`, false, mockLoc, true)] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`return toString(hello)`) | ||||
|     expect(code).toMatch(`return _${TO_STRING}(hello)`) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -137,7 +157,7 @@ describe('compiler: codegen', () => { | ||||
|         ] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`return ${CREATE_VNODE}(${COMMENT}, 0, "foo")`) | ||||
|     expect(code).toMatch(`return _${CREATE_VNODE}(_${COMMENT}, 0, "foo")`) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -163,12 +183,43 @@ describe('compiler: codegen', () => { | ||||
|     expect(code).toMatch(` | ||||
|     return [ | ||||
|       "foo", | ||||
|       toString(hello), | ||||
|       ${CREATE_VNODE}(${COMMENT}, 0, "foo") | ||||
|       _${TO_STRING}(hello), | ||||
|       _${CREATE_VNODE}(_${COMMENT}, 0, "foo") | ||||
|     ]`)
 | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
|   test('text + comment + interpolation w/ prefixIdentifiers: true', () => { | ||||
|     const { code } = generate( | ||||
|       createRoot({ | ||||
|         children: [ | ||||
|           { | ||||
|             type: NodeTypes.TEXT, | ||||
|             content: 'foo', | ||||
|             isEmpty: false, | ||||
|             loc: mockLoc | ||||
|           }, | ||||
|           createExpression(`hello`, false, mockLoc, true), | ||||
|           { | ||||
|             type: NodeTypes.COMMENT, | ||||
|             content: 'foo', | ||||
|             loc: mockLoc | ||||
|           } | ||||
|         ] | ||||
|       }), | ||||
|       { | ||||
|         prefixIdentifiers: true | ||||
|       } | ||||
|     ) | ||||
|     expect(code).toMatch(` | ||||
|   return [ | ||||
|     "foo", | ||||
|     ${TO_STRING}(hello), | ||||
|     ${CREATE_VNODE}(${COMMENT}, 0, "foo") | ||||
|   ]`)
 | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
|   test('compound expression', () => { | ||||
|     const { code } = generate( | ||||
|       createRoot({ | ||||
| @ -184,7 +235,7 @@ describe('compiler: codegen', () => { | ||||
|         ] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`return toString(_ctx.foo)`) | ||||
|     expect(code).toMatch(`return _${TO_STRING}(_ctx.foo)`) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -195,13 +246,11 @@ describe('compiler: codegen', () => { | ||||
|           { | ||||
|             type: NodeTypes.IF, | ||||
|             loc: mockLoc, | ||||
|             isRoot: true, | ||||
|             branches: [ | ||||
|               { | ||||
|                 type: NodeTypes.IF_BRANCH, | ||||
|                 condition: createExpression('foo', false, mockLoc), | ||||
|                 loc: mockLoc, | ||||
|                 isRoot: true, | ||||
|                 children: [ | ||||
|                   { | ||||
|                     type: NodeTypes.TEXT, | ||||
| @ -215,14 +264,12 @@ describe('compiler: codegen', () => { | ||||
|                 type: NodeTypes.IF_BRANCH, | ||||
|                 condition: createExpression('a + b', false, mockLoc), | ||||
|                 loc: mockLoc, | ||||
|                 isRoot: true, | ||||
|                 children: [createExpression(`bye`, false, mockLoc, true)] | ||||
|               }, | ||||
|               { | ||||
|                 type: NodeTypes.IF_BRANCH, | ||||
|                 condition: undefined, | ||||
|                 loc: mockLoc, | ||||
|                 isRoot: true, | ||||
|                 children: [ | ||||
|                   { | ||||
|                     type: NodeTypes.COMMENT, | ||||
| @ -240,8 +287,8 @@ describe('compiler: codegen', () => { | ||||
|     return foo | ||||
|       ? "foo" | ||||
|       : (a + b) | ||||
|         ? ${TO_STRING}(bye) | ||||
|         : ${CREATE_VNODE}(${COMMENT}, 0, "foo")`)
 | ||||
|         ? _${TO_STRING}(bye) | ||||
|         : _${CREATE_VNODE}(_${COMMENT}, 0, "foo")`)
 | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -252,13 +299,11 @@ describe('compiler: codegen', () => { | ||||
|           { | ||||
|             type: NodeTypes.IF, | ||||
|             loc: mockLoc, | ||||
|             isRoot: true, | ||||
|             branches: [ | ||||
|               { | ||||
|                 type: NodeTypes.IF_BRANCH, | ||||
|                 condition: createExpression('foo', false, mockLoc), | ||||
|                 loc: mockLoc, | ||||
|                 isRoot: true, | ||||
|                 children: [ | ||||
|                   { | ||||
|                     type: NodeTypes.TEXT, | ||||
| @ -272,7 +317,6 @@ describe('compiler: codegen', () => { | ||||
|                 type: NodeTypes.IF_BRANCH, | ||||
|                 condition: createExpression('a + b', false, mockLoc), | ||||
|                 loc: mockLoc, | ||||
|                 isRoot: true, | ||||
|                 children: [createExpression(`bye`, false, mockLoc, true)] | ||||
|               } | ||||
|             ] | ||||
| @ -284,7 +328,7 @@ describe('compiler: codegen', () => { | ||||
|     return foo | ||||
|       ? "foo" | ||||
|       : (a + b) | ||||
|         ? ${TO_STRING}(bye) | ||||
|         ? _${TO_STRING}(bye) | ||||
|         : null`)
 | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| @ -305,7 +349,38 @@ describe('compiler: codegen', () => { | ||||
|         ] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`renderList(list, (v, k, i) => toString(v))`) | ||||
|     expect(code).toMatch( | ||||
|       `return _${RENDER_LIST}(list, (v, k, i) => {
 | ||||
|       return _${TO_STRING}(v) | ||||
|     })` | ||||
|     ) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
|   test('forNode w/ prefixIdentifiers: true', () => { | ||||
|     const { code } = generate( | ||||
|       createRoot({ | ||||
|         children: [ | ||||
|           { | ||||
|             type: NodeTypes.FOR, | ||||
|             loc: mockLoc, | ||||
|             source: createExpression(`list`, false, mockLoc), | ||||
|             valueAlias: createExpression(`v`, false, mockLoc), | ||||
|             keyAlias: createExpression(`k`, false, mockLoc), | ||||
|             objectIndexAlias: createExpression(`i`, false, mockLoc), | ||||
|             children: [createExpression(`v`, false, mockLoc, true)] | ||||
|           } | ||||
|         ] | ||||
|       }), | ||||
|       { | ||||
|         prefixIdentifiers: true | ||||
|       } | ||||
|     ) | ||||
|     expect(code).toMatch( | ||||
|       `return ${RENDER_LIST}(list, (v, k, i) => {
 | ||||
|     return ${TO_STRING}(v) | ||||
|   })` | ||||
|     ) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -325,7 +400,11 @@ describe('compiler: codegen', () => { | ||||
|         ] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`renderList(list, (__value, k, i) => toString(v))`) | ||||
|     expect(code).toMatch( | ||||
|       `return _${RENDER_LIST}(list, (__value, k, i) => {
 | ||||
|       return _${TO_STRING}(v) | ||||
|     })` | ||||
|     ) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -345,7 +424,11 @@ describe('compiler: codegen', () => { | ||||
|         ] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`renderList(list, (v, __key, i) => toString(v))`) | ||||
|     expect(code).toMatch( | ||||
|       `return _${RENDER_LIST}(list, (v, __key, i) => {
 | ||||
|       return _${TO_STRING}(v) | ||||
|     })` | ||||
|     ) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
| @ -365,7 +448,11 @@ describe('compiler: codegen', () => { | ||||
|         ] | ||||
|       }) | ||||
|     ) | ||||
|     expect(code).toMatch(`renderList(list, (__value, __key, i) => toString(v))`) | ||||
|     expect(code).toMatch( | ||||
|       `return _${RENDER_LIST}(list, (__value, __key, i) => {
 | ||||
|       return _${TO_STRING}(v) | ||||
|     })` | ||||
|     ) | ||||
|     expect(code).toMatchSnapshot() | ||||
|   }) | ||||
| 
 | ||||
|  | ||||
| @ -2,35 +2,138 @@ import { compile } from '../src' | ||||
| import { SourceMapConsumer, RawSourceMap } from 'source-map' | ||||
| 
 | ||||
| // Integration tests for parser + transform + codegen
 | ||||
| test('basic source map support', async () => { | ||||
|   const source = `hello {{ world }}` | ||||
| test('function mode', async () => { | ||||
|   const source = ` | ||||
| <div id="foo" :class="bar"> | ||||
|   {{ world }} | ||||
|   <div v-if="ok">yes</div> | ||||
|   <template v-else>no</template> | ||||
|   <div v-for="(i, j) in list"><span>{{ i + j }}</span></div> | ||||
| </div> | ||||
| `.trim()
 | ||||
|   const { code, map } = compile(source, { | ||||
|     sourceMap: true, | ||||
|     filename: `foo.vue` | ||||
|   }) | ||||
|   expect(code).toMatch( | ||||
|     `const _Vue = Vue
 | ||||
| return function render() { | ||||
|   with (this) { | ||||
|     const { toString } = _Vue | ||||
|     return [ | ||||
|       "hello ", | ||||
|       toString(world) | ||||
|     ] | ||||
|   } | ||||
| }` | ||||
|   ) | ||||
| 
 | ||||
|   expect(code).toMatchSnapshot() | ||||
|   expect(map!.sources).toEqual([`foo.vue`]) | ||||
|   expect(map!.sourcesContent).toEqual([source]) | ||||
| 
 | ||||
|   const consumer = await new SourceMapConsumer(map as RawSourceMap) | ||||
|   const pos = consumer.originalPositionFor({ | ||||
|     line: 7, | ||||
|     column: 16 | ||||
|   }) | ||||
|   expect(pos).toMatchObject({ | ||||
| 
 | ||||
|   // id=
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 6, | ||||
|       column: 6 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 1, | ||||
|     column: 6 | ||||
|     column: 5 | ||||
|   }) | ||||
| 
 | ||||
|   // "foo"
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 6, | ||||
|       column: 10 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 1, | ||||
|     column: 8 | ||||
|   }) | ||||
| 
 | ||||
|   // :class=
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 7, | ||||
|       column: 6 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 1, | ||||
|     column: 15 | ||||
|   }) | ||||
|   // bar
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 7, | ||||
|       column: 13 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 1, | ||||
|     column: 22 | ||||
|   }) | ||||
| 
 | ||||
|   // {{ world }}
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 9, | ||||
|       column: 16 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 2, | ||||
|     column: 2 | ||||
|   }) | ||||
| 
 | ||||
|   // ok
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 10, | ||||
|       column: 6 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 3, | ||||
|     column: 13 | ||||
|   }) | ||||
| 
 | ||||
|   // i
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 13, | ||||
|       column: 25 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 5, | ||||
|     column: 15 | ||||
|   }) | ||||
| 
 | ||||
|   // j
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 13, | ||||
|       column: 28 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 5, | ||||
|     column: 18 | ||||
|   }) | ||||
| 
 | ||||
|   // list
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 13, | ||||
|       column: 18 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 5, | ||||
|     column: 24 | ||||
|   }) | ||||
| 
 | ||||
|   // i + j
 | ||||
|   expect( | ||||
|     consumer.originalPositionFor({ | ||||
|       line: 14, | ||||
|       column: 81 | ||||
|     }) | ||||
|   ).toMatchObject({ | ||||
|     line: 5, | ||||
|     column: 36 | ||||
|   }) | ||||
| }) | ||||
| 
 | ||||
| test.todo('function mode w/ prefixIdentifiers: true') | ||||
| 
 | ||||
| test.todo('module mode') | ||||
| 
 | ||||
| test.todo('module mode w/ prefixIdentifiers: true') | ||||
|  | ||||
| @ -894,8 +894,8 @@ describe('compiler: parse', () => { | ||||
|           isStatic: false, | ||||
|           isInterpolation: false, | ||||
|           loc: { | ||||
|             start: { offset: 10, line: 1, column: 11 }, | ||||
|             end: { offset: 13, line: 1, column: 14 }, | ||||
|             start: { offset: 11, line: 1, column: 12 }, | ||||
|             end: { offset: 12, line: 1, column: 13 }, | ||||
|             source: '"a"' | ||||
|           } | ||||
|         }, | ||||
| @ -1303,25 +1303,27 @@ describe('compiler: parse', () => { | ||||
| 
 | ||||
|   test('parse with correct location info', () => { | ||||
|     const [foo, bar, but, baz] = parse( | ||||
|       'foo \n is {{ bar }} but {{ baz }}' | ||||
|       ` | ||||
| foo | ||||
|  is {{ bar }} but {{ baz }}`.trim()
 | ||||
|     ).children | ||||
| 
 | ||||
|     let offset = 0 | ||||
|     expect(foo.loc.start).toEqual({ line: 1, column: 1, offset }) | ||||
|     offset += foo.loc.source.length | ||||
|     expect(foo.loc.end).toEqual({ line: 2, column: 4, offset }) | ||||
|     expect(foo.loc.end).toEqual({ line: 2, column: 5, offset }) | ||||
| 
 | ||||
|     expect(bar.loc.start).toEqual({ line: 2, column: 4, offset }) | ||||
|     expect(bar.loc.start).toEqual({ line: 2, column: 5, offset }) | ||||
|     offset += bar.loc.source.length | ||||
|     expect(bar.loc.end).toEqual({ line: 2, column: 13, offset }) | ||||
|     expect(bar.loc.end).toEqual({ line: 2, column: 14, offset }) | ||||
| 
 | ||||
|     expect(but.loc.start).toEqual({ line: 2, column: 13, offset }) | ||||
|     expect(but.loc.start).toEqual({ line: 2, column: 14, offset }) | ||||
|     offset += but.loc.source.length | ||||
|     expect(but.loc.end).toEqual({ line: 2, column: 18, offset }) | ||||
|     expect(but.loc.end).toEqual({ line: 2, column: 19, offset }) | ||||
| 
 | ||||
|     expect(baz.loc.start).toEqual({ line: 2, column: 18, offset }) | ||||
|     expect(baz.loc.start).toEqual({ line: 2, column: 19, offset }) | ||||
|     offset += baz.loc.source.length | ||||
|     expect(baz.loc.end).toEqual({ line: 2, column: 27, offset }) | ||||
|     expect(baz.loc.end).toEqual({ line: 2, column: 28, offset }) | ||||
|   }) | ||||
| 
 | ||||
|   describe('namedCharacterReferences option', () => { | ||||
|  | ||||
| @ -3,8 +3,7 @@ import { | ||||
|   CompilerOptions, | ||||
|   parse, | ||||
|   transform, | ||||
|   ErrorCodes, | ||||
|   compile | ||||
|   ErrorCodes | ||||
| } from '../../src' | ||||
| import { transformElement } from '../../src/transforms/transformElement' | ||||
| import { | ||||
| @ -74,7 +73,7 @@ describe('compiler: element transform', () => { | ||||
|     const { root, node } = parseWithElementTransform( | ||||
|       `<div id="foo" class="bar" />` | ||||
|     ) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     // should hoist the static object
 | ||||
|     expect(root.hoists).toMatchObject([ | ||||
|       createStaticObjectMatcher({ | ||||
| @ -95,7 +94,7 @@ describe('compiler: element transform', () => { | ||||
|     const { root, node } = parseWithElementTransform( | ||||
|       `<div id="foo"><span/></div>` | ||||
|     ) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(root.hoists).toMatchObject([ | ||||
|       createStaticObjectMatcher({ | ||||
|         id: 'foo' | ||||
| @ -112,7 +111,7 @@ describe('compiler: element transform', () => { | ||||
|           type: NodeTypes.ELEMENT, | ||||
|           tag: 'span', | ||||
|           codegenNode: { | ||||
|             callee: CREATE_VNODE, | ||||
|             callee: `_${CREATE_VNODE}`, | ||||
|             arguments: [`"span"`] | ||||
|           } | ||||
|         } | ||||
| @ -122,7 +121,7 @@ describe('compiler: element transform', () => { | ||||
| 
 | ||||
|   test('0 placeholder for children with no props', () => { | ||||
|     const { node } = parseWithElementTransform(`<div><span/></div>`) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments).toMatchObject([ | ||||
|       `"div"`, | ||||
|       `0`, | ||||
| @ -131,7 +130,7 @@ describe('compiler: element transform', () => { | ||||
|           type: NodeTypes.ELEMENT, | ||||
|           tag: 'span', | ||||
|           codegenNode: { | ||||
|             callee: CREATE_VNODE, | ||||
|             callee: `_${CREATE_VNODE}`, | ||||
|             arguments: [`"span"`] | ||||
|           } | ||||
|         } | ||||
| @ -143,7 +142,7 @@ describe('compiler: element transform', () => { | ||||
|     const { root, node } = parseWithElementTransform(`<div v-bind="obj" />`) | ||||
|     // single v-bind doesn't need mergeProps
 | ||||
|     expect(root.imports).not.toContain(MERGE_PROPS) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     // should directly use `obj` in props position
 | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.EXPRESSION, | ||||
| @ -156,10 +155,10 @@ describe('compiler: element transform', () => { | ||||
|       `<div id="foo" v-bind="obj" />` | ||||
|     ) | ||||
|     expect(root.imports).toContain(MERGE_PROPS) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|       callee: MERGE_PROPS, | ||||
|       callee: `_${MERGE_PROPS}`, | ||||
|       arguments: [ | ||||
|         createStaticObjectMatcher({ | ||||
|           id: 'foo' | ||||
| @ -177,10 +176,10 @@ describe('compiler: element transform', () => { | ||||
|       `<div v-bind="obj" id="foo" />` | ||||
|     ) | ||||
|     expect(root.imports).toContain(MERGE_PROPS) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|       callee: MERGE_PROPS, | ||||
|       callee: `_${MERGE_PROPS}`, | ||||
|       arguments: [ | ||||
|         { | ||||
|           type: NodeTypes.EXPRESSION, | ||||
| @ -198,10 +197,10 @@ describe('compiler: element transform', () => { | ||||
|       `<div id="foo" v-bind="obj" class="bar" />` | ||||
|     ) | ||||
|     expect(root.imports).toContain(MERGE_PROPS) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|       callee: MERGE_PROPS, | ||||
|       callee: `_${MERGE_PROPS}`, | ||||
|       arguments: [ | ||||
|         createStaticObjectMatcher({ | ||||
|           id: 'foo' | ||||
| @ -222,17 +221,17 @@ describe('compiler: element transform', () => { | ||||
|       `<div id="foo" v-on="obj" class="bar" />` | ||||
|     ) | ||||
|     expect(root.imports).toContain(MERGE_PROPS) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|       callee: MERGE_PROPS, | ||||
|       callee: `_${MERGE_PROPS}`, | ||||
|       arguments: [ | ||||
|         createStaticObjectMatcher({ | ||||
|           id: 'foo' | ||||
|         }), | ||||
|         { | ||||
|           type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|           callee: TO_HANDLERS, | ||||
|           callee: `_${TO_HANDLERS}`, | ||||
|           arguments: [ | ||||
|             { | ||||
|               type: NodeTypes.EXPRESSION, | ||||
| @ -252,17 +251,17 @@ describe('compiler: element transform', () => { | ||||
|       `<div id="foo" v-on="handlers" v-bind="obj" />` | ||||
|     ) | ||||
|     expect(root.imports).toContain(MERGE_PROPS) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|       callee: MERGE_PROPS, | ||||
|       callee: `_${MERGE_PROPS}`, | ||||
|       arguments: [ | ||||
|         createStaticObjectMatcher({ | ||||
|           id: 'foo' | ||||
|         }), | ||||
|         { | ||||
|           type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|           callee: TO_HANDLERS, | ||||
|           callee: `_${TO_HANDLERS}`, | ||||
|           arguments: [ | ||||
|             { | ||||
|               type: NodeTypes.EXPRESSION, | ||||
| @ -301,7 +300,7 @@ describe('compiler: element transform', () => { | ||||
|         } | ||||
|       } | ||||
|     }) | ||||
|     expect(node.callee).toBe(CREATE_VNODE) | ||||
|     expect(node.callee).toBe(`_${CREATE_VNODE}`) | ||||
|     expect(node.arguments[1]).toMatchObject({ | ||||
|       type: NodeTypes.JS_OBJECT_EXPRESSION, | ||||
|       properties: [ | ||||
| @ -333,11 +332,11 @@ describe('compiler: element transform', () => { | ||||
|     expect(root.imports).toContain(RESOLVE_DIRECTIVE) | ||||
|     expect(root.statements[0]).toMatch(`${RESOLVE_DIRECTIVE}("foo")`) | ||||
| 
 | ||||
|     expect(node.callee).toBe(APPLY_DIRECTIVES) | ||||
|     expect(node.callee).toBe(`_${APPLY_DIRECTIVES}`) | ||||
|     expect(node.arguments).toMatchObject([ | ||||
|       { | ||||
|         type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|         callee: CREATE_VNODE, | ||||
|         callee: `_${CREATE_VNODE}`, | ||||
|         arguments: [ | ||||
|           `"div"`, | ||||
|           { | ||||
| @ -388,7 +387,7 @@ describe('compiler: element transform', () => { | ||||
|     expect(root.statements[1]).toMatch(`${RESOLVE_DIRECTIVE}("bar")`) | ||||
|     expect(root.statements[2]).toMatch(`${RESOLVE_DIRECTIVE}("baz")`) | ||||
| 
 | ||||
|     expect(node.callee).toBe(APPLY_DIRECTIVES) | ||||
|     expect(node.callee).toBe(`_${APPLY_DIRECTIVES}`) | ||||
|     expect(node.arguments).toMatchObject([ | ||||
|       { | ||||
|         type: NodeTypes.JS_CALL_EXPRESSION | ||||
| @ -467,13 +466,7 @@ describe('compiler: element transform', () => { | ||||
|     ]) | ||||
|   }) | ||||
| 
 | ||||
|   test('props dedupe', () => { | ||||
|     const { code } = compile( | ||||
|       `<div class="a" :class="b" @click.foo="a" @click.bar="b" style="color: red" />
 | ||||
|       <div id="foo"/>` | ||||
|     ) | ||||
|     console.log(code) | ||||
|   }) | ||||
|   test.todo(`props dedupe`) | ||||
| 
 | ||||
|   test.todo('slot outlets') | ||||
| }) | ||||
|  | ||||
| @ -49,11 +49,11 @@ describe('compiler: transform v-bind', () => { | ||||
|         loc: { | ||||
|           start: { | ||||
|             line: 1, | ||||
|             column: 16 | ||||
|             column: 17 | ||||
|           }, | ||||
|           end: { | ||||
|             line: 1, | ||||
|             column: 20 | ||||
|             column: 19 | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|  | ||||
| @ -212,150 +212,155 @@ describe('compiler: transform v-for', () => { | ||||
|       const source = '<span v-for="item in items" />' | ||||
|       const forNode = parseWithForTransform(source) | ||||
| 
 | ||||
|       const itemOffset = source.indexOf('item') | ||||
|       expect(forNode.valueAlias!.content).toBe('item') | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('item') - 1 | ||||
|       ) | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset) | ||||
|       expect(forNode.valueAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item')) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1) | ||||
|       expect(forNode.valueAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('item') + 4 | ||||
|         itemOffset + 1 + `item`.length | ||||
|       ) | ||||
| 
 | ||||
|       const itemsOffset = source.indexOf('items') | ||||
|       expect(forNode.source.content).toBe('items') | ||||
|       expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1) | ||||
|       expect(forNode.source.loc.start.offset).toBe(itemsOffset) | ||||
|       expect(forNode.source.loc.start.line).toBe(1) | ||||
|       expect(forNode.source.loc.start.column).toBe(source.indexOf('items')) | ||||
|       expect(forNode.source.loc.start.column).toBe(itemsOffset + 1) | ||||
|       expect(forNode.source.loc.end.line).toBe(1) | ||||
|       expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5) | ||||
|       expect(forNode.source.loc.end.column).toBe( | ||||
|         itemsOffset + 1 + `items`.length | ||||
|       ) | ||||
|     }) | ||||
| 
 | ||||
|     test('bracketed value', () => { | ||||
|       const source = '<span v-for="( item ) in items" />' | ||||
|       const forNode = parseWithForTransform(source) | ||||
| 
 | ||||
|       const itemOffset = source.indexOf('item') | ||||
|       expect(forNode.valueAlias!.content).toBe('item') | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('item') - 1 | ||||
|       ) | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset) | ||||
|       expect(forNode.valueAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item')) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1) | ||||
|       expect(forNode.valueAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('item') + 4 | ||||
|         itemOffset + 1 + `item`.length | ||||
|       ) | ||||
| 
 | ||||
|       const itemsOffset = source.indexOf('items') | ||||
|       expect(forNode.source.content).toBe('items') | ||||
|       expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1) | ||||
|       expect(forNode.source.loc.start.offset).toBe(itemsOffset) | ||||
|       expect(forNode.source.loc.start.line).toBe(1) | ||||
|       expect(forNode.source.loc.start.column).toBe(source.indexOf('items')) | ||||
|       expect(forNode.source.loc.start.column).toBe(itemsOffset + 1) | ||||
|       expect(forNode.source.loc.end.line).toBe(1) | ||||
|       expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5) | ||||
|       expect(forNode.source.loc.end.column).toBe( | ||||
|         itemsOffset + 1 + `items`.length | ||||
|       ) | ||||
|     }) | ||||
| 
 | ||||
|     test('de-structured value', () => { | ||||
|       const source = '<span v-for="(  { id, key })in items" />' | ||||
|       const forNode = parseWithForTransform(source) | ||||
| 
 | ||||
|       const valueIndex = source.indexOf('{ id, key }') | ||||
|       expect(forNode.valueAlias!.content).toBe('{ id, key }') | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('{ id, key }') - 1 | ||||
|       ) | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe(valueIndex) | ||||
|       expect(forNode.valueAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe( | ||||
|         source.indexOf('{ id, key }') | ||||
|       ) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(valueIndex + 1) | ||||
|       expect(forNode.valueAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('{ id, key }') + '{ id, key }'.length | ||||
|         valueIndex + 1 + '{ id, key }'.length | ||||
|       ) | ||||
| 
 | ||||
|       const itemsOffset = source.indexOf('items') | ||||
|       expect(forNode.source.content).toBe('items') | ||||
|       expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1) | ||||
|       expect(forNode.source.loc.start.offset).toBe(itemsOffset) | ||||
|       expect(forNode.source.loc.start.line).toBe(1) | ||||
|       expect(forNode.source.loc.start.column).toBe(source.indexOf('items')) | ||||
|       expect(forNode.source.loc.start.column).toBe(itemsOffset + 1) | ||||
|       expect(forNode.source.loc.end.line).toBe(1) | ||||
|       expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5) | ||||
|       expect(forNode.source.loc.end.column).toBe( | ||||
|         itemsOffset + 1 + `items`.length | ||||
|       ) | ||||
|     }) | ||||
| 
 | ||||
|     test('bracketed value, key, index', () => { | ||||
|       const source = '<span v-for="( item, key, index ) in items" />' | ||||
|       const forNode = parseWithForTransform(source) | ||||
| 
 | ||||
|       const itemOffset = source.indexOf('item') | ||||
|       expect(forNode.valueAlias!.content).toBe('item') | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('item') - 1 | ||||
|       ) | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset) | ||||
|       expect(forNode.valueAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item')) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1) | ||||
|       expect(forNode.valueAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('item') + 4 | ||||
|         itemOffset + 1 + `item`.length | ||||
|       ) | ||||
| 
 | ||||
|       const keyOffset = source.indexOf('key') | ||||
|       expect(forNode.keyAlias!.content).toBe('key') | ||||
|       expect(forNode.keyAlias!.loc.start.offset).toBe(source.indexOf('key') - 1) | ||||
|       expect(forNode.keyAlias!.loc.start.offset).toBe(keyOffset) | ||||
|       expect(forNode.keyAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.keyAlias!.loc.start.column).toBe(source.indexOf('key')) | ||||
|       expect(forNode.keyAlias!.loc.start.column).toBe(keyOffset + 1) | ||||
|       expect(forNode.keyAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.keyAlias!.loc.end.column).toBe(source.indexOf('key') + 3) | ||||
|       expect(forNode.keyAlias!.loc.end.column).toBe( | ||||
|         keyOffset + 1 + `key`.length | ||||
|       ) | ||||
| 
 | ||||
|       const indexOffset = source.indexOf('index') | ||||
|       expect(forNode.objectIndexAlias!.content).toBe('index') | ||||
|       expect(forNode.objectIndexAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('index') - 1 | ||||
|       ) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.offset).toBe(indexOffset) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.column).toBe( | ||||
|         source.indexOf('index') | ||||
|       ) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.column).toBe(indexOffset + 1) | ||||
|       expect(forNode.objectIndexAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.objectIndexAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('index') + 5 | ||||
|         indexOffset + 1 + `index`.length | ||||
|       ) | ||||
| 
 | ||||
|       const itemsOffset = source.indexOf('items') | ||||
|       expect(forNode.source.content).toBe('items') | ||||
|       expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1) | ||||
|       expect(forNode.source.loc.start.offset).toBe(itemsOffset) | ||||
|       expect(forNode.source.loc.start.line).toBe(1) | ||||
|       expect(forNode.source.loc.start.column).toBe(source.indexOf('items')) | ||||
|       expect(forNode.source.loc.start.column).toBe(itemsOffset + 1) | ||||
|       expect(forNode.source.loc.end.line).toBe(1) | ||||
|       expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5) | ||||
|       expect(forNode.source.loc.end.column).toBe( | ||||
|         itemsOffset + 1 + `items`.length | ||||
|       ) | ||||
|     }) | ||||
| 
 | ||||
|     test('skipped key', () => { | ||||
|       const source = '<span v-for="( item,, index ) in items" />' | ||||
|       const forNode = parseWithForTransform(source) | ||||
| 
 | ||||
|       const itemOffset = source.indexOf('item') | ||||
|       expect(forNode.valueAlias!.content).toBe('item') | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('item') - 1 | ||||
|       ) | ||||
|       expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset) | ||||
|       expect(forNode.valueAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item')) | ||||
|       expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1) | ||||
|       expect(forNode.valueAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.valueAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('item') + 4 | ||||
|         itemOffset + 1 + `item`.length | ||||
|       ) | ||||
| 
 | ||||
|       const indexOffset = source.indexOf('index') | ||||
|       expect(forNode.objectIndexAlias!.content).toBe('index') | ||||
|       expect(forNode.objectIndexAlias!.loc.start.offset).toBe( | ||||
|         source.indexOf('index') - 1 | ||||
|       ) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.offset).toBe(indexOffset) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.line).toBe(1) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.column).toBe( | ||||
|         source.indexOf('index') | ||||
|       ) | ||||
|       expect(forNode.objectIndexAlias!.loc.start.column).toBe(indexOffset + 1) | ||||
|       expect(forNode.objectIndexAlias!.loc.end.line).toBe(1) | ||||
|       expect(forNode.objectIndexAlias!.loc.end.column).toBe( | ||||
|         source.indexOf('index') + 5 | ||||
|         indexOffset + 1 + `index`.length | ||||
|       ) | ||||
| 
 | ||||
|       const itemsOffset = source.indexOf('items') | ||||
|       expect(forNode.source.content).toBe('items') | ||||
|       expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1) | ||||
|       expect(forNode.source.loc.start.offset).toBe(itemsOffset) | ||||
|       expect(forNode.source.loc.start.line).toBe(1) | ||||
|       expect(forNode.source.loc.start.column).toBe(source.indexOf('items')) | ||||
|       expect(forNode.source.loc.start.column).toBe(itemsOffset + 1) | ||||
|       expect(forNode.source.loc.end.line).toBe(1) | ||||
|       expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5) | ||||
|       expect(forNode.source.loc.end.column).toBe( | ||||
|         itemsOffset + 1 + `items`.length | ||||
|       ) | ||||
|     }) | ||||
|   }) | ||||
| }) | ||||
|  | ||||
| @ -29,9 +29,7 @@ describe('compiler: transform v-if', () => { | ||||
|   test('basic v-if', () => { | ||||
|     const node = parseWithIfTransform(`<div v-if="ok"/>`) | ||||
|     expect(node.type).toBe(NodeTypes.IF) | ||||
|     expect(node.isRoot).toBe(true) | ||||
|     expect(node.branches.length).toBe(1) | ||||
|     expect(node.branches[0].isRoot).toBe(true) | ||||
|     expect(node.branches[0].condition!.content).toBe(`ok`) | ||||
|     expect(node.branches[0].children.length).toBe(1) | ||||
|     expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT) | ||||
|  | ||||
| @ -50,11 +50,11 @@ describe('compiler: transform v-bind', () => { | ||||
|         loc: { | ||||
|           start: { | ||||
|             line: 1, | ||||
|             column: 17 | ||||
|             column: 18 | ||||
|           }, | ||||
|           end: { | ||||
|             line: 1, | ||||
|             column: 26 | ||||
|             column: 25 | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|  | ||||
| @ -28,7 +28,7 @@ describe('advancePositionWithClone', () => { | ||||
|     const pos = p(1, 1, 0) | ||||
|     const newPos = advancePositionWithClone(pos, 'foo\nbar\nbaz', 10) | ||||
| 
 | ||||
|     expect(newPos.column).toBe(2) | ||||
|     expect(newPos.column).toBe(3) | ||||
|     expect(newPos.line).toBe(3) | ||||
|     expect(newPos.offset).toBe(10) | ||||
|   }) | ||||
| @ -62,7 +62,7 @@ describe('getInnerRange', () => { | ||||
|     expect(loc2.start.column).toBe(1) | ||||
|     expect(loc2.start.line).toBe(2) | ||||
|     expect(loc2.start.offset).toBe(4) | ||||
|     expect(loc2.end.column).toBe(3) | ||||
|     expect(loc2.end.column).toBe(4) | ||||
|     expect(loc2.end.line).toBe(2) | ||||
|     expect(loc2.end.offset).toBe(7) | ||||
|   }) | ||||
|  | ||||
| @ -118,14 +118,12 @@ export interface ExpressionNode extends Node { | ||||
| export interface IfNode extends Node { | ||||
|   type: NodeTypes.IF | ||||
|   branches: IfBranchNode[] | ||||
|   isRoot: boolean | ||||
| } | ||||
| 
 | ||||
| export interface IfBranchNode extends Node { | ||||
|   type: NodeTypes.IF_BRANCH | ||||
|   condition: ExpressionNode | undefined // else
 | ||||
|   children: ChildNode[] | ||||
|   isRoot: boolean | ||||
| } | ||||
| 
 | ||||
| export interface ForNode extends Node { | ||||
|  | ||||
| @ -65,6 +65,7 @@ export interface CodegenContext extends Required<CodegenOptions> { | ||||
|   offset: number | ||||
|   indentLevel: number | ||||
|   map?: SourceMapGenerator | ||||
|   helper(name: string): string | ||||
|   push(code: string, node?: CodegenNode): void | ||||
|   indent(): void | ||||
|   deindent(withoutNewLine?: boolean): void | ||||
| @ -98,11 +99,14 @@ function createCodegenContext( | ||||
|         ? undefined | ||||
|         : new (require('source-map')).SourceMapGenerator(), | ||||
| 
 | ||||
|     helper(name) { | ||||
|       return prefixIdentifiers ? name : `_${name}` | ||||
|     }, | ||||
|     push(code, node?: CodegenNode) { | ||||
|       context.code += code | ||||
|       if (context.map) { | ||||
|         if (node) { | ||||
|           context.map.addMapping({ | ||||
|           const mapping = { | ||||
|             source: context.filename, | ||||
|             original: { | ||||
|               line: node.loc.start.line, | ||||
| @ -112,9 +116,10 @@ function createCodegenContext( | ||||
|               line: context.line, | ||||
|               column: context.column - 1 | ||||
|             } | ||||
|           }) | ||||
|           } | ||||
|           context.map.addMapping(mapping) | ||||
|         } | ||||
|         advancePositionWithMutation(context, code, code.length) | ||||
|         advancePositionWithMutation(context, code) | ||||
|       } | ||||
|     }, | ||||
|     indent() { | ||||
| @ -144,7 +149,7 @@ export function generate( | ||||
| ): CodegenResult { | ||||
|   const context = createCodegenContext(ast, options) | ||||
|   const { mode, push, prefixIdentifiers, indent, deindent, newline } = context | ||||
|   const imports = ast.imports.join(', ') | ||||
|   const hasImports = ast.imports.length | ||||
| 
 | ||||
|   // preambles
 | ||||
|   if (mode === 'function') { | ||||
| @ -152,9 +157,9 @@ export function generate( | ||||
|     // In prefix mode, we place the const declaration at top so it's done
 | ||||
|     // only once; But if we not prefixing, we place the decalration inside the
 | ||||
|     // with block so it doesn't incur the `in` check cost for every helper access.
 | ||||
|     if (imports) { | ||||
|     if (hasImports) { | ||||
|       if (prefixIdentifiers) { | ||||
|         push(`const { ${imports} } = Vue\n`) | ||||
|         push(`const { ${ast.imports.join(', ')} } = Vue\n`) | ||||
|       } else { | ||||
|         // save Vue in a separate variable to avoid collision
 | ||||
|         push(`const _Vue = Vue`) | ||||
| @ -164,8 +169,8 @@ export function generate( | ||||
|     push(`return `) | ||||
|   } else { | ||||
|     // generate import statements for helpers
 | ||||
|     if (imports) { | ||||
|       push(`import { ${imports} } from 'vue'\n`) | ||||
|     if (hasImports) { | ||||
|       push(`import { ${ast.imports.join(', ')} } from 'vue'\n`) | ||||
|     } | ||||
|     genHoists(ast.hoists, context) | ||||
|     push(`export default `) | ||||
| @ -179,8 +184,9 @@ export function generate( | ||||
|     push(`with (this) {`) | ||||
|     indent() | ||||
|     // function mode const declarations should be inside with block
 | ||||
|     if (mode === 'function' && imports) { | ||||
|       push(`const { ${imports} } = _Vue`) | ||||
|     // also they should be renamed to avoid collision with user properties
 | ||||
|     if (mode === 'function' && hasImports) { | ||||
|       push(`const { ${ast.imports.map(n => `${n}: _${n}`).join(', ')} } = _Vue`) | ||||
|       newline() | ||||
|     } | ||||
|   } else { | ||||
| @ -199,7 +205,7 @@ export function generate( | ||||
| 
 | ||||
|   // generate the VNode tree expression
 | ||||
|   push(`return `) | ||||
|   genChildren(ast.children, context, true /* asRoot */) | ||||
|   genChildren(ast.children, context, true) | ||||
|   if (!prefixIdentifiers) { | ||||
|     deindent() | ||||
|     push(`}`) | ||||
| @ -223,13 +229,12 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) { | ||||
| } | ||||
| 
 | ||||
| // This will generate a single vnode call if:
 | ||||
| // - The list has length === 1, AND:
 | ||||
| // - This is a root node, OR:
 | ||||
| // - The only child is a text or expression.
 | ||||
| // - 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.
 | ||||
| function genChildren( | ||||
|   children: ChildNode[], | ||||
|   context: CodegenContext, | ||||
|   asRoot: boolean = false | ||||
|   allowSingle: boolean = false | ||||
| ) { | ||||
|   if (!children.length) { | ||||
|     return context.push(`null`) | ||||
| @ -237,7 +242,7 @@ function genChildren( | ||||
|   const child = children[0] | ||||
|   if ( | ||||
|     children.length === 1 && | ||||
|     (asRoot || | ||||
|     (allowSingle || | ||||
|       child.type === NodeTypes.TEXT || | ||||
|       child.type == NodeTypes.EXPRESSION) | ||||
|   ) { | ||||
| @ -336,10 +341,10 @@ function genText(node: TextNode | ExpressionNode, context: CodegenContext) { | ||||
| } | ||||
| 
 | ||||
| function genExpression(node: ExpressionNode, context: CodegenContext) { | ||||
|   const { push } = context | ||||
|   const { push, helper } = context | ||||
|   const { content, children, isStatic, isInterpolation } = node | ||||
|   if (isInterpolation) { | ||||
|     push(`${TO_STRING}(`) | ||||
|     push(`${helper(TO_STRING)}(`) | ||||
|   } | ||||
|   if (children) { | ||||
|     genCompoundExpression(node, context) | ||||
| @ -383,8 +388,11 @@ function genCompoundExpression(node: ExpressionNode, context: CodegenContext) { | ||||
| 
 | ||||
| function genComment(node: CommentNode, context: CodegenContext) { | ||||
|   if (__DEV__) { | ||||
|     context.push( | ||||
|       `${CREATE_VNODE}(${COMMENT}, 0, ${JSON.stringify(node.content)})`, | ||||
|     const { push, helper } = context | ||||
|     push( | ||||
|       `${helper(CREATE_VNODE)}(${helper(COMMENT)}, 0, ${JSON.stringify( | ||||
|         node.content | ||||
|       )})`,
 | ||||
|       node | ||||
|     ) | ||||
|   } | ||||
| @ -396,7 +404,7 @@ function genIf(node: IfNode, context: CodegenContext) { | ||||
| } | ||||
| 
 | ||||
| function genIfBranch( | ||||
|   { condition, children, isRoot }: IfBranchNode, | ||||
|   { condition, children }: IfBranchNode, | ||||
|   branches: IfBranchNode[], | ||||
|   nextIndex: number, | ||||
|   context: CodegenContext | ||||
| @ -411,7 +419,7 @@ function genIfBranch( | ||||
|     indent() | ||||
|     context.indentLevel++ | ||||
|     push(`? `) | ||||
|     genChildren(children, context, isRoot) | ||||
|     genChildren(children, context, true) | ||||
|     context.indentLevel-- | ||||
|     newline() | ||||
|     push(`: `) | ||||
| @ -424,14 +432,14 @@ function genIfBranch( | ||||
|   } else { | ||||
|     // v-else
 | ||||
|     __DEV__ && assert(nextIndex === branches.length) | ||||
|     genChildren(children, context, isRoot) | ||||
|     genChildren(children, context, true) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function genFor(node: ForNode, context: CodegenContext) { | ||||
|   const { push } = context | ||||
|   const { push, helper, indent, deindent } = context | ||||
|   const { source, keyAlias, valueAlias, objectIndexAlias, children } = node | ||||
|   push(`${RENDER_LIST}(`, node) | ||||
|   push(`${helper(RENDER_LIST)}(`, node) | ||||
|   genExpression(source, context) | ||||
|   push(`, (`) | ||||
|   if (valueAlias) { | ||||
| @ -455,9 +463,12 @@ function genFor(node: ForNode, context: CodegenContext) { | ||||
|     push(`, `) | ||||
|     genExpression(objectIndexAlias, context) | ||||
|   } | ||||
|   push(`) => `) | ||||
|   genChildren(children, context) | ||||
|   push(`)`) | ||||
|   push(`) => {`) | ||||
|   indent() | ||||
|   push(`return `) | ||||
|   genChildren(children, context, true) | ||||
|   deindent() | ||||
|   push(`})`) | ||||
| } | ||||
| 
 | ||||
| // JavaScript
 | ||||
|  | ||||
| @ -479,7 +479,14 @@ function parseAttribute( | ||||
|   advanceBy(context, name.length) | ||||
| 
 | ||||
|   // Value
 | ||||
|   let value: { content: string; loc: SourceLocation } | undefined = undefined | ||||
|   let value: | ||||
|     | { | ||||
|         content: string | ||||
|         isQuoted: boolean | ||||
|         loc: SourceLocation | ||||
|       } | ||||
|     | undefined = undefined | ||||
| 
 | ||||
|   if (/^[\t\r\n\f ]*=/.test(context.source)) { | ||||
|     advanceSpaces(context) | ||||
|     advanceBy(context, 1) | ||||
| @ -530,6 +537,13 @@ function parseAttribute( | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (value && value.isQuoted) { | ||||
|       const valueLoc = value.loc | ||||
|       valueLoc.start.offset++ | ||||
|       valueLoc.start.column++ | ||||
|       valueLoc.end = advancePositionWithClone(valueLoc.start, value.content) | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|       type: NodeTypes.DIRECTIVE, | ||||
|       name: | ||||
| @ -567,13 +581,20 @@ function parseAttribute( | ||||
| 
 | ||||
| function parseAttributeValue( | ||||
|   context: ParserContext | ||||
| ): { content: string; loc: SourceLocation } | undefined { | ||||
| ): | ||||
|   | { | ||||
|       content: string | ||||
|       isQuoted: boolean | ||||
|       loc: SourceLocation | ||||
|     } | ||||
|   | undefined { | ||||
|   const start = getCursor(context) | ||||
|   let content: string | ||||
| 
 | ||||
|   if (/^["']/.test(context.source)) { | ||||
|   const quote = context.source[0] | ||||
|   const isQuoted = quote === `"` || quote === `'` | ||||
|   if (isQuoted) { | ||||
|     // Quoted value.
 | ||||
|     const quote = context.source[0] | ||||
|     advanceBy(context, 1) | ||||
| 
 | ||||
|     const endIndex = context.source.indexOf(quote) | ||||
| @ -605,7 +626,7 @@ function parseAttributeValue( | ||||
|     content = parseTextData(context, match[0].length, TextModes.ATTRIBUTE_VALUE) | ||||
|   } | ||||
| 
 | ||||
|   return { content, loc: getSelection(context, start) } | ||||
|   return { content, isQuoted, loc: getSelection(context, start) } | ||||
| } | ||||
| 
 | ||||
| function parseInterpolation( | ||||
|  | ||||
| @ -59,6 +59,7 @@ export interface TransformContext extends Required<TransformOptions> { | ||||
|   parent: ParentNode | ||||
|   childIndex: number | ||||
|   currentNode: ChildNode | null | ||||
|   helper(name: string): string | ||||
|   replaceNode(node: ChildNode): void | ||||
|   removeNode(node?: ChildNode): void | ||||
|   onNodeRemoved: () => void | ||||
| @ -89,6 +90,10 @@ function createTransformContext( | ||||
|     parent: root, | ||||
|     childIndex: 0, | ||||
|     currentNode: null, | ||||
|     helper(name) { | ||||
|       context.imports.add(name) | ||||
|       return prefixIdentifiers ? name : `_${name}` | ||||
|     }, | ||||
|     replaceNode(node) { | ||||
|       /* istanbul ignore if */ | ||||
|       if (__DEV__ && !context.currentNode) { | ||||
| @ -195,15 +200,15 @@ export function traverseNode(node: ChildNode, context: TransformContext) { | ||||
| 
 | ||||
|   switch (node.type) { | ||||
|     case NodeTypes.COMMENT: | ||||
|       context.imports.add(CREATE_VNODE) | ||||
|       context.helper(CREATE_VNODE) | ||||
|       // inject import for the Comment symbol, which is needed for creating
 | ||||
|       // comment nodes with `createVNode`
 | ||||
|       context.imports.add(COMMENT) | ||||
|       context.helper(COMMENT) | ||||
|       break | ||||
|     case NodeTypes.EXPRESSION: | ||||
|       // no need to traverse, but we need to inject toString helper
 | ||||
|       if (node.isInterpolation) { | ||||
|         context.imports.add(TO_STRING) | ||||
|         context.helper(TO_STRING) | ||||
|       } | ||||
|       break | ||||
| 
 | ||||
|  | ||||
| @ -42,12 +42,11 @@ export const transformElement: NodeTransform = (node, context) => { | ||||
|       let componentIdentifier: string | undefined | ||||
| 
 | ||||
|       if (isComponent) { | ||||
|         context.imports.add(RESOLVE_COMPONENT) | ||||
|         componentIdentifier = `_component_${toValidId(node.tag)}` | ||||
|         context.statements.push( | ||||
|           `const ${componentIdentifier} = ${RESOLVE_COMPONENT}(${JSON.stringify( | ||||
|             node.tag | ||||
|           )})` | ||||
|           `const ${componentIdentifier} = ${context.helper( | ||||
|             RESOLVE_COMPONENT | ||||
|           )}(${JSON.stringify(node.tag)})` | ||||
|         ) | ||||
|       } | ||||
| 
 | ||||
| @ -70,13 +69,15 @@ export const transformElement: NodeTransform = (node, context) => { | ||||
|       } | ||||
| 
 | ||||
|       const { loc } = node | ||||
|       context.imports.add(CREATE_VNODE) | ||||
|       const vnode = createCallExpression(CREATE_VNODE, args, loc) | ||||
|       const vnode = createCallExpression( | ||||
|         context.helper(CREATE_VNODE), | ||||
|         args, | ||||
|         loc | ||||
|       ) | ||||
| 
 | ||||
|       if (runtimeDirectives && runtimeDirectives.length) { | ||||
|         context.imports.add(APPLY_DIRECTIVES) | ||||
|         node.codegenNode = createCallExpression( | ||||
|           APPLY_DIRECTIVES, | ||||
|           context.helper(APPLY_DIRECTIVES), | ||||
|           [ | ||||
|             vnode, | ||||
|             createArrayExpression( | ||||
| @ -147,11 +148,10 @@ function buildProps( | ||||
|             mergeArgs.push(exp) | ||||
|           } else { | ||||
|             // v-on="obj" -> toHandlers(obj)
 | ||||
|             context.imports.add(TO_HANDLERS) | ||||
|             mergeArgs.push({ | ||||
|               type: NodeTypes.JS_CALL_EXPRESSION, | ||||
|               loc, | ||||
|               callee: TO_HANDLERS, | ||||
|               callee: context.helper(TO_HANDLERS), | ||||
|               arguments: [exp] | ||||
|             }) | ||||
|           } | ||||
| @ -197,8 +197,11 @@ function buildProps( | ||||
|       ) | ||||
|     } | ||||
|     if (mergeArgs.length > 1) { | ||||
|       context.imports.add(MERGE_PROPS) | ||||
|       propsExpression = createCallExpression(MERGE_PROPS, mergeArgs, elementLoc) | ||||
|       propsExpression = createCallExpression( | ||||
|         context.helper(MERGE_PROPS), | ||||
|         mergeArgs, | ||||
|         elementLoc | ||||
|       ) | ||||
|     } else { | ||||
|       // single v-bind with nothing else - no need for a mergeProps call
 | ||||
|       propsExpression = mergeArgs[0] | ||||
| @ -285,12 +288,12 @@ function createDirectiveArgs( | ||||
|   dir: DirectiveNode, | ||||
|   context: TransformContext | ||||
| ): ArrayExpression { | ||||
|   // inject import for `resolveDirective`
 | ||||
|   context.imports.add(RESOLVE_DIRECTIVE) | ||||
|   // inject statement for resolving directive
 | ||||
|   const dirIdentifier = `_directive_${toValidId(dir.name)}` | ||||
|   context.statements.push( | ||||
|     `const ${dirIdentifier} = ${RESOLVE_DIRECTIVE}(${JSON.stringify(dir.name)})` | ||||
|     `const ${dirIdentifier} = ${context.helper( | ||||
|       RESOLVE_DIRECTIVE | ||||
|     )}(${JSON.stringify(dir.name)})` | ||||
|   ) | ||||
|   const dirArgs: ArrayExpression['elements'] = [dirIdentifier] | ||||
|   const { loc } = dir | ||||
|  | ||||
| @ -24,7 +24,7 @@ export const transformFor = createStructuralDirectiveTransform( | ||||
|       const parseResult = parseForExpression(dir.exp, context) | ||||
| 
 | ||||
|       if (parseResult) { | ||||
|         context.imports.add(RENDER_LIST) | ||||
|         context.helper(RENDER_LIST) | ||||
|         const { source, value, key, index } = parseResult | ||||
| 
 | ||||
|         context.replaceNode({ | ||||
|  | ||||
| @ -19,14 +19,10 @@ export const transformIf = createStructuralDirectiveTransform( | ||||
|       processExpression(dir.exp, context) | ||||
|     } | ||||
|     if (dir.name === 'if') { | ||||
|       // check if this v-if is root - so that in codegen we can avoid generating
 | ||||
|       // arrays for each branch
 | ||||
|       const isRoot = context.parent === context.root | ||||
|       context.replaceNode({ | ||||
|         type: NodeTypes.IF, | ||||
|         loc: node.loc, | ||||
|         branches: [createIfBranch(node, dir, isRoot)], | ||||
|         isRoot | ||||
|         branches: [createIfBranch(node, dir)] | ||||
|       }) | ||||
|     } else { | ||||
|       // locate the adjacent v-if
 | ||||
| @ -43,7 +39,7 @@ export const transformIf = createStructuralDirectiveTransform( | ||||
|         if (sibling && sibling.type === NodeTypes.IF) { | ||||
|           // move the node to the if node's branches
 | ||||
|           context.removeNode() | ||||
|           const branch = createIfBranch(node, dir, sibling.isRoot) | ||||
|           const branch = createIfBranch(node, dir) | ||||
|           if (__DEV__ && comments.length) { | ||||
|             branch.children = [...comments, ...branch.children] | ||||
|           } | ||||
| @ -67,16 +63,11 @@ export const transformIf = createStructuralDirectiveTransform( | ||||
|   } | ||||
| ) | ||||
| 
 | ||||
| function createIfBranch( | ||||
|   node: ElementNode, | ||||
|   dir: DirectiveNode, | ||||
|   isRoot: boolean | ||||
| ): IfBranchNode { | ||||
| function createIfBranch(node: ElementNode, dir: DirectiveNode): IfBranchNode { | ||||
|   return { | ||||
|     type: NodeTypes.IF_BRANCH, | ||||
|     loc: node.loc, | ||||
|     condition: dir.name === 'else' ? undefined : dir.exp, | ||||
|     children: node.tagType === ElementTypes.TEMPLATE ? node.children : [node], | ||||
|     isRoot | ||||
|     children: node.tagType === ElementTypes.TEMPLATE ? node.children : [node] | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -31,7 +31,7 @@ export function getInnerRange( | ||||
| export function advancePositionWithClone( | ||||
|   pos: Position, | ||||
|   source: string, | ||||
|   numberOfCharacters: number | ||||
|   numberOfCharacters: number = source.length | ||||
| ): Position { | ||||
|   return advancePositionWithMutation({ ...pos }, source, numberOfCharacters) | ||||
| } | ||||
| @ -41,7 +41,7 @@ export function advancePositionWithClone( | ||||
| export function advancePositionWithMutation( | ||||
|   pos: Position, | ||||
|   source: string, | ||||
|   numberOfCharacters: number | ||||
|   numberOfCharacters: number = source.length | ||||
| ): Position { | ||||
|   let linesCount = 0 | ||||
|   let lastNewLinePos = -1 | ||||
| @ -57,7 +57,7 @@ export function advancePositionWithMutation( | ||||
|   pos.column = | ||||
|     lastNewLinePos === -1 | ||||
|       ? pos.column + numberOfCharacters | ||||
|       : Math.max(1, numberOfCharacters - lastNewLinePos - 1) | ||||
|       : Math.max(1, numberOfCharacters - lastNewLinePos) | ||||
| 
 | ||||
|   return pos | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user