提交 02c7944d 编写于 作者: fxy060608's avatar fxy060608

wip(uts): 优化sourcemap

上级 6af48a93
......@@ -33,17 +33,18 @@ describe('compiler:codegen', () => {
test(`function:kotlin`, () => {
assert(
`<view/>`,
`function PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\n return createElementVNode("view")\n}`,
`
function PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\n return createElementVNode("view")\n}`,
{
targetLanguage: 'kotlin',
mode: 'function',
}
)
})
test(`UTSComponents:kotlin`, () => {
test(`UTSComponents`, () => {
assert(
`<view><uts-hello/><uts-hello/></view>`,
`import { UtsHelloElement } from 'uts.sdk.modules.utsHello'\nfunction PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\n return createElementVNode("view", null, [\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name),\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name)\n ])\n}`,
`import { UtsHelloElement } from 'uts.sdk.modules.utsHello';\nfunction PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\n return createElementVNode("view", null, [\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name),\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name)\n ])\n}`,
{
targetLanguage: 'kotlin',
mode: 'function',
......@@ -60,7 +61,7 @@ describe('compiler:codegen', () => {
)
assert(
`<view><uts-hello/><uts-hello/><uts-hello1/></view>`,
`import { UtsHelloElement } from 'uts.sdk.modules.utsHello'\nimport { UtsHello1Element } from 'uts.sdk.modules.utsHello'\nfunction PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\n return createElementVNode("view", null, [\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name),\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name),\n createElementVNode(uts.sdk.modules.utsHello.UtsHello1Component.name)\n ])\n}`,
`import { UtsHelloElement } from 'uts.sdk.modules.utsHello';import { UtsHello1Element } from 'uts.sdk.modules.utsHello';\nfunction PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\n return createElementVNode("view", null, [\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name),\n createElementVNode(uts.sdk.modules.utsHello.UtsHelloComponent.name),\n createElementVNode(uts.sdk.modules.utsHello.UtsHello1Component.name)\n ])\n}`,
{
targetLanguage: 'kotlin',
mode: 'function',
......@@ -85,7 +86,8 @@ describe('compiler:codegen', () => {
test(`easycom`, () => {
assert(
`<view><custom/><custom/><custom1/><index/><index1/></view>`,
`import _easycom_custom, { GenComponentsCustomCustomComponentPublicInstance as CustomComponentPublicInstance } from '@/components/custom/custom.vue'\nimport _easycom_custom1, { GenComponentsCustom1Custom1ComponentPublicInstance as Custom1ComponentPublicInstance } from '@/components/custom1/custom1.vue'\nimport _easycom_index, { GenComponentsIndexIndexComponentPublicInstance as IndexComponentPublicInstance } from '@/components/index/index.vue'\nfunction PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\nconst _component_custom = resolveEasyComponent("custom",_easycom_custom)\nconst _component_custom1 = resolveEasyComponent("custom1",_easycom_custom1)\nconst _component_index = resolveEasyComponent("index",_easycom_index)\nconst _component_index1 = resolveComponent("index1")\n\n return createElementVNode("view", null, [\n createVNode(_component_custom),\n createVNode(_component_custom),\n createVNode(_component_custom1),\n createVNode(_component_index),\n createVNode(_component_index1)\n ])\n}`,
`
import _easycom_custom, { GenComponentsCustomCustomComponentPublicInstance as CustomComponentPublicInstance } from '@/components/custom/custom.vue'\nimport _easycom_custom1, { GenComponentsCustom1Custom1ComponentPublicInstance as Custom1ComponentPublicInstance } from '@/components/custom1/custom1.vue'\nimport _easycom_index, { GenComponentsIndexIndexComponentPublicInstance as IndexComponentPublicInstance } from '@/components/index/index.vue'\nfunction PagesIndexIndexRender(): VNode | null {\nconst _ctx = this\nconst _component_custom = resolveEasyComponent("custom",_easycom_custom)\nconst _component_custom1 = resolveEasyComponent("custom1",_easycom_custom1)\nconst _component_index = resolveEasyComponent("index",_easycom_index)\nconst _component_index1 = resolveComponent("index1")\n\n return createElementVNode("view", null, [\n createVNode(_component_custom),\n createVNode(_component_custom),\n createVNode(_component_custom1),\n createVNode(_component_index),\n createVNode(_component_index1)\n ])\n}`,
{
targetLanguage: 'kotlin',
mode: 'function',
......@@ -98,7 +100,8 @@ describe('compiler:codegen', () => {
)
assert(
`<index/>`,
`function PagesIndexIndexRender(): VNode | null {
`
function PagesIndexIndexRender(): VNode | null {
const _ctx = this
const _component_index = resolveComponent("index", true)
......@@ -113,7 +116,7 @@ const _component_index = resolveComponent("index", true)
test(`UTSComponents and easycom`, () => {
assert(
`<view><uts-hello/><uts-hello/><custom/><custom/><custom1/><index/><index1/></view>`,
`import { UtsHelloElement } from 'uts.sdk.modules.utsHello'
`import { UtsHelloElement } from 'uts.sdk.modules.utsHello';
import _easycom_custom, { GenComponentsCustomCustomComponentPublicInstance as CustomComponentPublicInstance } from '@/components/custom/custom.vue'
import _easycom_custom1, { GenComponentsCustom1Custom1ComponentPublicInstance as Custom1ComponentPublicInstance } from '@/components/custom1/custom1.vue'
import _easycom_index, { GenComponentsIndexIndexComponentPublicInstance as IndexComponentPublicInstance } from '@/components/index/index.vue'
......
......@@ -4,7 +4,8 @@ describe('compiler: component', () => {
test('template component', () => {
assert(
`<view><Foo /></view>`,
`function PagesIndexIndexRender(): VNode | null {
`
function PagesIndexIndexRender(): VNode | null {
const _ctx = this
const _component_Foo = resolveComponent("Foo")
......
......@@ -92,7 +92,8 @@ describe('compiler: slot', () => {
test('component with slot', () => {
assert(
`<view><slot data="data"></slot></view>`,
`function PagesIndexIndexRender(): VNode | null {
`
function PagesIndexIndexRender(): VNode | null {
const _ctx = this
return createElementVNode("view", null, [
renderSlot(_ctx.$slots, "default", utsMapOf({ data: "data" }))
......@@ -108,7 +109,8 @@ const _ctx = this
test('template component with slot', () => {
assert(
`<view><Foo @click="test">test</Foo></view>`,
`function PagesIndexIndexRender(): VNode | null {
`
function PagesIndexIndexRender(): VNode | null {
const _ctx = this
const _component_Foo = resolveComponent("Foo")
......@@ -143,7 +145,8 @@ const _component_Foo = resolveComponent("Foo")
test('scoped slots', () => {
assert(
`<view><Foo><template v-slot="props"><text>msg: {{props.msg}}</text></template></Foo></view>`,
`function PagesIndexIndexRender(): VNode | null {
`
function PagesIndexIndexRender(): VNode | null {
const _ctx = this
const _component_Foo = resolveComponent("Foo")
......@@ -166,7 +169,8 @@ const _component_Foo = resolveComponent("Foo")
test('scoped slots shorthand', () => {
assert(
`<view><Foo><template #default="props"><text>msg: {{props.msg}}</text></template></Foo></view>`,
`function PagesIndexIndexRender(): VNode | null {
`
function PagesIndexIndexRender(): VNode | null {
const _ctx = this
const _component_Foo = resolveComponent("Foo")
......
......@@ -11,6 +11,7 @@ import {
FunctionExpression,
InterpolationNode,
JSChildNode,
Node,
NodeTypes,
OPEN_BLOCK,
ObjectExpression,
......@@ -26,6 +27,7 @@ import {
WITH_CTX,
WITH_DIRECTIVES,
advancePositionWithMutation,
createSimpleExpression,
getVNodeBlockHelper,
getVNodeHelper,
helperNameMap,
......@@ -63,7 +65,13 @@ type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode
export interface CodegenContext
extends Required<
Omit<CodegenOptions, 'sourceMapGeneratedLine' | 'className'>
Omit<
CodegenOptions,
| 'sourceMapGeneratedLine'
| 'className'
| 'originalLineOffset'
| 'generatedLineOffset'
>
> {
source: string
code: string
......@@ -95,6 +103,8 @@ function createCodegenContext(
filename = '',
matchEasyCom = NOOP,
parseUTSComponent = NOOP,
originalLineOffset = 0,
generatedLineOffset = 0,
}: CodegenOptions
): CodegenContext {
const context: CodegenContext = {
......@@ -164,11 +174,11 @@ function createCodegenContext(
name,
source: context.filename,
original: {
line: loc.line,
line: loc.line + originalLineOffset,
column: loc.column - 1, // source-map column is 0 based
},
generated: {
line: context.line,
line: context.line + generatedLineOffset,
column: context.column - 1,
},
})
......@@ -193,6 +203,7 @@ export function generate(
const { mode, deindent, indent, push, newline } = context
if (mode === 'function') {
push(UTS_COMPONENT_ELEMENT_IMPORTS)
newline()
genEasyComImports(ast.components, context)
push(genRenderFunctionDecl(options) + ` {`)
newline()
......@@ -230,7 +241,7 @@ export function generate(
context.code = context.code.replace(
UTS_COMPONENT_ELEMENT_IMPORTS,
context.importUTSElements.length
? context.importUTSElements.join('\n') + '\n'
? context.importUTSElements.join(';') + ';'
: ''
)
......@@ -500,6 +511,7 @@ function genComment(node: CommentNode, context: CodegenContext) {
function parseTag(
tag: string | symbol | CallExpression,
curNode: Node,
{
parseUTSComponent,
targetLanguage,
......@@ -525,11 +537,13 @@ function parseTag(
if (!importUTSElements.includes(importElementCode)) {
importUTSElements.push(importElementCode)
}
return (
return createSimpleExpression(
utsComponentOptions.namespace +
'.' +
utsComponentOptions.className +
'.name'
'.' +
utsComponentOptions.className +
'.name',
false,
curNode.loc
)
}
}
......@@ -562,7 +576,7 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
push(helper(callHelper) + `(`, node)
genNodeList(
genNullableArgs([
parseTag(tag, context),
parseTag(tag, node, context),
props,
children,
patchFlag,
......
......@@ -61,6 +61,14 @@ export interface CodegenOptions extends SharedTransformCodegenOptions {
}
| undefined
| void
/**
* template的offset
*/
originalLineOffset?: number
/**
* script的offset
*/
generatedLineOffset?: number
}
export interface ErrorHandlingOptions {
......
......@@ -335,30 +335,45 @@ export const ${genComponentPublicInstanceImported(options.root, filename)} = {}`
? createSourceMap(
descriptor.script?.loc.end.line ?? 0,
templateStartLine,
new MagicString(code).generateMap({
hires: true,
source: fileName,
includeContent: true,
}) as unknown as RawSourceMap,
createVueSourceMap(fileName, code, descriptor),
templateSourceMap
)
: undefined,
}
}
function createVueSourceMap(
fileName: string,
code: string,
descriptor: SFCDescriptor
) {
const str = new MagicString(code)
if (descriptor.script) {
const start = descriptor.script.loc.start
const end = descriptor.script.loc.end
str.overwrite(0, start.offset, '\n'.repeat(start.line - 1))
str.remove(end.offset, code.length)
}
return str.generateMap({
hires: true,
source: fileName,
includeContent: true,
}) as unknown as RawSourceMap
}
function createSourceMap(
scriptCodeOffset: number,
templateCodeOffset: number,
scriptMap: RawSourceMap,
vueMap: RawSourceMap,
templateMap?: RawSourceMap
) {
if (!templateMap) {
return scriptMap
return vueMap
}
const gen = fromMap(
// version property of result.map is declared as string
// but actually it is `3`
scriptMap as Omit<RawSourceMap, 'version'> as EncodedSourceMap
vueMap as Omit<RawSourceMap, 'version'> as EncodedSourceMap
)
const tracer = new TraceMap(
// same above
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册