@vue/language-core
Advanced tools
Comparing version 1.7.0 to 1.7.1
@@ -8,8 +8,8 @@ import { Segment } from '@volar/source-map'; | ||
import type { ScriptSetupRanges } from '../parsers/scriptSetupRanges'; | ||
import { collectCssVars, collectStyleCssClasses } from '../plugins/vue-tsx'; | ||
import { Sfc } from '../types'; | ||
import type { VueCompilerOptions } from '../types'; | ||
export declare function generate(ts: typeof import('typescript/lib/tsserverlibrary'), fileName: string, _sfc: Sfc, lang: string, scriptRanges: ScriptRanges | undefined, scriptSetupRanges: ScriptSetupRanges | undefined, cssVars: ReturnType<typeof collectCssVars>, cssModuleClasses: ReturnType<typeof collectStyleCssClasses>, cssScopedClasses: ReturnType<typeof collectStyleCssClasses>, htmlGen: ReturnType<typeof templateGen['generate']> | undefined, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, sharedTypesImport: string): { | ||
export declare function generate(ts: typeof import('typescript/lib/tsserverlibrary'), fileName: string, _sfc: Sfc, lang: string, scriptRanges: ScriptRanges | undefined, scriptSetupRanges: ScriptSetupRanges | undefined, htmlGen: ReturnType<typeof templateGen['generate']> | undefined, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, sharedTypesImport: string, codegenStack: boolean): { | ||
codes: Segment<FileRangeCapabilities>[]; | ||
codeStacks: SourceMaps.StackNode[]; | ||
mirrorBehaviorMappings: SourceMaps.Mapping<[MirrorBehaviorCapabilities, MirrorBehaviorCapabilities]>[]; | ||
}; |
@@ -12,4 +12,4 @@ "use strict"; | ||
const muggle = require("muggle-string"); | ||
function generate(ts, fileName, _sfc, lang, scriptRanges, scriptSetupRanges, cssVars, cssModuleClasses, cssScopedClasses, htmlGen, compilerOptions, vueCompilerOptions, sharedTypesImport) { | ||
const codes = []; | ||
function generate(ts, fileName, _sfc, lang, scriptRanges, scriptSetupRanges, htmlGen, compilerOptions, vueCompilerOptions, sharedTypesImport, codegenStack) { | ||
const [codes, codeStacks] = codegenStack ? muggle.track([]) : [[], []]; | ||
const mirrorBehaviorMappings = []; | ||
@@ -82,2 +82,3 @@ //#region monkey fix: https://github.com/vuejs/language-tools/pull/2113 | ||
codes, | ||
codeStacks, | ||
mirrorBehaviorMappings, | ||
@@ -722,6 +723,9 @@ }; | ||
/* CSS Module */ | ||
for (const cssModule of cssModuleClasses) { | ||
codes.push(`${cssModule.style.module}: Record<string, string> & import('${sharedTypesImport}').Prettify<{}`); | ||
for (const classNameRange of cssModule.classNameRanges) { | ||
generateCssClassProperty(cssModule.index, cssModule.style.content.substring(classNameRange.start + 1, classNameRange.end), classNameRange, 'string', false); | ||
for (let i = 0; i < _sfc.styles.length; i++) { | ||
const style = _sfc.styles[i]; | ||
if (!style.module) | ||
continue; | ||
codes.push(`${style.module}: Record<string, string> & import('${sharedTypesImport}').Prettify<{}`); | ||
for (const className of style.classNames) { | ||
generateCssClassProperty(i, className.text.substring(1), { start: className.offset, end: className.offset + className.text.length }, 'string', false); | ||
} | ||
@@ -740,5 +744,8 @@ codes.push('>;\n'); | ||
codes.push('type __VLS_StyleScopedClasses = {}'); | ||
for (const scopedCss of cssScopedClasses) { | ||
for (const classNameRange of scopedCss.classNameRanges) { | ||
generateCssClassProperty(scopedCss.index, scopedCss.style.content.substring(classNameRange.start + 1, classNameRange.end), classNameRange, 'boolean', true); | ||
for (let i = 0; i < _sfc.styles.length; i++) { | ||
const style = _sfc.styles[i]; | ||
if (!style.scoped) | ||
continue; | ||
for (const className of style.classNames) { | ||
generateCssClassProperty(i, className.text.substring(1), { start: className.offset, end: className.offset + className.text.length }, 'boolean', true); | ||
} | ||
@@ -752,5 +759,10 @@ } | ||
if (htmlGen) { | ||
muggle.setTracking(false); | ||
for (const s of htmlGen.codes) { | ||
codes.push(s); | ||
} | ||
muggle.setTracking(true); | ||
for (const s of htmlGen.codeStacks) { | ||
codeStacks.push(s); | ||
} | ||
} | ||
@@ -807,6 +819,5 @@ if (!htmlGen) { | ||
const identifiers = new Set(); | ||
for (const cssVar of cssVars) { | ||
for (const cssBind of cssVar.ranges) { | ||
const code = cssVar.style.content.substring(cssBind.start, cssBind.end); | ||
(0, transform_1.walkInterpolationFragment)(ts, code, ts.createSourceFile('/a.txt', code, ts.ScriptTarget.ESNext), (frag, fragOffset, onlyForErrorMapping) => { | ||
for (const style of _sfc.styles) { | ||
for (const cssBind of style.cssVars) { | ||
(0, transform_1.walkInterpolationFragment)(ts, cssBind.text, ts.createSourceFile('/a.txt', cssBind.text, ts.ScriptTarget.ESNext), (frag, fragOffset, onlyForErrorMapping) => { | ||
if (fragOffset === undefined) { | ||
@@ -818,4 +829,4 @@ codes.push(frag); | ||
frag, | ||
cssVar.style.name, | ||
cssBind.start + fragOffset, | ||
style.name, | ||
cssBind.offset + fragOffset, | ||
onlyForErrorMapping | ||
@@ -861,2 +872,3 @@ ? { diagnostic: true } | ||
function addVirtualCode(vueTag, start, end) { | ||
muggle.offsetStack(); | ||
codes.push([ | ||
@@ -868,4 +880,6 @@ sfc[vueTag].content.substring(start, end), | ||
]); | ||
muggle.resetOffsetStack(); | ||
} | ||
function addExtraReferenceVirtualCode(vueTag, start, end) { | ||
muggle.offsetStack(); | ||
codes.push([ | ||
@@ -881,2 +895,3 @@ sfc[vueTag].content.substring(start, end), | ||
]); | ||
muggle.resetOffsetStack(); | ||
} | ||
@@ -883,0 +898,0 @@ } |
@@ -5,8 +5,12 @@ import { Segment } from '@volar/source-map'; | ||
import type * as ts from 'typescript/lib/tsserverlibrary'; | ||
import { VueCompilerOptions } from '../types'; | ||
import { Sfc, VueCompilerOptions } from '../types'; | ||
import * as muggle from 'muggle-string'; | ||
type Code = Segment<FileRangeCapabilities>; | ||
export declare function generate(ts: typeof import('typescript/lib/tsserverlibrary'), compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, sourceTemplate: string, sourceLang: string, templateAst: CompilerDOM.RootNode, hasScriptSetupSlots: boolean, sharedTypesImport: string, cssScopedClasses?: string[]): { | ||
export declare function generate(ts: typeof import('typescript/lib/tsserverlibrary'), compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, sourceTemplate: string, sourceLang: string, sfc: Sfc, hasScriptSetupSlots: boolean, sharedTypesImport: string, codegenStack: boolean): { | ||
codes: Code[]; | ||
codeStacks: muggle.StackNode[]; | ||
formatCodes: Code[]; | ||
formatCodeStacks: muggle.StackNode[]; | ||
cssCodes: Code[]; | ||
cssCodeStacks: muggle.StackNode[]; | ||
tagNames: Record<string, number[]>; | ||
@@ -13,0 +17,0 @@ identifiers: Set<string>; |
import type { Language } from '@volar/language-core'; | ||
import { VueCompilerOptions } from './types'; | ||
import type * as ts from 'typescript/lib/tsserverlibrary'; | ||
export declare function createLanguage(compilerOptions?: ts.CompilerOptions, vueCompilerOptions?: VueCompilerOptions, ts?: typeof import('typescript/lib/tsserverlibrary')): Language; | ||
export declare function createLanguages(compilerOptions?: ts.CompilerOptions, vueCompilerOptions?: VueCompilerOptions, ts?: typeof import('typescript/lib/tsserverlibrary')): Language[]; | ||
export declare function createLanguage(compilerOptions?: ts.CompilerOptions, vueCompilerOptions?: VueCompilerOptions, ts?: typeof import('typescript/lib/tsserverlibrary'), codegenStack?: boolean): Language; | ||
export declare function createLanguages(compilerOptions?: ts.CompilerOptions, vueCompilerOptions?: VueCompilerOptions, ts?: typeof import('typescript/lib/tsserverlibrary'), codegenStack?: boolean): Language[]; |
@@ -9,5 +9,5 @@ "use strict"; | ||
const ts_1 = require("./utils/ts"); | ||
function createLanguage(compilerOptions = {}, vueCompilerOptions = (0, ts_1.resolveVueCompilerOptions)({}), ts = require('typescript')) { | ||
function createLanguage(compilerOptions = {}, vueCompilerOptions = (0, ts_1.resolveVueCompilerOptions)({}), ts = require('typescript'), codegenStack = false) { | ||
patchResolveModuleNames(ts, vueCompilerOptions); | ||
const vueLanguagePlugin = (0, plugins_1.getDefaultVueLanguagePlugins)(ts, compilerOptions, vueCompilerOptions); | ||
const vueLanguagePlugin = (0, plugins_1.getDefaultVueLanguagePlugins)(ts, compilerOptions, vueCompilerOptions, codegenStack); | ||
const sharedTypesSnapshot = ts.ScriptSnapshot.fromString(sharedTypes.getTypesCode(vueCompilerOptions)); | ||
@@ -19,3 +19,3 @@ const languageModule = { | ||
&& vueCompilerOptions.extensions.some(ext => fileName.endsWith(ext)))) { | ||
return new sourceFile_1.VueFile(fileName, snapshot, ts, vueLanguagePlugin); | ||
return new sourceFile_1.VueFile(fileName, snapshot, vueCompilerOptions, vueLanguagePlugin, ts, codegenStack); | ||
} | ||
@@ -68,5 +68,5 @@ }, | ||
exports.createLanguage = createLanguage; | ||
function createLanguages(compilerOptions = {}, vueCompilerOptions = (0, ts_1.resolveVueCompilerOptions)({}), ts = require('typescript')) { | ||
function createLanguages(compilerOptions = {}, vueCompilerOptions = (0, ts_1.resolveVueCompilerOptions)({}), ts = require('typescript'), codegenStack = false) { | ||
return [ | ||
createLanguage(compilerOptions, vueCompilerOptions, ts), | ||
createLanguage(compilerOptions, vueCompilerOptions, ts, codegenStack), | ||
...vueCompilerOptions.experimentalAdditionalLanguageModules?.map(module => require(module)) ?? [], | ||
@@ -73,0 +73,0 @@ ]; |
import type * as ts from 'typescript/lib/tsserverlibrary'; | ||
import { VueCompilerOptions } from './types'; | ||
import * as CompilerDOM from '@vue/compiler-dom'; | ||
export declare function getDefaultVueLanguagePlugins(ts: typeof import('typescript/lib/tsserverlibrary'), compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions): { | ||
export declare function getDefaultVueLanguagePlugins(ts: typeof import('typescript/lib/tsserverlibrary'), compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, codegenStack: boolean): { | ||
version: 1; | ||
@@ -6,0 +6,0 @@ name?: string | undefined; |
@@ -15,3 +15,3 @@ "use strict"; | ||
const CompilerVue2 = require("./utils/vue2TemplateCompiler"); | ||
function getDefaultVueLanguagePlugins(ts, compilerOptions, vueCompilerOptions) { | ||
function getDefaultVueLanguagePlugins(ts, compilerOptions, vueCompilerOptions, codegenStack) { | ||
const plugins = [ | ||
@@ -36,2 +36,3 @@ useMdFilePlugin, | ||
vueCompilerOptions, | ||
codegenStack, | ||
}; | ||
@@ -38,0 +39,0 @@ const pluginInstances = plugins |
@@ -1,14 +0,3 @@ | ||
import { Sfc, VueLanguagePlugin } from '../types'; | ||
import { TextRange } from '../types'; | ||
import { VueLanguagePlugin } from '../types'; | ||
declare const plugin: VueLanguagePlugin; | ||
export default plugin; | ||
export declare function collectStyleCssClasses(sfc: Sfc, condition: (style: Sfc['styles'][number]) => boolean): { | ||
style: (typeof sfc.styles)[number]; | ||
index: number; | ||
classNameRanges: TextRange[]; | ||
classNames: string[]; | ||
}[]; | ||
export declare function collectCssVars(sfc: Sfc): { | ||
style: (typeof sfc.styles)[number]; | ||
ranges: TextRange[]; | ||
}[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.collectCssVars = exports.collectStyleCssClasses = void 0; | ||
const reactivity_1 = require("@vue/reactivity"); | ||
@@ -10,6 +9,5 @@ const script_1 = require("../generators/script"); | ||
const language_core_1 = require("@volar/language-core"); | ||
const parseCssClassNames_1 = require("../utils/parseCssClassNames"); | ||
const parseCssVars_1 = require("../utils/parseCssVars"); | ||
const sharedTypes = require("../utils/directorySharedTypes"); | ||
const plugin = ({ modules, vueCompilerOptions, compilerOptions }) => { | ||
const muggle = require("muggle-string"); | ||
const plugin = ({ modules, vueCompilerOptions, compilerOptions, codegenStack }) => { | ||
const ts = modules.typescript; | ||
@@ -45,3 +43,5 @@ const instances = new WeakMap(); | ||
if (tsx) { | ||
embeddedFile.content = [...tsx.codes]; | ||
const [content, contentStacks] = codegenStack ? muggle.track([...tsx.codes], [...tsx.codeStacks]) : [[...tsx.codes], [...tsx.codeStacks]]; | ||
embeddedFile.content = content; | ||
embeddedFile.contentStacks = contentStacks; | ||
embeddedFile.mirrorBehaviorMappings = [...tsx.mirrorBehaviorMappings]; | ||
@@ -61,12 +61,14 @@ } | ||
if (_tsx.htmlGen.value) { | ||
embeddedFile.content = [..._tsx.htmlGen.value.formatCodes]; | ||
const [content, contentStacks] = codegenStack ? muggle.track([..._tsx.htmlGen.value.formatCodes], [..._tsx.htmlGen.value.formatCodeStacks]) : [[..._tsx.htmlGen.value.formatCodes], [..._tsx.htmlGen.value.formatCodeStacks]]; | ||
embeddedFile.content = content; | ||
embeddedFile.contentStacks = contentStacks; | ||
} | ||
for (const cssVar of _tsx.cssVars.value) { | ||
for (const style of sfc.styles) { | ||
embeddedFile.content.push('\n\n'); | ||
for (const range of cssVar.ranges) { | ||
for (const cssVar of style.cssVars) { | ||
embeddedFile.content.push('('); | ||
embeddedFile.content.push([ | ||
cssVar.style.content.substring(range.start, range.end), | ||
cssVar.style.name, | ||
range.start, | ||
cssVar.text, | ||
style.name, | ||
cssVar.offset, | ||
{}, | ||
@@ -81,3 +83,5 @@ ]); | ||
if (_tsx.htmlGen.value) { | ||
embeddedFile.content = [..._tsx.htmlGen.value.cssCodes]; | ||
const [content, contentStacks] = codegenStack ? muggle.track([..._tsx.htmlGen.value.cssCodes], [..._tsx.htmlGen.value.cssCodeStacks]) : [[..._tsx.htmlGen.value.cssCodes], [..._tsx.htmlGen.value.cssCodeStacks]]; | ||
embeddedFile.content = content; | ||
embeddedFile.contentStacks = contentStacks; | ||
} | ||
@@ -102,3 +106,2 @@ // for color pickers support | ||
}); | ||
const cssVars = (0, reactivity_1.computed)(() => collectCssVars(_sfc)); | ||
const scriptRanges = (0, reactivity_1.computed)(() => _sfc.scriptAst | ||
@@ -110,11 +113,6 @@ ? (0, scriptRanges_1.parseScriptRanges)(ts, _sfc.scriptAst, !!_sfc.scriptSetup, false) | ||
: undefined); | ||
const cssModuleClasses = (0, reactivity_1.computed)(() => collectStyleCssClasses(_sfc, style => !!style.module)); | ||
const cssScopedClasses = (0, reactivity_1.computed)(() => collectStyleCssClasses(_sfc, style => { | ||
const setting = vueCompilerOptions.experimentalResolveStyleCssClasses; | ||
return (setting === 'scoped' && style.scoped) || setting === 'always'; | ||
})); | ||
const htmlGen = (0, reactivity_1.computed)(() => { | ||
if (!_sfc.templateAst) | ||
return; | ||
return templateGen.generate(ts, compilerOptions, vueCompilerOptions, _sfc.template?.content ?? '', _sfc.template?.lang ?? 'html', _sfc.templateAst, hasScriptSetupSlots.value, sharedTypesImport, Object.values(cssScopedClasses.value).map(style => style.classNames).flat()); | ||
return templateGen.generate(ts, compilerOptions, vueCompilerOptions, _sfc.template?.content ?? '', _sfc.template?.lang ?? 'html', _sfc, hasScriptSetupSlots.value, sharedTypesImport, codegenStack); | ||
}); | ||
@@ -124,3 +122,3 @@ const hasScriptSetupSlots = (0, reactivity_1.shallowRef)(false); // remove when https://github.com/vuejs/core/pull/5912 merged | ||
hasScriptSetupSlots.value = !!scriptSetupRanges.value?.slotsTypeArg; | ||
return (0, script_1.generate)(ts, fileName, _sfc, lang.value, scriptRanges.value, scriptSetupRanges.value, cssVars.value, cssModuleClasses.value, cssScopedClasses.value, htmlGen.value, compilerOptions, vueCompilerOptions, sharedTypesImport); | ||
return (0, script_1.generate)(ts, fileName, _sfc, lang.value, scriptRanges.value, scriptSetupRanges.value, htmlGen.value, compilerOptions, vueCompilerOptions, sharedTypesImport, codegenStack); | ||
}); | ||
@@ -131,3 +129,2 @@ return { | ||
htmlGen, | ||
cssVars, | ||
}; | ||
@@ -137,31 +134,2 @@ } | ||
exports.default = plugin; | ||
function collectStyleCssClasses(sfc, condition) { | ||
const result = []; | ||
for (let i = 0; i < sfc.styles.length; i++) { | ||
const style = sfc.styles[i]; | ||
if (condition(style)) { | ||
const classNameRanges = [...(0, parseCssClassNames_1.parseCssClassNames)(style.content)]; | ||
result.push({ | ||
style: style, | ||
index: i, | ||
classNameRanges: classNameRanges, | ||
classNames: classNameRanges.map(range => style.content.substring(range.start + 1, range.end)), | ||
}); | ||
} | ||
} | ||
return result; | ||
} | ||
exports.collectStyleCssClasses = collectStyleCssClasses; | ||
function collectCssVars(sfc) { | ||
const result = []; | ||
for (let i = 0; i < sfc.styles.length; i++) { | ||
const style = sfc.styles[i]; | ||
result.push({ | ||
style, | ||
ranges: [...(0, parseCssVars_1.parseCssVars)(style.content)], | ||
}); | ||
} | ||
return result; | ||
} | ||
exports.collectCssVars = collectCssVars; | ||
//# sourceMappingURL=vue-tsx.js.map |
import { FileCapabilities, VirtualFile, FileKind, FileRangeCapabilities, MirrorBehaviorCapabilities } from '@volar/language-core'; | ||
import { Mapping, Segment } from '@volar/source-map'; | ||
import { Mapping, Segment, StackNode, Stack } from '@volar/source-map'; | ||
import * as CompilerDom from '@vue/compiler-dom'; | ||
import { SFCBlock, SFCParseResult, SFCScriptBlock, SFCStyleBlock, SFCTemplateBlock } from '@vue/compiler-sfc'; | ||
import type { SFCBlock, SFCParseResult, SFCScriptBlock, SFCStyleBlock, SFCTemplateBlock } from '@vue/compiler-sfc'; | ||
import { ComputedRef } from '@vue/reactivity'; | ||
import type * as ts from 'typescript/lib/tsserverlibrary'; | ||
import { Sfc, SfcBlock, VueLanguagePlugin } from './types'; | ||
import { VueCompilerOptions } from './types'; | ||
export declare class VueEmbeddedFile { | ||
fileName: string; | ||
content: Segment<FileRangeCapabilities>[]; | ||
contentStacks: StackNode[]; | ||
parentFileName?: string; | ||
kind: FileKind; | ||
capabilities: FileCapabilities; | ||
content: Segment<FileRangeCapabilities>[]; | ||
mirrorBehaviorMappings: Mapping<[MirrorBehaviorCapabilities, MirrorBehaviorCapabilities]>[]; | ||
constructor(fileName: string); | ||
constructor(fileName: string, content: Segment<FileRangeCapabilities>[], contentStacks: StackNode[]); | ||
} | ||
@@ -20,4 +22,6 @@ export declare class VueFile implements VirtualFile { | ||
snapshot: ts.IScriptSnapshot; | ||
private ts; | ||
private plugins; | ||
vueCompilerOptions: VueCompilerOptions; | ||
plugins: ReturnType<VueLanguagePlugin>[]; | ||
ts: typeof import('typescript/lib/tsserverlibrary'); | ||
codegenStack: boolean; | ||
parsedSfcCache: { | ||
@@ -37,2 +41,3 @@ snapshot: ts.IScriptSnapshot; | ||
mappings: Mapping<FileRangeCapabilities>[]; | ||
codegenStacks: Stack[]; | ||
get compiledSFCTemplate(): { | ||
@@ -45,3 +50,2 @@ errors: CompilerDom.CompilerError[]; | ||
get embeddedFiles(): VirtualFile[]; | ||
parsedSfc: SFCParseResult | undefined; | ||
sfc: Sfc; | ||
@@ -58,2 +62,3 @@ _sfcBlocks: ComputedRef<Record<string, SfcBlock>>; | ||
mappings: Mapping<FileRangeCapabilities>[]; | ||
codegenStacks: Stack[]; | ||
}[]>[]; | ||
@@ -64,13 +69,14 @@ _allEmbeddedFiles: ComputedRef<{ | ||
mappings: Mapping<FileRangeCapabilities>[]; | ||
codegenStacks: Stack[]; | ||
}[]>; | ||
_embeddedFiles: ComputedRef<VirtualFile[]>; | ||
constructor(fileName: string, snapshot: ts.IScriptSnapshot, ts: typeof import('typescript/lib/tsserverlibrary'), plugins: ReturnType<VueLanguagePlugin>[]); | ||
constructor(fileName: string, snapshot: ts.IScriptSnapshot, vueCompilerOptions: VueCompilerOptions, plugins: ReturnType<VueLanguagePlugin>[], ts: typeof import('typescript/lib/tsserverlibrary'), codegenStack: boolean); | ||
update(newScriptSnapshot: ts.IScriptSnapshot): void; | ||
parseSfc(): SFCParseResult | undefined; | ||
updateTemplate(block: SFCTemplateBlock | null): void; | ||
updateScript(block: SFCScriptBlock | null): void; | ||
updateScriptSetup(block: SFCScriptBlock | null): void; | ||
updateStyles(blocks: SFCStyleBlock[]): void; | ||
updateCustomBlocks(blocks: SFCBlock[]): void; | ||
updateBlock<T extends object>(oldBlock: T, newBlock: T): void; | ||
parseTemplateBlock(block: SFCTemplateBlock): NonNullable<Sfc['template']>; | ||
parseScriptBlock(block: SFCScriptBlock): NonNullable<Sfc['script']>; | ||
parseScriptSetupBlock(block: SFCScriptBlock): NonNullable<Sfc['scriptSetup']>; | ||
parseStyleBlock(block: SFCStyleBlock, i: number): Sfc['styles'][number]; | ||
parseCustomBlock(block: SFCBlock, i: number): Sfc['customBlocks'][number]; | ||
parseBlock(block: SFCBlock): Omit<SfcBlock, 'name' | 'lang'>; | ||
} |
@@ -8,8 +8,11 @@ "use strict"; | ||
const muggle = require("muggle-string"); | ||
const parseCssVars_1 = require("./utils/parseCssVars"); | ||
const parseCssClassNames_1 = require("./utils/parseCssClassNames"); | ||
class VueEmbeddedFile { | ||
constructor(fileName) { | ||
constructor(fileName, content, contentStacks) { | ||
this.fileName = fileName; | ||
this.content = content; | ||
this.contentStacks = contentStacks; | ||
this.kind = language_core_1.FileKind.TextFile; | ||
this.capabilities = {}; | ||
this.content = []; | ||
this.mirrorBehaviorMappings = []; | ||
@@ -29,11 +32,13 @@ } | ||
} | ||
// functions | ||
constructor(fileName, snapshot, ts, plugins) { | ||
constructor(fileName, snapshot, vueCompilerOptions, plugins, ts, codegenStack) { | ||
this.fileName = fileName; | ||
this.snapshot = snapshot; | ||
this.vueCompilerOptions = vueCompilerOptions; | ||
this.plugins = plugins; | ||
this.ts = ts; | ||
this.plugins = plugins; | ||
this.codegenStack = codegenStack; | ||
this.capabilities = language_core_1.FileCapabilities.full; | ||
this.kind = language_core_1.FileKind.TextFile; | ||
this.mappings = []; | ||
this.codegenStacks = []; | ||
// refs | ||
@@ -59,8 +64,2 @@ this.sfc = (0, reactivity_1.reactive)({ | ||
}), | ||
...{ | ||
// backward compatible | ||
getTemplateAst: () => { | ||
return this.compiledSFCTemplate?.ast; | ||
}, | ||
}, | ||
}) /* avoid Sfc unwrap in .d.ts by reactive */; | ||
@@ -177,3 +176,4 @@ // computed | ||
embeddedFiles[embeddedFileName] = (0, reactivity_1.computed)(() => { | ||
const file = new VueEmbeddedFile(embeddedFileName); | ||
const [content, stacks] = this.codegenStack ? muggle.track([]) : [[], []]; | ||
const file = new VueEmbeddedFile(embeddedFileName, content, stacks); | ||
for (const plugin of this.plugins) { | ||
@@ -189,3 +189,41 @@ if (plugin.resolveEmbeddedFile) { | ||
} | ||
return file; | ||
const newText = (0, source_map_1.toString)(file.content); | ||
const changeRanges = new Map(); | ||
const snapshot = { | ||
getText: (start, end) => newText.slice(start, end), | ||
getLength: () => newText.length, | ||
getChangeRange(oldSnapshot) { | ||
if (!changeRanges.has(oldSnapshot)) { | ||
changeRanges.set(oldSnapshot, undefined); | ||
const oldText = oldSnapshot.getText(0, oldSnapshot.getLength()); | ||
for (let start = 0; start < oldText.length && start < newText.length; start++) { | ||
if (oldText[start] !== newText[start]) { | ||
let end = oldText.length; | ||
for (let i = 0; i < oldText.length - start && i < newText.length - start; i++) { | ||
if (oldText[oldText.length - i - 1] !== newText[newText.length - i - 1]) { | ||
break; | ||
} | ||
end--; | ||
} | ||
let length = end - start; | ||
let newLength = length + (newText.length - oldText.length); | ||
if (newLength < 0) { | ||
length -= newLength; | ||
newLength = 0; | ||
} | ||
changeRanges.set(oldSnapshot, { | ||
span: { start, length }, | ||
newLength, | ||
}); | ||
break; | ||
} | ||
} | ||
} | ||
return changeRanges.get(oldSnapshot); | ||
}, | ||
}; | ||
return { | ||
file, | ||
snapshot, | ||
}; | ||
}); | ||
@@ -203,3 +241,4 @@ } | ||
return files.value.map(_file => { | ||
const file = _file.value; | ||
const file = _file.value.file; | ||
const snapshot = _file.value.snapshot; | ||
const mappings = (0, source_map_1.buildMappings)(file.content); | ||
@@ -214,41 +253,9 @@ for (const mapping of mappings) { | ||
]; | ||
mapping.source = undefined; | ||
} | ||
else { | ||
// ignore | ||
} | ||
mapping.source = undefined; | ||
} | ||
} | ||
const newText = (0, source_map_1.toString)(file.content); | ||
const changeRanges = new Map(); | ||
const snapshot = { | ||
getText: (start, end) => newText.slice(start, end), | ||
getLength: () => newText.length, | ||
getChangeRange(oldSnapshot) { | ||
if (!changeRanges.has(oldSnapshot)) { | ||
changeRanges.set(oldSnapshot, undefined); | ||
const oldText = oldSnapshot.getText(0, oldSnapshot.getLength()); | ||
for (let start = 0; start < oldText.length && start < newText.length; start++) { | ||
if (oldText[start] !== newText[start]) { | ||
let end = oldText.length; | ||
for (let i = 0; i < oldText.length - start && i < newText.length - start; i++) { | ||
if (oldText[oldText.length - i - 1] !== newText[newText.length - i - 1]) { | ||
break; | ||
} | ||
end--; | ||
} | ||
let length = end - start; | ||
let newLength = length + (newText.length - oldText.length); | ||
if (newLength < 0) { | ||
length -= newLength; | ||
newLength = 0; | ||
} | ||
changeRanges.set(oldSnapshot, { | ||
span: { start, length }, | ||
newLength, | ||
}); | ||
break; | ||
} | ||
} | ||
} | ||
return changeRanges.get(oldSnapshot); | ||
}, | ||
}; | ||
return { | ||
@@ -258,2 +265,3 @@ file, | ||
mappings, | ||
codegenStacks: (0, source_map_1.buildStacks)(file.content, file.contentStacks), | ||
}; | ||
@@ -282,3 +290,3 @@ }); | ||
} | ||
for (const { file, snapshot, mappings } of remain) { | ||
for (const { file, snapshot, mappings, codegenStacks } of remain) { | ||
embeddedFiles.push({ | ||
@@ -288,2 +296,3 @@ ...file, | ||
mappings, | ||
codegenStacks, | ||
embeddedFiles: [], | ||
@@ -296,3 +305,3 @@ }); | ||
for (let i = remain.length - 1; i >= 0; i--) { | ||
const { file, snapshot, mappings } = remain[i]; | ||
const { file, snapshot, mappings, codegenStacks } = remain[i]; | ||
if (!file.parentFileName) { | ||
@@ -303,2 +312,3 @@ embeddedFiles.push({ | ||
mappings, | ||
codegenStacks, | ||
embeddedFiles: [], | ||
@@ -315,2 +325,3 @@ }); | ||
mappings, | ||
codegenStacks, | ||
embeddedFiles: [], | ||
@@ -339,17 +350,13 @@ }); | ||
this.snapshot = newScriptSnapshot; | ||
this.parsedSfc = this.parseSfc(); | ||
if (this.parsedSfc) { | ||
this.updateTemplate(this.parsedSfc.descriptor.template); | ||
this.updateScript(this.parsedSfc.descriptor.script); | ||
this.updateScriptSetup(this.parsedSfc.descriptor.scriptSetup); | ||
this.updateStyles(this.parsedSfc.descriptor.styles); | ||
this.updateCustomBlocks(this.parsedSfc.descriptor.customBlocks); | ||
} | ||
else { | ||
this.updateTemplate(null); | ||
this.updateScript(null); | ||
this.updateScriptSetup(null); | ||
this.updateStyles([]); | ||
this.updateCustomBlocks([]); | ||
} | ||
const parsedSfc = this.parseSfc(); | ||
updateObj(this.sfc, { | ||
template: parsedSfc?.descriptor.template ? this.parseTemplateBlock(parsedSfc.descriptor.template) : null, | ||
script: parsedSfc?.descriptor.script ? this.parseScriptBlock(parsedSfc.descriptor.script) : null, | ||
scriptSetup: parsedSfc?.descriptor.scriptSetup ? this.parseScriptSetupBlock(parsedSfc.descriptor.scriptSetup) : null, | ||
styles: parsedSfc?.descriptor.styles.map(this.parseStyleBlock.bind(this)) ?? [], | ||
customBlocks: parsedSfc?.descriptor.customBlocks.map(this.parseCustomBlock.bind(this)) ?? [], | ||
templateAst: '__IGNORE__', | ||
scriptAst: '__IGNORE__', | ||
scriptSetupAst: '__IGNORE__', | ||
}); | ||
const str = [[this.snapshot.getText(0, this.snapshot.getLength()), undefined, 0, language_core_1.FileRangeCapabilities.full]]; | ||
@@ -416,43 +423,50 @@ for (const block of [ | ||
} | ||
updateTemplate(block) { | ||
const newData = block ? { | ||
parseTemplateBlock(block) { | ||
return { | ||
...this.parseBlock(block), | ||
name: 'template', | ||
start: this.snapshot.getText(0, block.loc.start.offset).lastIndexOf('<' + block.type), | ||
end: block.loc.end.offset + this.snapshot.getText(block.loc.end.offset, this.snapshot.getLength()).indexOf('>') + 1, | ||
startTagEnd: block.loc.start.offset, | ||
endTagStart: block.loc.end.offset, | ||
content: block.content, | ||
lang: block.lang ?? 'html', | ||
attrs: block.attrs, | ||
} : null; | ||
if (this.sfc.template && newData) { | ||
this.updateBlock(this.sfc.template, newData); | ||
} | ||
else { | ||
this.sfc.template = newData; | ||
} | ||
}; | ||
} | ||
updateScript(block) { | ||
const newData = block ? { | ||
parseScriptBlock(block) { | ||
return { | ||
...this.parseBlock(block), | ||
name: 'script', | ||
start: this.snapshot.getText(0, block.loc.start.offset).lastIndexOf('<' + block.type), | ||
end: block.loc.end.offset + this.snapshot.getText(block.loc.end.offset, this.snapshot.getLength()).indexOf('>') + 1, | ||
startTagEnd: block.loc.start.offset, | ||
endTagStart: block.loc.end.offset, | ||
content: block.content, | ||
lang: block.lang ?? 'js', | ||
src: block.src, | ||
srcOffset: block.src ? this.snapshot.getText(0, block.loc.start.offset).lastIndexOf(block.src) - block.loc.start.offset : -1, | ||
attrs: block.attrs, | ||
} : null; | ||
if (this.sfc.script && newData) { | ||
this.updateBlock(this.sfc.script, newData); | ||
} | ||
else { | ||
this.sfc.script = newData; | ||
} | ||
}; | ||
} | ||
updateScriptSetup(block) { | ||
const newData = block ? { | ||
parseScriptSetupBlock(block) { | ||
return { | ||
...this.parseBlock(block), | ||
name: 'scriptSetup', | ||
lang: block.lang ?? 'js', | ||
generic: typeof block.attrs.generic === 'string' ? block.attrs.generic : undefined, | ||
genericOffset: typeof block.attrs.generic === 'string' ? this.snapshot.getText(0, block.loc.start.offset).lastIndexOf(block.attrs.generic) - block.loc.start.offset : -1, | ||
}; | ||
} | ||
parseStyleBlock(block, i) { | ||
const setting = this.vueCompilerOptions.experimentalResolveStyleCssClasses; | ||
const shouldParseClassNames = block.module || (setting === 'scoped' && block.scoped) || setting === 'always'; | ||
return { | ||
...this.parseBlock(block), | ||
name: 'style_' + i, | ||
lang: block.lang ?? 'css', | ||
module: typeof block.module === 'string' ? block.module : block.module ? '$style' : undefined, | ||
scoped: !!block.scoped, | ||
cssVars: [...(0, parseCssVars_1.parseCssVars)(block.content)], | ||
classNames: shouldParseClassNames ? [...(0, parseCssClassNames_1.parseCssClassNames)(block.content)] : [], | ||
}; | ||
} | ||
parseCustomBlock(block, i) { | ||
return { | ||
...this.parseBlock(block), | ||
name: 'customBlock_' + i, | ||
lang: block.lang ?? 'txt', | ||
type: block.type, | ||
}; | ||
} | ||
parseBlock(block) { | ||
return { | ||
start: this.snapshot.getText(0, block.loc.start.offset).lastIndexOf('<' + block.type), | ||
@@ -463,77 +477,36 @@ end: block.loc.end.offset + this.snapshot.getText(block.loc.end.offset, this.snapshot.getLength()).indexOf('>') + 1, | ||
content: block.content, | ||
lang: block.lang ?? 'js', | ||
generic: typeof block.attrs.generic === 'string' ? block.attrs.generic : undefined, | ||
genericOffset: typeof block.attrs.generic === 'string' ? this.snapshot.getText(0, block.loc.start.offset).lastIndexOf(block.attrs.generic) - block.loc.start.offset : -1, | ||
attrs: block.attrs, | ||
} : null; | ||
if (this.sfc.scriptSetup && newData) { | ||
this.updateBlock(this.sfc.scriptSetup, newData); | ||
} | ||
else { | ||
this.sfc.scriptSetup = newData; | ||
} | ||
}; | ||
} | ||
updateStyles(blocks) { | ||
for (let i = 0; i < blocks.length; i++) { | ||
const block = blocks[i]; | ||
const newData = { | ||
name: 'style_' + i, | ||
start: this.snapshot.getText(0, block.loc.start.offset).lastIndexOf('<' + block.type), | ||
end: block.loc.end.offset + this.snapshot.getText(block.loc.end.offset, this.snapshot.getLength()).indexOf('>') + 1, | ||
startTagEnd: block.loc.start.offset, | ||
endTagStart: block.loc.end.offset, | ||
content: block.content, | ||
lang: block.lang ?? 'css', | ||
module: typeof block.module === 'string' ? block.module : block.module ? '$style' : undefined, | ||
scoped: !!block.scoped, | ||
attrs: block.attrs, | ||
}; | ||
if (this.sfc.styles.length > i) { | ||
this.updateBlock(this.sfc.styles[i], newData); | ||
} | ||
exports.VueFile = VueFile; | ||
function updateObj(oldObj, newObj) { | ||
if (Array.isArray(oldObj) && Array.isArray(newObj)) { | ||
for (let i = 0; i < newObj.length; i++) { | ||
if (oldObj.length > i) { | ||
updateObj(oldObj[i], newObj[i]); | ||
} | ||
else { | ||
this.sfc.styles.push(newData); | ||
oldObj.push(newObj[i]); | ||
} | ||
} | ||
while (this.sfc.styles.length > blocks.length) { | ||
this.sfc.styles.pop(); | ||
if (oldObj.length > newObj.length) { | ||
oldObj.splice(newObj.length, oldObj.length - newObj.length); | ||
} | ||
} | ||
updateCustomBlocks(blocks) { | ||
for (let i = 0; i < blocks.length; i++) { | ||
const block = blocks[i]; | ||
const newData = { | ||
name: 'customBlock_' + i, | ||
start: this.snapshot.getText(0, block.loc.start.offset).lastIndexOf('<' + block.type), | ||
end: block.loc.end.offset + this.snapshot.getText(block.loc.end.offset, this.snapshot.getLength()).indexOf('>') + 1, | ||
startTagEnd: block.loc.start.offset, | ||
endTagStart: block.loc.end.offset, | ||
content: block.content, | ||
lang: block.lang ?? 'txt', | ||
type: block.type, | ||
attrs: block.attrs, | ||
}; | ||
if (this.sfc.customBlocks.length > i) { | ||
this.updateBlock(this.sfc.customBlocks[i], newData); | ||
else { | ||
for (const key in newObj) { | ||
if (newObj[key] === '__IGNORE__') { | ||
continue; | ||
} | ||
else { | ||
this.sfc.customBlocks.push(newData); | ||
else if (oldObj[key] !== null && newObj[key] !== null && typeof oldObj[key] === 'object' && typeof newObj[key] === 'object') { | ||
updateObj(oldObj[key], newObj[key]); | ||
} | ||
} | ||
while (this.sfc.customBlocks.length > blocks.length) { | ||
this.sfc.customBlocks.pop(); | ||
} | ||
} | ||
updateBlock(oldBlock, newBlock) { | ||
for (const key in newBlock) { | ||
if (typeof oldBlock[key] === 'object' && typeof newBlock[key] === 'object') { | ||
this.updateBlock(oldBlock[key], newBlock[key]); | ||
} | ||
else { | ||
oldBlock[key] = newBlock[key]; | ||
oldObj[key] = newObj[key]; | ||
} | ||
} | ||
for (const key in oldBlock) { | ||
if (!(key in newBlock)) { | ||
delete oldBlock[key]; | ||
for (const key in oldObj) { | ||
if (!(key in newObj)) { | ||
delete oldObj[key]; | ||
} | ||
@@ -543,3 +516,2 @@ } | ||
} | ||
exports.VueFile = VueFile; | ||
//# sourceMappingURL=sourceFile.js.map |
@@ -1,3 +0,2 @@ | ||
import * as embedded from '@volar/language-core'; | ||
import { SFCParseResult } from '@vue/compiler-sfc'; | ||
import type { SFCParseResult } from '@vue/compiler-sfc'; | ||
import * as CompilerDom from '@vue/compiler-dom'; | ||
@@ -7,5 +6,2 @@ import type * as ts from 'typescript/lib/tsserverlibrary'; | ||
export type { SFCParseResult } from '@vue/compiler-sfc'; | ||
export interface VueLanguageServiceHost extends embedded.LanguageServiceHost { | ||
getVueCompilationSettings(): VueCompilerOptions | undefined; | ||
} | ||
export type RawVueCompilerOptions = Partial<Omit<VueCompilerOptions, 'target' | 'plugins'>> & { | ||
@@ -47,2 +43,3 @@ target?: 'auto' | 2 | 2.7 | 3 | 3.3; | ||
vueCompilerOptions: VueCompilerOptions; | ||
codegenStack: boolean; | ||
}) => { | ||
@@ -91,2 +88,10 @@ version: 1; | ||
scoped: boolean; | ||
cssVars: { | ||
text: string; | ||
offset: number; | ||
}[]; | ||
classNames: { | ||
text: string; | ||
offset: number; | ||
}[]; | ||
})[]; | ||
@@ -93,0 +98,0 @@ customBlocks: (SfcBlock & { |
export declare function parseCssClassNames(styleContent: string): Generator<{ | ||
start: number; | ||
end: number; | ||
offset: number; | ||
text: string; | ||
}, void, unknown>; |
@@ -13,3 +13,3 @@ "use strict"; | ||
if (matchText !== undefined) { | ||
yield { start: match.index, end: match.index + matchText.length }; | ||
yield { offset: match.index, text: matchText }; | ||
} | ||
@@ -16,0 +16,0 @@ } |
export declare function parseCssVars(styleContent: string): Generator<{ | ||
start: number; | ||
end: number; | ||
offset: number; | ||
text: string; | ||
}, void, unknown>; | ||
export declare function clearComments(css: string): string; |
@@ -14,3 +14,3 @@ "use strict"; | ||
const offset = match.index + styleContent.slice(match.index).indexOf(matchText); | ||
yield { start: offset, end: offset + matchText.length }; | ||
yield { offset, text: matchText }; | ||
} | ||
@@ -17,0 +17,0 @@ } |
{ | ||
"name": "@vue/language-core", | ||
"version": "1.7.0", | ||
"version": "1.7.1", | ||
"main": "out/index.js", | ||
@@ -16,15 +16,24 @@ "license": "MIT", | ||
"dependencies": { | ||
"@volar/language-core": "1.5.4", | ||
"@volar/source-map": "1.5.4", | ||
"@volar/language-core": "1.6.1", | ||
"@volar/source-map": "1.6.1", | ||
"@vue/compiler-dom": "^3.3.0-beta.3", | ||
"@vue/compiler-sfc": "^3.3.0-beta.3", | ||
"@vue/reactivity": "^3.3.0-beta.3", | ||
"@vue/shared": "^3.3.0-beta.3", | ||
"minimatch": "^9.0.0", | ||
"muggle-string": "^0.2.2", | ||
"muggle-string": "^0.3.1", | ||
"vue-template-compiler": "^2.7.14" | ||
}, | ||
"devDependencies": { | ||
"@types/minimatch": "^5.1.2" | ||
} | ||
"@types/minimatch": "^5.1.2", | ||
"@vue/compiler-sfc": "^3.3.0-beta.3" | ||
}, | ||
"peerDependencies": { | ||
"typescript": "*" | ||
}, | ||
"peerDependenciesMeta": { | ||
"typescript": { | ||
"optional": true | ||
} | ||
}, | ||
"gitHead": "8555895e2018cb871cceb19f0ff073fcf322d8e5" | ||
} |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2
5104
+ Added@volar/language-core@1.6.1(transitive)
+ Added@volar/source-map@1.6.1(transitive)
+ Addedmuggle-string@0.3.1(transitive)
+ Addedtypescript@5.6.2(transitive)
- Removed@vue/compiler-sfc@^3.3.0-beta.3
- Removed@jridgewell/sourcemap-codec@1.5.0(transitive)
- Removed@volar/language-core@1.5.4(transitive)
- Removed@volar/source-map@1.5.4(transitive)
- Removed@vue/compiler-sfc@3.5.6(transitive)
- Removed@vue/compiler-ssr@3.5.6(transitive)
- Removedmagic-string@0.30.11(transitive)
- Removedmuggle-string@0.2.2(transitive)
- Removednanoid@3.3.7(transitive)
- Removedpicocolors@1.1.0(transitive)
- Removedpostcss@8.4.47(transitive)
Updated@volar/language-core@1.6.1
Updated@volar/source-map@1.6.1
Updatedmuggle-string@^0.3.1