[be] Fix remaining lints and enable lint in CI
Lauren Tan committed
Mar 10, 2023 at 16:21 UTC
faa8eef0a89666dad5fb489162d1fe0a1b5836aa
21 files changed
+58
-52
compiler/.github/workflows/ci.yml
+2
@@ -21,5 +21,7 @@ jobs:
21
working-directory: forget
22
- run: yarn build
23
working-directory: forget
24
+ - run: yarn lint
25
+ working-directory: forget
26
- run: yarn test
27
working-directory: forget
compiler/forget/.eslintrc.js
+1
@@ -56,6 +56,7 @@ module.exports = {
56
"constructor",
57
],
58
"@typescript-eslint/array-type": ["off", "generic"],
59
+ "@typescript-eslint/triple-slash-reference": "off",
60
},
61
parser: "@typescript-eslint/parser",
62
plugins: ["@typescript-eslint"],
compiler/forget/src/CompilerError.ts
+1
-1
@@ -125,7 +125,7 @@ export class CompilerError extends Error {
125
126
override set message(_message: string) {}
127
128
- override toString() {
128
+ override toString(): string {
129
return this.details.map((detail) => detail.toString()).join("\n\n");
130
}
131
compiler/forget/src/Inference/AnalyseFunctions.ts
+8
-4
@@ -43,7 +43,7 @@ class State {
43
}
44
}
45
46
-export default function analyseFunctions(func: HIRFunction) {
46
+export default function analyseFunctions(func: HIRFunction): void {
47
const state = new State();
48
49
for (const [_, block] of func.body.blocks) {
@@ -73,7 +73,7 @@ export default function analyseFunctions(func: HIRFunction) {
73
}
74
}
75
76
-function lower(func: HIRFunction) {
76
+function lower(func: HIRFunction): void {
77
mergeConsecutiveBlocks(func);
78
enterSSA(func);
79
eliminateRedundantPhi(func);
@@ -85,7 +85,11 @@ function lower(func: HIRFunction) {
85
logHIRFunction("AnalyseFunction (inner)", func);
86
}
87
88
-function infer(value: FunctionExpression, state: State, context: Place[]) {
88
+function infer(
89
+ value: FunctionExpression,
90
+ state: State,
91
+ context: Place[]
92
+): void {
93
const mutations = new Set(
94
value.loweredFunc.context
95
.filter((dep) => isMutatedOrReassigned(dep.identifier))
@@ -127,7 +131,7 @@ function infer(value: FunctionExpression, state: State, context: Place[]) {
131
}
132
}
133
130
-function isMutatedOrReassigned(id: Identifier) {
134
+function isMutatedOrReassigned(id: Identifier): boolean {
135
// This check checks for mutation and reassingnment, so the usual check for
136
// mutation (ie, `mutableRange.end - mutableRange.start > 1`) isn't quite
137
// enough.
compiler/forget/src/Inference/DropMemoCalls.ts
+1
-1
@@ -1,6 +1,6 @@
1
import { Effect, HIRFunction, HookType, isHookType } from "../HIR";
2
3
-export default function (func: HIRFunction) {
3
+export default function (func: HIRFunction): void {
4
for (const [_, block] of func.body.blocks) {
5
for (const instr of block.instructions) {
6
switch (instr.value.kind) {
compiler/forget/src/Inference/InferAlias.ts
+4
-1
@@ -20,7 +20,10 @@ export function inferAliases(func: HIRFunction): DisjointSet<Identifier> {
20
return aliases;
21
}
22
23
-function inferInstr(instr: Instruction, aliases: DisjointSet<Identifier>) {
23
+function inferInstr(
24
+ instr: Instruction,
25
+ aliases: DisjointSet<Identifier>
26
+): void {
27
const { lvalue, value: instrValue } = instr;
28
let alias: Place | null = null;
29
switch (instrValue.kind) {
compiler/forget/src/Inference/InferAliasForPhis.ts
+1
-1
@@ -10,7 +10,7 @@ import DisjointSet from "../Utils/DisjointSet";
10
export function inferAliasForPhis(
11
func: HIRFunction,
12
aliases: DisjointSet<Identifier>
13
-) {
13
+): void {
14
for (const [_, block] of func.body.blocks) {
15
for (const phi of block.phis) {
16
const isPhiMutatedAfterCreation: boolean =
compiler/forget/src/Inference/InferAliasForStores.ts
+1
-1
@@ -20,7 +20,7 @@ import DisjointSet from "../Utils/DisjointSet";
20
export function inferAliasForStores(
21
func: HIRFunction,
22
aliases: DisjointSet<Identifier>
23
-) {
23
+): void {
24
for (const [_, block] of func.body.blocks) {
25
for (const instr of block.instructions) {
26
const { value, lvalue } = instr;
compiler/forget/src/Inference/InferMutableLifetimes.ts
+3
-3
@@ -60,7 +60,7 @@ import { assertExhaustive } from "../Utils/utils";
60
* ```
61
*/
62
63
-function infer(place: Place, instr: Instruction) {
63
+function infer(place: Place, instr: Instruction): void {
64
place.identifier.mutableRange.end = makeInstructionId(instr.id + 1);
65
}
66
@@ -68,7 +68,7 @@ function inferPlace(
68
place: Place,
69
instr: Instruction,
70
inferMutableRangeForStores: boolean
71
-) {
71
+): void {
72
switch (place.effect) {
73
case Effect.Unknown: {
74
throw new Error(
@@ -98,7 +98,7 @@ function inferPlace(
98
export function inferMutableLifetimes(
99
func: HIRFunction,
100
inferMutableRangeForStores: boolean
101
-) {
101
+): void {
102
for (const [_, block] of func.body.blocks) {
103
for (const phi of block.phis) {
104
let start = Number.MAX_SAFE_INTEGER;
compiler/forget/src/Inference/InferMutableRanges.ts
+1
-1
@@ -12,7 +12,7 @@ import { inferAliasForStores } from "./InferAliasForStores";
12
import { inferMutableLifetimes } from "./InferMutableLifetimes";
13
import { inferMutableRangesForAlias } from "./InferMutableRangesForAlias";
14
15
-export function inferMutableRanges(ir: HIRFunction) {
15
+export function inferMutableRanges(ir: HIRFunction): void {
16
// Infer mutable ranges for non fields
17
inferMutableLifetimes(ir, false);
18
compiler/forget/src/Inference/InferMutableRangesForAlias.ts
+2
-2
@@ -2,9 +2,9 @@ import { HIRFunction, Identifier, InstructionId } from "../HIR/HIR";
2
import DisjointSet from "../Utils/DisjointSet";
3
4
export function inferMutableRangesForAlias(
5
- fn: HIRFunction,
5
+ _fn: HIRFunction,
6
aliases: DisjointSet<Identifier>
7
-) {
7
+): void {
8
const aliasSets = aliases.buildSets();
9
for (const aliasSet of aliasSets) {
10
// Update mutableRange.end only if the identifiers have actually been
compiler/forget/src/Inference/InferReferenceEffects.ts
+10
-11
@@ -76,7 +76,7 @@ import { assertExhaustive } from "../Utils/utils";
76
* When control flow paths converge the types of values are merged together, with the value
77
* types forming a lattice to ensure convergence.
78
*/
79
-export default function inferReferenceEffects(fn: HIRFunction) {
79
+export default function inferReferenceEffects(fn: HIRFunction): void {
80
// Initial state contains function params
81
// TODO: include module declarations here as well
82
const initialState = InferenceState.empty();
@@ -124,7 +124,7 @@ export default function inferReferenceEffects(fn: HIRFunction) {
124
// so track the list of incoming state for each successor block.
125
// These are merged when reaching that block again.
126
const queuedStates: Map<BlockId, InferenceState> = new Map();
127
- function queue(blockId: BlockId, state: InferenceState) {
127
+ function queue(blockId: BlockId, state: InferenceState): void {
128
let queuedState = queuedStates.get(blockId);
129
if (queuedState != null) {
130
// merge the queued states for this block
@@ -187,7 +187,7 @@ class InferenceState {
187
/**
188
* (Re)initializes a @param value with its default @param kind.
189
*/
190
- initialize(value: InstructionValue, kind: ValueKind) {
190
+ initialize(value: InstructionValue, kind: ValueKind): void {
191
invariant(
192
value.kind !== "LoadLocal",
193
"Expected all top-level identifiers to be defined as variables, not values"
@@ -225,7 +225,7 @@ class InferenceState {
225
/**
226
* Updates the value at @param place to point to the same value as @param value.
227
*/
228
- alias(place: Place, value: Place) {
228
+ alias(place: Place, value: Place): void {
229
const values = this.#variables.get(value.identifier.id);
230
invariant(
231
values != null,
@@ -238,7 +238,7 @@ class InferenceState {
238
/**
239
* Defines (initializing or updating) a variable with a specific kind of value.
240
*/
241
- define(place: Place, value: InstructionValue) {
241
+ define(place: Place, value: InstructionValue): void {
242
invariant(
243
this.#values.has(value),
244
`Expected value to be initialized at '${printSourceLocation(value.loc)}'`
@@ -262,7 +262,7 @@ class InferenceState {
262
* Similarly, a freeze reference is converted to readonly if the
263
* value is already frozen or is immutable.
264
*/
265
- reference(place: Place, effectKind: Effect) {
265
+ reference(place: Place, effectKind: Effect): void {
266
const values = this.#variables.get(place.identifier.id);
267
if (values === undefined) {
268
place.effect = effectKind === Effect.Mutate ? Effect.Mutate : Effect.Read;
@@ -442,7 +442,7 @@ class InferenceState {
442
return result;
443
}
444
445
- inferPhi(phi: Phi) {
445
+ inferPhi(phi: Phi): void {
446
const values: Set<InstructionValue> = new Set();
447
for (const [_, operand] of phi.operands) {
448
const operandValues = this.#variables.get(operand.id);
@@ -554,11 +554,10 @@ function mergeValues(a: ValueKind, b: ValueKind): ValueKind {
554
* recording references on the @param state according to JS semantics.
555
*/
556
function inferBlock(
557
- env: Environment,
558
-
557
+ _env: Environment,
558
state: InferenceState,
559
block: BasicBlock
561
-) {
560
+): void {
561
for (const phi of block.phis) {
562
state.inferPhi(phi);
563
}
@@ -876,7 +875,7 @@ function inferBlock(
875
function hasContextRefOperand(
876
state: InferenceState,
877
instrValue: InstructionValue
879
-) {
878
+): boolean {
879
for (const place of eachInstructionValueOperand(instrValue)) {
880
if (state.isDefined(place) && state.kind(place) === ValueKind.Context) {
881
return true;
compiler/forget/src/Optimization/ConstantPropagation.ts
+1
-1
@@ -119,7 +119,7 @@ function applyConstantPropagation(fn: HIRFunction): boolean {
119
const testValue = read(constants, terminal.test);
120
if (testValue !== null) {
121
hasChanges = true;
122
- const targetBlockId = Boolean(testValue.value)
122
+ const targetBlockId = testValue.value
123
? terminal.consequent
124
: terminal.alternate;
125
block.terminal = {
compiler/forget/src/Optimization/DeadCodeElimination.ts
+1
-2
@@ -60,7 +60,7 @@ export function deadCodeElimination(fn: HIRFunction): void {
60
}
61
for (const phi of block.phis) {
62
if (used.has(phi.id)) {
63
- for (const [pred, operand] of phi.operands) {
63
+ for (const [_pred, operand] of phi.operands) {
64
used.add(operand);
65
}
66
}
@@ -196,7 +196,6 @@ function pruneableValue(
196
case "ArrayExpression":
197
case "BinaryExpression":
198
case "ComputedLoad":
199
- case "ComputedStore":
199
case "FunctionExpression":
200
case "LoadLocal":
201
case "JsxExpression":
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
-3
@@ -498,9 +498,6 @@ function codegenInstruction(
498
cx.temp.set(instr.lvalue.identifier.id, value);
499
return t.emptyStatement();
500
} else {
501
- const kind = cx.hasDeclared(instr.lvalue.identifier)
502
- ? InstructionKind.Reassign
503
- : InstructionKind.Const;
501
if (cx.hasDeclared(instr.lvalue.identifier)) {
502
return createExpressionStatement(
503
instr.loc,
compiler/forget/src/ReactiveScopes/DeriveMinimalDependencies.ts
+9
-9
@@ -1,5 +1,5 @@
1
import invariant from "invariant";
2
-import { Identifier, IdentifierId, ReactiveScopeDependency } from "../HIR";
2
+import { Identifier, ReactiveScopeDependency } from "../HIR";
3
import { printIdentifier } from "../HIR/PrintHIR";
4
import { assertExhaustive } from "../Utils/utils";
5
@@ -46,7 +46,7 @@ export class ReactiveScopeDependencyTree {
46
return rootNode;
47
}
48
49
- add(dep: ReactiveScopeDependencyInfo) {
49
+ add(dep: ReactiveScopeDependencyInfo): void {
50
const path = dep.path ?? [];
51
let currNode = this.#getOrCreateRoot(dep.identifier);
52
@@ -102,7 +102,7 @@ export class ReactiveScopeDependencyTree {
102
depsFromInnerScope: ReactiveScopeDependencyTree,
103
innerScopeInConditionalWithinParent: boolean,
104
checkValidDepIdFn: (id: Identifier) => boolean
105
- ) {
105
+ ): void {
106
for (const [id, otherRoot] of depsFromInnerScope.#roots) {
107
if (!checkValidDepIdFn(id)) {
108
continue;
@@ -119,7 +119,7 @@ export class ReactiveScopeDependencyTree {
119
120
promoteDepsFromExhaustiveConditionals(
121
trees: Array<ReactiveScopeDependencyTree>
122
- ) {
122
+ ): void {
123
invariant(
124
trees.length > 1,
125
"Expected trees to be at least 2 elements long."
@@ -180,13 +180,13 @@ enum PropertyAccessType {
180
UnconditionalDependency = "UnconditionalDependency",
181
}
182
183
-function isUnconditional(access: PropertyAccessType) {
183
+function isUnconditional(access: PropertyAccessType): boolean {
184
return (
185
access === PropertyAccessType.UnconditionalAccess ||
186
access === PropertyAccessType.UnconditionalDependency
187
);
188
}
189
-function isDependency(access: PropertyAccessType) {
189
+function isDependency(access: PropertyAccessType): boolean {
190
return (
191
access === PropertyAccessType.ConditionalDependency ||
192
access === PropertyAccessType.UnconditionalDependency
@@ -318,7 +318,7 @@ function deriveMinimalDependenciesInSubtree(
318
* conditional equivalent, mutating subtree in place.
319
* @param subtree unconditional node representing a subtree of dependencies
320
*/
321
-function demoteSubtreeToConditional(subtree: DependencyNode) {
321
+function demoteSubtreeToConditional(subtree: DependencyNode): void {
322
const stack: Array<DependencyNode> = [subtree];
323
324
let node;
@@ -355,7 +355,7 @@ function addSubtree(
355
currNode: DependencyNode,
356
otherNode: DependencyNode,
357
demoteOtherNode: boolean
358
-) {
358
+): void {
359
let otherType = otherNode.accessType;
360
if (demoteOtherNode) {
361
otherType = isDependency(otherType)
@@ -405,7 +405,7 @@ function addSubtree(
405
function addSubtreeIntersection(
406
otherProperties: Array<Map<string, DependencyNode>>,
407
currProperties: Map<string, DependencyNode>
408
-) {
408
+): void {
409
invariant(
410
otherProperties.length > 1,
411
"[DeriveMinimalDependencies] Expected otherProperties to be at least 2 elements long."
compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts
+1
-1
@@ -29,7 +29,7 @@ class State {
29
}
30
31
class Visitor extends ReactiveFunctionVisitor<State> {
32
- override visitInstruction(instr: ReactiveInstruction, state: State) {
32
+ override visitInstruction(instr: ReactiveInstruction, state: State): void {
33
this.traverseInstruction(instr, state);
34
const lval = instr.lvalue;
35
if (lval == null) {
compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+2
-2
@@ -158,7 +158,7 @@ class Context {
158
*/
159
promoteDepsFromExhaustiveConditionals(
160
depsInConditionals: Array<ReactiveScopeDependencyTree>
161
- ) {
161
+ ): void {
162
this.#dependencies.promoteDepsFromExhaustiveConditionals(
163
depsInConditionals
164
);
@@ -205,7 +205,7 @@ class Context {
205
}
206
207
// Checks if identifier is a valid dependency in the current scope
208
- #checkValidDependencyId(identifier: Identifier) {
208
+ #checkValidDependencyId(identifier: Identifier): boolean {
209
// If this operand is used in a scope, has a dynamic value, and was defined
210
// before this scope, then its a dependency of the scope.
211
const currentDeclaration =
compiler/forget/src/SSA/EliminateRedundantPhi.ts
+5
-2
@@ -27,7 +27,7 @@ import {
27
* and phis rewrite all their identifiers based on this table. The algorithm loops over the CFG repeatedly
28
* until there are no new rewrites: for a CFG without back-edges it completes in a single pass.
29
*/
30
-export function eliminateRedundantPhi(fn: HIRFunction) {
30
+export function eliminateRedundantPhi(fn: HIRFunction): void {
31
const ir = fn.body;
32
const rewrites: Map<Identifier, Identifier> = new Map();
33
@@ -111,7 +111,10 @@ export function eliminateRedundantPhi(fn: HIRFunction) {
111
} while (rewrites.size > size && hasBackEdge);
112
}
113
114
-function rewritePlace(place: Place, rewrites: Map<Identifier, Identifier>) {
114
+function rewritePlace(
115
+ place: Place,
116
+ rewrites: Map<Identifier, Identifier>
117
+): void {
118
const rewrite = rewrites.get(place.identifier);
119
if (rewrite != null) {
120
place.identifier = rewrite;
compiler/forget/src/TypeInference/InferTypes.ts
+4
-5
@@ -11,7 +11,7 @@ import {
11
} from "../HIR/HIR";
12
import { eachInstructionLValue, eachInstructionOperand } from "../HIR/visitors";
13
14
-function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]) {
14
+function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]): boolean {
15
switch (op) {
16
case "+":
17
case "-":
@@ -22,7 +22,6 @@ function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]) {
22
case "&":
23
case "|":
24
case ">>":
25
- case ">>":
25
case "<<":
26
case "^":
27
case ">":
@@ -36,7 +35,7 @@ function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]) {
35
}
36
}
37
39
-export default function (func: HIRFunction) {
38
+export default function (func: HIRFunction): void {
39
const unifier = new Unifier();
40
for (const e of generate(func)) {
41
unifier.unify(e.left, e.right);
@@ -44,7 +43,7 @@ export default function (func: HIRFunction) {
43
apply(func, unifier);
44
}
45
47
-function apply(func: HIRFunction, unifier: Unifier) {
46
+function apply(func: HIRFunction, unifier: Unifier): void {
47
for (const [_, block] of func.body.blocks) {
48
for (const phi of block.phis) {
49
phi.type = unifier.get(phi.type);
@@ -169,7 +168,7 @@ type Substitution = Map<TypeId, Type>;
168
class Unifier {
169
substitutions: Substitution = new Map();
170
172
- unify(tA: Type, tB: Type) {
171
+ unify(tA: Type, tB: Type): void {
172
if (typeEquals(tA, tB)) {
173
return;
174
}
compiler/forget/src/Utils/DisjointSet.ts
-1
@@ -80,7 +80,6 @@ export default class DisjointSet<T> {
80
canonicalize(): Map<T, T> {
81
const entries = new Map<T, T>();
82
for (const item of this.#entries.keys()) {
83
- const parent = this.#entries.get(item)!;
83
const root = this.find(item)!;
84
entries.set(item, root);
85
}