Skip to content

Commit

Permalink
feat: upgrade to vue language tools 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
so1ve committed Mar 28, 2024
1 parent 3e72132 commit aa392a2
Show file tree
Hide file tree
Showing 7 changed files with 1,034 additions and 1,778 deletions.
11 changes: 4 additions & 7 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
const { so1ve } = require("@so1ve/eslint-config");
import { so1ve } from "@so1ve/eslint-config";

module.exports = so1ve(
{},
{
ignores: ["packages/**/test/__fixtures__/**"],
},
);
export default so1ve({
ignores: ["packages/**/test/__fixtures__/**"],
});
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"private": true,
"version": "0.5.0",
"packageManager": "[email protected]",
"type": "module",
"scripts": {
"build": "pnpm -r run build",
"lint": "eslint . && prettier . --check",
Expand All @@ -13,13 +14,13 @@
},
"devDependencies": {
"@antfu/ni": "^0.21.8",
"@so1ve/eslint-config": "1.0.2",
"@so1ve/prettier-config": "1.0.2",
"@so1ve/eslint-config": "^2.0.0",
"@so1ve/prettier-config": "^2.0.0",
"@types/node": "^20.8.10",
"@vue-macros/test-utils": "^1.2.1",
"bumpp": "^9.2.0",
"eslint": "^8.53.0",
"prettier": "^3.0.3",
"eslint": "^8.57.0",
"prettier": "^3.2.5",
"typescript": "^5.2.2",
"unbuild": "^2.0.0",
"vite": "^5.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/language/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"stub": "unbuild --stub"
},
"dependencies": {
"@volar/typescript": "1.10.10",
"@volar/typescript": "~2.1.6",
"@vue.ts/common": "workspace:*",
"@vue/language-core": "1.8.22"
"@vue/language-core": "2.0.7"
}
}
89 changes: 65 additions & 24 deletions packages/language/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { createRequire } from "node:module";
import * as path from "node:path";

import {
createLanguageServiceHost,
decorateLanguageService,
} from "@volar/typescript";
import { createLanguage as createTypescriptLanguage } from "@volar/typescript";
import * as vue from "@vue/language-core";
import { normalizePath } from "@vue.ts/common";
import type ts from "typescript/lib/tsserverlibrary";
Expand All @@ -20,23 +17,27 @@ function createLanguage(
return createLanguageWorker(
() => vue.createParsedCommandLine(ts, ts.sys, tsconfigPath),
path.dirname(tsconfig),
tsconfig,
ts,
);
}

function createLanguageWorker(
loadParsedCommandLine: () => vue.ParsedCommandLine,
rootPath: string,
configFileName: string | undefined,
ts: typeof import("typescript/lib/tsserverlibrary"),
) {
let parsedCommandLine = loadParsedCommandLine();
let fileNames = parsedCommandLine.fileNames.map(normalizePath);
let projectVersion = 0;

const scriptSnapshots = new Map<string, ts.IScriptSnapshot>();
const _host: vue.TypeScriptLanguageHost = {
workspacePath: rootPath,
rootPath,
const _host: vue.TypeScriptProjectHost = {
// Commented to wait for volar 2.2.0-alpha.0
// ...ts.sys,
// configFileName,
getCurrentDirectory: () => rootPath,
getProjectVersion: () => projectVersion.toString(),
getCompilationSettings: () => parsedCommandLine.options,
getScriptFileNames: () => fileNames,
Expand All @@ -51,13 +52,27 @@ function createLanguageWorker(

return scriptSnapshots.get(fileName);
},
getLanguageId: (fileName) => {
if (
parsedCommandLine.vueOptions.extensions.some((ext) =>
fileName.endsWith(ext),
)
) {
return "vue";
}

return vue.resolveCommonLanguageId(fileName);
},
// scriptIdToFileName: (id) => id,
// fileNameToScriptId: (id) => id,
};

return {
...baseCreateLanguageWorker(
_host,
vue.resolveVueCompilerOptions(parsedCommandLine.vueOptions),
ts,
configFileName,
_host,
parsedCommandLine.vueOptions,
),
updateFile(fileName: string, text: string) {
fileName = normalizePath(fileName);
Expand All @@ -84,38 +99,64 @@ function createLanguageWorker(
type Language = ReturnType<typeof createLanguage>;

function baseCreateLanguageWorker(
host: vue.TypeScriptLanguageHost,
vueCompilerOptions: vue.VueCompilerOptions,
ts: typeof import("typescript/lib/tsserverlibrary"),
configFileName: string | undefined,
host: vue.TypeScriptProjectHost,
vueCompilerOptions: vue.VueCompilerOptions,
) {
const vueLanguages = ts
? // eslint-disable-next-line etc/no-deprecated
vue.createLanguages(host.getCompilationSettings(), vueCompilerOptions, ts)
: [];
const core = vue.createLanguageContext(host, vueLanguages);
const tsLsHost = createLanguageServiceHost(core, ts, ts.sys);
const tsLs = ts.createLanguageService(tsLsHost);
const vueLanguagePlugin = vue.createVueLanguagePlugin(
ts,
(id) => id,
(fileName) => {
if (ts.sys.useCaseSensitiveFileNames) {
return host.getScriptFileNames().includes(fileName) ?? false;
} else {
const lowerFileName = fileName.toLowerCase();
for (const rootFile of host.getScriptFileNames()) {
if (rootFile.toLowerCase() === lowerFileName) {
return true;
}
}

decorateLanguageService(core.virtualFiles, tsLs, false);
return false;
}
},
host.getCompilationSettings(),
vueCompilerOptions,
);
const language = createTypescriptLanguage(
ts,
ts.sys,
[vueLanguagePlugin],
configFileName,
host,
{
fileIdToFileName: (id) => id,
fileNameToFileId: (id) => id,
},
);
const { languageServiceHost } = language.typescript!;
const tsLs = ts.createLanguageService(languageServiceHost);

const getScriptKind = tsLsHost.getScriptKind!;
tsLsHost.getScriptKind = (fileName) => {
const getScriptKind =
languageServiceHost.getScriptKind?.bind(languageServiceHost);
languageServiceHost.getScriptKind = (fileName) => {
if (fileName.endsWith(".vue.js")) {
return ts.ScriptKind.TS;
}
if (fileName.endsWith(".vue.jsx")) {
return ts.ScriptKind.TSX;
}

return getScriptKind(fileName);
return getScriptKind!(fileName);
};

const program = tsLs.getProgram()!;
const typeChecker = program.getTypeChecker();

function getScriptSetupBlock(normalizedFilepath: string) {
const sourceFile = core.virtualFiles.getSource(normalizedFilepath)?.root;
if (!(sourceFile instanceof vue.VueFile)) {
const sourceFile = language.files.get(normalizedFilepath)?.generated?.code;
if (!(sourceFile instanceof vue.VueGeneratedCode)) {
return;
}
if (!sourceFile.sfc.scriptSetup) {
Expand Down
3 changes: 2 additions & 1 deletion packages/tsx-auto-props/test/__fixtures__/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"esModuleInterop": true,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"jsx": "preserve"
"jsx": "preserve",
"jsxImportSource": "vue"
}
}
Loading

0 comments on commit aa392a2

Please sign in to comment.