mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-16 09:25:03 +01:00
more eslint rules and fix bugs
This commit is contained in:
parent
12fcc4f1bb
commit
854112da3c
13 changed files with 67 additions and 29 deletions
|
|
@ -1,13 +1,22 @@
|
||||||
/* eslint-env node */
|
/* eslint-env node */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
ignorePatterns: ["/target/**", "/jest.config.js"],
|
ignorePatterns: ["/target/**", "/*.js", "/*.cjs"],
|
||||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
extends: [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/strict-type-checked",
|
||||||
|
"plugin:@typescript-eslint/stylistic-type-checked",
|
||||||
|
],
|
||||||
parser: "@typescript-eslint/parser",
|
parser: "@typescript-eslint/parser",
|
||||||
|
parserOptions: {
|
||||||
|
project: true,
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
plugins: ["@typescript-eslint"],
|
plugins: ["@typescript-eslint"],
|
||||||
root: true,
|
root: true,
|
||||||
rules: {
|
rules: {
|
||||||
// Sometimes you just need a `while(true)`.
|
// Some silly rules forbidding things that are not wrong:
|
||||||
"no-constant-condition": "off",
|
"no-constant-condition": "off",
|
||||||
|
"no-empty": "off",
|
||||||
// Typescript already checks problematic fallthrough.
|
// Typescript already checks problematic fallthrough.
|
||||||
// The eslint rule is a bit dumb and also complains about
|
// The eslint rule is a bit dumb and also complains about
|
||||||
// obvious clear fallthrough like `case "a": case "b"`.
|
// obvious clear fallthrough like `case "a": case "b"`.
|
||||||
|
|
@ -23,5 +32,29 @@ module.exports = {
|
||||||
// `any` is genrally bad, but sometimes it's the nicest solution
|
// `any` is genrally bad, but sometimes it's the nicest solution
|
||||||
// Just let me use it without any ceremony.
|
// Just let me use it without any ceremony.
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||||
|
// This needs to be turned off until the AST types are redesigned.
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
|
// "value is always truthy" YES IT IS. Typescript already emits errors
|
||||||
|
// for the important cases here.
|
||||||
|
"@typescript-eslint/no-unnecessary-condition": "off",
|
||||||
|
"@typescript-eslint/no-confusing-void-expression": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
ignoreArrowShorthand: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// No, I will use `type` instead of `interface`.
|
||||||
|
"@typescript-eslint/consistent-type-definitions": ["error", "type"],
|
||||||
|
// Useful extra lints that are not on by default:
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "warn",
|
||||||
|
// This has caused several bugs before. Thanks eslint!
|
||||||
|
"@typescript-eslint/strict-boolean-expressions": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
allowNullableObject: true,
|
||||||
|
allowNullableBoolean: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
.prettierignore
Normal file
1
.prettierignore
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
"dev": "node-dev --respawn src/index.ts",
|
"dev": "node-dev --respawn src/index.ts",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"fmt": "prettier -w .",
|
"fmt": "prettier -w .",
|
||||||
"test": "jest"
|
"test": "jest",
|
||||||
|
"lint": "eslint ."
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ export type Folder = {
|
||||||
type: FoldFn<Type>;
|
type: FoldFn<Type>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ITEM_DEFAULT: symbol = Symbol("item must not be overriden");
|
const ITEM_DEFAULT = Symbol("item must not be overriden");
|
||||||
|
|
||||||
export const DEFAULT_FOLDER: Folder = {
|
export const DEFAULT_FOLDER: Folder = {
|
||||||
ast() {
|
ast() {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export class CompilerError extends Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function withErrorHandler(input: string, f: () => void) {
|
export function withErrorHandler(input: string, f: () => void): void {
|
||||||
try {
|
try {
|
||||||
f();
|
f();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,13 @@ function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIdent(packageName)) {
|
if (!isValidIdent(packageName)) {
|
||||||
console.error(`error: package name \`${packageName}\` is not a valid identifer`);
|
console.error(
|
||||||
|
`error: package name \`${packageName}\` is not a valid identifer`
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`package name: '${packageName}'`);
|
console.log(`package name: '${packageName}'`);
|
||||||
|
|
||||||
|
|
||||||
withErrorHandler(input, () => {
|
withErrorHandler(input, () => {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
@ -92,7 +93,7 @@ function main() {
|
||||||
if (error && error.code === 1) {
|
if (error && error.code === 1) {
|
||||||
console.log(stderr);
|
console.log(stderr);
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
console.error(`failed to spawn wasm-tools: ${error}`);
|
console.error(`failed to spawn wasm-tools: ${error.message}`);
|
||||||
} else {
|
} else {
|
||||||
if (stderr) {
|
if (stderr) {
|
||||||
console.log(stderr);
|
console.log(stderr);
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,7 @@ export type DatalessToken =
|
||||||
| "=="
|
| "=="
|
||||||
| "<="
|
| "<="
|
||||||
| ">="
|
| ">="
|
||||||
| "!="
|
| "!=";
|
||||||
| "!";
|
|
||||||
|
|
||||||
export type TokenIdent = { kind: "identifier"; ident: string };
|
export type TokenIdent = { kind: "identifier"; ident: string };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -441,6 +441,7 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
kind = `${valty}.ne`;
|
kind = `${valty}.ne`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
const instr: wasm.NumericInstr = { kind } as any; // Typescript is buggy.
|
const instr: wasm.NumericInstr = { kind } as any; // Typescript is buggy.
|
||||||
instrs.push(instr);
|
instrs.push(instr);
|
||||||
} else if (lhsTy.kind === "bool" && rhsTy.kind === "bool") {
|
} else if (lhsTy.kind === "bool" && rhsTy.kind === "bool") {
|
||||||
|
|
@ -582,11 +583,11 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
switch (expr.lhs.ty!.kind) {
|
switch (expr.lhs.ty!.kind) {
|
||||||
case "tuple": {
|
case "tuple": {
|
||||||
// Tuples have a by-value ABI, so we can simply index.
|
// Tuples have a by-value ABI, so we can simply index.
|
||||||
const lhsSize = argRetAbi(expr.lhs.ty!).length;
|
const lhsSize = argRetAbi(expr.lhs.ty).length;
|
||||||
const resultAbi = argRetAbi(expr.ty!);
|
const resultAbi = argRetAbi(expr.ty!);
|
||||||
const resultSize = resultAbi.length;
|
const resultSize = resultAbi.length;
|
||||||
const wasmIdx = wasmTypeIdxForTupleField(
|
const wasmIdx = wasmTypeIdxForTupleField(
|
||||||
expr.lhs.ty!,
|
expr.lhs.ty,
|
||||||
expr.field.fieldIdx!
|
expr.field.fieldIdx!
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -625,7 +626,7 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "if": {
|
case "if": {
|
||||||
lowerExpr(fcx, instrs, expr.cond!);
|
lowerExpr(fcx, instrs, expr.cond);
|
||||||
|
|
||||||
fcx.currentBlockDepth++;
|
fcx.currentBlockDepth++;
|
||||||
const thenInstrs: wasm.Instr[] = [];
|
const thenInstrs: wasm.Instr[] = [];
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ function printItem(item: Item): string {
|
||||||
return id + printImportDef(item.node);
|
return id + printImportDef(item.node);
|
||||||
}
|
}
|
||||||
case "mod": {
|
case "mod": {
|
||||||
return id +printMod(item.node);
|
return id + printMod(item.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ export class InferContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public assign(lhs_: Ty, rhs_: Ty, span: Span) {
|
public assign(lhs_: Ty, rhs_: Ty, span: Span): void {
|
||||||
const lhs = this.resolveIfPossible(lhs_);
|
const lhs = this.resolveIfPossible(lhs_);
|
||||||
const rhs = this.resolveIfPossible(rhs_);
|
const rhs = this.resolveIfPossible(rhs_);
|
||||||
|
|
||||||
|
|
@ -586,7 +586,7 @@ export function checkBody(
|
||||||
|
|
||||||
const type: Type | undefined = loweredBindingTy && {
|
const type: Type | undefined = loweredBindingTy && {
|
||||||
...expr.type!,
|
...expr.type!,
|
||||||
ty: loweredBindingTy!,
|
ty: loweredBindingTy,
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -689,7 +689,7 @@ export function checkBody(
|
||||||
case "call": {
|
case "call": {
|
||||||
const lhs = this.expr(expr.lhs);
|
const lhs = this.expr(expr.lhs);
|
||||||
lhs.ty = infcx.resolveIfPossible(lhs.ty!);
|
lhs.ty = infcx.resolveIfPossible(lhs.ty!);
|
||||||
const lhsTy = lhs.ty!;
|
const lhsTy = lhs.ty;
|
||||||
if (lhsTy.kind !== "fn") {
|
if (lhsTy.kind !== "fn") {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`expression of type ${printTy(lhsTy)} is not callable`,
|
`expression of type ${printTy(lhsTy)} is not callable`,
|
||||||
|
|
@ -700,7 +700,7 @@ export function checkBody(
|
||||||
const args = expr.args.map((arg) => this.expr(arg));
|
const args = expr.args.map((arg) => this.expr(arg));
|
||||||
|
|
||||||
lhsTy.params.forEach((param, i) => {
|
lhsTy.params.forEach((param, i) => {
|
||||||
if (!args[i]) {
|
if (args.length <= i) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`missing argument of type ${printTy(param)}`,
|
`missing argument of type ${printTy(param)}`,
|
||||||
expr.span
|
expr.span
|
||||||
|
|
@ -905,7 +905,8 @@ export function checkBody(
|
||||||
|
|
||||||
const resolveTy = (ty: Ty, span: Span) => {
|
const resolveTy = (ty: Ty, span: Span) => {
|
||||||
const resTy = infcx.resolveIfPossible(ty);
|
const resTy = infcx.resolveIfPossible(ty);
|
||||||
if (!resTy) {
|
// TODO: When doing deep resolution, we need to check for _any_ vars.
|
||||||
|
if (resTy.kind === "var") {
|
||||||
throw new CompilerError("cannot infer type", span);
|
throw new CompilerError("cannot infer type", span);
|
||||||
}
|
}
|
||||||
return resTy;
|
return resTy;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ export function encodeUtf8(s: string): Uint8Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Ids {
|
export class Ids {
|
||||||
nextId: number = 0;
|
nextId = 0;
|
||||||
|
|
||||||
public next(): number {
|
public next(): number {
|
||||||
return this.nextId++;
|
return this.nextId++;
|
||||||
|
|
@ -22,13 +22,13 @@ export function unwrap<T>(value: T | undefined): T {
|
||||||
* It uses JSON+string equality instead of refernece equality.
|
* It uses JSON+string equality instead of refernece equality.
|
||||||
*/
|
*/
|
||||||
export class ComplexMap<K, V> {
|
export class ComplexMap<K, V> {
|
||||||
inner: Map<string | number, V> = new Map();
|
inner = new Map<string | number, V>();
|
||||||
|
|
||||||
public get(key: K): V | undefined {
|
public get(key: K): V | undefined {
|
||||||
return this.inner.get(this.mangleKey(key));
|
return this.inner.get(this.mangleKey(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
public set(key: K, value: V) {
|
public set(key: K, value: V): void {
|
||||||
this.inner.set(this.mangleKey(key), value);
|
this.inner.set(this.mangleKey(key), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,7 @@ export type ControlInstr =
|
||||||
|
|
||||||
export type Instr =
|
export type Instr =
|
||||||
| NumericInstr
|
| NumericInstr
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||||
| VectorInstr
|
| VectorInstr
|
||||||
| ReferenceInstr
|
| ReferenceInstr
|
||||||
| ParametricInstr
|
| ParametricInstr
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,8 @@ function printString(s: string, f: FmtCtx) {
|
||||||
|
|
||||||
function printBinaryString(buf: Uint8Array, f: FmtCtx) {
|
function printBinaryString(buf: Uint8Array, f: FmtCtx) {
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
for (let i = 0; i < buf.length; i++) {
|
|
||||||
const byte = buf[i];
|
buf.forEach((byte) => {
|
||||||
const noEscape =
|
const noEscape =
|
||||||
(byte > 0x30 && byte <= 0x5a) || (byte > 0x61 && byte <= 0x71);
|
(byte > 0x30 && byte <= 0x5a) || (byte > 0x61 && byte <= 0x71);
|
||||||
if (noEscape) {
|
if (noEscape) {
|
||||||
|
|
@ -149,13 +149,13 @@ function printBinaryString(buf: Uint8Array, f: FmtCtx) {
|
||||||
} else {
|
} else {
|
||||||
parts.push(`\\${byte.toString(16).padStart(2, "0")}`);
|
parts.push(`\\${byte.toString(16).padStart(2, "0")}`);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
f.word(`"${parts.join("")}"`);
|
f.word(`"${parts.join("")}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function printId(id: string | undefined, f: FmtCtx) {
|
function printId(id: string | undefined, f: FmtCtx) {
|
||||||
if (id) {
|
if (id !== undefined) {
|
||||||
f.word(`$${id}`);
|
f.word(`$${id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +215,7 @@ function printBlockType(type: Blocktype, f: FmtCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function printMemarg(arg: MemArg, f: FmtCtx) {
|
function printMemarg(arg: MemArg, f: FmtCtx) {
|
||||||
if (arg.offset /*0->false*/) {
|
if (arg.offset === undefined || arg.offset === 0) {
|
||||||
f.word(`offset=${arg.offset}`);
|
f.word(`offset=${arg.offset}`);
|
||||||
}
|
}
|
||||||
if (arg.align !== undefined) {
|
if (arg.align !== undefined) {
|
||||||
|
|
@ -437,7 +437,7 @@ function printInstr(instr: Instr, f: FmtCtx) {
|
||||||
f.controlFlow(instr.kind);
|
f.controlFlow(instr.kind);
|
||||||
f.word(instr.func);
|
f.word(instr.func);
|
||||||
const name = f.mod.funcs[instr.func]?._name;
|
const name = f.mod.funcs[instr.func]?._name;
|
||||||
if (name) {
|
if (name !== undefined) {
|
||||||
f.comment(name);
|
f.comment(name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue