From 864ec76148c2cb9a821f26b2fb81db04e7e9e813 Mon Sep 17 00:00:00 2001 From: johnsoncodehk Date: Fri, 22 Apr 2022 02:17:12 +0800 Subject: [PATCH] fix: template context properties error missing close #1205 --- .../vue-code-gen/src/generators/template.ts | 22 +++++++++++++++- packages/vue-code-gen/src/transform.ts | 25 +++++++++++++------ .../src/use/useSfcTemplateScript.ts | 23 ++++++++++++++++- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/packages/vue-code-gen/src/generators/template.ts b/packages/vue-code-gen/src/generators/template.ts index d9466fa78..53fd3c97d 100644 --- a/packages/vue-code-gen/src/generators/template.ts +++ b/packages/vue-code-gen/src/generators/template.ts @@ -1758,7 +1758,7 @@ export function generate( prefix: string, suffix: string, ) { - walkInterpolationFragment(ts, prefix + mapCode + suffix, (frag, fragOffset) => { + walkInterpolationFragment(ts, prefix + mapCode + suffix, (frag, fragOffset, lastCtxAccess) => { if (fragOffset === undefined) { tsCodeGen.addText(frag); } @@ -1776,6 +1776,26 @@ export function generate( fragOffset = 0; } if (sourceOffset !== undefined && data !== undefined) { + // fix https://github.com/johnsoncodehk/volar/issues/1205 + if (lastCtxAccess && data.capabilities.diagnostic) { + tsCodeGen.addMapping2({ + data: { + vueTag: data.vueTag, + capabilities: { + diagnostic: true, + }, + }, + mode: SourceMaps.Mode.Totally, + sourceRange: { + start: sourceOffset + fragOffset, + end: sourceOffset + fragOffset + lastCtxAccess.varLength, + }, + mappedRange: { + start: tsCodeGen.getText().length - lastCtxAccess.ctxText.length, + end: tsCodeGen.getText().length + lastCtxAccess.varLength, + }, + }); + } writeCode( frag, { diff --git a/packages/vue-code-gen/src/transform.ts b/packages/vue-code-gen/src/transform.ts index 7d4553137..2fe8b46b4 100644 --- a/packages/vue-code-gen/src/transform.ts +++ b/packages/vue-code-gen/src/transform.ts @@ -4,7 +4,7 @@ import type * as ts from 'typescript/lib/tsserverlibrary'; export function walkInterpolationFragment( ts: typeof import('typescript/lib/tsserverlibrary'), code: string, - cb: (fragment: string, offset: number | undefined) => void, + cb: (fragment: string, offset: number | undefined, beforeCtxAccess?: { ctxText: string, varLength: number; }) => void, localVars: Record, identifiers: Set, ) { @@ -40,6 +40,8 @@ export function walkInterpolationFragment( ctxVars = ctxVars.sort((a, b) => a.offset - b.offset); // localVarOffsets = localVarOffsets.sort((a, b) => a - b); + let lastCtxAccess: { ctxText: string, varLength: number; } | undefined; + if (ctxVars.length) { if (ctxVars[0].isShorthand) { @@ -52,23 +54,32 @@ export function walkInterpolationFragment( for (let i = 0; i < ctxVars.length - 1; i++) { - cb('__VLS_ctx.', undefined); - + writeCtxAccess(ctxVars[i].text.length); if (ctxVars[i + 1].isShorthand) { - cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), ctxVars[i].offset); + cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), ctxVars[i].offset, lastCtxAccess); cb(': ', undefined); } else { - cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset), ctxVars[i].offset); + cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset), ctxVars[i].offset, lastCtxAccess); } + lastCtxAccess = undefined; } - cb('__VLS_ctx.', undefined); - cb(code.substring(ctxVars[ctxVars.length - 1].offset), ctxVars[ctxVars.length - 1].offset); + writeCtxAccess(ctxVars[ctxVars.length - 1].text.length); + cb(code.substring(ctxVars[ctxVars.length - 1].offset), ctxVars[ctxVars.length - 1].offset, lastCtxAccess); + lastCtxAccess = undefined; } else { cb(code, 0); } + + function writeCtxAccess(varLength: number) { + cb('__VLS_ctx.', undefined); + lastCtxAccess = { + ctxText: '__VLS_ctx.', + varLength, + }; + } } function walkIdentifiers( diff --git a/packages/vue-typescript/src/use/useSfcTemplateScript.ts b/packages/vue-typescript/src/use/useSfcTemplateScript.ts index 607f1c0e1..2a4be2bdb 100644 --- a/packages/vue-typescript/src/use/useSfcTemplateScript.ts +++ b/packages/vue-typescript/src/use/useSfcTemplateScript.ts @@ -230,11 +230,32 @@ export function useSfcTemplateScript( walkInterpolationFragment( ts, bindText, - (frag, fragOffset) => { + (frag, fragOffset, lastCtxAccess) => { if (fragOffset === undefined) { codeGen.addText(frag); } else { + // fix https://github.com/johnsoncodehk/volar/issues/1205 + if (lastCtxAccess) { + codeGen.addMapping2({ + data: { + vueTag: 'style', + vueTagIndex: i, + capabilities: { + diagnostic: true, + }, + }, + mode: SourceMaps.Mode.Totally, + sourceRange: { + start: cssBind.start + fragOffset, + end: cssBind.start + fragOffset + lastCtxAccess.varLength, + }, + mappedRange: { + start: codeGen.getText().length - lastCtxAccess.ctxText.length, + end: codeGen.getText().length + lastCtxAccess.varLength, + }, + }); + } codeGen.addCode( frag, {