Rename Red Knot (#17820)

This commit is contained in:
Micha Reiser 2025-05-03 19:49:15 +02:00 committed by GitHub
parent e6a798b962
commit b51c4f82ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1564 changed files with 1598 additions and 1578 deletions

View file

@ -1,5 +1,5 @@
**.md
ruff/dist
ruff/ruff_wasm
knot/dist
knot/red_knot_wasm
ty/dist
ty/ty_wasm

View file

@ -5,8 +5,8 @@ In-browser playground for Ruff. Available [https://play.ruff.rs/](https://play.r
## Getting started
Install the NPM dependencies with `npm install`, and run, and run the development server with
`npm start --workspace ruff-playground` or `npm start --workspace knot-playground`.
You may need to restart the server after making changes to Ruff or Red Knot to re-build the WASM
`npm start --workspace ruff-playground` or `npm start --workspace ty-playground`.
You may need to restart the server after making changes to Ruff or ty to re-build the WASM
module.
To run the datastore, which is based
@ -37,4 +37,4 @@ additional inspiration from the [Biome Playground](https://biomejs.dev/playgroun
### Stack overflows
If you see stack overflows in the playground, build the WASM module in release mode:
`npm run --workspace knot-playground build:wasm`.
`npm run --workspace ty-playground build:wasm`.

View file

@ -8,7 +8,7 @@
"name": "playground",
"version": "0.0.0",
"workspaces": [
"knot",
"ty",
"ruff",
"shared"
],
@ -30,9 +30,10 @@
"wasm-pack": "^0.13.1"
}
},
"knot": {
"name": "knot-playground",
"ty": {
"name": "ty-playground",
"version": "0.0.0",
"extraneous": true,
"dependencies": {
"@monaco-editor/react": "^4.7.0",
"classnames": "^2.5.1",
@ -42,7 +43,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-resizable-panels": "^2.1.7",
"red_knot_wasm": "file:red_knot_wasm",
"ty_wasm": "file:ty_wasm",
"shared": "0.0.0",
"smol-toml": "^1.3.1"
},
@ -50,8 +51,9 @@
"vite-plugin-static-copy": "^2.3.0"
}
},
"knot/red_knot_wasm": {
"ty/ty_wasm": {
"version": "0.0.0",
"extraneous": true,
"license": "MIT"
},
"node_modules/@esbuild/aix-ppc64": {
@ -4078,10 +4080,6 @@
"json-buffer": "3.0.1"
}
},
"node_modules/knot-playground": {
"resolved": "knot",
"link": true
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -4991,10 +4989,6 @@
"node": ">=8.10.0"
}
},
"node_modules/red_knot_wasm": {
"resolved": "knot/red_knot_wasm",
"link": true
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@ -5641,6 +5635,14 @@
"strip-bom": "^3.0.0"
}
},
"node_modules/ty_wasm": {
"resolved": "ty/ty_wasm",
"link": true
},
"node_modules/ty-playground": {
"resolved": "ty",
"link": true
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -5881,9 +5883,9 @@
}
},
"node_modules/vite-plugin-static-copy": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.0.tgz",
"integrity": "sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.1.tgz",
"integrity": "sha512-EfsPcBm3ewg3UMG8RJaC0ADq6/qnUZnokXx4By4+2cAcipjT9i0Y0owIJGqmZI7d6nxk4qB1q5aXOwNuSyPdyA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -6037,9 +6039,9 @@
"license": "ISC"
},
"node_modules/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
"version": "8.18.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
"integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@ -6094,7 +6096,7 @@
}
},
"ruff/ruff_wasm": {
"version": "0.11.4",
"version": "0.11.8",
"license": "MIT"
},
"shared": {
@ -6105,6 +6107,31 @@
"react": "^19.0.0",
"react-resizable-panels": "^2.1.7"
}
},
"ty": {
"name": "ty-playground",
"version": "0.0.0",
"dependencies": {
"@monaco-editor/react": "^4.7.0",
"classnames": "^2.5.1",
"lz-string": "^1.5.0",
"monaco-editor": "^0.52.2",
"pyodide": "^0.27.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-resizable-panels": "^2.1.7",
"shared": "0.0.0",
"smol-toml": "^1.3.1",
"ty_wasm": "file:ty_wasm"
},
"devDependencies": {
"vite-plugin-static-copy": "^2.3.0"
}
},
"ty/ty_wasm": {
"name": "ty_wasm",
"version": "0.0.0",
"license": "MIT"
}
}
}

View file

@ -5,15 +5,15 @@
"type": "module",
"scripts": {
"check": "npm run dev:wasm && npm run lint && npm run tsc",
"dev:wasm": "npm run dev:wasm --workspace knot-playground && npm run dev:wasm --workspace ruff-playground",
"dev:build": "npm run dev:build --workspace knot-playground && npm run dev:build --workspace ruff-playground",
"dev:wasm": "npm run dev:wasm --workspace ty-playground && npm run dev:wasm --workspace ruff-playground",
"dev:build": "npm run dev:build --workspace ty-playground && npm run dev:build --workspace ruff-playground",
"fmt": "prettier --cache -w .",
"fmt:check": "prettier --cache --check .",
"lint": "eslint --cache --ext .ts,.tsx ruff/src knot/src",
"lint": "eslint --cache --ext .ts,.tsx ruff/src ty/src",
"tsc": "tsc"
},
"workspaces": [
"knot",
"ty",
"ruff",
"shared"
],

