diff --git a/packages/uni-app-uts/__tests__/android/codegen.spec.ts b/packages/uni-app-uts/__tests__/android/codegen.spec.ts index 37704ff257181621889a684853cb9803e1cb3ddb..1b296de57c8949a62c1a50e080cca00c5f70e196 100644 --- a/packages/uni-app-uts/__tests__/android/codegen.spec.ts +++ b/packages/uni-app-uts/__tests__/android/codegen.spec.ts @@ -33,17 +33,18 @@ describe('compiler:codegen', () => { test(`function:kotlin`, () => { assert( ``, - `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( ``, - `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( ``, - `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( ``, - `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( ``, - `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( ``, - `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' diff --git a/packages/uni-app-uts/__tests__/android/transforms/component.spec.ts b/packages/uni-app-uts/__tests__/android/transforms/component.spec.ts index 8c1fc31b035a266c1c2148b6f20257f9c03c840a..ea2f19f267a05b6f299006946ca6cb7b8a0e5dae 100644 --- a/packages/uni-app-uts/__tests__/android/transforms/component.spec.ts +++ b/packages/uni-app-uts/__tests__/android/transforms/component.spec.ts @@ -4,7 +4,8 @@ describe('compiler: component', () => { test('template component', () => { assert( ``, - `function PagesIndexIndexRender(): VNode | null { + ` +function PagesIndexIndexRender(): VNode | null { const _ctx = this const _component_Foo = resolveComponent("Foo") diff --git a/packages/uni-app-uts/__tests__/android/transforms/vSlot.spec.ts b/packages/uni-app-uts/__tests__/android/transforms/vSlot.spec.ts index 2726871837dd5548c44bead832deaaeb4236a8aa..84035fb91f8afd77410c72ec70050eea897b00e1 100644 --- a/packages/uni-app-uts/__tests__/android/transforms/vSlot.spec.ts +++ b/packages/uni-app-uts/__tests__/android/transforms/vSlot.spec.ts @@ -92,7 +92,8 @@ describe('compiler: slot', () => { test('component with slot', () => { assert( ``, - `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( `test`, - `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( ``, - `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( ``, - `function PagesIndexIndexRender(): VNode | null { + ` +function PagesIndexIndexRender(): VNode | null { const _ctx = this const _component_Foo = resolveComponent("Foo") diff --git a/packages/uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts b/packages/uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts index 476c71a5c4c14790aee1a64b0c0b2ca7a6f523d1..50d6276bdc21b92c93f5c0b14c3d99e224cd7191 100644 --- a/packages/uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts +++ b/packages/uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts @@ -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 + 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, diff --git a/packages/uni-app-uts/src/plugins/android/uvue/compiler/options.ts b/packages/uni-app-uts/src/plugins/android/uvue/compiler/options.ts index 14371c37e80305e94aea61303eed5457fa014a1d..6cd07bb63c78461061acf4f3fd72f775c75824b2 100644 --- a/packages/uni-app-uts/src/plugins/android/uvue/compiler/options.ts +++ b/packages/uni-app-uts/src/plugins/android/uvue/compiler/options.ts @@ -61,6 +61,14 @@ export interface CodegenOptions extends SharedTransformCodegenOptions { } | undefined | void + /** + * template的offset + */ + originalLineOffset?: number + /** + * script的offset + */ + generatedLineOffset?: number } export interface ErrorHandlingOptions { diff --git a/packages/uni-app-uts/src/plugins/android/uvue/index.ts b/packages/uni-app-uts/src/plugins/android/uvue/index.ts index 6021507baa4e62a18abf9cd9c5bdebda9b9cf986..0bebfc0a0a35d5c2b9e866b8ad90e2d32ff903cf 100644 --- a/packages/uni-app-uts/src/plugins/android/uvue/index.ts +++ b/packages/uni-app-uts/src/plugins/android/uvue/index.ts @@ -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 as EncodedSourceMap + vueMap as Omit as EncodedSourceMap ) const tracer = new TraceMap( // same above