Skip to content

Commit

Permalink
feat: improve typing for @marko/run projects
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Mar 8, 2023
1 parent 89ad8bb commit d2fbcd5
Show file tree
Hide file tree
Showing 94 changed files with 1,905 additions and 2,249 deletions.
7 changes: 7 additions & 0 deletions .changeset/big-buttons-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@marko/language-server": patch
"@marko/language-tools": patch
"marko-vscode": patch
---

Improve typing of @marko/run projects.
2,725 changes: 1,004 additions & 1,721 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.0",
"@types/mocha": "^10.0.1",
"@types/node": "^18.14.2",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"esbuild": "^0.17.10",
"@types/node": "^18.14.6",
"@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.1",
"esbuild": "^0.17.11",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"eslint-config-prettier": "^8.7.0",
"eslint-import-resolver-typescript": "^3.5.3",
"eslint-plugin-import": "^2.27.5",
"fast-glob": "^3.2.12",
Expand All @@ -23,7 +23,7 @@
},
"private": true,
"scripts": {
"build": "npm run -ws build",
"build": "NODE_ENV=production npm run -ws build",
"build:dev": "tsx ./packages/vscode/build.mts",
"change": "npm exec changeset add",
"format": "npm run build && eslint -f visualstudio --fix . && prettier \"./**/*{.ts,.js,.json,.md,.yml,rc}\" --write",
Expand Down
8 changes: 4 additions & 4 deletions packages/language-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"@babel/helper-validator-identifier": "^7.19.1",
"@marko/language-tools": "^1.0.0",
"@marko/babel-utils": "^5.21.4",
"@marko/compiler": "^5.25.0",
"@marko/translator-default": "^5.23.0",
"htmljs-parser": "^5.3.0",
"marko": "^5.23.0",
"@marko/compiler": "^5.26.0",
"@marko/translator-default": "^5.24.0",
"htmljs-parser": "^5.4.0",
"marko": "^5.24.0",
"prettier": "^2.8.4",
"prettier-plugin-marko": "^1.2.3",
"relative-import-path": "^1.0.0",
Expand Down
17 changes: 14 additions & 3 deletions packages/language-server/src/service/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,12 @@ function processScript(doc: TextDocument, tsProject: TSProject) {
parsed,
lookup,
scriptLang: getScriptLang(filename, ts, host, markoScriptLang),
runtimeTypesCode: getProjectTypeLibs(markoProject, ts, host)
?.markoTypesCode,
runtimeTypesCode: getProjectTypeLibs(
tsProject.rootDir,
markoProject,
ts,
host
)?.markoTypesCode,
componentFilename: getComponentFilename(filename),
});
}
Expand Down Expand Up @@ -647,6 +651,8 @@ function getTSProject(docFsPath: string): TSProject {
extraTSCompilerExtensions
);

options.rootDir ??= rootDir;

