@samitouri / QOS-React-2 / commits / faa8eef0a8

[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 }