View file

@ -16,6 +16,10 @@
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["ruff/src", "knot/src"],
"references": [{ "path": "./tsconfig.node.json" }]
"include": ["ruff/src", "ty/src"],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}

View file

@ -5,5 +5,5 @@
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["ruff/vite.config.ts", "knot/vite.config.ts"]
"include": ["ruff/vite.config.ts", "ty/vite.config.ts"]
}

View file

@ -9,18 +9,18 @@
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<meta name="msapplication-TileColor" content="#d7ff64" />
<meta name="theme-color" content="#ffffff" />
<title>Playground | Red Knot</title>
<title>Playground | ty</title>
<meta
name="description"
content="An in-browser playground for Red Knot, an extremely fast Python type-checker written in Rust."
content="An in-browser playground for ty, an extremely fast Python type-checker written in Rust."
/>
<meta name="keywords" content="ruff, python, rust, webassembly, wasm" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@astral_sh" />
<meta property="og:title" content="Playground | Ruff" />
<meta property="og:title" content="Playground | ty" />
<meta
property="og:description"
content="An in-browser playground for Ruff, an extremely fast Python type-checker written in Rust."
content="An in-browser playground for ty, an extremely fast Python type-checker written in Rust."
/>
<meta property="og:url" content="https://play.ruff.rs" />
<meta property="og:image" content="/Astral.png" />

View file

