Console methods are readonly

Defines common `console` methods to tell the compiler that they take readonly 
args. This ensures that things like `console.log()` aren't accidentally viewed 
as a mutation. Previously the pattern of "build object, then log it after 
mutation is done" would have grouped the console.log as part of the mutation and 
the log only would fire if the value got reconstructed. Now we know the log 
isn't mutating, and the log will happen regardless of whether the value is 
rebuilt or cached.
This commit is contained in:
Joe Savona
2023-04-27 10:34:31 -07:00
parent 2ddbbd4735
commit b69d70664c
6 changed files with 147 additions and 19 deletions
+62 -3
View File
@@ -8,11 +8,11 @@
import { Effect, ValueKind } from "./HIR";
import { Hook } from "./Hooks";
import {
BUILTIN_SHAPES,
BuiltInArrayId,
ShapeRegistry,
addFunction,
addObject,
BuiltInArrayId,
BUILTIN_SHAPES,
ShapeRegistry,
} from "./ObjectShape";
import { BuiltInType, HookType, PolyType } from "./Types";
@@ -128,6 +128,65 @@ const TYPED_GLOBALS: Array<[string, BuiltInType]> = [
],
["Infinity", { kind: "Primitive" }],
["NaN", { kind: "Primitive" }],
[
"console",
addObject(DEFAULT_SHAPES, "console", [
[
"error",
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: { kind: "Primitive" },
calleeEffect: Effect.Read,
}),
],
[
"info",
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: { kind: "Primitive" },
calleeEffect: Effect.Read,
}),
],
[
"log",
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: { kind: "Primitive" },
calleeEffect: Effect.Read,
}),
],
[
"table",
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: { kind: "Primitive" },
calleeEffect: Effect.Read,
}),
],
[
"trace",
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: { kind: "Primitive" },
calleeEffect: Effect.Read,
}),
],
[
"warn",
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: { kind: "Primitive" },
calleeEffect: Effect.Read,
}),
],
]),
],
// TODO: rest of Global objects
];
@@ -0,0 +1,46 @@
## Input
```javascript
function Component(props) {
const x = makeObject(props);
// These calls should view x as readonly and be grouped outside of the reactive scope for x:
console.log(x);
console.info(x);
console.warn(x);
console.error(x);
console.trace(x);
console.table(x);
return x;
}
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function Component(props) {
const $ = useMemoCache(2);
const c_0 = $[0] !== props;
let t0;
if (c_0) {
t0 = makeObject(props);
$[0] = props;
$[1] = t0;
} else {
t0 = $[1];
}
const x = t0;
console.log(x);
console.info(x);
console.warn(x);
console.error(x);
console.trace(x);
console.table(x);
return x;
}
```
@@ -0,0 +1,11 @@
function Component(props) {
const x = makeObject(props);
// These calls should view x as readonly and be grouped outside of the reactive scope for x:
console.log(x);
console.info(x);
console.warn(x);
console.error(x);
console.trace(x);
console.table(x);
return x;
}
@@ -19,7 +19,7 @@ function foo(props) {
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function foo(props) {
const $ = useMemoCache(4);
const $ = useMemoCache(5);
const c_0 = $[0] !== props.bar;
let x;
if (c_0) {
@@ -31,15 +31,19 @@ function foo(props) {
x = $[1];
}
const c_2 = $[2] !== props;
let t0;
if (c_2) {
const _ = props.cond ? (([x] = [[]]), x.push(props.foo)) : null;
console.log(_);
t0 = props.cond ? (([x] = [[]]), x.push(props.foo)) : null;
$[2] = props;
$[3] = x;
$[3] = t0;
$[4] = x;
} else {
x = $[3];
t0 = $[3];
x = $[4];
}
const _ = t0;
console.log(_);
return x;
}
@@ -17,7 +17,7 @@ function foo(props) {
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function foo(props) {
const $ = useMemoCache(4);
const $ = useMemoCache(5);
const c_0 = $[0] !== props.bar;
let x;
if (c_0) {
@@ -29,14 +29,18 @@ function foo(props) {
x = $[1];
}
const c_2 = $[2] !== props;
let t0;
if (c_2) {
const _ = props.cond ? ((x = []), x.push(props.foo)) : null;
console.log(_);
t0 = props.cond ? ((x = []), x.push(props.foo)) : null;
$[2] = props;
$[3] = x;
$[3] = t0;
$[4] = x;
} else {
x = $[3];
t0 = $[3];
x = $[4];
}
const _ = t0;
console.log(_);
return x;
}
@@ -19,7 +19,7 @@ function foo(props) {
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function foo(props) {
const $ = useMemoCache(4);
const $ = useMemoCache(5);
const c_0 = $[0] !== props.bar;
let x;
if (c_0) {
@@ -31,16 +31,20 @@ function foo(props) {
x = $[1];
}
const c_2 = $[2] !== props;
let t0;
if (c_2) {
const _ = props.cond
t0 = props.cond
? ((x = []), x.push(props.foo))
: ((x = []), x.push(props.bar));
console.log(_);
$[2] = props;
$[3] = x;
$[3] = t0;
$[4] = x;
} else {
x = $[3];
t0 = $[3];
x = $[4];
}
const _ = t0;
console.log(_);
return x;
}