Skip to content

Commit

Permalink
fix(language-core): escape \ and ' in className avoid type error (#4619)
Browse files Browse the repository at this point in the history
  • Loading branch information
linghaoSu authored Aug 2, 2024
1 parent dc6f943 commit f242e85
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
48 changes: 42 additions & 6 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,9 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
ctx.codeFeatures.navigationWithoutRename,
];
yield `'`;
yield [
className,
'template',
offset,
ctx.codeFeatures.navigationAndAdditionalCompletion,
];

// fix https://github.com/vuejs/language-tools/issues/4537
yield* escapeString(className, offset, ['\\', '\'']);
yield `'`;
yield [
'',
Expand Down Expand Up @@ -136,6 +133,45 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
}
yield endOfLine;
}

function* escapeString(className: string, offset: number, escapeTargets: string[]): Generator<Code> {
let count = 0;

const currentEscapeTargets = [...escapeTargets];
const firstEscapeTarget = currentEscapeTargets.shift()!;
const splitted = className.split(firstEscapeTarget);

for (let i = 0; i < splitted.length; i++) {
const part = splitted[i];
const partLength = part.length;

if (escapeTargets.length > 0) {
yield* escapeString(part, offset + count, [...currentEscapeTargets]);
} else {
yield [
part,
'template',
offset + count,
ctx.codeFeatures.navigationAndAdditionalCompletion,
];
}

if (i !== splitted.length - 1) {
yield '\\';

yield [
firstEscapeTarget,
'template',
offset + count + partLength,
ctx.codeFeatures.navigationAndAdditionalCompletion,
];

count += partLength + 1;
} else {
count += partLength;
}
}
}
}

export function* forEachElementNode(node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode): Generator<CompilerDOM.ElementNode> {
Expand Down
17 changes: 17 additions & 0 deletions test-workspace/tsc/vue3/#4537/main.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script setup lang="ts" generic="T">
defineProps<{
type: T;
}>();
defineModel<boolean>({ required: true });
</script>

<template>
<div class="['radio']"></div>
</template>

<style>
.\[\'radio\'\] {
color: red
}
</style>

0 comments on commit f242e85

Please sign in to comment.