// Only ts like files can inject globals into the project, so we filter out everything else.
const potentialGlobalFiles = new Set<string>(
fileNames.filter((file) => /\.[cm]?ts$/.test(file))
Expand Down Expand Up @@ -762,7 +768,12 @@ function getTSProject(docFsPath: string): TSProject {
service: ts.createLanguageService(host),
markoProject,
markoScriptLang,
markoProjectTypeLibs: getProjectTypeLibs(markoProject, ts, host),
markoProjectTypeLibs: getProjectTypeLibs(
options.rootDir!,
markoProject,
ts,
host
),
};

projectCache.set(rootDir, tsProject);
Expand Down
22 changes: 16 additions & 6 deletions packages/language-server/src/ts-plugin/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,25 @@ export function patch(
cache: Map<string, ExtractedSnapshot | { snapshot: ts.IScriptSnapshot }>,
host: ts.LanguageServiceHost
) {
const rootDir = host.getCurrentDirectory();
const projectTypeLibs = getProjectTypeLibs(
getMarkoProject(host.getCurrentDirectory()),
rootDir,
getMarkoProject(rootDir),
ts,
host
);
const projectTypeLibsFiles = [
projectTypeLibs.internalTypesFile,
projectTypeLibs.markoTypesFile,
];

if (projectTypeLibs.markoRunTypesFile) {
projectTypeLibsFiles.push(projectTypeLibs.markoRunTypesFile);
}

if (projectTypeLibs.markoRunGeneratedTypesFile) {
projectTypeLibsFiles.push(projectTypeLibs.markoRunGeneratedTypesFile);
}

const isMarkoTSFile = (fileName: string) =>
getScriptLang(fileName, ts, host, scriptLang) === ScriptLang.ts;
Expand All @@ -39,11 +53,7 @@ export function patch(
*/
const getScriptFileNames = host.getScriptFileNames.bind(host);
host.getScriptFileNames = () => [
...new Set([
...getScriptFileNames(),
projectTypeLibs.internalTypesFile,
projectTypeLibs.markoTypesFile,
]),
...new Set(projectTypeLibsFiles.concat(getScriptFileNames())),
];

/**
Expand Down
35 changes: 29 additions & 6 deletions packages/language-server/src/utils/get-runtime-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,56 @@ const internalTypesFile = path.join(__dirname, "marko.internal.d.ts");
const defaultMarkoTypesFile = path.join(__dirname, "marko.runtime.d.ts");

export default function getProjectTypeLibs(
rootDir: string,
project: MarkoProject,
ts: typeof TS,
host: LanguageServiceHost
) {
let cached = project.cache.get(getProjectTypeLibs) as
| {
internalTypesFile: string;
markoRunTypesFile: string | undefined;
markoRunGeneratedTypesFile: string | undefined;
markoTypesFile: string;
markoTypesCode: string;
}
| undefined;

if (cached === undefined) {
const { resolvedTypeReferenceDirective } = ts.resolveTypeReferenceDirective(
(project.translator.runtimeTypes as string | undefined) || "marko",
path.join(host.getCurrentDirectory(), "_.d.ts"),
host.getCompilationSettings(),
host
const markoRunGeneratedTypesFile = path.join(
rootDir,
".marko-run/routes.d.ts"
);
const resolveFromFile = path.join(host.getCurrentDirectory(), "_.d.ts");
const compilerOptions = host.getCompilationSettings();
const { resolvedTypeReferenceDirective: resolvedMarkoTypes } =
ts.resolveTypeReferenceDirective(
(project.translator.runtimeTypes as string | undefined) || "marko",
resolveFromFile,
compilerOptions,
host
);

const { resolvedTypeReferenceDirective: resolvedMarkoRunTypes } =
ts.resolveTypeReferenceDirective(
"@marko/run",
resolveFromFile,
compilerOptions,
host
);

const markoTypesFile =
resolvedTypeReferenceDirective?.resolvedFileName || defaultMarkoTypesFile;
resolvedMarkoTypes?.resolvedFileName || defaultMarkoTypesFile;
const markoRunTypesFile = resolvedMarkoRunTypes?.resolvedFileName;

cached = {
internalTypesFile,
markoTypesFile,
markoTypesCode: host.readFile(markoTypesFile, "utf-8") || "",
markoRunTypesFile,
markoRunGeneratedTypesFile: host.fileExists(markoRunGeneratedTypesFile)
? markoRunGeneratedTypesFile
: undefined,
};

project.cache.set(getProjectTypeLibs, cached);
Expand Down
4 changes: 4 additions & 0 deletions packages/language-tools/marko.internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ declare global {
export const never: never;
export const any: any;

export function getGlobal<Override>(
override: Override
): 1 extends Override & 0 ? Marko.Global : Override;

export function attrTagNames<Input, Keys extends keyof Input>(
input: Input
): Record<string, never> & {
Expand Down
6 changes: 3 additions & 3 deletions packages/language-tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
"dependencies": {
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/parser": "^7.21.2",
"htmljs-parser": "^5.3.0",
"htmljs-parser": "^5.4.0",
"relative-import-path": "^1.0.0"
},
"devDependencies": {
"@babel/code-frame": "^7.18.6",
"@marko/compiler": "^5.25.0",
"@marko/compiler": "^5.26.0",
"@types/babel__code-frame": "^7.0.3",
"@types/babel__helper-validator-identifier": "^7.15.0",
"@typescript/vfs": "^1.4.0",
"marko": "^5.23.0",
"marko": "^5.24.0",
"mitata": "^0.1.6",
"tsx": "^3.12.3"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ export interface Input {}
abstract class Component extends Marko.Component<Input> {}
export { type Component };
(function (this: void) {
const input = 1 as any as Input;
const component = 1 as any as Component;
const out = Marko._.out;
const input = Marko._.any as Input;
const component = Marko._.any as Component;
const state = Marko._.state(component);
Marko._.noop({ input, out, component, state });
const $global = Marko._.getGlobal(
// @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
(Marko._.error, Marko._.any as MarkoRun.Context)
);
const out = Marko._.out;
Marko._.noop({ input, component, state, out, $global });
Marko._.renderNativeTag("input")()()({
type: "checkbox",
disabled: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ export interface Input {
abstract class Component extends Marko.Component<Input> {}
export { type Component };
(function (this: void) {
const input = 1 as any as Input;
const component = 1 as any as Component;
const out = Marko._.out;
const input = Marko._.any as Input;
const component = Marko._.any as Component;
const state = Marko._.state(component);
Marko._.noop({ input, out, component, state });
const $global = Marko._.getGlobal(
// @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
(Marko._.error, Marko._.any as MarkoRun.Context)
);
const out = Marko._.out;
Marko._.noop({ input, component, state, out, $global });
return;
})();
export default new (class Template extends Marko._.Template<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ export interface Input {}
abstract class Component extends Marko.Component<Input> {}
export { type Component };
(function (this: void) {
const input = 1 as any as Input;
const component = 1 as any as Component;
const out = Marko._.out;
const input = Marko._.any as Input;
const component = Marko._.any as Component;
const state = Marko._.state(component);
Marko._.noop({ input, out, component, state });
const $global = Marko._.getGlobal(
// @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
(Marko._.error, Marko._.any as MarkoRun.Context)
);
const out = Marko._.out;
Marko._.noop({ input, component, state, out, $global });
Marko._.assertRendered(
Marko._.rendered,
1,
Expand Down
Loading

0 comments on commit d2fbcd5

Please sign in to comment.