babel-plugin-react-compiler 0.0.0-experimental-23b8160-20240916 → 0.0.0-experimental-ca8e0be-20240916
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +457 -321
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -139601,6 +139601,8 @@ var InstructionKind;
|
|
139601
139601
|
InstructionKind['Catch'] = 'Catch';
|
139602
139602
|
InstructionKind['HoistedConst'] = 'HoistedConst';
|
139603
139603
|
InstructionKind['HoistedLet'] = 'HoistedLet';
|
139604
|
+
InstructionKind['HoistedFunction'] = 'HoistedFunction';
|
139605
|
+
InstructionKind['Function'] = 'Function';
|
139604
139606
|
})(InstructionKind || (InstructionKind = {}));
|
139605
139607
|
function makeTemporaryIdentifier(id, loc) {
|
139606
139608
|
return {
|
@@ -144017,7 +144019,14 @@ function lowerStatement(builder, stmtPath, label = null) {
|
|
144017
144019
|
if (builder.environment.isHoistedIdentifier(binding.identifier)) {
|
144018
144020
|
continue;
|
144019
144021
|
}
|
144020
|
-
|
144022
|
+
let kind;
|
144023
|
+
if (binding.kind === 'const' || binding.kind === 'var') {
|
144024
|
+
kind = InstructionKind.HoistedConst;
|
144025
|
+
} else if (binding.kind === 'let') {
|
144026
|
+
kind = InstructionKind.HoistedLet;
|
144027
|
+
} else if (binding.path.isFunctionDeclaration()) {
|
144028
|
+
kind = InstructionKind.HoistedFunction;
|
144029
|
+
} else if (!binding.path.isVariableDeclarator()) {
|
144021
144030
|
builder.errors.push({
|
144022
144031
|
severity: exports.ErrorSeverity.Todo,
|
144023
144032
|
reason: 'Unsupported declaration type for hoisting',
|
@@ -144029,11 +144038,7 @@ function lowerStatement(builder, stmtPath, label = null) {
|
|
144029
144038
|
: GeneratedSource,
|
144030
144039
|
});
|
144031
144040
|
continue;
|
144032
|
-
} else
|
144033
|
-
binding.kind !== 'const' &&
|
144034
|
-
binding.kind !== 'var' &&
|
144035
|
-
binding.kind !== 'let'
|
144036
|
-
) {
|
144041
|
+
} else {
|
144037
144042
|
builder.errors.push({
|
144038
144043
|
severity: exports.ErrorSeverity.Todo,
|
144039
144044
|
reason: 'Handle non-const declarations for hoisting',
|
@@ -144065,12 +144070,6 @@ function lowerStatement(builder, stmtPath, label = null) {
|
|
144065
144070
|
? _j
|
144066
144071
|
: GeneratedSource,
|
144067
144072
|
};
|
144068
|
-
const kind =
|
144069
|
-
binding.kind === 'const' || binding.kind === 'var'
|
144070
|
-
? InstructionKind.HoistedConst
|
144071
|
-
: binding.kind === 'let'
|
144072
|
-
? InstructionKind.HoistedLet
|
144073
|
-
: assertExhaustive(binding.kind, 'Unexpected binding kind');
|
144074
144073
|
lowerValueToTemporary(builder, {
|
144075
144074
|
kind: 'DeclareContext',
|
144076
144075
|
lvalue: {kind: kind, place: place},
|
@@ -144615,7 +144614,7 @@ function lowerStatement(builder, stmtPath, label = null) {
|
|
144615
144614
|
(_10 = stmt.node.loc) !== null && _10 !== void 0
|
144616
144615
|
? _10
|
144617
144616
|
: GeneratedSource,
|
144618
|
-
InstructionKind.
|
144617
|
+
InstructionKind.Function,
|
144619
144618
|
id,
|
144620
144619
|
fn,
|
144621
144620
|
'Assignment'
|
@@ -150159,6 +150158,17 @@ const REACT_APIS = [
|
|
150159
150158
|
returnValueKind: exports.ValueKind.Mutable,
|
150160
150159
|
}),
|
150161
150160
|
],
|
150161
|
+
[
|
150162
|
+
'useImperativeHandle',
|
150163
|
+
addHook(DEFAULT_SHAPES, {
|
150164
|
+
positionalParams: [],
|
150165
|
+
restParam: exports.Effect.Freeze,
|
150166
|
+
returnType: {kind: 'Primitive'},
|
150167
|
+
calleeEffect: exports.Effect.Read,
|
150168
|
+
hookKind: 'useImperativeHandle',
|
150169
|
+
returnValueKind: exports.ValueKind.Frozen,
|
150170
|
+
}),
|
150171
|
+
],
|
150162
150172
|
[
|
150163
150173
|
'useMemo',
|
150164
150174
|
addHook(DEFAULT_SHAPES, {
|
@@ -157991,22 +158001,12 @@ function codegenTerminal(cx, terminal) {
|
|
157991
158001
|
suggestions: null,
|
157992
158002
|
});
|
157993
158003
|
case InstructionKind.Catch:
|
157994
|
-
CompilerError.invariant(false, {
|
157995
|
-
reason: 'Unexpected catch variable as for..in collection',
|
157996
|
-
description: null,
|
157997
|
-
loc: iterableItem.loc,
|
157998
|
-
suggestions: null,
|
157999
|
-
});
|
158000
158004
|
case InstructionKind.HoistedConst:
|
158001
|
-
CompilerError.invariant(false, {
|
158002
|
-
reason: 'Unexpected HoistedConst variable in for..in collection',
|
158003
|
-
description: null,
|
158004
|
-
loc: iterableItem.loc,
|
158005
|
-
suggestions: null,
|
158006
|
-
});
|
158007
158005
|
case InstructionKind.HoistedLet:
|
158006
|
+
case InstructionKind.HoistedFunction:
|
158007
|
+
case InstructionKind.Function:
|
158008
158008
|
CompilerError.invariant(false, {
|
158009
|
-
reason:
|
158009
|
+
reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..in collection`,
|
158010
158010
|
description: null,
|
158011
158011
|
loc: iterableItem.loc,
|
158012
158012
|
suggestions: null,
|
@@ -158080,30 +158080,13 @@ function codegenTerminal(cx, terminal) {
|
|
158080
158080
|
varDeclKind = 'let';
|
158081
158081
|
break;
|
158082
158082
|
case InstructionKind.Reassign:
|
158083
|
-
CompilerError.invariant(false, {
|
158084
|
-
reason:
|
158085
|
-
'Destructure should never be Reassign as it would be an Object/ArrayPattern',
|
158086
|
-
description: null,
|
158087
|
-
loc: iterableItem.loc,
|
158088
|
-
suggestions: null,
|
158089
|
-
});
|
158090
158083
|
case InstructionKind.Catch:
|
158091
|
-
CompilerError.invariant(false, {
|
158092
|
-
reason: 'Unexpected catch variable as for..of collection',
|
158093
|
-
description: null,
|
158094
|
-
loc: iterableItem.loc,
|
158095
|
-
suggestions: null,
|
158096
|
-
});
|
158097
158084
|
case InstructionKind.HoistedConst:
|
158098
|
-
CompilerError.invariant(false, {
|
158099
|
-
reason: 'Unexpected HoistedConst variable in for..of collection',
|
158100
|
-
description: null,
|
158101
|
-
loc: iterableItem.loc,
|
158102
|
-
suggestions: null,
|
158103
|
-
});
|
158104
158085
|
case InstructionKind.HoistedLet:
|
158086
|
+
case InstructionKind.HoistedFunction:
|
158087
|
+
case InstructionKind.Function:
|
158105
158088
|
CompilerError.invariant(false, {
|
158106
|
-
reason:
|
158089
|
+
reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..of collection`,
|
158107
158090
|
description: null,
|
158108
158091
|
loc: iterableItem.loc,
|
158109
158092
|
suggestions: null,
|
@@ -158262,6 +158245,39 @@ function codegenInstructionNullable(cx, instr) {
|
|
158262
158245
|
t__namespace.variableDeclarator(codegenLValue(cx, lvalue), value),
|
158263
158246
|
]);
|
158264
158247
|
}
|
158248
|
+
case InstructionKind.Function: {
|
158249
|
+
CompilerError.invariant(instr.lvalue === null, {
|
158250
|
+
reason: `Function declaration cannot be referenced as an expression`,
|
158251
|
+
description: null,
|
158252
|
+
loc: instr.value.loc,
|
158253
|
+
suggestions: null,
|
158254
|
+
});
|
158255
|
+
const genLvalue = codegenLValue(cx, lvalue);
|
158256
|
+
CompilerError.invariant(genLvalue.type === 'Identifier', {
|
158257
|
+
reason: 'Expected an identifier as a function declaration lvalue',
|
158258
|
+
description: null,
|
158259
|
+
loc: instr.value.loc,
|
158260
|
+
suggestions: null,
|
158261
|
+
});
|
158262
|
+
CompilerError.invariant(
|
158263
|
+
(value === null || value === void 0 ? void 0 : value.type) ===
|
158264
|
+
'FunctionExpression',
|
158265
|
+
{
|
158266
|
+
reason: 'Expected a function as a function declaration value',
|
158267
|
+
description: null,
|
158268
|
+
loc: instr.value.loc,
|
158269
|
+
suggestions: null,
|
158270
|
+
}
|
158271
|
+
);
|
158272
|
+
return createFunctionDeclaration(
|
158273
|
+
instr.loc,
|
158274
|
+
genLvalue,
|
158275
|
+
value.params,
|
158276
|
+
value.body,
|
158277
|
+
value.generator,
|
158278
|
+
value.async
|
158279
|
+
);
|
158280
|
+
}
|
158265
158281
|
case InstructionKind.Let: {
|
158266
158282
|
CompilerError.invariant(instr.lvalue === null, {
|
158267
158283
|
reason: `Const declaration cannot be referenced as an expression`,
|
@@ -158303,19 +158319,11 @@ function codegenInstructionNullable(cx, instr) {
|
|
158303
158319
|
case InstructionKind.Catch: {
|
158304
158320
|
return t__namespace.emptyStatement();
|
158305
158321
|
}
|
158306
|
-
case InstructionKind.HoistedLet:
|
158322
|
+
case InstructionKind.HoistedLet:
|
158323
|
+
case InstructionKind.HoistedConst:
|
158324
|
+
case InstructionKind.HoistedFunction: {
|
158307
158325
|
CompilerError.invariant(false, {
|
158308
|
-
reason:
|
158309
|
-
'Expected HoistedLet to have been pruned in PruneHoistedContexts',
|
158310
|
-
description: null,
|
158311
|
-
loc: instr.loc,
|
158312
|
-
suggestions: null,
|
158313
|
-
});
|
158314
|
-
}
|
158315
|
-
case InstructionKind.HoistedConst: {
|
158316
|
-
CompilerError.invariant(false, {
|
158317
|
-
reason:
|
158318
|
-
'Expected HoistedConsts to have been pruned in PruneHoistedContexts',
|
158326
|
+
reason: `Expected ${kind} to have been pruned in PruneHoistedContexts`,
|
158319
158327
|
description: null,
|
158320
158328
|
loc: instr.loc,
|
158321
158329
|
suggestions: null,
|
@@ -158463,6 +158471,7 @@ function withLoc(fn) {
|
|
158463
158471
|
const createBinaryExpression = withLoc(t__namespace.binaryExpression);
|
158464
158472
|
const createExpressionStatement = withLoc(t__namespace.expressionStatement);
|
158465
158473
|
const createVariableDeclaration = withLoc(t__namespace.variableDeclaration);
|
158474
|
+
const createFunctionDeclaration = withLoc(t__namespace.functionDeclaration);
|
158466
158475
|
const createTaggedTemplateExpression = withLoc(
|
158467
158476
|
t__namespace.taggedTemplateExpression
|
158468
158477
|
);
|
@@ -162063,6 +162072,16 @@ let Visitor$8 = class Visitor extends ReactiveFunctionTransform {
|
|
162063
162072
|
);
|
162064
162073
|
return {kind: 'remove'};
|
162065
162074
|
}
|
162075
|
+
if (
|
162076
|
+
instruction.value.kind === 'DeclareContext' &&
|
162077
|
+
instruction.value.lvalue.kind === 'HoistedFunction'
|
162078
|
+
) {
|
162079
|
+
state.set(
|
162080
|
+
instruction.value.lvalue.place.identifier.declarationId,
|
162081
|
+
InstructionKind.Function
|
162082
|
+
);
|
162083
|
+
return {kind: 'remove'};
|
162084
|
+
}
|
162066
162085
|
if (
|
162067
162086
|
instruction.value.kind === 'StoreContext' &&
|
162068
162087
|
state.has(instruction.value.lvalue.place.identifier.declarationId)
|
@@ -167172,7 +167191,7 @@ function equation(left, right) {
|
|
167172
167191
|
return {left: left, right: right};
|
167173
167192
|
}
|
167174
167193
|
function* generate(func) {
|
167175
|
-
if (func.
|
167194
|
+
if (func.fnType === 'Component') {
|
167176
167195
|
const [props, ref] = func.params;
|
167177
167196
|
if (props && props.kind === 'Identifier') {
|
167178
167197
|
yield equation(props.identifier.type, {
|
@@ -168204,16 +168223,131 @@ function validateNoCapitalizedCalls(fn) {
|
|
168204
168223
|
}
|
168205
168224
|
}
|
168206
168225
|
}
|
168226
|
+
var _Env_changed;
|
168227
|
+
class Env extends Map {
|
168228
|
+
constructor() {
|
168229
|
+
super(...arguments);
|
168230
|
+
_Env_changed.set(this, false);
|
168231
|
+
}
|
168232
|
+
resetChanged() {
|
168233
|
+
__classPrivateFieldSet(this, _Env_changed, false, 'f');
|
168234
|
+
}
|
168235
|
+
hasChanged() {
|
168236
|
+
return __classPrivateFieldGet(this, _Env_changed, 'f');
|
168237
|
+
}
|
168238
|
+
set(key, value) {
|
168239
|
+
const cur = this.get(key);
|
168240
|
+
const widenedValue = joinRefAccessTypes(
|
168241
|
+
value,
|
168242
|
+
cur !== null && cur !== void 0 ? cur : {kind: 'None'}
|
168243
|
+
);
|
168244
|
+
if (
|
168245
|
+
!(cur == null && widenedValue.kind === 'None') &&
|
168246
|
+
(cur == null || !tyEqual(cur, widenedValue))
|
168247
|
+
) {
|
168248
|
+
__classPrivateFieldSet(this, _Env_changed, true, 'f');
|
168249
|
+
}
|
168250
|
+
return super.set(key, widenedValue);
|
168251
|
+
}
|
168252
|
+
}
|
168253
|
+
_Env_changed = new WeakMap();
|
168207
168254
|
function validateNoRefAccessInRender(fn) {
|
168208
|
-
const
|
168209
|
-
|
168210
|
-
|
168211
|
-
|
168212
|
-
|
168213
|
-
|
168255
|
+
const env = new Env();
|
168256
|
+
validateNoRefAccessInRenderImpl(fn, env).unwrap();
|
168257
|
+
}
|
168258
|
+
function refTypeOfType(identifier) {
|
168259
|
+
if (isRefValueType(identifier)) {
|
168260
|
+
return {kind: 'RefValue'};
|
168261
|
+
} else if (isUseRefType(identifier)) {
|
168262
|
+
return {kind: 'Ref'};
|
168263
|
+
} else {
|
168264
|
+
return {kind: 'None'};
|
168265
|
+
}
|
168214
168266
|
}
|
168215
|
-
function
|
168216
|
-
|
168267
|
+
function tyEqual(a, b) {
|
168268
|
+
if (a.kind !== b.kind) {
|
168269
|
+
return false;
|
168270
|
+
}
|
168271
|
+
switch (a.kind) {
|
168272
|
+
case 'None':
|
168273
|
+
return true;
|
168274
|
+
case 'Ref':
|
168275
|
+
return true;
|
168276
|
+
case 'RefValue':
|
168277
|
+
CompilerError.invariant(b.kind === 'RefValue', {
|
168278
|
+
reason: 'Expected ref value',
|
168279
|
+
loc: null,
|
168280
|
+
});
|
168281
|
+
return a.loc == b.loc;
|
168282
|
+
case 'Structure': {
|
168283
|
+
CompilerError.invariant(b.kind === 'Structure', {
|
168284
|
+
reason: 'Expected structure',
|
168285
|
+
loc: null,
|
168286
|
+
});
|
168287
|
+
const fnTypesEqual =
|
168288
|
+
(a.fn === null && b.fn === null) ||
|
168289
|
+
(a.fn !== null &&
|
168290
|
+
b.fn !== null &&
|
168291
|
+
a.fn.readRefEffect === b.fn.readRefEffect &&
|
168292
|
+
tyEqual(a.fn.returnType, b.fn.returnType));
|
168293
|
+
return (
|
168294
|
+
fnTypesEqual &&
|
168295
|
+
(a.value === b.value ||
|
168296
|
+
(a.value !== null && b.value !== null && tyEqual(a.value, b.value)))
|
168297
|
+
);
|
168298
|
+
}
|
168299
|
+
}
|
168300
|
+
}
|
168301
|
+
function joinRefAccessTypes(...types) {
|
168302
|
+
function joinRefAccessRefTypes(a, b) {
|
168303
|
+
if (a.kind === 'RefValue') {
|
168304
|
+
return a;
|
168305
|
+
} else if (b.kind === 'RefValue') {
|
168306
|
+
return b;
|
168307
|
+
} else if (a.kind === 'Ref' || b.kind === 'Ref') {
|
168308
|
+
return {kind: 'Ref'};
|
168309
|
+
} else {
|
168310
|
+
CompilerError.invariant(
|
168311
|
+
a.kind === 'Structure' && b.kind === 'Structure',
|
168312
|
+
{reason: 'Expected structure', loc: null}
|
168313
|
+
);
|
168314
|
+
const fn =
|
168315
|
+
a.fn === null
|
168316
|
+
? b.fn
|
168317
|
+
: b.fn === null
|
168318
|
+
? a.fn
|
168319
|
+
: {
|
168320
|
+
readRefEffect: a.fn.readRefEffect || b.fn.readRefEffect,
|
168321
|
+
returnType: joinRefAccessTypes(
|
168322
|
+
a.fn.returnType,
|
168323
|
+
b.fn.returnType
|
168324
|
+
),
|
168325
|
+
};
|
168326
|
+
const value =
|
168327
|
+
a.value === null
|
168328
|
+
? b.value
|
168329
|
+
: b.value === null
|
168330
|
+
? a.value
|
168331
|
+
: joinRefAccessRefTypes(a.value, b.value);
|
168332
|
+
return {kind: 'Structure', fn: fn, value: value};
|
168333
|
+
}
|
168334
|
+
}
|
168335
|
+
return types.reduce(
|
168336
|
+
(a, b) => {
|
168337
|
+
if (a.kind === 'None') {
|
168338
|
+
return b;
|
168339
|
+
} else if (b.kind === 'None') {
|
168340
|
+
return a;
|
168341
|
+
} else {
|
168342
|
+
return joinRefAccessRefTypes(a, b);
|
168343
|
+
}
|
168344
|
+
},
|
168345
|
+
{kind: 'None'}
|
168346
|
+
);
|
168347
|
+
}
|
168348
|
+
function validateNoRefAccessInRenderImpl(fn, env) {
|
168349
|
+
var _a, _b, _c, _d, _e, _f;
|
168350
|
+
let returnValues = [];
|
168217
168351
|
let place;
|
168218
168352
|
for (const param of fn.params) {
|
168219
168353
|
if (param.kind === 'Identifier') {
|
@@ -168221,291 +168355,293 @@ function validateNoRefAccessInRenderImpl(fn, state) {
|
|
168221
168355
|
} else {
|
168222
168356
|
place = param.place;
|
168223
168357
|
}
|
168224
|
-
|
168225
|
-
|
168226
|
-
}
|
168227
|
-
if (isUseRefType(place.identifier)) {
|
168228
|
-
state.refs.add(place.identifier.id);
|
168229
|
-
}
|
168358
|
+
const type = refTypeOfType(place.identifier);
|
168359
|
+
env.set(place.identifier.id, type);
|
168230
168360
|
}
|
168231
|
-
|
168232
|
-
|
168233
|
-
|
168234
|
-
|
168235
|
-
|
168236
|
-
|
168237
|
-
|
168238
|
-
|
168239
|
-
|
168240
|
-
|
168241
|
-
|
168242
|
-
|
168243
|
-
|
168244
|
-
|
168245
|
-
|
168246
|
-
|
168247
|
-
|
168248
|
-
: null
|
168249
|
-
);
|
168250
|
-
}
|
168251
|
-
if (state.refAccessingFunctions.has(operand.id)) {
|
168252
|
-
state.refAccessingFunctions.add(phi.id.id);
|
168253
|
-
}
|
168254
|
-
});
|
168255
|
-
}
|
168256
|
-
for (const instr of block.instructions) {
|
168257
|
-
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168258
|
-
if (isRefValueType(operand.identifier)) {
|
168259
|
-
CompilerError.invariant(state.refValues.has(operand.identifier.id), {
|
168260
|
-
reason: 'Expected ref value to be in state',
|
168261
|
-
loc: operand.loc,
|
168262
|
-
});
|
168263
|
-
}
|
168264
|
-
if (isUseRefType(operand.identifier)) {
|
168265
|
-
CompilerError.invariant(state.refs.has(operand.identifier.id), {
|
168266
|
-
reason: 'Expected ref to be in state',
|
168267
|
-
loc: operand.loc,
|
168268
|
-
});
|
168269
|
-
}
|
168361
|
+
for (let i = 0; (i == 0 || env.hasChanged()) && i < 10; i++) {
|
168362
|
+
env.resetChanged();
|
168363
|
+
returnValues = [];
|
168364
|
+
const errors = new CompilerError();
|
168365
|
+
for (const [, block] of fn.body.blocks) {
|
168366
|
+
for (const phi of block.phis) {
|
168367
|
+
env.set(
|
168368
|
+
phi.id.id,
|
168369
|
+
joinRefAccessTypes(
|
168370
|
+
...Array(...phi.operands.values()).map(operand => {
|
168371
|
+
var _a;
|
168372
|
+
return (_a = env.get(operand.id)) !== null && _a !== void 0
|
168373
|
+
? _a
|
168374
|
+
: {kind: 'None'};
|
168375
|
+
})
|
168376
|
+
)
|
168377
|
+
);
|
168270
168378
|
}
|
168271
|
-
|
168272
|
-
|
168273
|
-
|
168274
|
-
|
168275
|
-
|
168276
|
-
|
168277
|
-
|
168278
|
-
|
168279
|
-
case 'ComputedLoad':
|
168280
|
-
case 'PropertyLoad': {
|
168281
|
-
if (typeof instr.value.property !== 'string') {
|
168282
|
-
validateNoRefValueAccess(errors, state, instr.value.property);
|
168283
|
-
}
|
168284
|
-
if (
|
168285
|
-
state.refAccessingFunctions.has(instr.value.object.identifier.id)
|
168286
|
-
) {
|
168287
|
-
state.refAccessingFunctions.add(instr.lvalue.identifier.id);
|
168288
|
-
}
|
168289
|
-
if (state.refs.has(instr.value.object.identifier.id)) {
|
168290
|
-
state.refs.add(instr.lvalue.identifier.id);
|
168291
|
-
state.refValues.set(instr.lvalue.identifier.id, instr.loc);
|
168292
|
-
}
|
168293
|
-
break;
|
168294
|
-
}
|
168295
|
-
case 'LoadContext':
|
168296
|
-
case 'LoadLocal': {
|
168297
|
-
if (
|
168298
|
-
state.refAccessingFunctions.has(instr.value.place.identifier.id)
|
168299
|
-
) {
|
168300
|
-
state.refAccessingFunctions.add(instr.lvalue.identifier.id);
|
168301
|
-
}
|
168302
|
-
const refValue = state.refValues.get(instr.value.place.identifier.id);
|
168303
|
-
if (refValue !== undefined) {
|
168304
|
-
state.refValues.set(instr.lvalue.identifier.id, refValue);
|
168379
|
+
for (const instr of block.instructions) {
|
168380
|
+
switch (instr.value.kind) {
|
168381
|
+
case 'JsxExpression':
|
168382
|
+
case 'JsxFragment': {
|
168383
|
+
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168384
|
+
validateNoDirectRefValueAccess(errors, operand, env);
|
168385
|
+
}
|
168386
|
+
break;
|
168305
168387
|
}
|
168306
|
-
|
168307
|
-
|
168388
|
+
case 'ComputedLoad':
|
168389
|
+
case 'PropertyLoad': {
|
168390
|
+
if (typeof instr.value.property !== 'string') {
|
168391
|
+
validateNoDirectRefValueAccess(errors, instr.value.property, env);
|
168392
|
+
}
|
168393
|
+
const objType = env.get(instr.value.object.identifier.id);
|
168394
|
+
let lookupType = null;
|
168395
|
+
if (
|
168396
|
+
(objType === null || objType === void 0
|
168397
|
+
? void 0
|
168398
|
+
: objType.kind) === 'Structure'
|
168399
|
+
) {
|
168400
|
+
lookupType = objType.value;
|
168401
|
+
} else if (
|
168402
|
+
(objType === null || objType === void 0
|
168403
|
+
? void 0
|
168404
|
+
: objType.kind) === 'Ref'
|
168405
|
+
) {
|
168406
|
+
lookupType = {kind: 'RefValue', loc: instr.loc};
|
168407
|
+
}
|
168408
|
+
env.set(
|
168409
|
+
instr.lvalue.identifier.id,
|
168410
|
+
lookupType !== null && lookupType !== void 0
|
168411
|
+
? lookupType
|
168412
|
+
: refTypeOfType(instr.lvalue.identifier)
|
168413
|
+
);
|
168414
|
+
break;
|
168308
168415
|
}
|
168309
|
-
|
168310
|
-
|
168311
|
-
|
168312
|
-
|
168313
|
-
|
168314
|
-
|
168315
|
-
|
168316
|
-
|
168317
|
-
instr.value.lvalue.place.identifier.id
|
168416
|
+
case 'LoadContext':
|
168417
|
+
case 'LoadLocal': {
|
168418
|
+
env.set(
|
168419
|
+
instr.lvalue.identifier.id,
|
168420
|
+
(_a = env.get(instr.value.place.identifier.id)) !== null &&
|
168421
|
+
_a !== void 0
|
168422
|
+
? _a
|
168423
|
+
: refTypeOfType(instr.lvalue.identifier)
|
168318
168424
|
);
|
168319
|
-
|
168425
|
+
break;
|
168320
168426
|
}
|
168321
|
-
|
168322
|
-
|
168323
|
-
|
168324
|
-
isRefValueType(instr.value.lvalue.place.identifier)
|
168325
|
-
) {
|
168326
|
-
state.refValues.set(
|
168427
|
+
case 'StoreContext':
|
168428
|
+
case 'StoreLocal': {
|
168429
|
+
env.set(
|
168327
168430
|
instr.value.lvalue.place.identifier.id,
|
168328
|
-
|
168431
|
+
(_b = env.get(instr.value.value.identifier.id)) !== null &&
|
168432
|
+
_b !== void 0
|
168433
|
+
? _b
|
168434
|
+
: refTypeOfType(instr.value.lvalue.place.identifier)
|
168329
168435
|
);
|
168330
|
-
|
168436
|
+
env.set(
|
168331
168437
|
instr.lvalue.identifier.id,
|
168332
|
-
|
168438
|
+
(_c = env.get(instr.value.value.identifier.id)) !== null &&
|
168439
|
+
_c !== void 0
|
168440
|
+
? _c
|
168441
|
+
: refTypeOfType(instr.lvalue.identifier)
|
168333
168442
|
);
|
168443
|
+
break;
|
168334
168444
|
}
|
168335
|
-
|
168336
|
-
|
168337
|
-
|
168338
|
-
|
168339
|
-
|
168340
|
-
|
168341
|
-
|
168342
|
-
|
168343
|
-
|
168344
|
-
);
|
168345
|
-
const destructuredRef = state.refs.has(
|
168346
|
-
instr.value.value.identifier.id
|
168347
|
-
);
|
168348
|
-
for (const lval of eachPatternOperand(instr.value.lvalue.pattern)) {
|
168349
|
-
if (isUseRefType(lval.identifier)) {
|
168350
|
-
state.refs.add(lval.identifier.id);
|
168351
|
-
}
|
168352
|
-
if (destructuredRef || isRefValueType(lval.identifier)) {
|
168353
|
-
state.refs.add(lval.identifier.id);
|
168354
|
-
state.refValues.set(lval.identifier.id, null);
|
168445
|
+
case 'Destructure': {
|
168446
|
+
const objType = env.get(instr.value.value.identifier.id);
|
168447
|
+
let lookupType = null;
|
168448
|
+
if (
|
168449
|
+
(objType === null || objType === void 0
|
168450
|
+
? void 0
|
168451
|
+
: objType.kind) === 'Structure'
|
168452
|
+
) {
|
168453
|
+
lookupType = objType.value;
|
168355
168454
|
}
|
168356
|
-
|
168357
|
-
|
168455
|
+
env.set(
|
168456
|
+
instr.lvalue.identifier.id,
|
168457
|
+
lookupType !== null && lookupType !== void 0
|
168458
|
+
? lookupType
|
168459
|
+
: refTypeOfType(instr.lvalue.identifier)
|
168460
|
+
);
|
168461
|
+
for (const lval of eachPatternOperand(instr.value.lvalue.pattern)) {
|
168462
|
+
env.set(
|
168463
|
+
lval.identifier.id,
|
168464
|
+
lookupType !== null && lookupType !== void 0
|
168465
|
+
? lookupType
|
168466
|
+
: refTypeOfType(lval.identifier)
|
168467
|
+
);
|
168358
168468
|
}
|
168469
|
+
break;
|
168359
168470
|
}
|
168360
|
-
|
168361
|
-
|
168362
|
-
|
168363
|
-
|
168364
|
-
|
168365
|
-
|
168366
|
-
|
168367
|
-
|
168368
|
-
|
168369
|
-
|
168370
|
-
(
|
168371
|
-
|
168372
|
-
|
168373
|
-
|
168374
|
-
|
168375
|
-
|
168376
|
-
|
168377
|
-
|
168378
|
-
|
168471
|
+
case 'ObjectMethod':
|
168472
|
+
case 'FunctionExpression': {
|
168473
|
+
let returnType = {kind: 'None'};
|
168474
|
+
let readRefEffect = false;
|
168475
|
+
const result = validateNoRefAccessInRenderImpl(
|
168476
|
+
instr.value.loweredFunc.func,
|
168477
|
+
env
|
168478
|
+
);
|
168479
|
+
if (result.isOk()) {
|
168480
|
+
returnType = result.unwrap();
|
168481
|
+
} else if (result.isErr()) {
|
168482
|
+
readRefEffect = true;
|
168483
|
+
}
|
168484
|
+
env.set(instr.lvalue.identifier.id, {
|
168485
|
+
kind: 'Structure',
|
168486
|
+
fn: {readRefEffect: readRefEffect, returnType: returnType},
|
168487
|
+
value: null,
|
168488
|
+
});
|
168489
|
+
break;
|
168379
168490
|
}
|
168380
|
-
|
168381
|
-
|
168382
|
-
|
168383
|
-
|
168491
|
+
case 'MethodCall':
|
168492
|
+
case 'CallExpression': {
|
168493
|
+
const callee =
|
168494
|
+
instr.value.kind === 'CallExpression'
|
168495
|
+
? instr.value.callee
|
168496
|
+
: instr.value.property;
|
168497
|
+
const hookKind = getHookKindForType(fn.env, callee.identifier.type);
|
168498
|
+
let returnType = {kind: 'None'};
|
168499
|
+
const fnType = env.get(callee.identifier.id);
|
168500
|
+
if (
|
168501
|
+
(fnType === null || fnType === void 0 ? void 0 : fnType.kind) ===
|
168502
|
+
'Structure' &&
|
168503
|
+
fnType.fn !== null
|
168504
|
+
) {
|
168505
|
+
returnType = fnType.fn.returnType;
|
168506
|
+
if (fnType.fn.readRefEffect) {
|
168507
|
+
errors.push({
|
168508
|
+
severity: exports.ErrorSeverity.InvalidReact,
|
168509
|
+
reason:
|
168510
|
+
'This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)',
|
168511
|
+
loc: callee.loc,
|
168512
|
+
description:
|
168513
|
+
callee.identifier.name !== null &&
|
168514
|
+
callee.identifier.name.kind === 'named'
|
168515
|
+
? `Function \`${callee.identifier.name.value}\` accesses a ref`
|
168516
|
+
: null,
|
168517
|
+
suggestions: null,
|
168518
|
+
});
|
168519
|
+
}
|
168520
|
+
}
|
168384
168521
|
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168385
|
-
|
168522
|
+
if (hookKind != null) {
|
168523
|
+
validateNoDirectRefValueAccess(errors, operand, env);
|
168524
|
+
} else {
|
168525
|
+
validateNoRefAccess(errors, env, operand, operand.loc);
|
168526
|
+
}
|
168386
168527
|
}
|
168528
|
+
env.set(instr.lvalue.identifier.id, returnType);
|
168529
|
+
break;
|
168387
168530
|
}
|
168388
|
-
|
168389
|
-
|
168390
|
-
|
168391
|
-
const callee = instr.value.callee;
|
168392
|
-
const isUseEffect = isEffectHook(callee.identifier);
|
168393
|
-
if (!isUseEffect) {
|
168394
|
-
if (state.refAccessingFunctions.has(callee.identifier.id)) {
|
168395
|
-
errors.push({
|
168396
|
-
severity: exports.ErrorSeverity.InvalidReact,
|
168397
|
-
reason:
|
168398
|
-
'This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)',
|
168399
|
-
loc: callee.loc,
|
168400
|
-
description:
|
168401
|
-
callee.identifier.name !== null &&
|
168402
|
-
callee.identifier.name.kind === 'named'
|
168403
|
-
? `Function \`${callee.identifier.name.value}\` accesses a ref`
|
168404
|
-
: null,
|
168405
|
-
suggestions: null,
|
168406
|
-
});
|
168407
|
-
}
|
168531
|
+
case 'ObjectExpression':
|
168532
|
+
case 'ArrayExpression': {
|
168533
|
+
const types = [];
|
168408
168534
|
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168409
|
-
|
168410
|
-
|
168411
|
-
|
168412
|
-
|
168413
|
-
|
168414
|
-
_a !== void 0
|
168415
|
-
? _a
|
168416
|
-
: operand.loc
|
168535
|
+
validateNoDirectRefValueAccess(errors, operand, env);
|
168536
|
+
types.push(
|
168537
|
+
(_d = env.get(operand.identifier.id)) !== null && _d !== void 0
|
168538
|
+
? _d
|
168539
|
+
: {kind: 'None'}
|
168417
168540
|
);
|
168418
168541
|
}
|
168419
|
-
|
168420
|
-
|
168421
|
-
|
168422
|
-
|
168423
|
-
|
168424
|
-
|
168425
|
-
|
168426
|
-
|
168427
|
-
|
168542
|
+
const value = joinRefAccessTypes(...types);
|
168543
|
+
if (value.kind === 'None') {
|
168544
|
+
env.set(instr.lvalue.identifier.id, {kind: 'None'});
|
168545
|
+
} else {
|
168546
|
+
env.set(instr.lvalue.identifier.id, {
|
168547
|
+
kind: 'Structure',
|
168548
|
+
value: value,
|
168549
|
+
fn: null,
|
168550
|
+
});
|
168428
168551
|
}
|
168429
|
-
|
168430
|
-
|
168552
|
+
break;
|
168553
|
+
}
|
168554
|
+
case 'PropertyDelete':
|
168555
|
+
case 'PropertyStore':
|
168556
|
+
case 'ComputedDelete':
|
168557
|
+
case 'ComputedStore': {
|
168558
|
+
validateNoRefAccess(errors, env, instr.value.object, instr.loc);
|
168559
|
+
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168560
|
+
if (operand === instr.value.object) {
|
168561
|
+
continue;
|
168562
|
+
}
|
168563
|
+
validateNoRefValueAccess(errors, env, operand);
|
168431
168564
|
}
|
168432
|
-
|
168433
|
-
|
168434
|
-
|
168565
|
+
break;
|
168566
|
+
}
|
168567
|
+
case 'StartMemoize':
|
168568
|
+
case 'FinishMemoize':
|
168569
|
+
break;
|
168570
|
+
default: {
|
168571
|
+
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168572
|
+
validateNoRefValueAccess(errors, env, operand);
|
168435
168573
|
}
|
168574
|
+
break;
|
168436
168575
|
}
|
168437
|
-
break;
|
168438
168576
|
}
|
168439
|
-
|
168440
|
-
|
168441
|
-
|
168442
|
-
|
168443
|
-
|
168444
|
-
|
168445
|
-
|
168446
|
-
|
168447
|
-
|
168448
|
-
|
168449
|
-
? _b
|
168450
|
-
: instr.loc
|
168577
|
+
if (isUseRefType(instr.lvalue.identifier)) {
|
168578
|
+
env.set(
|
168579
|
+
instr.lvalue.identifier.id,
|
168580
|
+
joinRefAccessTypes(
|
168581
|
+
(_e = env.get(instr.lvalue.identifier.id)) !== null &&
|
168582
|
+
_e !== void 0
|
168583
|
+
? _e
|
168584
|
+
: {kind: 'None'},
|
168585
|
+
{kind: 'Ref'}
|
168586
|
+
)
|
168451
168587
|
);
|
168452
|
-
for (const operand of eachInstructionValueOperand(instr.value)) {
|
168453
|
-
if (operand === instr.value.object) {
|
168454
|
-
continue;
|
168455
|
-
}
|
168456
|
-
validateNoRefValueAccess(errors, state, operand);
|
168457
|
-
}
|
168458
|
-
break;
|
168459
168588
|
}
|
168460
|
-
|
168461
|
-
|
168462
|
-
|
168463
|
-
|
168464
|
-
|
168465
|
-
|
168466
|
-
|
168467
|
-
|
168589
|
+
if (isRefValueType(instr.lvalue.identifier)) {
|
168590
|
+
env.set(
|
168591
|
+
instr.lvalue.identifier.id,
|
168592
|
+
joinRefAccessTypes(
|
168593
|
+
(_f = env.get(instr.lvalue.identifier.id)) !== null &&
|
168594
|
+
_f !== void 0
|
168595
|
+
? _f
|
168596
|
+
: {kind: 'None'},
|
168597
|
+
{kind: 'RefValue', loc: instr.loc}
|
168598
|
+
)
|
168599
|
+
);
|
168468
168600
|
}
|
168469
168601
|
}
|
168470
|
-
|
168471
|
-
|
168472
|
-
|
168473
|
-
|
168474
|
-
|
168475
|
-
|
168476
|
-
|
168477
|
-
state.refValues.set(instr.lvalue.identifier.id, instr.loc);
|
168602
|
+
for (const operand of eachTerminalOperand(block.terminal)) {
|
168603
|
+
if (block.terminal.kind !== 'return') {
|
168604
|
+
validateNoRefValueAccess(errors, env, operand);
|
168605
|
+
} else {
|
168606
|
+
validateNoDirectRefValueAccess(errors, operand, env);
|
168607
|
+
returnValues.push(env.get(operand.identifier.id));
|
168608
|
+
}
|
168478
168609
|
}
|
168479
168610
|
}
|
168480
|
-
|
168481
|
-
|
168482
|
-
validateNoRefValueAccess(errors, state, operand);
|
168483
|
-
} else {
|
168484
|
-
validateNoDirectRefValueAccess(errors, operand, state);
|
168485
|
-
}
|
168611
|
+
if (errors.hasErrors()) {
|
168612
|
+
return Err(errors);
|
168486
168613
|
}
|
168487
168614
|
}
|
168488
|
-
|
168489
|
-
|
168490
|
-
|
168491
|
-
|
168615
|
+
CompilerError.invariant(!env.hasChanged(), {
|
168616
|
+
reason: 'Ref type environment did not converge',
|
168617
|
+
loc: null,
|
168618
|
+
});
|
168619
|
+
return Ok(
|
168620
|
+
joinRefAccessTypes(...returnValues.filter(env => env !== undefined))
|
168621
|
+
);
|
168622
|
+
}
|
168623
|
+
function destructure(type) {
|
168624
|
+
if (
|
168625
|
+
(type === null || type === void 0 ? void 0 : type.kind) === 'Structure' &&
|
168626
|
+
type.value !== null
|
168627
|
+
) {
|
168628
|
+
return destructure(type.value);
|
168492
168629
|
}
|
168630
|
+
return type;
|
168493
168631
|
}
|
168494
|
-
function validateNoRefValueAccess(errors,
|
168632
|
+
function validateNoRefValueAccess(errors, env, operand) {
|
168495
168633
|
var _a;
|
168634
|
+
const type = destructure(env.get(operand.identifier.id));
|
168496
168635
|
if (
|
168497
|
-
|
168498
|
-
|
168636
|
+
(type === null || type === void 0 ? void 0 : type.kind) === 'RefValue' ||
|
168637
|
+
((type === null || type === void 0 ? void 0 : type.kind) === 'Structure' &&
|
168638
|
+
((_a = type.fn) === null || _a === void 0 ? void 0 : _a.readRefEffect))
|
168499
168639
|
) {
|
168500
168640
|
errors.push({
|
168501
168641
|
severity: exports.ErrorSeverity.InvalidReact,
|
168502
168642
|
reason:
|
168503
168643
|
'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)',
|
168504
|
-
loc:
|
168505
|
-
(_a = state.refValues.get(operand.identifier.id)) !== null &&
|
168506
|
-
_a !== void 0
|
168507
|
-
? _a
|
168508
|
-
: operand.loc,
|
168644
|
+
loc: (type.kind === 'RefValue' && type.loc) || operand.loc,
|
168509
168645
|
description:
|
168510
168646
|
operand.identifier.name !== null &&
|
168511
168647
|
operand.identifier.name.kind === 'named'
|
@@ -168515,17 +168651,20 @@ function validateNoRefValueAccess(errors, state, operand) {
|
|
168515
168651
|
});
|
168516
168652
|
}
|
168517
168653
|
}
|
168518
|
-
function validateNoRefAccess(errors,
|
168654
|
+
function validateNoRefAccess(errors, env, operand, loc) {
|
168655
|
+
var _a;
|
168656
|
+
const type = destructure(env.get(operand.identifier.id));
|
168519
168657
|
if (
|
168520
|
-
|
168521
|
-
|
168522
|
-
|
168658
|
+
(type === null || type === void 0 ? void 0 : type.kind) === 'Ref' ||
|
168659
|
+
(type === null || type === void 0 ? void 0 : type.kind) === 'RefValue' ||
|
168660
|
+
((type === null || type === void 0 ? void 0 : type.kind) === 'Structure' &&
|
168661
|
+
((_a = type.fn) === null || _a === void 0 ? void 0 : _a.readRefEffect))
|
168523
168662
|
) {
|
168524
168663
|
errors.push({
|
168525
168664
|
severity: exports.ErrorSeverity.InvalidReact,
|
168526
168665
|
reason:
|
168527
168666
|
'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)',
|
168528
|
-
loc: loc,
|
168667
|
+
loc: (type.kind === 'RefValue' && type.loc) || loc,
|
168529
168668
|
description:
|
168530
168669
|
operand.identifier.name !== null &&
|
168531
168670
|
operand.identifier.name.kind === 'named'
|
@@ -168535,18 +168674,15 @@ function validateNoRefAccess(errors, state, operand, loc) {
|
|
168535
168674
|
});
|
168536
168675
|
}
|
168537
168676
|
}
|
168538
|
-
function validateNoDirectRefValueAccess(errors, operand,
|
168677
|
+
function validateNoDirectRefValueAccess(errors, operand, env) {
|
168539
168678
|
var _a;
|
168540
|
-
|
168679
|
+
const type = destructure(env.get(operand.identifier.id));
|
168680
|
+
if ((type === null || type === void 0 ? void 0 : type.kind) === 'RefValue') {
|
168541
168681
|
errors.push({
|
168542
168682
|
severity: exports.ErrorSeverity.InvalidReact,
|
168543
168683
|
reason:
|
168544
168684
|
'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)',
|
168545
|
-
loc:
|
168546
|
-
(_a = state.refValues.get(operand.identifier.id)) !== null &&
|
168547
|
-
_a !== void 0
|
168548
|
-
? _a
|
168549
|
-
: operand.loc,
|
168685
|
+
loc: (_a = type.loc) !== null && _a !== void 0 ? _a : operand.loc,
|
168550
168686
|
description:
|
168551
168687
|
operand.identifier.name !== null &&
|
168552
168688
|
operand.identifier.name.kind === 'named'
|