diff --git a/package-lock.json b/package-lock.json index 98679a65d..a5f3d3110 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,80 +10,25 @@ "license": "MIT", "dependencies": { "commander": "^10.0.0", + "reflect-metadata": "^0.1.13", "source-map-support": "^0.5.21", "tslib": "^2.5.0", "yagl": "^0.5.1" }, "bin": { - "bolt": "lib/bin/bolt.js" + "bolt": "lib/bin/bolt.js", + "bolt-self": "lib/bin/bolt-self.js" }, "devDependencies": { - "@types/commonmark": "^0.27.6", - "@types/glob": "^8.1.0", - "@types/node": "^18.15.11", - "@types/yargs": "^17.0.24", - "commonmark": "^0.30.0", - "glob": "^10.0.0" + "@types/node": "^18.15.11" } }, - "node_modules/@types/commonmark": { - "version": "0.27.6", - "resolved": "https://registry.npmjs.org/@types/commonmark/-/commonmark-0.27.6.tgz", - "integrity": "sha512-t3S2hOtSSuBp1H5PTFmekGFu9U9LBzGvHy93zHwusvj4RIGUrBQ4zHvw49CkJtAl6fZvsadKhYbv8WTxJLbBmw==", - "dev": true - }, - "node_modules/@types/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", - "dev": true, - "dependencies": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, "node_modules/@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "dev": true }, - "node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -97,114 +42,10 @@ "node": ">=14" } }, - "node_modules/commonmark": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.30.0.tgz", - "integrity": "sha512-j1yoUo4gxPND1JWV9xj5ELih0yMv1iCWDG6eEQIPLSWLxzCXiFoyS7kvB+WwU+tZMf4snwJMMtaubV0laFpiBA==", - "dev": true, - "dependencies": { - "entities": "~2.0", - "mdurl": "~1.0.1", - "minimist": ">=1.2.2", - "string.prototype.repeat": "^0.2.0" - }, - "bin": { - "commonmark": "bin/commonmark" - }, - "engines": { - "node": "*" - } - }, - "node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/glob": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz", - "integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^9.0.0", - "minipass": "^5.0.0", - "path-scurry": "^1.6.4" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/lru-cache": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz", - "integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", - "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", - "dev": true, - "dependencies": { - "lru-cache": "^9.0.0", - "minipass": "^5.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "node_modules/source-map": { "version": "0.6.1", @@ -223,12 +64,6 @@ "source-map": "^0.6.0" } }, - "node_modules/string.prototype.repeat": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", - "integrity": "sha512-1BH+X+1hSthZFW+X+JaUkjkkUPwIlLEMJBLANN3hOob3RhEk5snLWNECDnYbgn/m5c5JV7Ersu1Yubaf+05cIA==", - "dev": true - }, "node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", @@ -241,64 +76,12 @@ } }, "dependencies": { - "@types/commonmark": { - "version": "0.27.6", - "resolved": "https://registry.npmjs.org/@types/commonmark/-/commonmark-0.27.6.tgz", - "integrity": "sha512-t3S2hOtSSuBp1H5PTFmekGFu9U9LBzGvHy93zHwusvj4RIGUrBQ4zHvw49CkJtAl6fZvsadKhYbv8WTxJLbBmw==", - "dev": true - }, - "@types/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", - "dev": true, - "requires": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, "@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "dev": true }, - "@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -309,84 +92,10 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.0.tgz", "integrity": "sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==" }, - "commonmark": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.30.0.tgz", - "integrity": "sha512-j1yoUo4gxPND1JWV9xj5ELih0yMv1iCWDG6eEQIPLSWLxzCXiFoyS7kvB+WwU+tZMf4snwJMMtaubV0laFpiBA==", - "dev": true, - "requires": { - "entities": "~2.0", - "mdurl": "~1.0.1", - "minimist": ">=1.2.2", - "string.prototype.repeat": "^0.2.0" - } - }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "glob": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz", - "integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "minimatch": "^9.0.0", - "minipass": "^5.0.0", - "path-scurry": "^1.6.4" - } - }, - "lru-cache": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz", - "integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==", - "dev": true - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true - }, - "path-scurry": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", - "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", - "dev": true, - "requires": { - "lru-cache": "^9.0.0", - "minipass": "^5.0.0" - } + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "source-map": { "version": "0.6.1", @@ -402,12 +111,6 @@ "source-map": "^0.6.0" } }, - "string.prototype.repeat": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", - "integrity": "sha512-1BH+X+1hSthZFW+X+JaUkjkkUPwIlLEMJBLANN3hOob3RhEk5snLWNECDnYbgn/m5c5JV7Ersu1Yubaf+05cIA==", - "dev": true - }, "tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", diff --git a/package.json b/package.json index 7b55a400c..39dc94d7f 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,11 @@ "description": "A new programming language for the web", "main": "lib/index.js", "bin": { - "bolt": "lib/bin/bolt.js" + "bolt": "lib/bin/bolt.js", + "bolt-self": "lib/bin/bolt-self.js" }, "scripts": { - "test": "node ./lib/bin/bolt-selftest.js run" + "test": "node ./lib/bin/bolt-self.js check" }, "repository": { "type": "git", @@ -23,16 +24,12 @@ "license": "MIT", "dependencies": { "commander": "^10.0.0", + "reflect-metadata": "^0.1.13", "source-map-support": "^0.5.21", "tslib": "^2.5.0", "yagl": "^0.5.1" }, "devDependencies": { - "@types/commonmark": "^0.27.6", - "@types/glob": "^8.1.0", - "@types/node": "^18.15.11", - "@types/yargs": "^17.0.24", - "commonmark": "^0.30.0", - "glob": "^10.0.0" + "@types/node": "^18.15.11" } } diff --git a/src/bin/bolt-selftest.ts b/src/bin/bolt-selftest.ts deleted file mode 100644 index 6f205356c..000000000 --- a/src/bin/bolt-selftest.ts +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env node - -import "source-map-support/register" - -import * as commonmark from "commonmark" -import { sync as globSync } from "glob" -import fs from "fs"; -import path from "path"; -import { Checker } from "../checker"; -import { TextFile } from "../cst"; -import { ConsoleDiagnostics } from "../diagnostics"; -import { parseSourceFile } from ".."; -import { Analyser } from "../analysis"; -import { Command } from "commander"; - -const projectDir = path.resolve(__dirname, '..', '..'); - -interface Test { - code: string; -} - -const program = new Command() - .name('bolt-selftest'); - -program - .command('run') - .option('-t', '--tag', 'Tag to add to test results') - .action(async (args) => { - for await (const test of loadTests()) { - console.log('--------'); - console.log(test.code); - const diagnostics = new ConsoleDiagnostics(); - const file = new TextFile("#", test.code); - let sourceFile = parseSourceFile(file, diagnostics); - if (sourceFile !== null) { - sourceFile.setParents(); - const analyser = new Analyser(); - analyser.addSourceFile(sourceFile); - const checker = new Checker(analyser, diagnostics); - checker.check(sourceFile); - } - } - }); - -program.parse(); - -async function* loadTests(): AsyncIterable { - for (const filename of globSync(path.join(projectDir, 'src', 'test', '**', '*.md'))) { - const text = await fs.promises.readFile(filename, 'utf-8'); - const reader = new commonmark.Parser(); - const root = reader.parse(text); - let child = root.firstChild; - while (child !== null) { - if (child.type === 'code_block') { - yield { code: child.literal! }; - } - child = child.next; - } - } -} - diff --git a/src/checker.ts b/src/checker.ts index a15f07049..5d34b52e3 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -34,9 +34,10 @@ import { TypeclassNotFoundDiagnostic, TypeclassDeclaredTwiceDiagnostic, } from "./diagnostics"; -import { assert, assertNever, first, isEmpty, last, MultiMap, toStringTag, InspectFn } from "./util"; +import { assert, assertNever, first, isEmpty, last, MultiMap, toStringTag, InspectFn, JSONValue, ignore, deserializable } from "./util"; import { Analyser } from "./analysis"; import { InspectOptions } from "util"; +import { deserialize } from "v8"; const MAX_TYPE_ERROR_COUNT = 5; @@ -55,15 +56,13 @@ export enum TypeKind { abstract class TypeBase { + @ignore public abstract readonly kind: TypeKind; + @ignore public next: Type = this as any; - public constructor( - public node: Syntax | null = null - ) { - - } + public abstract node: Syntax | null; public static join(a: Type, b: Type): void { const keep = a.next; @@ -90,10 +89,18 @@ abstract class TypeBase { } +export function isType(value: any): value is Type { + return value !== undefined + && value !== null + && value instanceof TypeBase; +} + +@deserializable() class TVar extends TypeBase { public readonly kind = TypeKind.Var; + @ignore public context = new Set(); public constructor( @@ -127,6 +134,12 @@ export class TNil extends TypeBase { public readonly kind = TypeKind.Nil; + public constructor( + public node: Syntax | null = null + ) { + super(); + } + public substitute(_sub: TVSub): Type { return this; } @@ -145,10 +158,17 @@ export class TNil extends TypeBase { } +@deserializable() export class TAbsent extends TypeBase { public readonly kind = TypeKind.Absent; + public constructor( + public node: Syntax | null = null, + ) { + super(); + } + public substitute(_sub: TVSub): Type { return this; } @@ -167,15 +187,16 @@ export class TAbsent extends TypeBase { } +@deserializable() export class TPresent extends TypeBase { public readonly kind = TypeKind.Present; public constructor( public type: Type, - node: Syntax | null = null, + public node: Syntax | null = null, ) { - super(node); + super(); } public substitute(sub: TVSub): Type { @@ -196,6 +217,7 @@ export class TPresent extends TypeBase { } +@deserializable() export class TArrow extends TypeBase { public readonly kind = TypeKind.Arrow; @@ -203,9 +225,9 @@ export class TArrow extends TypeBase { public constructor( public paramType: Type, public returnType: Type, - node: Syntax | null = null, + public node: Syntax | null = null, ) { - super(node); + super(); } public static build(paramTypes: Type[], returnType: Type, node: Syntax | null = null): Type { @@ -248,6 +270,7 @@ export class TArrow extends TypeBase { } +@deserializable() export class TCon extends TypeBase { public readonly kind = TypeKind.Con; @@ -258,7 +281,7 @@ export class TCon extends TypeBase { public displayName: string, public node: Syntax | null = null, ) { - super(node); + super(); } public *getTypeVars(): Iterable { @@ -295,6 +318,7 @@ export class TCon extends TypeBase { } +@deserializable() class TTuple extends TypeBase { public readonly kind = TypeKind.Tuple; @@ -303,7 +327,7 @@ class TTuple extends TypeBase { public elementTypes: Type[], public node: Syntax | null = null, ) { - super(node); + super(); } public *getTypeVars(): Iterable { @@ -338,6 +362,7 @@ class TTuple extends TypeBase { } +@deserializable() export class TField extends TypeBase { public readonly kind = TypeKind.Field; @@ -348,7 +373,7 @@ export class TField extends TypeBase { public restType: Type, public node: Syntax | null = null, ) { - super(node); + super(); } public getTypeVars(): Iterable { @@ -401,6 +426,7 @@ export class TField extends TypeBase { } +@deserializable() export class TApp extends TypeBase { public readonly kind = TypeKind.App; @@ -410,7 +436,7 @@ export class TApp extends TypeBase { public right: Type, public node: Syntax | null = null ) { - super(node); + super(); } public static build(resultType: Type, types: Type[], node: Syntax | null = null): Type { @@ -452,6 +478,7 @@ export class TApp extends TypeBase { } +@deserializable() export class TNominal extends TypeBase { public readonly kind = TypeKind.Nominal; @@ -460,7 +487,7 @@ export class TNominal extends TypeBase { public decl: StructDeclaration | EnumDeclaration, public node: Syntax | null = null, ) { - super(node); + super(); } public *getTypeVars(): Iterable { diff --git a/src/cst.ts b/src/cst.ts index 9e9a57aa1..dddbfbbe0 100644 --- a/src/cst.ts +++ b/src/cst.ts @@ -2,7 +2,7 @@ import type stream from "stream"; import path from "path" -import { assert, implementationLimitation, IndentWriter, JSONObject, JSONValue, unreachable } from "./util"; +import { assert, deserializable, implementationLimitation, IndentWriter, JSONObject, JSONValue, nonenumerable, unreachable } from "./util"; import { isNodeWithScope, Scope } from "./scope" import { InferContext, Kind, KindEnv, Scheme, Type, TypeEnv } from "./checker" import { Emitter } from "./emitter"; @@ -13,6 +13,7 @@ export type Value = bigint | string +@deserializable() export class TextPosition { public constructor( @@ -45,6 +46,7 @@ export class TextPosition { } +@deserializable() export class TextRange { constructor( @@ -63,6 +65,7 @@ export class TextRange { } +@deserializable() export class TextFile { public constructor( @@ -229,15 +232,21 @@ export type Syntax | StructExpressionElement | StructPatternElement -function isIgnoredProperty(key: string): boolean { +function isnonenumerabledProperty(key: string): boolean { return key === 'kind' || key === 'parent'; } abstract class SyntaxBase { + @nonenumerable + public abstract readonly kind: SyntaxKind; + + @nonenumerable public parent: Syntax | null = null; + @nonenumerable public inferredKind?: Kind; + @nonenumerable public inferredType?: Type; public abstract getFirstToken(): Token; @@ -307,7 +316,7 @@ abstract class SyntaxBase { } for (const key of Object.getOwnPropertyNames(this)) { - if (isIgnoredProperty(key)) { + if (isnonenumerabledProperty(key)) { continue; } visit((this as any)[key]); @@ -334,7 +343,7 @@ abstract class SyntaxBase { public *getFields(): Iterable<[string, any]> { for (const key of Object.getOwnPropertyNames(this)) { - if (!isIgnoredProperty(key)) { + if (!isnonenumerabledProperty(key)) { yield [key, (this as any)[key]]; } } @@ -368,7 +377,7 @@ abstract class SyntaxBase { const obj: JSONObject = {}; obj['type'] = this.constructor.name; for (const [key, value] of this.getFields()) { - if (isIgnoredProperty(key)) { + if (isnonenumerabledProperty(key)) { continue; } obj[key] = encode(value); @@ -417,7 +426,7 @@ abstract class SyntaxBase { export function forEachChild(node: Syntax, callback: (node: Syntax) => void): void { for (const key of Object.getOwnPropertyNames(node)) { - if (isIgnoredProperty(key)) { + if (isnonenumerabledProperty(key)) { continue; } visitField((node as any)[key]); @@ -442,6 +451,7 @@ export function forEachChild(node: Syntax, callback: (node: Syntax) => void): vo abstract class TokenBase extends SyntaxBase { + @nonenumerable private endPos: TextPosition | null = null; public constructor( @@ -505,6 +515,7 @@ abstract class VirtualTokenBase extends TokenBase { } } +@deserializable() export class EndOfFile extends VirtualTokenBase { public readonly kind = SyntaxKind.EndOfFile; @@ -515,6 +526,7 @@ export class EndOfFile extends VirtualTokenBase { } +@deserializable() export class BlockEnd extends VirtualTokenBase { public readonly kind = SyntaxKind.BlockEnd; @@ -525,6 +537,7 @@ export class BlockEnd extends VirtualTokenBase { } +@deserializable() export class BlockStart extends VirtualTokenBase { public readonly kind = SyntaxKind.BlockStart; @@ -535,6 +548,7 @@ export class BlockStart extends VirtualTokenBase { } +@deserializable() export class LineFoldEnd extends VirtualTokenBase { public readonly kind = SyntaxKind.LineFoldEnd; @@ -545,14 +559,15 @@ export class LineFoldEnd extends VirtualTokenBase { } +@deserializable() export class Integer extends TokenBase { public readonly kind = SyntaxKind.Integer; public constructor( + startPos: TextPosition | null = null, public value: bigint, public radix: number, - startPos: TextPosition | null = null, ) { super(startPos); } @@ -563,9 +578,9 @@ export class Integer extends TokenBase { public clone(): Integer { return new Integer( + this.startPos, this.value, this.radix, - this.startPos ); } @@ -586,13 +601,14 @@ export class Integer extends TokenBase { } +@deserializable() export class StringLiteral extends TokenBase { public readonly kind = SyntaxKind.StringLiteral; public constructor( - public contents: string, startPos: TextPosition | null = null, + public contents: string, ) { super(startPos); } @@ -603,8 +619,8 @@ export class StringLiteral extends TokenBase { public clone(): StringLiteral { return new StringLiteral( + this.startPos, this.contents, - this.startPos ); } @@ -626,61 +642,64 @@ export class StringLiteral extends TokenBase { } +@deserializable() export class IdentifierAlt extends TokenBase { public readonly kind = SyntaxKind.IdentifierAlt; public constructor( - public text: string, startPos: TextPosition | null = null, + public text: string, ) { super(startPos); } public clone(): IdentifierAlt { return new IdentifierAlt( + this.startPos, this.text, - this.startPos ); } } +@deserializable() export class Identifier extends TokenBase { public readonly kind = SyntaxKind.Identifier; public constructor( - public text: string, startPos: TextPosition | null = null, + public text: string, ) { super(startPos); } public clone(): Identifier { return new Identifier( + this.startPos, this.text, - this.startPos ); } } +@deserializable() export class CustomOperator extends TokenBase { public readonly kind = SyntaxKind.CustomOperator; public constructor( - public text: string, startPos: TextPosition | null = null, + public text: string, ) { super(startPos); } public clone(): CustomOperator { return new CustomOperator( - this.text, this.startPos, + this.text, ); } @@ -695,26 +714,28 @@ export function isExprOperator(node: Syntax): node is ExprOperator { || node.kind === SyntaxKind.VBar } +@deserializable() export class Assignment extends TokenBase { public readonly kind = SyntaxKind.Assignment; public constructor( - public text: string, startPos: TextPosition | null = null, + public text: string, ) { super(startPos); } public clone(): Assignment { return new Assignment( + this.startPos, this.text, - this.startPos ); } } +@deserializable() export class LParen extends TokenBase { public readonly kind = SyntaxKind.LParen; @@ -729,6 +750,7 @@ export class LParen extends TokenBase { } +@deserializable() export class RParen extends TokenBase { public readonly kind = SyntaxKind.RParen; @@ -743,6 +765,7 @@ export class RParen extends TokenBase { } +@deserializable() export class LBrace extends TokenBase { public readonly kind = SyntaxKind.LBrace; @@ -757,6 +780,7 @@ export class LBrace extends TokenBase { } +@deserializable() export class RBrace extends TokenBase { public readonly kind = SyntaxKind.RBrace; @@ -771,6 +795,7 @@ export class RBrace extends TokenBase { } +@deserializable() export class LBracket extends TokenBase { public readonly kind = SyntaxKind.LBracket; @@ -785,6 +810,7 @@ export class LBracket extends TokenBase { } +@deserializable() export class RBracket extends TokenBase { public readonly kind = SyntaxKind.RBracket; @@ -799,6 +825,7 @@ export class RBracket extends TokenBase { } +@deserializable() export class Dot extends TokenBase { public readonly kind = SyntaxKind.Dot; @@ -813,6 +840,7 @@ export class Dot extends TokenBase { } +@deserializable() export class Comma extends TokenBase { public readonly kind = SyntaxKind.Comma; @@ -827,6 +855,7 @@ export class Comma extends TokenBase { } +@deserializable() export class DotDot extends TokenBase { public readonly kind = SyntaxKind.DotDot; @@ -841,6 +870,7 @@ export class DotDot extends TokenBase { } +@deserializable() export class Colon extends TokenBase { public readonly kind = SyntaxKind.Colon; @@ -855,6 +885,7 @@ export class Colon extends TokenBase { } +@deserializable() export class Equals extends TokenBase { public readonly kind = SyntaxKind.Equals; @@ -869,6 +900,7 @@ export class Equals extends TokenBase { } +@deserializable() export class Backslash extends TokenBase { public readonly kind = SyntaxKind.Equals; @@ -883,6 +915,7 @@ export class Backslash extends TokenBase { } +@deserializable() export class IfKeyword extends TokenBase { public readonly kind = SyntaxKind.IfKeyword; @@ -897,6 +930,7 @@ export class IfKeyword extends TokenBase { } +@deserializable() export class ElseKeyword extends TokenBase { public readonly kind = SyntaxKind.ElseKeyword; @@ -911,6 +945,7 @@ export class ElseKeyword extends TokenBase { } +@deserializable() export class ElifKeyword extends TokenBase { public readonly kind = SyntaxKind.ElifKeyword; @@ -925,6 +960,7 @@ export class ElifKeyword extends TokenBase { } +@deserializable() export class StructKeyword extends TokenBase { public readonly kind = SyntaxKind.StructKeyword; @@ -939,6 +975,7 @@ export class StructKeyword extends TokenBase { } +@deserializable() export class EnumKeyword extends TokenBase { public readonly kind = SyntaxKind.EnumKeyword; @@ -953,6 +990,7 @@ export class EnumKeyword extends TokenBase { } +@deserializable() export class ReturnKeyword extends TokenBase { public readonly kind = SyntaxKind.ReturnKeyword; @@ -967,6 +1005,7 @@ export class ReturnKeyword extends TokenBase { } +@deserializable() export class MatchKeyword extends TokenBase { public readonly kind = SyntaxKind.MatchKeyword; @@ -981,6 +1020,7 @@ export class MatchKeyword extends TokenBase { } +@deserializable() export class ForeignKeyword extends TokenBase { public readonly kind = SyntaxKind.ForeignKeyword; @@ -995,6 +1035,7 @@ export class ForeignKeyword extends TokenBase { } +@deserializable() export class ModKeyword extends TokenBase { public readonly kind = SyntaxKind.ModKeyword; @@ -1009,6 +1050,7 @@ export class ModKeyword extends TokenBase { } +@deserializable() export class MutKeyword extends TokenBase { public readonly kind = SyntaxKind.MutKeyword; @@ -1023,6 +1065,7 @@ export class MutKeyword extends TokenBase { } +@deserializable() export class ImportKeyword extends TokenBase { public readonly kind = SyntaxKind.ImportKeyword; @@ -1037,6 +1080,7 @@ export class ImportKeyword extends TokenBase { } +@deserializable() export class ClassKeyword extends TokenBase { public readonly kind = SyntaxKind.ClassKeyword; @@ -1051,6 +1095,7 @@ export class ClassKeyword extends TokenBase { } +@deserializable() export class InstanceKeyword extends TokenBase { public readonly kind = SyntaxKind.InstanceKeyword; @@ -1066,6 +1111,7 @@ export class InstanceKeyword extends TokenBase { } +@deserializable() export class TypeKeyword extends TokenBase { public readonly kind = SyntaxKind.TypeKeyword; @@ -1080,6 +1126,7 @@ export class TypeKeyword extends TokenBase { } +@deserializable() export class PubKeyword extends TokenBase { public readonly kind = SyntaxKind.PubKeyword; @@ -1094,6 +1141,7 @@ export class PubKeyword extends TokenBase { } +@deserializable() export class LetKeyword extends TokenBase { public readonly kind = SyntaxKind.LetKeyword; @@ -1108,6 +1156,7 @@ export class LetKeyword extends TokenBase { } +@deserializable() export class RArrow extends TokenBase { public readonly kind = SyntaxKind.RArrow; @@ -1122,6 +1171,7 @@ export class RArrow extends TokenBase { } +@deserializable() export class RArrowAlt extends TokenBase { public readonly kind = SyntaxKind.RArrowAlt; @@ -1136,6 +1186,7 @@ export class RArrowAlt extends TokenBase { } +@deserializable() export class VBar extends TokenBase { public readonly kind = SyntaxKind.VBar; @@ -1196,6 +1247,7 @@ export type Token export type TokenKind = Token['kind'] +@deserializable() export class ArrowTypeExpression extends SyntaxBase { public readonly kind = SyntaxKind.ArrowTypeExpression; @@ -1227,6 +1279,7 @@ export class ArrowTypeExpression extends SyntaxBase { } +@deserializable() export class TupleTypeExpression extends SyntaxBase { public readonly kind = SyntaxKind.TupleTypeExpression; @@ -1257,6 +1310,7 @@ export class TupleTypeExpression extends SyntaxBase { } +@deserializable() export class ReferenceTypeExpression extends SyntaxBase { public readonly kind = SyntaxKind.ReferenceTypeExpression; @@ -1288,6 +1342,7 @@ export class ReferenceTypeExpression extends SyntaxBase { } +@deserializable() export class AppTypeExpression extends SyntaxBase { public readonly kind = SyntaxKind.AppTypeExpression; @@ -1319,6 +1374,7 @@ export class AppTypeExpression extends SyntaxBase { } +@deserializable() export class VarTypeExpression extends SyntaxBase { public readonly kind = SyntaxKind.VarTypeExpression; @@ -1343,6 +1399,7 @@ export class VarTypeExpression extends SyntaxBase { } +@deserializable() export class NestedTypeExpression extends SyntaxBase { public readonly kind = SyntaxKind.NestedTypeExpression; @@ -1381,6 +1438,7 @@ export type TypeExpression | NestedTypeExpression | TupleTypeExpression +@deserializable() export class NamedPattern extends SyntaxBase { public readonly kind = SyntaxKind.NamedPattern; @@ -1409,6 +1467,7 @@ export class NamedPattern extends SyntaxBase { } +@deserializable() export class TuplePattern extends SyntaxBase { public readonly kind = SyntaxKind.TuplePattern; @@ -1439,6 +1498,7 @@ export class TuplePattern extends SyntaxBase { } +@deserializable() export class NamedTuplePattern extends SyntaxBase { public readonly kind = SyntaxKind.NamedTuplePattern; @@ -1470,6 +1530,7 @@ export class NamedTuplePattern extends SyntaxBase { } +@deserializable() export class StructPatternField extends SyntaxBase { public readonly kind = SyntaxKind.StructPatternField; @@ -1500,6 +1561,7 @@ export class StructPatternField extends SyntaxBase { } +@deserializable() export class VariadicStructPatternElement extends SyntaxBase { public readonly kind = SyntaxKind.VariadicStructPatternElement; @@ -1531,6 +1593,7 @@ export class VariadicStructPatternElement extends SyntaxBase { } +@deserializable() export class PunnedStructPatternField extends SyntaxBase { public readonly kind = SyntaxKind.PunnedStructPatternField; @@ -1560,6 +1623,7 @@ export type StructPatternElement | PunnedStructPatternField | StructPatternField +@deserializable() export class StructPattern extends SyntaxBase { public readonly kind = SyntaxKind.StructPattern; @@ -1590,6 +1654,7 @@ export class StructPattern extends SyntaxBase { } +@deserializable() export class NestedPattern extends SyntaxBase { public readonly kind = SyntaxKind.NestedPattern; @@ -1620,6 +1685,7 @@ export class NestedPattern extends SyntaxBase { } +@deserializable() export class DisjunctivePattern extends SyntaxBase { public readonly kind = SyntaxKind.DisjunctivePattern; @@ -1651,6 +1717,7 @@ export class DisjunctivePattern extends SyntaxBase { } +@deserializable() export class LiteralPattern extends SyntaxBase { public readonly kind = SyntaxKind.LiteralPattern; @@ -1684,6 +1751,7 @@ export type Pattern | DisjunctivePattern | LiteralPattern +@deserializable() export class TupleExpression extends SyntaxBase { public readonly kind = SyntaxKind.TupleExpression; @@ -1714,6 +1782,7 @@ export class TupleExpression extends SyntaxBase { } +@deserializable() export class NestedExpression extends SyntaxBase { public readonly kind = SyntaxKind.NestedExpression; @@ -1744,6 +1813,7 @@ export class NestedExpression extends SyntaxBase { } +@deserializable() export class ConstantExpression extends SyntaxBase { public readonly kind = SyntaxKind.ConstantExpression; @@ -1768,6 +1838,7 @@ export class ConstantExpression extends SyntaxBase { } +@deserializable() export class CallExpression extends SyntaxBase { public readonly kind = SyntaxKind.CallExpression; @@ -1799,6 +1870,7 @@ export class CallExpression extends SyntaxBase { } +@deserializable() export class StructExpressionField extends SyntaxBase { public readonly kind = SyntaxKind.StructExpressionField; @@ -1829,6 +1901,7 @@ export class StructExpressionField extends SyntaxBase { } +@deserializable() export class PunnedStructExpressionField extends SyntaxBase { public readonly kind = SyntaxKind.PunnedStructExpressionField; @@ -1857,6 +1930,7 @@ export type StructExpressionElement = StructExpressionField | PunnedStructExpressionField; +@deserializable() export class StructExpression extends SyntaxBase { public readonly kind = SyntaxKind.StructExpression; @@ -1887,6 +1961,7 @@ export class StructExpression extends SyntaxBase { } +@deserializable() export class MatchArm extends SyntaxBase { public readonly kind = SyntaxKind.MatchArm; @@ -1917,6 +1992,7 @@ export class MatchArm extends SyntaxBase { } +@deserializable() export class FunctionExpression extends SyntaxBase { public readonly kind = SyntaxKind.FunctionExpression; @@ -1948,6 +2024,7 @@ export class FunctionExpression extends SyntaxBase { } +@deserializable() export class MatchExpression extends SyntaxBase { public readonly kind = SyntaxKind.MatchExpression; @@ -1984,6 +2061,7 @@ export class MatchExpression extends SyntaxBase { } +@deserializable() export class ReferenceExpression extends SyntaxBase { public readonly kind = SyntaxKind.ReferenceExpression; @@ -2015,6 +2093,7 @@ export class ReferenceExpression extends SyntaxBase { } +@deserializable() export class MemberExpression extends SyntaxBase { public readonly kind = SyntaxKind.MemberExpression; @@ -2043,6 +2122,7 @@ export class MemberExpression extends SyntaxBase { } +@deserializable() export class PrefixExpression extends SyntaxBase { public readonly kind = SyntaxKind.PrefixExpression; @@ -2071,6 +2151,7 @@ export class PrefixExpression extends SyntaxBase { } +@deserializable() export class PostfixExpression extends SyntaxBase { public readonly kind = SyntaxKind.PostfixExpression; @@ -2099,6 +2180,7 @@ export class PostfixExpression extends SyntaxBase { } +@deserializable() export class InfixExpression extends SyntaxBase { public readonly kind = SyntaxKind.InfixExpression; @@ -2143,6 +2225,7 @@ export type Expression | PostfixExpression | FunctionExpression +@deserializable() export class IfStatementCase extends SyntaxBase { public readonly kind = SyntaxKind.IfStatementCase; @@ -2178,6 +2261,7 @@ export class IfStatementCase extends SyntaxBase { } +@deserializable() export class IfStatement extends SyntaxBase { public readonly kind = SyntaxKind.IfStatement; @@ -2204,6 +2288,7 @@ export class IfStatement extends SyntaxBase { } +@deserializable() export class ReturnStatement extends SyntaxBase { public readonly kind = SyntaxKind.ReturnStatement; @@ -2235,6 +2320,7 @@ export class ReturnStatement extends SyntaxBase { } +@deserializable() export class AssignStatement extends SyntaxBase { public readonly kind = SyntaxKind.AssignStatement; @@ -2265,6 +2351,7 @@ export class AssignStatement extends SyntaxBase { } +@deserializable() export class ExpressionStatement extends SyntaxBase { public readonly kind = SyntaxKind.ExpressionStatement; @@ -2295,6 +2382,7 @@ export type Statement | IfStatement | AssignStatement +@deserializable() export class Param extends SyntaxBase { public readonly kind = SyntaxKind.Param; @@ -2321,6 +2409,7 @@ export class Param extends SyntaxBase { } +@deserializable() export class EnumDeclarationStructElement extends SyntaxBase { public readonly kind = SyntaxKind.EnumDeclarationStructElement; @@ -2356,6 +2445,7 @@ export class EnumDeclarationStructElement extends SyntaxBase { } +@deserializable() export class EnumDeclarationTupleElement extends SyntaxBase { public readonly kind = SyntaxKind.EnumDeclarationTupleElement; @@ -2391,10 +2481,12 @@ export type EnumDeclarationElement = EnumDeclarationStructElement | EnumDeclarationTupleElement +@deserializable() export class EnumDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.EnumDeclaration; + @nonenumerable public typeEnv?: TypeEnv; public constructor( @@ -2433,6 +2525,7 @@ export class EnumDeclaration extends SyntaxBase { } +@deserializable() export class StructDeclarationField extends SyntaxBase { public readonly kind = SyntaxKind.StructDeclarationField; @@ -2463,10 +2556,12 @@ export class StructDeclarationField extends SyntaxBase { } +@deserializable() export class StructDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.StructDeclaration; + @nonenumerable public typeEnv?: TypeEnv; public constructor( @@ -2505,6 +2600,7 @@ export class StructDeclaration extends SyntaxBase { } +@deserializable() export class TypeAssert extends SyntaxBase { public readonly kind = SyntaxKind.TypeAssert; @@ -2537,6 +2633,7 @@ export type Body = ExprBody | BlockBody +@deserializable() export class ExprBody extends SyntaxBase { public readonly kind = SyntaxKind.ExprBody; @@ -2569,6 +2666,7 @@ export type LetBodyElement = LetDeclaration | Statement +@deserializable() export class BlockBody extends SyntaxBase { public readonly kind = SyntaxKind.BlockBody; @@ -2600,6 +2698,7 @@ export class BlockBody extends SyntaxBase { } +@deserializable() export class WrappedOperator extends SyntaxBase { public readonly kind = SyntaxKind.WrappedOperator; @@ -2630,10 +2729,12 @@ export class WrappedOperator extends SyntaxBase { } +@deserializable() export class TypeDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.TypeDeclaration; + @nonenumerable public typeEnv?: TypeEnv; public constructor( @@ -2671,14 +2772,21 @@ export class TypeDeclaration extends SyntaxBase { } +@deserializable() export class LetDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.LetDeclaration; + @nonenumerable public scope?: Scope; + + @nonenumerable public typeEnv?: TypeEnv; + @nonenumerable public activeCycle?: boolean; + + @nonenumerable public context?: InferContext; public constructor( @@ -2741,6 +2849,7 @@ export class LetDeclaration extends SyntaxBase { } +@deserializable() export class ImportDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.ImportDeclaration; @@ -2776,6 +2885,7 @@ export type Declaration | EnumDeclaration | TypeDeclaration +@deserializable() export class Initializer extends SyntaxBase { public readonly kind = SyntaxKind.Initializer; @@ -2804,6 +2914,7 @@ export class Initializer extends SyntaxBase { } +@deserializable() export class ClassConstraint extends SyntaxBase { public readonly kind = SyntaxKind.ClassConstraint; @@ -2832,6 +2943,7 @@ export class ClassConstraint extends SyntaxBase { } +@deserializable() export class ClassConstraintClause extends SyntaxBase { public readonly kind = SyntaxKind.ClassConstraintClause; @@ -2867,10 +2979,12 @@ export type ClassDeclarationElement = LetDeclaration | TypeDeclaration +@deserializable() export class ClassDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.ClassDeclaration; + @nonenumerable public typeEnv?: TypeEnv; public constructor( @@ -2970,10 +3084,12 @@ export type InstanceDeclarationElement = LetDeclaration | TypeDeclaration +@deserializable() export class InstanceDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.InstanceDeclaration; + @nonenumerable public typeEnv?: TypeEnv; public constructor( @@ -3016,11 +3132,14 @@ export class InstanceDeclaration extends SyntaxBase { } } +@deserializable() export class ModuleDeclaration extends SyntaxBase { public readonly kind = SyntaxKind.ModuleDeclaration; + @nonenumerable public typeEnv?: TypeEnv; + @nonenumerable public kindEnv?: KindEnv; public constructor( @@ -3066,12 +3185,16 @@ export type SourceFileElement | InstanceDeclaration | ModuleDeclaration +@deserializable() export class SourceFile extends SyntaxBase { public readonly kind = SyntaxKind.SourceFile; + @nonenumerable public scope?: Scope; + @nonenumerable public typeEnv?: TypeEnv; + @nonenumerable public kindEnv?: KindEnv; public constructor( diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 3824e3c18..744720d1b 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -1,7 +1,7 @@ import { TypeKind, type Type, Kind, KindType } from "./checker"; import { ClassConstraint, ClassDeclaration, IdentifierAlt, InstanceDeclaration, Syntax, SyntaxKind, TextFile, TextPosition, TextRange, Token } from "./cst"; -import { assertNever, countDigits, IndentWriter } from "./util"; +import { assertNever, countDigits, deserializable, IndentWriter } from "./util"; const ANSI_RESET = "\u001b[0m" const ANSI_BOLD = "\u001b[1m" @@ -47,12 +47,16 @@ const enum DiagnosticKind { FieldNotFound, } -interface DiagnosticBase { - level: Level; - readonly kind: DiagnosticKind; +abstract class DiagnosticBase { + + public abstract readonly kind: DiagnosticKind; + + public abstract level: Level; + } -export class UnexpectedCharDiagnostic implements DiagnosticBase { +@deserializable() +export class UnexpectedCharDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.UnexpectedChar; @@ -63,13 +67,14 @@ export class UnexpectedCharDiagnostic implements DiagnosticBase { public position: TextPosition, public actual: string, ) { - + super(); } } -export class UnexpectedTokenDiagnostic implements DiagnosticBase { +@deserializable() +export class UnexpectedTokenDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.UnexpectedToken; @@ -80,12 +85,13 @@ export class UnexpectedTokenDiagnostic implements DiagnosticBase { public actual: Token, public expected: SyntaxKind[], ) { - + super(); } } -export class TypeclassDeclaredTwiceDiagnostic implements DiagnosticBase { +@deserializable() +export class TypeclassDeclaredTwiceDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.TypeclassDecaredTwice; @@ -95,12 +101,13 @@ export class TypeclassDeclaredTwiceDiagnostic implements DiagnosticBase { public name: IdentifierAlt, public origDecl: ClassDeclaration, ) { - + super(); } } -export class TypeclassNotFoundDiagnostic implements DiagnosticBase { +@deserializable() +export class TypeclassNotFoundDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.TypeclassNotFound; @@ -110,12 +117,13 @@ export class TypeclassNotFoundDiagnostic implements DiagnosticBase { public name: IdentifierAlt, public origin: InstanceDeclaration | ClassConstraint | null = null, ) { - + super(); } } -export class BindingNotFoundDiagnostic implements DiagnosticBase { +@deserializable() +export class BindingNotFoundDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.BindingNotFound; @@ -126,12 +134,13 @@ export class BindingNotFoundDiagnostic implements DiagnosticBase { public name: string, public node: Syntax, ) { - + super(); } } -export class TypeMismatchDiagnostic implements DiagnosticBase { +@deserializable() +export class TypeMismatchDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.TypeMismatch; @@ -143,12 +152,13 @@ export class TypeMismatchDiagnostic implements DiagnosticBase { public trace: Syntax[], public fieldPath: string[], ) { - + super(); } } -export class FieldNotFoundDiagnostic implements DiagnosticBase { +@deserializable() +export class FieldNotFoundDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.FieldNotFound; @@ -160,12 +170,13 @@ export class FieldNotFoundDiagnostic implements DiagnosticBase { public present: Syntax | null, public cause: Syntax | null = null, ) { - + super(); } } -export class KindMismatchDiagnostic implements DiagnosticBase { +@deserializable() +export class KindMismatchDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.KindMismatch; @@ -176,12 +187,13 @@ export class KindMismatchDiagnostic implements DiagnosticBase { public right: Kind, public origin: Syntax | null, ) { - + super(); } } -export class ModuleNotFoundDiagnostic implements DiagnosticBase { +@deserializable() +export class ModuleNotFoundDiagnostic extends DiagnosticBase { public readonly kind = DiagnosticKind.ModuleNotFound; @@ -191,7 +203,7 @@ export class ModuleNotFoundDiagnostic implements DiagnosticBase { public modulePath: string[], public node: Syntax, ) { - + super(); } } diff --git a/src/scanner.ts b/src/scanner.ts index 0c33c8f4d..58ce79dc4 100644 --- a/src/scanner.ts +++ b/src/scanner.ts @@ -212,7 +212,7 @@ export class Scanner extends BufferedStream { } } } - return new StringLiteral(contents, startPos); + return new StringLiteral(startPos, contents); } case EOF: @@ -233,7 +233,7 @@ export class Scanner extends BufferedStream { if (text === '') { return new Colon(startPos); } else if (text === '=') { - return new Assignment(':', startPos); + return new Assignment(startPos, ':'); } else { throw new ScanError(this.file, startPos, ':' + text); } @@ -273,9 +273,9 @@ export class Scanner extends BufferedStream { } else if (text === '=') { return new Equals(startPos); } else if (text.endsWith('=') && text[text.length-2] !== '=') { - return new Assignment(text.substring(0, text.length-1), startPos); + return new Assignment(startPos, text.substring(0, text.length-1)); } else { - return new CustomOperator(text, startPos); + return new CustomOperator(startPos, text); } } @@ -307,7 +307,7 @@ export class Scanner extends BufferedStream { this.getChar(); value = value * BigInt(10) + BigInt(toDecimal(c1)); } - return new Integer(value, 10, startPos); + return new Integer(startPos, value, 10); } case 'a': @@ -385,9 +385,9 @@ export class Scanner extends BufferedStream { case 'mod': return new ModKeyword(startPos); default: if (isUpper(text[0])) { - return new IdentifierAlt(text, startPos); + return new IdentifierAlt(startPos, text); } else { - return new Identifier(text, startPos); + return new Identifier(startPos, text); } } } diff --git a/src/util.ts b/src/util.ts index b57e55986..80bd19b8b 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,5 @@ +import "reflect-metadata" import path from "path" import stream from "stream" import { InspectOptions } from "util"; @@ -242,3 +243,56 @@ export class MultiMap { } +export const classes = new Map; + +export function deserializable() { + return (constructor: Function) => { + if (classes.has(constructor.name)) { + throw new Error(`A class with the name '${constructor.name}' has already been registered.`); + } + classes.set(constructor.name, constructor); + } +} + +export function getIgnoredFields(target: any): Set { + const fields = Reflect.getOwnMetadata('ignoredFields', target) ?? new Set; + for (;;) { + target = Object.getPrototypeOf(target); + if (target === null) { + break; + } + const otherFields = Reflect.getOwnMetadata('ignoredFields', target); + if (otherFields !== undefined) { + for (const field of otherFields) { + fields.add(field); + } + } + } + return fields; +} + +export function ignore(target: any, propertyKey: string) { + if (!Reflect.hasOwnMetadata('ignoredFields', target.constructor)) { + Reflect.defineMetadata('ignoredFields', new Set([ propertyKey ]), target.constructor); + } + Reflect.getOwnMetadata('ignoredFields', target.constructor).add(propertyKey); +} + +export const nonenumerable: { + (target: any, name: string): void; + (target: any, name: string, desc: PropertyDescriptor): PropertyDescriptor; +} = (target: any, name: string, desc?: any) => { + if (desc) { + desc.enumerable = false; + return desc; + } + Object.defineProperty(target, name, { + set(value) { + Object.defineProperty(this, name, { + value, writable: true, configurable: true, + }); + }, + configurable: true, + }); +}; + diff --git a/tsconfig.json b/tsconfig.json index b61a9b28b..120e849c9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,8 @@ "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, - "skipLibCheck": true + "skipLibCheck": true, + "experimentalDecorators": true }, "include": ["src"] }