Skip to content

Commit

Permalink
fix: property access errors loss in template
Browse files Browse the repository at this point in the history
close #1264
  • Loading branch information
johnsoncodehk committed May 10, 2022
1 parent e361bdd commit 221404d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 64 deletions.
31 changes: 9 additions & 22 deletions packages/vue-code-gen/src/generators/template.ts
Expand Up @@ -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);
}
Expand All @@ -1777,34 +1777,21 @@ 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,
{
start: sourceOffset + fragOffset,
end: sourceOffset + fragOffset + frag.length,
},
SourceMaps.Mode.Offset,
data,
isJustForErrorMapping
? {
vueTag: data.vueTag,
capabilities: {
diagnostic: true,
},
}
: data,
);
}
else {
Expand Down
28 changes: 10 additions & 18 deletions packages/vue-code-gen/src/transform.ts
Expand Up @@ -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<string, number>,
identifiers: Set<string>,
) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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(
Expand Down
20 changes: 19 additions & 1 deletion packages/vue-language-service/src/languageFeatures/validation.ts
Expand Up @@ -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;

Expand Down
27 changes: 4 additions & 23 deletions packages/vue-typescript/src/use/useSfcTemplateScript.ts
Expand Up @@ -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,
{
Expand All @@ -266,7 +245,9 @@ export function useSfcTemplateScript(
{
vueTag: 'style',
vueTagIndex: i,
capabilities: {
capabilities: isJustForErrorMapping ? {
diagnostic: true,
} : {
basic: true,
references: true,
definitions: true,
Expand Down

0 comments on commit 221404d

Please sign in to comment.