Skip to content

Commit

Permalink
feat: add option experimentalDisableTemplateSupport
Browse files Browse the repository at this point in the history
close #577
  • Loading branch information
johnsoncodehk committed Mar 14, 2022
1 parent 887446a commit 825f4f8
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 40 deletions.
Expand Up @@ -23,6 +23,10 @@
"experimentalTemplateCompilerOptionsRequirePath": {
"type": "string",
"markdownDescription": "https://github.com/johnsoncodehk/volar/issues/698"
},
"experimentalDisableTemplateSupport": {
"type": "boolean",
"markdownDescription": "https://github.com/johnsoncodehk/volar/issues/577"
}
}
}
Expand Down
27 changes: 18 additions & 9 deletions packages/typescript-vue-plugin/src/apis.ts
Expand Up @@ -55,10 +55,13 @@ export function register({ vueDocuments, scriptTsLsRaw, templateTsLsRaw }: TypeS
const tsLs = lsType === 'script' ? scriptTsLsRaw : templateTsLsRaw;
const loopChecker = new Set<string>();
let symbols: (ts.DefinitionInfo | ts.ReferenceEntry | ts.ImplementationLocation | ts.RenameLocation)[] = [];
withTeleports(fileName, position);

if (tsLs)
withTeleports(fileName, position, tsLs);

return symbols.map(s => transformDocumentSpanLike(lsType, s)).filter(shared.notEmpty);

function withTeleports(fileName: string, position: number) {
function withTeleports(fileName: string, position: number, tsLs: ts.LanguageService) {
if (loopChecker.has(fileName + ':' + position))
return;
loopChecker.add(fileName + ':' + position);
Expand Down Expand Up @@ -92,7 +95,7 @@ export function register({ vueDocuments, scriptTsLsRaw, templateTsLsRaw }: TypeS
)) {
if (loopChecker.has(ref.fileName + ':' + teleRange.start))
continue;
withTeleports(ref.fileName, teleRange.start);
withTeleports(ref.fileName, teleRange.start, tsLs);
}
}
}
Expand All @@ -108,14 +111,17 @@ export function register({ vueDocuments, scriptTsLsRaw, templateTsLsRaw }: TypeS
const loopChecker = new Set<string>();
let textSpan: ts.TextSpan | undefined;
let symbols: ts.DefinitionInfo[] = [];
withTeleports(fileName, position);

if (tsLs)
withTeleports(fileName, position, tsLs);

if (!textSpan) return;
return {
textSpan: textSpan,
definitions: symbols?.map(s => transformDocumentSpanLike(lsType, s)).filter(shared.notEmpty),
};

function withTeleports(fileName: string, position: number) {
function withTeleports(fileName: string, position: number, tsLs: ts.LanguageService) {
if (loopChecker.has(fileName + ':' + position))
return;
loopChecker.add(fileName + ':' + position);
Expand All @@ -141,7 +147,7 @@ export function register({ vueDocuments, scriptTsLsRaw, templateTsLsRaw }: TypeS
)) {
if (loopChecker.has(ref.fileName + ':' + teleRange.start))
continue;
withTeleports(ref.fileName, teleRange.start);
withTeleports(ref.fileName, teleRange.start, tsLs);
}
}
}
Expand All @@ -161,10 +167,13 @@ export function register({ vueDocuments, scriptTsLsRaw, templateTsLsRaw }: TypeS
const tsLs = lsType === 'script' ? scriptTsLsRaw : templateTsLsRaw;
const loopChecker = new Set<string>();
let symbols: ts.ReferencedSymbol[] = [];
withTeleports(fileName, position);

if (tsLs)
withTeleports(fileName, position, tsLs);

return symbols.map(s => transformReferencedSymbol(lsType, s)).filter(shared.notEmpty);

function withTeleports(fileName: string, position: number) {
function withTeleports(fileName: string, position: number, tsLs: ts.LanguageService) {
if (loopChecker.has(fileName + ':' + position))
return;
loopChecker.add(fileName + ':' + position);
Expand All @@ -187,7 +196,7 @@ export function register({ vueDocuments, scriptTsLsRaw, templateTsLsRaw }: TypeS
)) {
if (loopChecker.has(ref.fileName + ':' + teleRange.start))
continue;
withTeleports(ref.fileName, teleRange.start);
withTeleports(ref.fileName, teleRange.start, tsLs);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/vue-language-service/src/ideFeatures/d3.ts
Expand Up @@ -35,7 +35,7 @@ export function register({ typescript: ts, vueDocuments, templateTsLs }: Languag
}[] = [];

const sourceFile = vueDocuments.get(document.uri);
const tsDoc = templateTsLs.__internal__.getTextDocument(document.uri);
const tsDoc = templateTsLs?.__internal__.getTextDocument(document.uri);

if (sourceFile) {

Expand Down
Expand Up @@ -157,7 +157,7 @@ export function register(context: LanguageServiceRuntimeContext, updateTemplateS

const pluginCache = cacheMap.get(plugin.id) ?? cacheMap.set(plugin.id, new Map()).get(plugin.id)!;
const cache = pluginCache.get(document.uri);
const tsProjectVersion = _lsType === 'nonTs' ? undefined : context.getTsLs(_lsType).__internal__.host.getProjectVersion?.();
const tsProjectVersion = _lsType === 'nonTs' ? undefined : context.getTsLs(_lsType)?.__internal__.host.getProjectVersion?.();

if (_lsType === 'nonTs') {
if (cache && cache.documentVersion === document.version) {
Expand Down
6 changes: 3 additions & 3 deletions packages/vue-language-service/src/languageService.ts
Expand Up @@ -183,8 +183,8 @@ export function createLanguageService(
// includeCompletionsForModuleExports: true, // set in server/src/tsConfigs.ts
includeCompletionsWithInsertText: true, // if missing, { 'aaa-bbb': any, ccc: any } type only has result ['ccc']
},
)
const templateTsPlugins = useTsPlugins(
);
const templateTsPlugins = tsRuntime.context.templateTsLs ? useTsPlugins(
tsRuntime.context.templateTsLs,
true,
{
Expand All @@ -194,7 +194,7 @@ export function createLanguageService(
includeCompletionsForModuleExports: false,
includeCompletionsForImportStatements: false,
},
)
) : [];
const autoDotValuePlugin = defineLanguageServicePlugin(
useAutoDotValuePlugin({
getSettings: _getSettings,
Expand Down
Expand Up @@ -65,7 +65,7 @@ export default function (host: {
getSemanticTokenLegend(): vscode.SemanticTokensLegend,
getScanner(document: TextDocument): html.Scanner | undefined,
scriptTsLs: ts2.LanguageService,
templateTsLs: ts2.LanguageService,
templateTsLs: ts2.LanguageService | undefined,
templateLanguagePlugin: EmbeddedLanguagePlugin,
isSupportedDocument: (document: TextDocument) => boolean,
getNameCases?: (uri: string) => Promise<{
Expand Down Expand Up @@ -261,7 +261,12 @@ export default function (host: {
async function resolveHtmlItem(item: vscode.CompletionItem, data: HtmlCompletionData) {

let tsItem: vscode.CompletionItem | undefined = data.tsItem;
if (!tsItem) return item;

if (!tsItem)
return item;

if (!host.templateTsLs)
return item;

tsItem = await host.templateTsLs.doCompletionResolve(tsItem);
item.tags = [...item.tags ?? [], ...tsItem.tags ?? []];
Expand Down Expand Up @@ -750,11 +755,16 @@ export default function (host: {
const projectVersion = ref<number>();
const usedTags = ref(new Set<string>());
const result = computed(() => {

const result = new Map<string, { item: vscode.CompletionItem | undefined, bind: vscode.CompletionItem[], on: vscode.CompletionItem[] }>();

if (!host.templateTsLs)
return result;

{ // watching
projectVersion.value;
usedTags.value;
}
const result = new Map<string, { item: vscode.CompletionItem | undefined, bind: vscode.CompletionItem[], on: vscode.CompletionItem[] }>();

pauseTracking();
const doc = sfcTemplateScript.textDocument.value;
Expand Down
18 changes: 8 additions & 10 deletions packages/vue-tsc/src/apis.ts
Expand Up @@ -20,8 +20,8 @@ export function register(

function getRootFileNames() {
const set = new Set([
...getProgram('script').getRootFileNames().filter(fileName => scriptTsHost.fileExists?.(fileName)),
...getProgram('template').getRootFileNames().filter(fileName => templateTsHost.fileExists?.(fileName)),
...getProgram('script')?.getRootFileNames().filter(fileName => scriptTsHost.fileExists?.(fileName)) ?? [],
...getProgram('template')?.getRootFileNames().filter(fileName => templateTsHost?.fileExists?.(fileName)) ?? [],
]);
return [...set.values()];
}
Expand Down Expand Up @@ -62,7 +62,7 @@ export function register(
continue;

const program = getProgram(sourceMap.lsType);
const embeddedSourceFile = program.getSourceFile(shared.uriToFsPath(sourceMap.mappedDocument.uri));
const embeddedSourceFile = program?.getSourceFile(shared.uriToFsPath(sourceMap.mappedDocument.uri));

if (embeddedSourceFile) {

Expand All @@ -82,24 +82,22 @@ export function register(
}

function getGlobalDiagnostics(cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] {
return lsTypes.map(lsType => transformDiagnostics(lsType, getProgram(lsType).getGlobalDiagnostics(cancellationToken))).flat();
return lsTypes.map(lsType => transformDiagnostics(lsType, getProgram(lsType)?.getGlobalDiagnostics(cancellationToken) ?? [])).flat();
}
function emit(targetSourceFile?: ts.SourceFile, _writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: ts.CustomTransformers): ts.EmitResult {
const scriptResult = getProgram('script').emit(targetSourceFile, (vueHost.writeFile ?? ts.sys.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
const templateResult = getProgram('template').emit(targetSourceFile, undefined, cancellationToken, emitOnlyDtsFiles, customTransformers);
const scriptResult = getProgram('script')!.emit(targetSourceFile, (vueHost.writeFile ?? ts.sys.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
const templateResult = getProgram('template')?.emit(targetSourceFile, undefined, cancellationToken, emitOnlyDtsFiles, customTransformers);
return {
emitSkipped: scriptResult.emitSkipped,
emittedFiles: scriptResult.emittedFiles,
diagnostics: [
...transformDiagnostics('script', scriptResult.diagnostics),
...transformDiagnostics('template', templateResult.diagnostics),
...transformDiagnostics('template', templateResult?.diagnostics ?? []),
],
};
}
function getProgram(lsType: 'script' | 'template') {
const program = (lsType === 'script' ? scriptTsLsRaw : templateTsLsRaw).getProgram();
if (!program) throw '!program';
return program;
return (lsType === 'script' ? scriptTsLsRaw : templateTsLsRaw)?.getProgram();
}

// transform
Expand Down
13 changes: 7 additions & 6 deletions packages/vue-typescript/src/types.ts
Expand Up @@ -9,8 +9,8 @@ import type { VueDocuments } from './vueDocuments';
import type { TextRange } from './utils/sourceMaps';

export type LanguageServiceHostBase = ts2.LanguageServiceHost & {
getVueCompilationSettings?(): VueCompilerOptions,
getVueProjectVersion?(): string;
getVueCompilationSettings?(): VueCompilerOptions,
getVueProjectVersion?(): string;
};

export interface ITemplateScriptData {
Expand All @@ -27,6 +27,7 @@ export interface VueCompilerOptions {
experimentalCompatMode?: 2 | 3;
experimentalTemplateCompilerOptions?: any;
experimentalTemplateCompilerOptionsRequirePath?: string;
experimentalDisableTemplateSupport?: boolean;
}

export type BasicRuntimeContext = {
Expand Down Expand Up @@ -54,10 +55,10 @@ export type TypeScriptFeaturesRuntimeContext = {
vueHost: LanguageServiceHostBase;
documentContext: DocumentContext;
scriptTsHost: ts.LanguageServiceHost;
templateTsHost: ts.LanguageServiceHost;
templateTsHost: ts.LanguageServiceHost | undefined;
scriptTsLsRaw: ts.LanguageService;
templateTsLsRaw: ts.LanguageService;
templateTsLsRaw: ts.LanguageService | undefined;
scriptTsLs: ts2.LanguageService;
templateTsLs: ts2.LanguageService;
getTsLs: (lsType: 'template' | 'script') => ts2.LanguageService;
templateTsLs: ts2.LanguageService | undefined;
getTsLs: <T extends 'template' | 'script'>(lsType: T) => T extends 'script' ? ts2.LanguageService : (ts2.LanguageService | undefined);
}
16 changes: 9 additions & 7 deletions packages/vue-typescript/src/typescriptRuntime.ts
Expand Up @@ -38,15 +38,17 @@ export function createTypeScriptRuntime(
const templateScriptUpdateUris = new Set<string>();
const initProgressCallback: ((p: number) => void)[] = [];

const templateTsHost = createTsLsHost('template');
const templateTsHost = options.compilerOptions.experimentalDisableTemplateSupport ? undefined : createTsLsHost('template');
const scriptTsHost = createTsLsHost('script');
const templateTsLsRaw = ts.createLanguageService(templateTsHost);
const templateTsLsRaw = templateTsHost ? ts.createLanguageService(templateTsHost) : undefined;
const scriptTsLsRaw = ts.createLanguageService(scriptTsHost);

shared.injectCacheLogicToLanguageServiceHost(ts, templateTsHost, templateTsLsRaw);
if (templateTsHost && templateTsLsRaw) {
shared.injectCacheLogicToLanguageServiceHost(ts, templateTsHost, templateTsLsRaw);
}
shared.injectCacheLogicToLanguageServiceHost(ts, scriptTsHost, scriptTsLsRaw);

const templateTsLs = ts2.createLanguageService(ts, templateTsHost, templateTsLsRaw);
const templateTsLs = templateTsHost && templateTsLsRaw ? ts2.createLanguageService(ts, templateTsHost, templateTsLsRaw) : undefined;
const scriptTsLs = ts2.createLanguageService(ts, scriptTsHost, scriptTsLsRaw);
const localTypesScript = ts.ScriptSnapshot.fromString(localTypes.getTypesCode(isVue2));
const compilerHost = ts.createCompilerHost(vueHost.getCompilationSettings());
Expand Down Expand Up @@ -102,7 +104,7 @@ export function createTypeScriptRuntime(
templateTsLs,
scriptTsLs,
documentContext,
getTsLs: (lsType: 'template' | 'script') => lsType === 'template' ? templateTsLs : scriptTsLs,
getTsLs: (lsType: 'template' | 'script') => lsType === 'template' ? templateTsLs! : scriptTsLs,
};

return {
Expand All @@ -113,7 +115,7 @@ export function createTypeScriptRuntime(
getScriptContentVersion: () => scriptContentVersion,
dispose: () => {
scriptTsLs.dispose();
templateTsLs.dispose();
templateTsLs?.dispose();
},
onInitProgress(cb: (p: number) => void) {
initProgressCallback.push(cb);
Expand Down Expand Up @@ -422,7 +424,7 @@ export function createTypeScriptRuntime(
lastScriptProjectVersionWhenTemplateProjectVersionUpdate = scriptContentVersion;
let currentNums = 0;
for (const uri of templateScriptUpdateUris) {
if (vueDocuments.get(uri)?.updateTemplateScript(templateTsLs)) {
if (templateTsLs && vueDocuments.get(uri)?.updateTemplateScript(templateTsLs)) {
templateScriptUpdated = true;
}
currentNums++;
Expand Down

0 comments on commit 825f4f8

Please sign in to comment.