diff --git a/packages/vue-code-gen/src/generators/template.ts b/packages/vue-code-gen/src/generators/template.ts index 5562f90b2..d3e110cbf 100644 --- a/packages/vue-code-gen/src/generators/template.ts +++ b/packages/vue-code-gen/src/generators/template.ts @@ -1759,7 +1759,7 @@ export function generate( prefix: string, suffix: string, ) { - walkInterpolationFragment(ts, prefix + mapCode + suffix, (frag, fragOffset, lastCtxAccess) => { + walkInterpolationFragment(ts, prefix + mapCode + suffix, (frag, fragOffset, isJustForErrorMapping) => { if (fragOffset === undefined) { tsCodeGen.addText(frag); } @@ -1777,26 +1777,6 @@ 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, { @@ -1804,7 +1784,14 @@ export function generate( end: sourceOffset + fragOffset + frag.length, }, SourceMaps.Mode.Offset, - data, + isJustForErrorMapping + ? { + vueTag: data.vueTag, + capabilities: { + diagnostic: true, + }, + } + : data, ); } else { diff --git a/packages/vue-code-gen/src/transform.ts b/packages/vue-code-gen/src/transform.ts index 2fe8b46b4..83a8a6a92 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, beforeCtxAccess?: { ctxText: string, varLength: number; }) => void, + cb: (fragment: string, offset: number | undefined, isJustForErrorMapping?: boolean) => void, localVars: Record, identifiers: Set, ) { @@ -40,8 +40,6 @@ 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) { @@ -54,32 +52,26 @@ export function walkInterpolationFragment( for (let i = 0; i < ctxVars.length - 1; i++) { - writeCtxAccess(ctxVars[i].text.length); + // fix https://github.com/johnsoncodehk/volar/issues/1205 + // fix https://github.com/johnsoncodehk/volar/issues/1264 + cb('', ctxVars[i + 1].offset, true); + cb('__VLS_ctx.', undefined); if (ctxVars[i + 1].isShorthand) { - cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), ctxVars[i].offset, lastCtxAccess); + cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), ctxVars[i].offset); cb(': ', undefined); } else { - cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset), ctxVars[i].offset, lastCtxAccess); + cb(code.substring(ctxVars[i].offset, ctxVars[i + 1].offset), ctxVars[i].offset); } - lastCtxAccess = undefined; } - writeCtxAccess(ctxVars[ctxVars.length - 1].text.length); - cb(code.substring(ctxVars[ctxVars.length - 1].offset), ctxVars[ctxVars.length - 1].offset, lastCtxAccess); - lastCtxAccess = undefined; + cb('', ctxVars[ctxVars.length - 1].offset, true); + cb('__VLS_ctx.', undefined); + cb(code.substring(ctxVars[ctxVars.length - 1].offset), ctxVars[ctxVars.length - 1].offset); } else { cb(code, 0); } - - function writeCtxAccess(varLength: number) { - cb('__VLS_ctx.', undefined); - lastCtxAccess = { - ctxText: '__VLS_ctx.', - varLength, - }; - } } function walkIdentifiers( diff --git a/packages/vue-language-service/src/languageFeatures/validation.ts b/packages/vue-language-service/src/languageFeatures/validation.ts index 4f95145f8..a99ce9dc5 100644 --- a/packages/vue-language-service/src/languageFeatures/validation.ts +++ b/packages/vue-language-service/src/languageFeatures/validation.ts @@ -160,12 +160,30 @@ export function register(context: LanguageServiceRuntimeContext) { if (sourceMap) { - const sourceRange = sourceMap.getSourceRange( + let sourceRange = sourceMap.getSourceRange( error.range.start, error.range.end, data => !!data.capabilities.diagnostic, )?.[0]; + // fix https://github.com/johnsoncodehk/volar/issues/1205 + // fix https://github.com/johnsoncodehk/volar/issues/1264 + if (!sourceRange) { + const start = sourceMap.getSourceRange( + error.range.start, + error.range.start, + data => !!data.capabilities.diagnostic, + )?.[0].start; + const end = sourceMap.getSourceRange( + error.range.end, + error.range.end, + data => !!data.capabilities.diagnostic, + )?.[0].end; + if (start && end) { + sourceRange = { start, end }; + } + } + if (!sourceRange) continue; diff --git a/packages/vue-typescript/src/use/useSfcTemplateScript.ts b/packages/vue-typescript/src/use/useSfcTemplateScript.ts index d3937ed53..473197164 100644 --- a/packages/vue-typescript/src/use/useSfcTemplateScript.ts +++ b/packages/vue-typescript/src/use/useSfcTemplateScript.ts @@ -230,32 +230,11 @@ export function useSfcTemplateScript( walkInterpolationFragment( ts, bindText, - (frag, fragOffset, lastCtxAccess) => { + (frag, fragOffset, isJustForErrorMapping) => { 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, { @@ -266,7 +245,9 @@ export function useSfcTemplateScript( { vueTag: 'style', vueTagIndex: i, - capabilities: { + capabilities: isJustForErrorMapping ? { + diagnostic: true, + } : { basic: true, references: true, definitions: true,