@ -1,13 +1,13 @@
{
"name": "knot-playground",
"name": "ty-playground",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"prebuild": "npm run build:wasm",
"build": "vite build",
"build:wasm": "wasm-pack build ../../crates/red_knot_wasm --target web --out-dir ../../playground/knot/red_knot_wasm",
"dev:wasm": "wasm-pack build ../../crates/red_knot_wasm --dev --target web --out-dir ../../playground/knot/red_knot_wasm",
"build:wasm": "wasm-pack build ../../crates/ty_wasm --target web --out-dir ../../playground/ty/ty_wasm",
"dev:wasm": "wasm-pack build ../../crates/ty_wasm --dev --target web --out-dir ../../playground/ty/ty_wasm",
"predev:build": "npm run dev:wasm",
"dev:build": "vite build",
"prestart": "npm run dev:wasm",
@ -23,9 +23,9 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-resizable-panels": "^2.1.7",
"red_knot_wasm": "file:red_knot_wasm",
"shared": "0.0.0",
"smol-toml": "^1.3.1"
"smol-toml": "^1.3.1",
"ty_wasm": "file:ty_wasm"
},
"overrides": {
"@monaco-editor/react": {

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

View file

@ -13,7 +13,7 @@ import {
Theme,
VerticalResizeHandle,
} from "shared";
import type { Workspace } from "red_knot_wasm";
import type { Workspace } from "ty_wasm";
import { Panel, PanelGroup } from "react-resizable-panels";
import { Files, isPythonFile } from "./Files";
import SecondarySideBar from "./SecondarySideBar";

View file

@ -1,4 +1,4 @@
import type { Severity, Range, TextRange } from "red_knot_wasm";
import type { Severity, Range, TextRange } from "ty_wasm";
import classNames from "classnames";
import { Theme } from "shared";
import { useMemo } from "react";

View file

@ -18,11 +18,11 @@ import {
import { useCallback, useEffect, useRef } from "react";
import { Theme } from "shared";
import {
Range as KnotRange,
Range as TyRange,
Severity,
type Workspace,
Position as KnotPosition,
} from "red_knot_wasm";
Position as TyPosition,
} from "ty_wasm";
import IStandaloneCodeEditor = editor.IStandaloneCodeEditor;
import { FileId, ReadonlyFiles } from "../Playground";
@ -194,7 +194,7 @@ class PlaygroundServer
const inlayHints = workspace.inlayHints(
selectedHandle,
iRangeToKnotRange(range),
MonacoRangeToTyRange(range),
);
if (inlayHints.length === 0) {
@ -300,7 +300,7 @@ class PlaygroundServer
const hover = workspace.hover(
selectedHandle,
new KnotPosition(position.lineNumber, position.column),
new TyPosition(position.lineNumber, position.column),
);
if (hover == null) {
@ -308,7 +308,7 @@ class PlaygroundServer
}
return {
range: knotRangeToIRange(hover.range),
range: tyRangeToMonacoRange(hover.range),
contents: [{ value: hover.markdown, isTrusted: true }],
};
}
@ -334,7 +334,7 @@ class PlaygroundServer
const links = workspace.gotoTypeDefinition(
selectedHandle,
new KnotPosition(position.lineNumber, position.column),
new TyPosition(position.lineNumber, position.column),
);
return (
@ -343,16 +343,16 @@ class PlaygroundServer
const targetSelection =
link.selection_range == null
? undefined
: knotRangeToIRange(link.selection_range);
: tyRangeToMonacoRange(link.selection_range);
const originSelection =
link.origin_selection_range == null
? undefined
: knotRangeToIRange(link.origin_selection_range);
: tyRangeToMonacoRange(link.origin_selection_range);
return {
uri: Uri.parse(link.path),
range: knotRangeToIRange(link.full_range),
range: tyRangeToMonacoRange(link.full_range),
targetSelectionRange: targetSelection,
originSelectionRange: originSelection,
} as languages.LocationLink;
@ -450,7 +450,7 @@ class PlaygroundServer
}
}
function knotRangeToIRange(range: KnotRange): IRange {
function tyRangeToMonacoRange(range: TyRange): IRange {
return {
startLineNumber: range.start.line,
startColumn: range.start.column,
@ -459,9 +459,9 @@ function knotRangeToIRange(range: KnotRange): IRange {
};
}
function iRangeToKnotRange(range: IRange): KnotRange {
return new KnotRange(
new KnotPosition(range.startLineNumber, range.startColumn),
new KnotPosition(range.endLineNumber, range.endColumn),
function MonacoRangeToTyRange(range: IRange): TyRange {
return new TyRange(
new TyPosition(range.startLineNumber, range.startColumn),
new TyPosition(range.endLineNumber, range.endColumn),
);
}

View file

@ -2,7 +2,7 @@ import { Icons, Theme } from "shared";
import classNames from "classnames";
import { useState } from "react";
import { FileId } from "../Playground";
import { type FileHandle } from "red_knot_wasm";
import { type FileHandle } from "ty_wasm";
export interface Props {
// The file names

View file

@ -10,13 +10,13 @@ import {
useState,
} from "react";
import { ErrorMessage, Header, setupMonaco, useTheme } from "shared";
import { FileHandle, PositionEncoding, Workspace } from "red_knot_wasm";
import { FileHandle, PositionEncoding, Workspace } from "ty_wasm";
import { persist, persistLocal, restore } from "./Editor/persist";
import { loader } from "@monaco-editor/react";
import knotSchema from "../../../knot.schema.json";
import tySchema from "../../../ty.schema.json";
import Chrome, { formatError } from "./Editor/Chrome";
export const SETTINGS_FILE_NAME = "knot.json";
export const SETTINGS_FILE_NAME = "ty.json";
export default function Playground() {
const [theme, setTheme] = useTheme();
@ -224,13 +224,13 @@ def with_style(line, word, style):
output += "-" * len(word)
print(with_style("Red Knot is a fast type checker for Python.", "fast", "underlined"))
print(with_style("ty is a fast type checker for Python.", "fast", "underlined"))
`;
const DEFAULT_WORKSPACE = {
files: {
"main.py": DEFAULT_PROGRAM,
"knot.json": DEFAULT_SETTINGS,
"ty.json": DEFAULT_SETTINGS,
},
current: "main.py",
};
@ -268,7 +268,7 @@ interface FilesState {
* The database file handles by file id.
*
* Files without a file handle are well-known files that are only handled by the
* playground (e.g. knot.json)
* playground (e.g. ty.json)
*/
handles: Readonly<{ [id: FileId]: FileHandle | null }>;
@ -451,14 +451,14 @@ export interface InitializedPlayground {
// Run once during startup. Initializes monaco, loads the wasm file, and restores the previous editor state.
async function startPlayground(): Promise<InitializedPlayground> {
const red_knot = await import("../red_knot_wasm");
await red_knot.default();
const ty = await import("../ty_wasm");
await ty.default();
const monaco = await loader.init();
setupMonaco(monaco, {
uri: "https://raw.githubusercontent.com/astral-sh/ruff/main/knot.schema.json",
fileMatch: ["knot.json"],
schema: knotSchema,
uri: "https://raw.githubusercontent.com/astral-sh/ruff/main/ty.schema.json",
fileMatch: ["ty.json"],
schema: tySchema,
});
const restored = await restore();
@ -483,7 +483,7 @@ function updateOptions(
workspace?.updateOptions(settings);
setError(null);
} catch (error) {
setError(`Failed to update 'knot.json' options: ${formatError(error)}`);
setError(`Failed to update 'ty.json' options: ${formatError(error)}`);
}
}
@ -520,8 +520,17 @@ function restoreWorkspace(
) {
let hasSettings = false;
for (const [name, content] of Object.entries(state.files)) {
// eslint-disable-next-line prefer-const
for (let [name, content] of Object.entries(state.files)) {
let handle = null;
if (
name === "knot.json" &&
!Object.keys(state.files).includes(SETTINGS_FILE_NAME)
) {
name = SETTINGS_FILE_NAME;
}
if (name === SETTINGS_FILE_NAME) {
updateOptions(workspace, content, setError);
hasSettings = true;
@ -536,8 +545,11 @@ function restoreWorkspace(
updateOptions(workspace, null, setError);
}
const selected =
state.current === "knot.json" ? SETTINGS_FILE_NAME : state.current;
dispatchFiles({
type: "selectFileByName",
name: state.current,
name: selected,
});
}