Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9de6284f7 |
@@ -474,7 +474,7 @@ module.exports = {
|
||||
{
|
||||
files: ['packages/react-server-dom-turbopack/**/*.js'],
|
||||
globals: {
|
||||
__turbopack_load_by_url__: 'readonly',
|
||||
__turbopack_load__: 'readonly',
|
||||
__turbopack_require__: 'readonly',
|
||||
},
|
||||
},
|
||||
|
||||
44
.github/workflows/runtime_build_and_test.yml
vendored
44
.github/workflows/runtime_build_and_test.yml
vendored
@@ -6,12 +6,6 @@ on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- compiler/**
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
commit_sha:
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
permissions: {}
|
||||
|
||||
@@ -34,7 +28,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- name: Check cache hit
|
||||
uses: actions/cache/restore@v4
|
||||
id: node_modules
|
||||
@@ -75,7 +69,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- name: Check cache hit
|
||||
uses: actions/cache/restore@v4
|
||||
id: node_modules
|
||||
@@ -123,7 +117,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/github-script@v7
|
||||
id: set-matrix
|
||||
with:
|
||||
@@ -142,7 +136,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -172,7 +166,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -204,7 +198,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -260,7 +254,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -331,7 +325,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -426,7 +420,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -471,7 +465,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -499,7 +493,7 @@ jobs:
|
||||
merge-multiple: true
|
||||
- name: Display structure of build
|
||||
run: ls -R build
|
||||
- run: echo ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
|
||||
- run: echo ${{ github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
|
||||
- name: Scrape warning messages
|
||||
run: |
|
||||
mkdir -p ./build/__test_utils__
|
||||
@@ -536,7 +530,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -576,7 +570,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -613,7 +607,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -654,7 +648,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -728,7 +722,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -785,7 +779,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -830,7 +824,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
@@ -879,7 +873,7 @@ jobs:
|
||||
node ./scripts/print-warnings/print-warnings.js > build/__test_utils__/ReactAllWarnings.js
|
||||
- name: Display structure of build for PR
|
||||
run: ls -R build
|
||||
- run: echo ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
|
||||
- run: echo ${{ github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
|
||||
- run: node ./scripts/tasks/danger
|
||||
- name: Archive sizebot results
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
pipelineUsesReanimatedPlugin,
|
||||
} from '../Entrypoint/Reanimated';
|
||||
import validateNoUntransformedReferences from '../Entrypoint/ValidateNoUntransformedReferences';
|
||||
import {CompilerError} from '..';
|
||||
|
||||
const ENABLE_REACT_COMPILER_TIMINGS =
|
||||
process.env['ENABLE_REACT_COMPILER_TIMINGS'] === '1';
|
||||
@@ -35,58 +34,51 @@ export default function BabelPluginReactCompiler(
|
||||
*/
|
||||
Program: {
|
||||
enter(prog, pass): void {
|
||||
try {
|
||||
const filename = pass.filename ?? 'unknown';
|
||||
if (ENABLE_REACT_COMPILER_TIMINGS === true) {
|
||||
performance.mark(`${filename}:start`, {
|
||||
detail: 'BabelPlugin:Program:start',
|
||||
});
|
||||
}
|
||||
let opts = parsePluginOptions(pass.opts);
|
||||
const isDev =
|
||||
(typeof __DEV__ !== 'undefined' && __DEV__ === true) ||
|
||||
process.env['NODE_ENV'] === 'development';
|
||||
if (
|
||||
opts.enableReanimatedCheck === true &&
|
||||
pipelineUsesReanimatedPlugin(pass.file.opts.plugins)
|
||||
) {
|
||||
opts = injectReanimatedFlag(opts);
|
||||
}
|
||||
if (
|
||||
opts.environment.enableResetCacheOnSourceFileChanges !== false &&
|
||||
isDev
|
||||
) {
|
||||
opts = {
|
||||
...opts,
|
||||
environment: {
|
||||
...opts.environment,
|
||||
enableResetCacheOnSourceFileChanges: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
const result = compileProgram(prog, {
|
||||
opts,
|
||||
filename: pass.filename ?? null,
|
||||
comments: pass.file.ast.comments ?? [],
|
||||
code: pass.file.code,
|
||||
const filename = pass.filename ?? 'unknown';
|
||||
if (ENABLE_REACT_COMPILER_TIMINGS === true) {
|
||||
performance.mark(`${filename}:start`, {
|
||||
detail: 'BabelPlugin:Program:start',
|
||||
});
|
||||
}
|
||||
let opts = parsePluginOptions(pass.opts);
|
||||
const isDev =
|
||||
(typeof __DEV__ !== 'undefined' && __DEV__ === true) ||
|
||||
process.env['NODE_ENV'] === 'development';
|
||||
if (
|
||||
opts.enableReanimatedCheck === true &&
|
||||
pipelineUsesReanimatedPlugin(pass.file.opts.plugins)
|
||||
) {
|
||||
opts = injectReanimatedFlag(opts);
|
||||
}
|
||||
if (
|
||||
opts.environment.enableResetCacheOnSourceFileChanges !== false &&
|
||||
isDev
|
||||
) {
|
||||
opts = {
|
||||
...opts,
|
||||
environment: {
|
||||
...opts.environment,
|
||||
enableResetCacheOnSourceFileChanges: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
const result = compileProgram(prog, {
|
||||
opts,
|
||||
filename: pass.filename ?? null,
|
||||
comments: pass.file.ast.comments ?? [],
|
||||
code: pass.file.code,
|
||||
});
|
||||
validateNoUntransformedReferences(
|
||||
prog,
|
||||
pass.filename ?? null,
|
||||
opts.logger,
|
||||
opts.environment,
|
||||
result,
|
||||
);
|
||||
if (ENABLE_REACT_COMPILER_TIMINGS === true) {
|
||||
performance.mark(`${filename}:end`, {
|
||||
detail: 'BabelPlugin:Program:end',
|
||||
});
|
||||
validateNoUntransformedReferences(
|
||||
prog,
|
||||
pass.filename ?? null,
|
||||
opts.logger,
|
||||
opts.environment,
|
||||
result,
|
||||
);
|
||||
if (ENABLE_REACT_COMPILER_TIMINGS === true) {
|
||||
performance.mark(`${filename}:end`, {
|
||||
detail: 'BabelPlugin:Program:end',
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof CompilerError) {
|
||||
throw new Error(e.printErrorMessage(pass.file.code));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
exit(_, pass): void {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {codeFrameColumns} from '@babel/code-frame';
|
||||
import type {SourceLocation} from './HIR';
|
||||
import {Err, Ok, Result} from './Utils/Result';
|
||||
import {assertExhaustive} from './Utils/utils';
|
||||
@@ -16,11 +15,6 @@ export enum ErrorSeverity {
|
||||
* misunderstanding on the user’s part.
|
||||
*/
|
||||
InvalidJS = 'InvalidJS',
|
||||
/**
|
||||
* JS syntax that is not supported and which we do not plan to support. Developers should
|
||||
* rewrite to use supported forms.
|
||||
*/
|
||||
UnsupportedJS = 'UnsupportedJS',
|
||||
/**
|
||||
* Code that breaks the rules of React.
|
||||
*/
|
||||
@@ -45,24 +39,6 @@ export enum ErrorSeverity {
|
||||
Invariant = 'Invariant',
|
||||
}
|
||||
|
||||
export type CompilerDiagnosticOptions = {
|
||||
severity: ErrorSeverity;
|
||||
category: string;
|
||||
description: string;
|
||||
details: Array<CompilerDiagnosticDetail>;
|
||||
suggestions?: Array<CompilerSuggestion> | null | undefined;
|
||||
};
|
||||
|
||||
export type CompilerDiagnosticDetail =
|
||||
/**
|
||||
* A/the source of the error
|
||||
*/
|
||||
{
|
||||
kind: 'error';
|
||||
loc: SourceLocation;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export enum CompilerSuggestionOperation {
|
||||
InsertBefore,
|
||||
InsertAfter,
|
||||
@@ -93,94 +69,6 @@ export type CompilerErrorDetailOptions = {
|
||||
suggestions?: Array<CompilerSuggestion> | null | undefined;
|
||||
};
|
||||
|
||||
export class CompilerDiagnostic {
|
||||
options: CompilerDiagnosticOptions;
|
||||
|
||||
constructor(options: CompilerDiagnosticOptions) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
get category(): CompilerDiagnosticOptions['category'] {
|
||||
return this.options.category;
|
||||
}
|
||||
get description(): CompilerDiagnosticOptions['description'] {
|
||||
return this.options.description;
|
||||
}
|
||||
get severity(): CompilerDiagnosticOptions['severity'] {
|
||||
return this.options.severity;
|
||||
}
|
||||
get suggestions(): CompilerDiagnosticOptions['suggestions'] {
|
||||
return this.options.suggestions;
|
||||
}
|
||||
|
||||
primaryLocation(): SourceLocation | null {
|
||||
return this.options.details.filter(d => d.kind === 'error')[0]?.loc ?? null;
|
||||
}
|
||||
|
||||
printErrorMessage(source: string): string {
|
||||
const buffer = [
|
||||
printErrorSummary(this.severity, this.category),
|
||||
'\n\n',
|
||||
this.description,
|
||||
];
|
||||
for (const detail of this.options.details) {
|
||||
switch (detail.kind) {
|
||||
case 'error': {
|
||||
const loc = detail.loc;
|
||||
if (typeof loc === 'symbol') {
|
||||
continue;
|
||||
}
|
||||
let codeFrame: string;
|
||||
try {
|
||||
codeFrame = codeFrameColumns(
|
||||
source,
|
||||
{
|
||||
start: {
|
||||
line: loc.start.line,
|
||||
column: loc.start.column + 1,
|
||||
},
|
||||
end: {
|
||||
line: loc.end.line,
|
||||
column: loc.end.column + 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
message: detail.message,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
codeFrame = detail.message;
|
||||
}
|
||||
buffer.push(
|
||||
`\n\n${loc.filename}:${loc.start.line}:${loc.start.column}\n`,
|
||||
);
|
||||
buffer.push(codeFrame);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assertExhaustive(
|
||||
detail.kind,
|
||||
`Unexpected detail kind ${(detail as any).kind}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer.join('');
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const buffer = [printErrorSummary(this.severity, this.category)];
|
||||
if (this.description != null) {
|
||||
buffer.push(`. ${this.description}.`);
|
||||
}
|
||||
const loc = this.primaryLocation();
|
||||
if (loc != null && typeof loc !== 'symbol') {
|
||||
buffer.push(` (${loc.start.line}:${loc.start.column})`);
|
||||
}
|
||||
return buffer.join('');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Each bailout or invariant in HIR lowering creates an {@link CompilerErrorDetail}, which is then
|
||||
* aggregated into a single {@link CompilerError} later.
|
||||
@@ -208,62 +96,24 @@ export class CompilerErrorDetail {
|
||||
return this.options.suggestions;
|
||||
}
|
||||
|
||||
primaryLocation(): SourceLocation | null {
|
||||
return this.loc;
|
||||
}
|
||||
|
||||
printErrorMessage(source: string): string {
|
||||
const buffer = [printErrorSummary(this.severity, this.reason)];
|
||||
printErrorMessage(): string {
|
||||
const buffer = [`${this.severity}: ${this.reason}`];
|
||||
if (this.description != null) {
|
||||
buffer.push(`\n\n${this.description}.`);
|
||||
buffer.push(`. ${this.description}`);
|
||||
}
|
||||
const loc = this.loc;
|
||||
if (loc != null && typeof loc !== 'symbol') {
|
||||
let codeFrame: string;
|
||||
try {
|
||||
codeFrame = codeFrameColumns(
|
||||
source,
|
||||
{
|
||||
start: {
|
||||
line: loc.start.line,
|
||||
column: loc.start.column + 1,
|
||||
},
|
||||
end: {
|
||||
line: loc.end.line,
|
||||
column: loc.end.column + 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
message: this.reason,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
codeFrame = '';
|
||||
}
|
||||
buffer.push(
|
||||
`\n\n${loc.filename}:${loc.start.line}:${loc.start.column}\n`,
|
||||
);
|
||||
buffer.push(codeFrame);
|
||||
buffer.push('\n\n');
|
||||
if (this.loc != null && typeof this.loc !== 'symbol') {
|
||||
buffer.push(` (${this.loc.start.line}:${this.loc.end.line})`);
|
||||
}
|
||||
return buffer.join('');
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const buffer = [printErrorSummary(this.severity, this.reason)];
|
||||
if (this.description != null) {
|
||||
buffer.push(`. ${this.description}.`);
|
||||
}
|
||||
const loc = this.loc;
|
||||
if (loc != null && typeof loc !== 'symbol') {
|
||||
buffer.push(` (${loc.start.line}:${loc.start.column})`);
|
||||
}
|
||||
return buffer.join('');
|
||||
return this.printErrorMessage();
|
||||
}
|
||||
}
|
||||
|
||||
export class CompilerError extends Error {
|
||||
details: Array<CompilerErrorDetail | CompilerDiagnostic> = [];
|
||||
details: Array<CompilerErrorDetail> = [];
|
||||
|
||||
static invariant(
|
||||
condition: unknown,
|
||||
@@ -281,12 +131,6 @@ export class CompilerError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
static throwDiagnostic(options: CompilerDiagnosticOptions): never {
|
||||
const errors = new CompilerError();
|
||||
errors.pushDiagnostic(new CompilerDiagnostic(options));
|
||||
throw errors;
|
||||
}
|
||||
|
||||
static throwTodo(
|
||||
options: Omit<CompilerErrorDetailOptions, 'severity'>,
|
||||
): never {
|
||||
@@ -361,21 +205,6 @@ export class CompilerError extends Error {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
printErrorMessage(source: string): string {
|
||||
return (
|
||||
`Found ${this.details.length} error${this.details.length === 1 ? '' : 's'}:\n` +
|
||||
this.details.map(detail => detail.printErrorMessage(source)).join('\n')
|
||||
);
|
||||
}
|
||||
|
||||
merge(other: CompilerError): void {
|
||||
this.details.push(...other.details);
|
||||
}
|
||||
|
||||
pushDiagnostic(diagnostic: CompilerDiagnostic): void {
|
||||
this.details.push(diagnostic);
|
||||
}
|
||||
|
||||
push(options: CompilerErrorDetailOptions): CompilerErrorDetail {
|
||||
const detail = new CompilerErrorDetail({
|
||||
reason: options.reason,
|
||||
@@ -412,46 +241,13 @@ export class CompilerError extends Error {
|
||||
case ErrorSeverity.InvalidJS:
|
||||
case ErrorSeverity.InvalidReact:
|
||||
case ErrorSeverity.InvalidConfig:
|
||||
case ErrorSeverity.UnsupportedJS: {
|
||||
return true;
|
||||
}
|
||||
case ErrorSeverity.CannotPreserveMemoization:
|
||||
case ErrorSeverity.Todo: {
|
||||
case ErrorSeverity.Todo:
|
||||
return false;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
assertExhaustive(detail.severity, 'Unhandled error severity');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function printErrorSummary(severity: ErrorSeverity, message: string): string {
|
||||
let severityCategory: string;
|
||||
switch (severity) {
|
||||
case ErrorSeverity.InvalidConfig:
|
||||
case ErrorSeverity.InvalidJS:
|
||||
case ErrorSeverity.InvalidReact:
|
||||
case ErrorSeverity.UnsupportedJS: {
|
||||
severityCategory = 'Error';
|
||||
break;
|
||||
}
|
||||
case ErrorSeverity.CannotPreserveMemoization: {
|
||||
severityCategory = 'Memoization';
|
||||
break;
|
||||
}
|
||||
case ErrorSeverity.Invariant: {
|
||||
severityCategory = 'Invariant';
|
||||
break;
|
||||
}
|
||||
case ErrorSeverity.Todo: {
|
||||
severityCategory = 'Todo';
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assertExhaustive(severity, `Unexpected severity '${severity}'`);
|
||||
}
|
||||
}
|
||||
return `${severityCategory}: ${message}`;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,7 @@
|
||||
|
||||
import * as t from '@babel/types';
|
||||
import {z} from 'zod';
|
||||
import {
|
||||
CompilerDiagnostic,
|
||||
CompilerError,
|
||||
CompilerErrorDetail,
|
||||
CompilerErrorDetailOptions,
|
||||
} from '../CompilerError';
|
||||
import {CompilerError, CompilerErrorDetailOptions} from '../CompilerError';
|
||||
import {
|
||||
EnvironmentConfig,
|
||||
ExternalFunction,
|
||||
@@ -229,7 +224,7 @@ export type LoggerEvent =
|
||||
export type CompileErrorEvent = {
|
||||
kind: 'CompileError';
|
||||
fnLoc: t.SourceLocation | null;
|
||||
detail: CompilerErrorDetail | CompilerDiagnostic;
|
||||
detail: CompilerErrorDetailOptions;
|
||||
};
|
||||
export type CompileDiagnosticEvent = {
|
||||
kind: 'CompileDiagnostic';
|
||||
|
||||
@@ -94,7 +94,7 @@ import {validateLocalsNotReassignedAfterRender} from '../Validation/ValidateLoca
|
||||
import {outlineFunctions} from '../Optimization/OutlineFunctions';
|
||||
import {propagatePhiTypes} from '../TypeInference/PropagatePhiTypes';
|
||||
import {lowerContextAccess} from '../Optimization/LowerContextAccess';
|
||||
import {validateNoSetStateInEffects} from '../Validation/ValidateNoSetStateInEffects';
|
||||
import {validateNoSetStateInPassiveEffects} from '../Validation/ValidateNoSetStateInPassiveEffects';
|
||||
import {validateNoJSXInTryStatement} from '../Validation/ValidateNoJSXInTryStatement';
|
||||
import {propagateScopeDependenciesHIR} from '../HIR/PropagateScopeDependenciesHIR';
|
||||
import {outlineJSX} from '../Optimization/OutlineJsx';
|
||||
@@ -292,8 +292,8 @@ function runWithEnvironment(
|
||||
validateNoSetStateInRender(hir).unwrap();
|
||||
}
|
||||
|
||||
if (env.config.validateNoSetStateInEffects) {
|
||||
env.logErrors(validateNoSetStateInEffects(hir));
|
||||
if (env.config.validateNoSetStateInPassiveEffects) {
|
||||
env.logErrors(validateNoSetStateInPassiveEffects(hir));
|
||||
}
|
||||
|
||||
if (env.config.validateNoJSXInTryStatements) {
|
||||
|
||||
@@ -181,7 +181,7 @@ function logError(
|
||||
context.opts.logger.logEvent(context.filename, {
|
||||
kind: 'CompileError',
|
||||
fnLoc,
|
||||
detail,
|
||||
detail: detail.options,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -8,63 +8,35 @@
|
||||
import {NodePath} from '@babel/core';
|
||||
import * as t from '@babel/types';
|
||||
|
||||
import {CompilerError, EnvironmentConfig, ErrorSeverity, Logger} from '..';
|
||||
import {
|
||||
CompilerError,
|
||||
CompilerErrorDetailOptions,
|
||||
EnvironmentConfig,
|
||||
ErrorSeverity,
|
||||
Logger,
|
||||
} from '..';
|
||||
import {getOrInsertWith} from '../Utils/utils';
|
||||
import {Environment, GeneratedSource} from '../HIR';
|
||||
import {Environment} from '../HIR';
|
||||
import {DEFAULT_EXPORT} from '../HIR/Environment';
|
||||
import {CompileProgramMetadata} from './Program';
|
||||
import {CompilerDiagnostic, CompilerDiagnosticOptions} from '../CompilerError';
|
||||
|
||||
function throwInvalidReact(
|
||||
options: Omit<CompilerDiagnosticOptions, 'severity'>,
|
||||
options: Omit<CompilerErrorDetailOptions, 'severity'>,
|
||||
{logger, filename}: TraversalState,
|
||||
): never {
|
||||
const detail: CompilerDiagnosticOptions = {
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
const detail: CompilerErrorDetailOptions = {
|
||||
...options,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
};
|
||||
logger?.logEvent(filename, {
|
||||
kind: 'CompileError',
|
||||
fnLoc: null,
|
||||
detail: new CompilerDiagnostic(detail),
|
||||
detail,
|
||||
});
|
||||
CompilerError.throwDiagnostic(detail);
|
||||
}
|
||||
|
||||
function isAutodepsSigil(
|
||||
arg: NodePath<t.ArgumentPlaceholder | t.SpreadElement | t.Expression>,
|
||||
): boolean {
|
||||
// Check for AUTODEPS identifier imported from React
|
||||
if (arg.isIdentifier() && arg.node.name === 'AUTODEPS') {
|
||||
const binding = arg.scope.getBinding(arg.node.name);
|
||||
if (binding && binding.path.isImportSpecifier()) {
|
||||
const importSpecifier = binding.path.node as t.ImportSpecifier;
|
||||
if (importSpecifier.imported.type === 'Identifier') {
|
||||
return (importSpecifier.imported as t.Identifier).name === 'AUTODEPS';
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for React.AUTODEPS member expression
|
||||
if (arg.isMemberExpression() && !arg.node.computed) {
|
||||
const object = arg.get('object');
|
||||
const property = arg.get('property');
|
||||
|
||||
if (
|
||||
object.isIdentifier() &&
|
||||
object.node.name === 'React' &&
|
||||
property.isIdentifier() &&
|
||||
property.node.name === 'AUTODEPS'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
CompilerError.throw(detail);
|
||||
}
|
||||
function assertValidEffectImportReference(
|
||||
autodepsIndex: number,
|
||||
numArgs: number,
|
||||
paths: Array<NodePath<t.Node>>,
|
||||
context: TraversalState,
|
||||
): void {
|
||||
@@ -77,10 +49,11 @@ function assertValidEffectImportReference(
|
||||
maybeCalleeLoc != null &&
|
||||
context.inferredEffectLocations.has(maybeCalleeLoc);
|
||||
/**
|
||||
* Error on effect calls that still have AUTODEPS in their args
|
||||
* Only error on untransformed references of the form `useMyEffect(...)`
|
||||
* or `moduleNamespace.useMyEffect(...)`, with matching argument counts.
|
||||
* TODO: do we also want a mode to also hard error on non-call references?
|
||||
*/
|
||||
const hasAutodepsArg = args.some(isAutodepsSigil);
|
||||
if (hasAutodepsArg && !hasInferredEffect) {
|
||||
if (args.length === numArgs && !hasInferredEffect) {
|
||||
const maybeErrorDiagnostic = matchCompilerDiagnostic(
|
||||
path,
|
||||
context.transformErrors,
|
||||
@@ -92,18 +65,14 @@ function assertValidEffectImportReference(
|
||||
*/
|
||||
throwInvalidReact(
|
||||
{
|
||||
category:
|
||||
'Cannot infer dependencies of this effect. This will break your build!',
|
||||
description:
|
||||
'To resolve, either pass a dependency array or fix reported compiler bailout diagnostics.' +
|
||||
(maybeErrorDiagnostic ? ` ${maybeErrorDiagnostic}` : ''),
|
||||
details: [
|
||||
{
|
||||
kind: 'error',
|
||||
message: 'Cannot infer dependencies',
|
||||
loc: parent.node.loc ?? GeneratedSource,
|
||||
},
|
||||
],
|
||||
reason:
|
||||
'[InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. ' +
|
||||
'This will break your build! ' +
|
||||
'To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics.',
|
||||
description: maybeErrorDiagnostic
|
||||
? `(Bailout reason: ${maybeErrorDiagnostic})`
|
||||
: null,
|
||||
loc: parent.node.loc ?? null,
|
||||
},
|
||||
context,
|
||||
);
|
||||
@@ -123,20 +92,13 @@ function assertValidFireImportReference(
|
||||
);
|
||||
throwInvalidReact(
|
||||
{
|
||||
category:
|
||||
'[Fire] Untransformed reference to compiler-required feature.',
|
||||
description:
|
||||
'Either remove this `fire` call or ensure it is successfully transformed by the compiler' +
|
||||
maybeErrorDiagnostic
|
||||
? ` ${maybeErrorDiagnostic}`
|
||||
: '',
|
||||
details: [
|
||||
{
|
||||
kind: 'error',
|
||||
message: 'Untransformed `fire` call',
|
||||
loc: paths[0].node.loc ?? GeneratedSource,
|
||||
},
|
||||
],
|
||||
reason:
|
||||
'[Fire] Untransformed reference to compiler-required feature. ' +
|
||||
'Either remove this `fire` call or ensure it is successfully transformed by the compiler',
|
||||
description: maybeErrorDiagnostic
|
||||
? `(Bailout reason: ${maybeErrorDiagnostic})`
|
||||
: null,
|
||||
loc: paths[0].node.loc ?? null,
|
||||
},
|
||||
context,
|
||||
);
|
||||
@@ -166,12 +128,12 @@ export default function validateNoUntransformedReferences(
|
||||
if (env.inferEffectDependencies) {
|
||||
for (const {
|
||||
function: {source, importSpecifierName},
|
||||
autodepsIndex,
|
||||
numRequiredArgs,
|
||||
} of env.inferEffectDependencies) {
|
||||
const module = getOrInsertWith(moduleLoadChecks, source, () => new Map());
|
||||
module.set(
|
||||
importSpecifierName,
|
||||
assertValidEffectImportReference.bind(null, autodepsIndex),
|
||||
assertValidEffectImportReference.bind(null, numRequiredArgs),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1359,7 +1359,7 @@ function lowerStatement(
|
||||
builder.errors.push({
|
||||
reason: `JavaScript 'with' syntax is not supported`,
|
||||
description: `'with' syntax is considered deprecated and removed from JavaScript standards, consider alternatives`,
|
||||
severity: ErrorSeverity.UnsupportedJS,
|
||||
severity: ErrorSeverity.InvalidJS,
|
||||
loc: stmtPath.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
@@ -1371,15 +1371,13 @@ function lowerStatement(
|
||||
return;
|
||||
}
|
||||
case 'ClassDeclaration': {
|
||||
/**
|
||||
* In theory we could support inline class declarations, but this is rare enough in practice
|
||||
* and complex enough to support that we don't anticipate supporting anytime soon. Developers
|
||||
* are encouraged to lift classes out of component/hook declarations.
|
||||
/*
|
||||
* We can in theory support nested classes, similarly to functions where we track values
|
||||
* captured by the class and consider mutations of the instances to mutate the class itself
|
||||
*/
|
||||
builder.errors.push({
|
||||
reason: 'Inline `class` declarations are not supported',
|
||||
description: `Move class declarations outside of components/hooks`,
|
||||
severity: ErrorSeverity.UnsupportedJS,
|
||||
reason: `Support nested class declarations`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
loc: stmtPath.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
@@ -1390,48 +1388,10 @@ function lowerStatement(
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'EnumDeclaration':
|
||||
case 'TSEnumDeclaration': {
|
||||
lowerValueToTemporary(builder, {
|
||||
kind: 'UnsupportedNode',
|
||||
loc: stmtPath.node.loc ?? GeneratedSource,
|
||||
node: stmtPath.node,
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'ExportAllDeclaration':
|
||||
case 'ExportDefaultDeclaration':
|
||||
case 'ExportNamedDeclaration':
|
||||
case 'ImportDeclaration':
|
||||
case 'TSExportAssignment':
|
||||
case 'TSImportEqualsDeclaration': {
|
||||
builder.errors.push({
|
||||
reason:
|
||||
'JavaScript `import` and `export` statements may only appear at the top level of a module',
|
||||
severity: ErrorSeverity.InvalidJS,
|
||||
loc: stmtPath.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
lowerValueToTemporary(builder, {
|
||||
kind: 'UnsupportedNode',
|
||||
loc: stmtPath.node.loc ?? GeneratedSource,
|
||||
node: stmtPath.node,
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'TSNamespaceExportDeclaration': {
|
||||
builder.errors.push({
|
||||
reason:
|
||||
'TypeScript `namespace` statements may only appear at the top level of a module',
|
||||
severity: ErrorSeverity.InvalidJS,
|
||||
loc: stmtPath.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
lowerValueToTemporary(builder, {
|
||||
kind: 'UnsupportedNode',
|
||||
loc: stmtPath.node.loc ?? GeneratedSource,
|
||||
node: stmtPath.node,
|
||||
});
|
||||
case 'TypeAlias':
|
||||
case 'TSInterfaceDeclaration':
|
||||
case 'TSTypeAliasDeclaration': {
|
||||
// We do not preserve type annotations/syntax through transformation
|
||||
return;
|
||||
}
|
||||
case 'DeclareClass':
|
||||
@@ -1444,14 +1404,30 @@ function lowerStatement(
|
||||
case 'DeclareOpaqueType':
|
||||
case 'DeclareTypeAlias':
|
||||
case 'DeclareVariable':
|
||||
case 'EnumDeclaration':
|
||||
case 'ExportAllDeclaration':
|
||||
case 'ExportDefaultDeclaration':
|
||||
case 'ExportNamedDeclaration':
|
||||
case 'ImportDeclaration':
|
||||
case 'InterfaceDeclaration':
|
||||
case 'OpaqueType':
|
||||
case 'TSDeclareFunction':
|
||||
case 'TSInterfaceDeclaration':
|
||||
case 'TSEnumDeclaration':
|
||||
case 'TSExportAssignment':
|
||||
case 'TSImportEqualsDeclaration':
|
||||
case 'TSModuleDeclaration':
|
||||
case 'TSTypeAliasDeclaration':
|
||||
case 'TypeAlias': {
|
||||
// We do not preserve type annotations/syntax through transformation
|
||||
case 'TSNamespaceExportDeclaration': {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerStatement) Handle ${stmtPath.type} statements`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
loc: stmtPath.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
lowerValueToTemporary(builder, {
|
||||
kind: 'UnsupportedNode',
|
||||
loc: stmtPath.node.loc ?? GeneratedSource,
|
||||
node: stmtPath.node,
|
||||
});
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
@@ -2271,17 +2247,11 @@ function lowerExpression(
|
||||
});
|
||||
for (const [name, locations] of Object.entries(fbtLocations)) {
|
||||
if (locations.length > 1) {
|
||||
CompilerError.throwDiagnostic({
|
||||
severity: ErrorSeverity.Todo,
|
||||
category: 'Support duplicate fbt tags',
|
||||
description: `Support \`<${tagName}>\` tags with multiple \`<${tagName}:${name}>\` values`,
|
||||
details: locations.map(loc => {
|
||||
return {
|
||||
kind: 'error',
|
||||
message: `Multiple \`<${tagName}:${name}>\` tags found`,
|
||||
loc,
|
||||
};
|
||||
}),
|
||||
CompilerError.throwTodo({
|
||||
reason: `Support <${tagName}> tags with multiple <${tagName}:${name}> values`,
|
||||
loc: locations.at(-1) ?? GeneratedSource,
|
||||
description: null,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3007,8 +2977,6 @@ function isReorderableExpression(
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'TSAsExpression':
|
||||
case 'TSNonNullExpression':
|
||||
case 'TypeCastExpression': {
|
||||
return isReorderableExpression(
|
||||
builder,
|
||||
@@ -3509,8 +3477,9 @@ function lowerFunction(
|
||||
);
|
||||
let loweredFunc: HIRFunction;
|
||||
if (lowering.isErr()) {
|
||||
const functionErrors = lowering.unwrapErr();
|
||||
builder.errors.merge(functionErrors);
|
||||
lowering
|
||||
.unwrapErr()
|
||||
.details.forEach(detail => builder.errors.pushErrorDetail(detail));
|
||||
return null;
|
||||
}
|
||||
loweredFunc = lowering.unwrap();
|
||||
@@ -3569,7 +3538,7 @@ function lowerIdentifier(
|
||||
reason: `The 'eval' function is not supported`,
|
||||
description:
|
||||
'Eval is an anti-pattern in JavaScript, and the code executed cannot be evaluated by React Compiler',
|
||||
severity: ErrorSeverity.UnsupportedJS,
|
||||
severity: ErrorSeverity.InvalidJS,
|
||||
loc: exprPath.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
|
||||
@@ -265,19 +265,21 @@ export const EnvironmentConfigSchema = z.object({
|
||||
* {
|
||||
* module: 'react',
|
||||
* imported: 'useEffect',
|
||||
* autodepsIndex: 1,
|
||||
* numRequiredArgs: 1,
|
||||
* },{
|
||||
* module: 'MyExperimentalEffectHooks',
|
||||
* imported: 'useExperimentalEffect',
|
||||
* autodepsIndex: 2,
|
||||
* numRequiredArgs: 2,
|
||||
* },
|
||||
* ]
|
||||
* would insert dependencies for calls of `useEffect` imported from `react` and calls of
|
||||
* useExperimentalEffect` from `MyExperimentalEffectHooks`.
|
||||
*
|
||||
* `autodepsIndex` tells the compiler which index we expect the AUTODEPS to appear in.
|
||||
* With the configuration above, we'd insert dependencies for `useEffect` if it has two
|
||||
* arguments, and the second is AUTODEPS.
|
||||
* `numRequiredArgs` tells the compiler the amount of arguments required to append a dependency
|
||||
* array to the end of the call. With the configuration above, we'd insert dependencies for
|
||||
* `useEffect` if it is only given a single argument and it would be appended to the argument list.
|
||||
*
|
||||
* numRequiredArgs must always be greater than 0, otherwise there is no function to analyze for dependencies
|
||||
*
|
||||
* Still experimental.
|
||||
*/
|
||||
@@ -286,7 +288,7 @@ export const EnvironmentConfigSchema = z.object({
|
||||
z.array(
|
||||
z.object({
|
||||
function: ExternalFunctionSchema,
|
||||
autodepsIndex: z.number().min(1, 'autodepsIndex must be > 0'),
|
||||
numRequiredArgs: z.number().min(1, 'numRequiredArgs must be > 0'),
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -318,10 +320,10 @@ export const EnvironmentConfigSchema = z.object({
|
||||
validateNoSetStateInRender: z.boolean().default(true),
|
||||
|
||||
/**
|
||||
* Validates that setState is not called synchronously within an effect (useEffect and friends).
|
||||
* Validates that setState is not called directly within a passive effect (useEffect).
|
||||
* Scheduling a setState (with an event listener, subscription, etc) is valid.
|
||||
*/
|
||||
validateNoSetStateInEffects: z.boolean().default(false),
|
||||
validateNoSetStateInPassiveEffects: z.boolean().default(false),
|
||||
|
||||
/**
|
||||
* Validates against creating JSX within a try block and recommends using an error boundary
|
||||
|
||||
@@ -9,7 +9,6 @@ import {Effect, ValueKind, ValueReason} from './HIR';
|
||||
import {
|
||||
BUILTIN_SHAPES,
|
||||
BuiltInArrayId,
|
||||
BuiltInAutodepsId,
|
||||
BuiltInFireFunctionId,
|
||||
BuiltInFireId,
|
||||
BuiltInMapId,
|
||||
@@ -781,7 +780,6 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
|
||||
BuiltInUseEffectEventId,
|
||||
),
|
||||
],
|
||||
['AUTODEPS', addObject(DEFAULT_SHAPES, BuiltInAutodepsId, [])],
|
||||
];
|
||||
|
||||
TYPED_GLOBALS.push(
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import {Binding, NodePath} from '@babel/traverse';
|
||||
import * as t from '@babel/types';
|
||||
import {CompilerError, ErrorSeverity} from '../CompilerError';
|
||||
import {CompilerError} from '../CompilerError';
|
||||
import {Environment} from './Environment';
|
||||
import {
|
||||
BasicBlock,
|
||||
@@ -308,18 +308,9 @@ export default class HIRBuilder {
|
||||
|
||||
resolveBinding(node: t.Identifier): Identifier {
|
||||
if (node.name === 'fbt') {
|
||||
CompilerError.throwDiagnostic({
|
||||
severity: ErrorSeverity.Todo,
|
||||
category: 'Support local variables named `fbt`',
|
||||
description:
|
||||
'Local variables named `fbt` may conflict with the fbt plugin and are not yet supported',
|
||||
details: [
|
||||
{
|
||||
kind: 'error',
|
||||
message: 'Rename to avoid conflict with fbt plugin',
|
||||
loc: node.loc ?? GeneratedSource,
|
||||
},
|
||||
],
|
||||
CompilerError.throwTodo({
|
||||
reason: 'Support local variables named "fbt"',
|
||||
loc: node.loc ?? null,
|
||||
});
|
||||
}
|
||||
const originalName = node.name;
|
||||
|
||||
@@ -384,7 +384,6 @@ export const BuiltInFireId = 'BuiltInFire';
|
||||
export const BuiltInFireFunctionId = 'BuiltInFireFunction';
|
||||
export const BuiltInUseEffectEventId = 'BuiltInUseEffectEvent';
|
||||
export const BuiltinEffectEventId = 'BuiltInEffectEventFunction';
|
||||
export const BuiltInAutodepsId = 'BuiltInAutoDepsId';
|
||||
|
||||
// See getReanimatedModuleType() in Globals.ts — this is part of supporting Reanimated's ref-like types
|
||||
export const ReanimatedSharedValueId = 'ReanimatedSharedValueId';
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import generate from '@babel/generator';
|
||||
import {CompilerError} from '../CompilerError';
|
||||
import {printReactiveScopeSummary} from '../ReactiveScopes/PrintReactiveFunction';
|
||||
import DisjointSet from '../Utils/DisjointSet';
|
||||
@@ -465,7 +466,7 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
|
||||
break;
|
||||
}
|
||||
case 'UnsupportedNode': {
|
||||
value = `UnsupportedNode ${instrValue.node.type}`;
|
||||
value = `UnsupportedNode(${generate(instrValue.node).code})`;
|
||||
break;
|
||||
}
|
||||
case 'LoadLocal': {
|
||||
|
||||
@@ -57,8 +57,6 @@ import {
|
||||
} from '../HIR/visitors';
|
||||
import {empty} from '../Utils/Stack';
|
||||
import {getOrInsertWith} from '../Utils/utils';
|
||||
import {deadCodeElimination} from '../Optimization';
|
||||
import {BuiltInAutodepsId} from '../HIR/ObjectShape';
|
||||
|
||||
/**
|
||||
* Infers reactive dependencies captured by useEffect lambdas and adds them as
|
||||
@@ -79,7 +77,7 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
);
|
||||
moduleTargets.set(
|
||||
effectTarget.function.importSpecifierName,
|
||||
effectTarget.autodepsIndex,
|
||||
effectTarget.numRequiredArgs,
|
||||
);
|
||||
}
|
||||
const autodepFnLoads = new Map<IdentifierId, number>();
|
||||
@@ -137,6 +135,7 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
}
|
||||
} else if (value.kind === 'LoadGlobal') {
|
||||
loadGlobals.add(lvalue.identifier.id);
|
||||
|
||||
/*
|
||||
* TODO: Handle properties on default exports, like
|
||||
* import React from 'react';
|
||||
@@ -170,22 +169,8 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
) {
|
||||
const callee =
|
||||
value.kind === 'CallExpression' ? value.callee : value.property;
|
||||
|
||||
const autodepsArgIndex = value.args.findIndex(
|
||||
arg =>
|
||||
arg.kind === 'Identifier' &&
|
||||
arg.identifier.type.kind === 'Object' &&
|
||||
arg.identifier.type.shapeId === BuiltInAutodepsId,
|
||||
);
|
||||
const autodepsArgExpectedIndex = autodepFnLoads.get(
|
||||
callee.identifier.id,
|
||||
);
|
||||
|
||||
if (
|
||||
value.args.length > 0 &&
|
||||
autodepsArgExpectedIndex != null &&
|
||||
autodepsArgIndex === autodepsArgExpectedIndex &&
|
||||
autodepFnLoads.has(callee.identifier.id) &&
|
||||
value.args.length === autodepFnLoads.get(callee.identifier.id) &&
|
||||
value.args[0].kind === 'Identifier'
|
||||
) {
|
||||
// We have a useEffect call with no deps array, so we need to infer the deps
|
||||
@@ -275,10 +260,7 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
effects: null,
|
||||
},
|
||||
});
|
||||
value.args[autodepsArgIndex] = {
|
||||
...depsPlace,
|
||||
effect: Effect.Freeze,
|
||||
};
|
||||
value.args.push({...depsPlace, effect: Effect.Freeze});
|
||||
fn.env.inferredEffectLocations.add(callee.loc);
|
||||
} else if (loadGlobals.has(value.args[0].identifier.id)) {
|
||||
// Global functions have no reactive dependencies, so we can insert an empty array
|
||||
@@ -293,10 +275,7 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
effects: null,
|
||||
},
|
||||
});
|
||||
value.args[autodepsArgIndex] = {
|
||||
...depsPlace,
|
||||
effect: Effect.Freeze,
|
||||
};
|
||||
value.args.push({...depsPlace, effect: Effect.Freeze});
|
||||
fn.env.inferredEffectLocations.add(callee.loc);
|
||||
}
|
||||
} else if (
|
||||
@@ -344,7 +323,6 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
// Renumber instructions and fix scope ranges
|
||||
markInstructionIds(fn.body);
|
||||
fixScopeAndIdentifierRanges(fn.body);
|
||||
deadCodeElimination(fn);
|
||||
|
||||
fn.env.hasInferredEffect = true;
|
||||
}
|
||||
@@ -430,7 +408,6 @@ function rewriteSplices(
|
||||
rewriteBlocks.push(currBlock);
|
||||
|
||||
let cursor = 0;
|
||||
|
||||
for (const rewrite of splices) {
|
||||
while (originalInstrs[cursor].id < rewrite.location) {
|
||||
CompilerError.invariant(
|
||||
@@ -452,7 +429,7 @@ function rewriteSplices(
|
||||
|
||||
if (rewrite.kind === 'instr') {
|
||||
currBlock.instructions.push(rewrite.value);
|
||||
} else if (rewrite.kind === 'block') {
|
||||
} else {
|
||||
const {entry, blocks} = rewrite.value;
|
||||
const entryBlock = blocks.get(entry)!;
|
||||
// splice in all instructions from the entry block
|
||||
|
||||
@@ -829,14 +829,12 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor<
|
||||
};
|
||||
}
|
||||
case 'UnsupportedNode': {
|
||||
const lvalues = [];
|
||||
if (lvalue !== null) {
|
||||
lvalues.push({place: lvalue, level: MemoizationLevel.Never});
|
||||
}
|
||||
return {
|
||||
lvalues,
|
||||
rvalues: [],
|
||||
};
|
||||
CompilerError.invariant(false, {
|
||||
reason: `Unexpected unsupported node`,
|
||||
description: null,
|
||||
loc: value.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
default: {
|
||||
assertExhaustive(
|
||||
|
||||
@@ -75,21 +75,21 @@ const testComplexConfigDefaults: PartialEnvironmentConfig = {
|
||||
source: 'react',
|
||||
importSpecifierName: 'useEffect',
|
||||
},
|
||||
autodepsIndex: 1,
|
||||
numRequiredArgs: 1,
|
||||
},
|
||||
{
|
||||
function: {
|
||||
source: 'shared-runtime',
|
||||
importSpecifierName: 'useSpecialEffect',
|
||||
},
|
||||
autodepsIndex: 2,
|
||||
numRequiredArgs: 2,
|
||||
},
|
||||
{
|
||||
function: {
|
||||
source: 'useEffectWrapper',
|
||||
importSpecifierName: 'default',
|
||||
},
|
||||
autodepsIndex: 1,
|
||||
numRequiredArgs: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -11,22 +11,20 @@ import {
|
||||
IdentifierId,
|
||||
isSetStateType,
|
||||
isUseEffectHookType,
|
||||
isUseInsertionEffectHookType,
|
||||
isUseLayoutEffectHookType,
|
||||
Place,
|
||||
} from '../HIR';
|
||||
import {eachInstructionValueOperand} from '../HIR/visitors';
|
||||
import {Result} from '../Utils/Result';
|
||||
|
||||
/**
|
||||
* Validates against calling setState in the body of an effect (useEffect and friends),
|
||||
* Validates against calling setState in the body of a *passive* effect (useEffect),
|
||||
* while allowing calling setState in callbacks scheduled by the effect.
|
||||
*
|
||||
* Calling setState during execution of a useEffect triggers a re-render, which is
|
||||
* often bad for performance and frequently has more efficient and straightforward
|
||||
* alternatives. See https://react.dev/learn/you-might-not-need-an-effect for examples.
|
||||
*/
|
||||
export function validateNoSetStateInEffects(
|
||||
export function validateNoSetStateInPassiveEffects(
|
||||
fn: HIRFunction,
|
||||
): Result<void, CompilerError> {
|
||||
const setStateFunctions: Map<IdentifierId, Place> = new Map();
|
||||
@@ -81,11 +79,7 @@ export function validateNoSetStateInEffects(
|
||||
instr.value.kind === 'MethodCall'
|
||||
? instr.value.receiver
|
||||
: instr.value.callee;
|
||||
if (
|
||||
isUseEffectHookType(callee.identifier) ||
|
||||
isUseLayoutEffectHookType(callee.identifier) ||
|
||||
isUseInsertionEffectHookType(callee.identifier)
|
||||
) {
|
||||
if (isUseEffectHookType(callee.identifier)) {
|
||||
const arg = instr.value.args[0];
|
||||
if (arg !== undefined && arg.kind === 'Identifier') {
|
||||
const setState = setStateFunctions.get(arg.identifier.id);
|
||||
@@ -20,7 +20,7 @@ describe('parseConfigPragma()', () => {
|
||||
validateHooksUsage: 1,
|
||||
} as any);
|
||||
}).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: Expected boolean, received number at "validateHooksUsage"."`,
|
||||
`"InvalidConfig: Could not validate environment config. Update React Compiler config to fix the error. Validation error: Expected boolean, received number at "validateHooksUsage""`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -33,12 +33,12 @@ describe('parseConfigPragma()', () => {
|
||||
source: 'react',
|
||||
importSpecifierName: 'useEffect',
|
||||
},
|
||||
autodepsIndex: 0,
|
||||
numRequiredArgs: 0,
|
||||
},
|
||||
],
|
||||
} as any);
|
||||
}).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: autodepsIndex must be > 0 at "inferEffectDependencies[0].autodepsIndex"."`,
|
||||
`"InvalidConfig: Could not validate environment config. Update React Compiler config to fix the error. Validation error: numRequiredArgs must be > 0 at "inferEffectDependencies[0].numRequiredArgs""`,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -15,19 +15,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Todo: (BuildHIR::lowerAssignment) Handle computed properties in ObjectPattern
|
||||
|
||||
error._todo.computed-lval-in-destructure.ts:3:9
|
||||
1 | function Component(props) {
|
||||
2 | const computedKey = props.key;
|
||||
> 3 | const {[computedKey]: x} = props.val;
|
||||
| ^^^^^^^^^^^^^^^^ (BuildHIR::lowerAssignment) Handle computed properties in ObjectPattern
|
||||
| ^^^^^^^^^^^^^^^^ Todo: (BuildHIR::lowerAssignment) Handle computed properties in ObjectPattern (3:3)
|
||||
4 |
|
||||
5 | return x;
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,19 +15,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
|
||||
error.assign-global-in-component-tag-function.ts:3:4
|
||||
1 | function Component() {
|
||||
2 | const Foo = () => {
|
||||
> 3 | someGlobal = true;
|
||||
| ^^^^^^^^^^ Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
| ^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
|
||||
4 | };
|
||||
5 | return <Foo />;
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,19 +18,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
|
||||
error.assign-global-in-jsx-children.ts:3:4
|
||||
1 | function Component() {
|
||||
2 | const foo = () => {
|
||||
> 3 | someGlobal = true;
|
||||
| ^^^^^^^^^^ Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
| ^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
|
||||
4 | };
|
||||
5 | // Children are generally access/called during render, so
|
||||
6 | // modifying a global in a children function is almost
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
|
||||
error.assign-global-in-jsx-spread-attribute.ts:4:4
|
||||
2 | function Component() {
|
||||
3 | const foo = () => {
|
||||
> 4 | someGlobal = true;
|
||||
| ^^^^^^^^^^ Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
| ^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (4:4)
|
||||
5 | };
|
||||
6 | return <div {...foo} />;
|
||||
7 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,21 +16,13 @@ function Foo(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: React Compiler has skipped optimizing this component because one or more React rule violations were reported by Flow. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
|
||||
|
||||
$FlowFixMe[react-rule-hook].
|
||||
|
||||
error.bailout-on-flow-suppression.ts:4:2
|
||||
2 |
|
||||
3 | function Foo(props) {
|
||||
> 4 | // $FlowFixMe[react-rule-hook]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React Compiler has skipped optimizing this component because one or more React rule violations were reported by Flow. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: React Compiler has skipped optimizing this component because one or more React rule violations were reported by Flow. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. $FlowFixMe[react-rule-hook] (4:4)
|
||||
5 | useX();
|
||||
6 | return null;
|
||||
7 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,35 +19,15 @@ function lowercasecomponent() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
|
||||
|
||||
eslint-disable my-app/react-rule.
|
||||
|
||||
error.bailout-on-suppression-of-custom-rule.ts:3:0
|
||||
1 | // @eslintSuppressionRules:["my-app","react-rule"]
|
||||
2 |
|
||||
> 3 | /* eslint-disable my-app/react-rule */
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. eslint-disable my-app/react-rule (3:3)
|
||||
|
||||
InvalidReact: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. eslint-disable-next-line my-app/react-rule (7:7)
|
||||
4 | function lowercasecomponent() {
|
||||
5 | 'use forget';
|
||||
6 | const x = [];
|
||||
|
||||
|
||||
Error: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
|
||||
|
||||
eslint-disable-next-line my-app/react-rule.
|
||||
|
||||
error.bailout-on-suppression-of-custom-rule.ts:7:2
|
||||
5 | 'use forget';
|
||||
6 | const x = [];
|
||||
> 7 | // eslint-disable-next-line my-app/react-rule
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
|
||||
8 | return <div>{x}</div>;
|
||||
9 | }
|
||||
10 | /* eslint-enable my-app/react-rule */
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -36,10 +36,6 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:20:12
|
||||
18 | );
|
||||
19 | const ref = useRef(null);
|
||||
> 20 | useEffect(() => {
|
||||
@@ -51,24 +47,12 @@ error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:20:12
|
||||
> 23 | }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 24 | }, [update]);
|
||||
| ^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^ InvalidReact: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead (20:24)
|
||||
|
||||
InvalidReact: The function modifies a local variable here (14:14)
|
||||
25 |
|
||||
26 | return 'ok';
|
||||
27 | }
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:14:6
|
||||
12 | ...partialParams,
|
||||
13 | };
|
||||
> 14 | nextParams.param = 'value';
|
||||
| ^^^^^^^^^^ The function modifies a local variable here
|
||||
15 | console.log(nextParams);
|
||||
16 | },
|
||||
17 | [params]
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,19 +14,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Invariant: Const declaration cannot be referenced as an expression
|
||||
|
||||
error.call-args-destructuring-asignment-complex.ts:3:9
|
||||
1 | function Component(props) {
|
||||
2 | let x = makeObject();
|
||||
> 3 | x.foo(([[x]] = makeObject()));
|
||||
| ^^^^^ Const declaration cannot be referenced as an expression
|
||||
| ^^^^^ Invariant: Const declaration cannot be referenced as an expression (3:3)
|
||||
4 | return x;
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,20 +14,12 @@ function Foo() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config
|
||||
|
||||
Bar may be a component..
|
||||
|
||||
error.capitalized-function-call-aliased.ts:4:2
|
||||
2 | function Foo() {
|
||||
3 | let x = Bar;
|
||||
> 4 | x(); // ERROR
|
||||
| ^^^ Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config
|
||||
| ^^^ InvalidReact: Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config. Bar may be a component. (4:4)
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,21 +15,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config
|
||||
|
||||
SomeFunc may be a component..
|
||||
|
||||
error.capitalized-function-call.ts:3:12
|
||||
1 | // @validateNoCapitalizedCalls
|
||||
2 | function Component() {
|
||||
> 3 | const x = SomeFunc();
|
||||
| ^^^^^^^^^^ Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config
|
||||
| ^^^^^^^^^^ InvalidReact: Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config. SomeFunc may be a component. (3:3)
|
||||
4 |
|
||||
5 | return x;
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,21 +15,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config
|
||||
|
||||
SomeFunc may be a component..
|
||||
|
||||
error.capitalized-method-call.ts:3:12
|
||||
1 | // @validateNoCapitalizedCalls
|
||||
2 | function Component() {
|
||||
> 3 | const x = someGlobal.SomeFunc();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Capitalized functions are reserved for components, which must be invoked with JSX. If this is a component, render it with JSX. Otherwise, ensure that it has no hook calls and rename it to begin with a lowercase letter. Alternatively, if you know for a fact that this function is not a component, you can allowlist it via the compiler config. SomeFunc may be a component. (3:3)
|
||||
4 |
|
||||
5 | return x;
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -32,55 +32,19 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 4 errors:
|
||||
Error: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.capture-ref-for-mutation.ts:12:13
|
||||
10 | };
|
||||
11 | const moveLeft = {
|
||||
> 12 | handler: handleKey('left')(),
|
||||
| ^^^^^^^^^^^^^^^^^ This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^^^^^^^ InvalidReact: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (12:12)
|
||||
|
||||
InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (12:12)
|
||||
|
||||
InvalidReact: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (15:15)
|
||||
|
||||
InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (15:15)
|
||||
13 | };
|
||||
14 | const moveRight = {
|
||||
15 | handler: handleKey('right')(),
|
||||
|
||||
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.capture-ref-for-mutation.ts:12:13
|
||||
10 | };
|
||||
11 | const moveLeft = {
|
||||
> 12 | handler: handleKey('left')(),
|
||||
| ^^^^^^^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
13 | };
|
||||
14 | const moveRight = {
|
||||
15 | handler: handleKey('right')(),
|
||||
|
||||
|
||||
Error: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.capture-ref-for-mutation.ts:15:13
|
||||
13 | };
|
||||
14 | const moveRight = {
|
||||
> 15 | handler: handleKey('right')(),
|
||||
| ^^^^^^^^^^^^^^^^^^ This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
16 | };
|
||||
17 | return [moveLeft, moveRight];
|
||||
18 | }
|
||||
|
||||
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.capture-ref-for-mutation.ts:15:13
|
||||
13 | };
|
||||
14 | const moveRight = {
|
||||
> 15 | handler: handleKey('right')(),
|
||||
| ^^^^^^^^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
16 | };
|
||||
17 | return [moveLeft, moveRight];
|
||||
18 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
|
||||
error.conditional-hook-unknown-hook-react-namespace.ts:4:8
|
||||
2 | let x = null;
|
||||
3 | if (props.cond) {
|
||||
> 4 | x = React.useNonexistentHook();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (4:4)
|
||||
5 | }
|
||||
6 | return x;
|
||||
7 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
|
||||
error.conditional-hooks-as-method-call.ts:4:8
|
||||
2 | let x = null;
|
||||
3 | if (props.cond) {
|
||||
> 4 | x = Foo.useFoo();
|
||||
| ^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
| ^^^^^^^^^^ InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (4:4)
|
||||
5 | }
|
||||
6 | return x;
|
||||
7 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -28,21 +28,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `x` cannot be reassigned after render.
|
||||
|
||||
error.context-variable-only-chained-assign.ts:10:19
|
||||
8 | };
|
||||
9 | const fn2 = () => {
|
||||
> 10 | const copy2 = (x = 4);
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `x` cannot be reassigned after render (10:10)
|
||||
11 | return [invoke(fn1), copy2, identity(copy2)];
|
||||
12 | };
|
||||
13 | return invoke(fn2);
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,21 +17,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `x` cannot be reassigned after render.
|
||||
|
||||
error.declare-reassign-variable-in-function-declaration.ts:4:4
|
||||
2 | let x = null;
|
||||
3 | function foo() {
|
||||
> 4 | x = 9;
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `x` cannot be reassigned after render (4:4)
|
||||
5 | }
|
||||
6 | const y = bar(foo);
|
||||
7 | return <Child y={y} />;
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Todo: (BuildHIR::node.lowerReorderableExpression) Expression type `ArrowFunctionExpression` cannot be safely reordered
|
||||
|
||||
error.default-param-accesses-local.ts:3:6
|
||||
1 | function Component(
|
||||
2 | x,
|
||||
> 3 | y = () => {
|
||||
@@ -33,12 +29,10 @@ error.default-param-accesses-local.ts:3:6
|
||||
> 4 | return x;
|
||||
| ^^^^^^^^^^^^^
|
||||
> 5 | }
|
||||
| ^^^^ (BuildHIR::node.lowerReorderableExpression) Expression type `ArrowFunctionExpression` cannot be safely reordered
|
||||
| ^^^^ Todo: (BuildHIR::node.lowerReorderableExpression) Expression type `ArrowFunctionExpression` cannot be safely reordered (3:5)
|
||||
6 | ) {
|
||||
7 | return y();
|
||||
8 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,21 +19,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Todo: [hoisting] EnterSSA: Expected identifier to be defined before being used
|
||||
|
||||
Identifier x$1 is undefined.
|
||||
|
||||
error.dont-hoist-inline-reference.ts:3:2
|
||||
1 | import {identity} from 'shared-runtime';
|
||||
2 | function useInvalid() {
|
||||
> 3 | const x = identity(x);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ [hoisting] EnterSSA: Expected identifier to be defined before being used
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ Todo: [hoisting] EnterSSA: Expected identifier to be defined before being used. Identifier x$1 is undefined (3:3)
|
||||
4 | return x;
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,21 +15,13 @@ function useFoo(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Todo: Encountered conflicting global in generated program
|
||||
|
||||
Conflict from local binding __DEV__.
|
||||
|
||||
error.emit-freeze-conflicting-global.ts:3:8
|
||||
1 | // @enableEmitFreeze @instrumentForget
|
||||
2 | function useFoo(props) {
|
||||
> 3 | const __DEV__ = 'conflicting global';
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Encountered conflicting global in generated program
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Todo: Encountered conflicting global in generated program. Conflict from local binding __DEV__ (3:3)
|
||||
4 | console.log(__DEV__);
|
||||
5 | return foo(props.x);
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,21 +15,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `callback` cannot be reassigned after render.
|
||||
|
||||
error.function-expression-references-variable-its-assigned-to.ts:3:4
|
||||
1 | function Component() {
|
||||
2 | let callback = () => {
|
||||
> 3 | callback = null;
|
||||
| ^^^^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `callback` cannot be reassigned after render (3:3)
|
||||
4 | };
|
||||
5 | return <div onClick={callback} />;
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -24,12 +24,6 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Memoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected
|
||||
|
||||
The inferred dependency was `props.items`, but the source dependencies were [props?.items, props.cond]. Inferred different dependency than source.
|
||||
|
||||
error.hoist-optional-member-expression-with-conditional-optional.ts:4:23
|
||||
2 | import {ValidateMemoization} from 'shared-runtime';
|
||||
3 | function Component(props) {
|
||||
> 4 | const data = useMemo(() => {
|
||||
@@ -47,12 +41,10 @@ error.hoist-optional-member-expression-with-conditional-optional.ts:4:23
|
||||
> 10 | return x;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 11 | }, [props?.items, props.cond]);
|
||||
| ^^^^ React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `props.items`, but the source dependencies were [props?.items, props.cond]. Inferred different dependency than source (4:11)
|
||||
12 | return (
|
||||
13 | <ValidateMemoization inputs={[props?.items, props.cond]} output={data} />
|
||||
14 | );
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -24,12 +24,6 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Memoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected
|
||||
|
||||
The inferred dependency was `props.items`, but the source dependencies were [props?.items, props.cond]. Inferred different dependency than source.
|
||||
|
||||
error.hoist-optional-member-expression-with-conditional.ts:4:23
|
||||
2 | import {ValidateMemoization} from 'shared-runtime';
|
||||
3 | function Component(props) {
|
||||
> 4 | const data = useMemo(() => {
|
||||
@@ -47,12 +41,10 @@ error.hoist-optional-member-expression-with-conditional.ts:4:23
|
||||
> 10 | return x;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 11 | }, [props?.items, props.cond]);
|
||||
| ^^^^ React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `props.items`, but the source dependencies were [props?.items, props.cond]. Inferred different dependency than source (4:11)
|
||||
12 | return (
|
||||
13 | <ValidateMemoization inputs={[props?.items, props.cond]} output={data} />
|
||||
14 | );
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Todo: Support functions with unreachable code that may contain hoisted declarations
|
||||
|
||||
error.hoisting-simple-function-declaration.ts:6:2
|
||||
4 | }
|
||||
5 | return baz(); // OK: FuncDecls are HoistableDeclarations that have both declaration and value hoisting
|
||||
> 6 | function baz() {
|
||||
@@ -35,12 +31,10 @@ error.hoisting-simple-function-declaration.ts:6:2
|
||||
> 7 | return bar();
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
> 8 | }
|
||||
| ^^^^ Support functions with unreachable code that may contain hoisted declarations
|
||||
| ^^^^ Todo: Support functions with unreachable code that may contain hoisted declarations (6:8)
|
||||
9 | }
|
||||
10 |
|
||||
11 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -29,19 +29,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook
|
||||
|
||||
error.hook-call-freezes-captured-identifier.ts:13:2
|
||||
11 | });
|
||||
12 |
|
||||
> 13 | x.value += count;
|
||||
| ^ Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook
|
||||
| ^ InvalidReact: Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook (13:13)
|
||||
14 | return <Stringify x={x} cb={cb} />;
|
||||
15 | }
|
||||
16 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -29,19 +29,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook
|
||||
|
||||
error.hook-call-freezes-captured-memberexpr.ts:13:2
|
||||
11 | });
|
||||
12 |
|
||||
> 13 | x.value += count;
|
||||
| ^ Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook
|
||||
| ^ InvalidReact: Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook (13:13)
|
||||
14 | return <Stringify x={x} cb={cb} />;
|
||||
15 | }
|
||||
16 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -23,31 +23,15 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
|
||||
error.hook-property-load-local-hook.ts:7:12
|
||||
5 |
|
||||
6 | function Foo() {
|
||||
> 7 | let bar = useFoo.useBar;
|
||||
| ^^^^^^^^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
| ^^^^^^^^^^^^^ InvalidReact: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values (7:7)
|
||||
|
||||
InvalidReact: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values (8:8)
|
||||
8 | return bar();
|
||||
9 | }
|
||||
10 |
|
||||
|
||||
|
||||
Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
|
||||
error.hook-property-load-local-hook.ts:8:9
|
||||
6 | function Foo() {
|
||||
7 | let bar = useFoo.useBar;
|
||||
> 8 | return bar();
|
||||
| ^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
9 | }
|
||||
10 |
|
||||
11 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -20,31 +20,15 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.hook-ref-value.ts:5:23
|
||||
3 | function Component(props) {
|
||||
4 | const ref = useRef();
|
||||
> 5 | useEffect(() => {}, [ref.current]);
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (5:5)
|
||||
|
||||
InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (5:5)
|
||||
6 | }
|
||||
7 |
|
||||
8 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.hook-ref-value.ts:5:23
|
||||
3 | function Component(props) {
|
||||
4 | const ref = useRef();
|
||||
> 5 | useEffect(() => {}, [ref.current]);
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
6 | }
|
||||
7 |
|
||||
8 | export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,22 +15,16 @@ function component(a, b) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: useMemo callbacks may not be async or generator functions
|
||||
|
||||
error.invalid-ReactUseMemo-async-callback.ts:2:24
|
||||
1 | function component(a, b) {
|
||||
> 2 | let x = React.useMemo(async () => {
|
||||
| ^^^^^^^^^^^^^
|
||||
> 3 | await a;
|
||||
| ^^^^^^^^^^^^
|
||||
> 4 | }, []);
|
||||
| ^^^^ useMemo callbacks may not be async or generator functions
|
||||
| ^^^^ InvalidReact: useMemo callbacks may not be async or generator functions (2:4)
|
||||
5 | return x;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,19 +15,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-access-ref-during-render.ts:4:16
|
||||
2 | function Component(props) {
|
||||
3 | const ref = useRef(null);
|
||||
> 4 | const value = ref.current;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4)
|
||||
5 | return value;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,18 +19,12 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-aliased-ref-in-callback-invoked-during-render-.ts:9:33
|
||||
7 | return <Foo item={item} current={current} />;
|
||||
8 | };
|
||||
> 9 | return <Items>{props.items.map(item => renderItem(item))}</Items>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (9:9)
|
||||
10 | }
|
||||
11 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,19 +15,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-array-push-frozen.ts:4:2
|
||||
2 | const x = [];
|
||||
3 | <div>{x}</div>;
|
||||
> 4 | x.push(props.value);
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (4:4)
|
||||
5 | return x;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,18 +14,12 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
|
||||
error.invalid-assign-hook-to-local.ts:2:12
|
||||
1 | function Component(props) {
|
||||
> 2 | const x = useState;
|
||||
| ^^^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
| ^^^^^^^^ InvalidReact: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values (2:2)
|
||||
3 | const state = x(null);
|
||||
4 | return state[0];
|
||||
5 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-computed-store-to-frozen-value.ts:5:2
|
||||
3 | // freeze
|
||||
4 | <div>{x}</div>;
|
||||
> 5 | x[0] = true;
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (5:5)
|
||||
6 | return x;
|
||||
7 | }
|
||||
8 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,19 +18,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
|
||||
error.invalid-conditional-call-aliased-hook-import.ts:6:11
|
||||
4 | let data;
|
||||
5 | if (props.cond) {
|
||||
> 6 | data = readFragment();
|
||||
| ^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
| ^^^^^^^^^^^^ InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (6:6)
|
||||
7 | }
|
||||
8 | return data;
|
||||
9 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,19 +18,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
|
||||
error.invalid-conditional-call-aliased-react-hook.ts:6:10
|
||||
4 | let s;
|
||||
5 | if (props.cond) {
|
||||
> 6 | [s] = state();
|
||||
| ^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
| ^^^^^ InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (6:6)
|
||||
7 | }
|
||||
8 | return s;
|
||||
9 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,19 +18,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
|
||||
error.invalid-conditional-call-non-hook-imported-as-hook.ts:6:11
|
||||
4 | let data;
|
||||
5 | if (props.cond) {
|
||||
> 6 | data = useArray();
|
||||
| ^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
|
||||
| ^^^^^^^^ InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (6:6)
|
||||
7 | }
|
||||
8 | return data;
|
||||
9 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -22,31 +22,15 @@ function Component({item, cond}) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-conditional-setState-in-useMemo.ts:7:6
|
||||
5 | useMemo(() => {
|
||||
6 | if (cond) {
|
||||
> 7 | setPrevItem(item);
|
||||
| ^^^^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^^^^ InvalidReact: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState) (7:7)
|
||||
|
||||
InvalidReact: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState) (8:8)
|
||||
8 | setState(0);
|
||||
9 | }
|
||||
10 | }, [cond, key, init]);
|
||||
|
||||
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-conditional-setState-in-useMemo.ts:8:6
|
||||
6 | if (cond) {
|
||||
7 | setPrevItem(item);
|
||||
> 8 | setState(0);
|
||||
| ^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
9 | }
|
||||
10 | }, [cond, key, init]);
|
||||
11 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-delete-computed-property-of-frozen-value.ts:5:9
|
||||
3 | // freeze
|
||||
4 | <div>{x}</div>;
|
||||
> 5 | delete x[y];
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (5:5)
|
||||
6 | return x;
|
||||
7 | }
|
||||
8 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-delete-property-of-frozen-value.ts:5:9
|
||||
3 | // freeze
|
||||
4 | <div>{x}</div>;
|
||||
> 5 | delete x.y;
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (5:5)
|
||||
6 | return x;
|
||||
7 | }
|
||||
8 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -13,18 +13,12 @@ function useFoo(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
|
||||
error.invalid-destructure-assignment-to-global.ts:2:3
|
||||
1 | function useFoo(props) {
|
||||
> 2 | [x] = props;
|
||||
| ^ Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
| ^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (2:2)
|
||||
3 | return {x};
|
||||
4 | }
|
||||
5 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,19 +15,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
|
||||
error.invalid-destructure-to-local-global-variables.ts:3:6
|
||||
1 | function Component(props) {
|
||||
2 | let a;
|
||||
> 3 | [a, b] = props.value;
|
||||
| ^ Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
| ^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
|
||||
4 |
|
||||
5 | return [a, b];
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-disallow-mutating-ref-in-render.ts:4:2
|
||||
2 | function Component() {
|
||||
3 | const ref = useRef(null);
|
||||
> 4 | ref.current = false;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4)
|
||||
5 |
|
||||
6 | return <button ref={ref} />;
|
||||
7 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -21,31 +21,15 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-disallow-mutating-refs-in-render-transitive.ts:9:2
|
||||
7 | };
|
||||
8 | const changeRef = setRef;
|
||||
> 9 | changeRef();
|
||||
| ^^^^^^^^^ This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^ InvalidReact: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (9:9)
|
||||
|
||||
InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (9:9)
|
||||
10 |
|
||||
11 | return <button ref={ref} />;
|
||||
12 | }
|
||||
|
||||
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-disallow-mutating-refs-in-render-transitive.ts:9:2
|
||||
7 | };
|
||||
8 | const changeRef = setRef;
|
||||
> 9 | changeRef();
|
||||
| ^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
10 |
|
||||
11 | return <button ref={ref} />;
|
||||
12 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -13,20 +13,12 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: The 'eval' function is not supported
|
||||
|
||||
Eval is an anti-pattern in JavaScript, and the code executed cannot be evaluated by React Compiler.
|
||||
|
||||
error.invalid-eval-unsupported.ts:2:2
|
||||
1 | function Component(props) {
|
||||
> 2 | eval('props.x = true');
|
||||
| ^^^^ The 'eval' function is not supported
|
||||
| ^^^^ InvalidJS: The 'eval' function is not supported. Eval is an anti-pattern in JavaScript, and the code executed cannot be evaluated by React Compiler (2:2)
|
||||
3 | return <div />;
|
||||
4 | }
|
||||
5 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,21 +18,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating a value returned from 'useState()', which should not be mutated. Use the setter function to update instead
|
||||
|
||||
Found mutation of `x`.
|
||||
|
||||
error.invalid-function-expression-mutates-immutable-value.ts:5:4
|
||||
3 | const onChange = e => {
|
||||
4 | // INVALID! should use copy-on-write and pass the new value
|
||||
> 5 | x.value = e.target.value;
|
||||
| ^ Mutating a value returned from 'useState()', which should not be mutated. Use the setter function to update instead
|
||||
| ^ InvalidReact: Mutating a value returned from 'useState()', which should not be mutated. Use the setter function to update instead. Found mutation of `x` (5:5)
|
||||
6 | setX(x);
|
||||
7 | };
|
||||
8 | return <input value={x.value} onChange={onChange} />;
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -35,19 +35,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
|
||||
error.invalid-global-reassignment-indirect.ts:9:4
|
||||
7 |
|
||||
8 | const setGlobal = () => {
|
||||
> 9 | someGlobal = true;
|
||||
| ^^^^^^^^^^ Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
|
||||
| ^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (9:9)
|
||||
10 | };
|
||||
11 | const indirectSetGlobal = () => {
|
||||
12 | setGlobal();
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -38,35 +38,15 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This variable is accessed before it is declared, which may prevent it from updating as the assigned value changes over time
|
||||
|
||||
Variable `setState` is accessed before it is declared.
|
||||
|
||||
error.invalid-hoisting-setstate.ts:19:18
|
||||
17 | * $2 = Function context=setState
|
||||
18 | */
|
||||
> 19 | useEffect(() => setState(2), []);
|
||||
| ^^^^^^^^ This variable is accessed before it is declared, which may prevent it from updating as the assigned value changes over time
|
||||
| ^^^^^^^^ InvalidReact: This variable is accessed before it is declared, which may prevent it from updating as the assigned value changes over time. Variable `setState` is accessed before it is declared (19:19)
|
||||
|
||||
InvalidReact: This variable is accessed before it is declared, which prevents the earlier access from updating when this value changes over time. Variable `setState` is accessed before it is declared (21:21)
|
||||
20 |
|
||||
21 | const [state, setState] = useState(0);
|
||||
22 | return <Stringify state={state} />;
|
||||
|
||||
|
||||
Error: This variable is accessed before it is declared, which prevents the earlier access from updating when this value changes over time
|
||||
|
||||
Variable `setState` is accessed before it is declared.
|
||||
|
||||
error.invalid-hoisting-setstate.ts:21:16
|
||||
19 | useEffect(() => setState(2), []);
|
||||
20 |
|
||||
> 21 | const [state, setState] = useState(0);
|
||||
| ^^^^^^^^ This variable is accessed before it is declared, which prevents the earlier access from updating when this value changes over time
|
||||
22 | return <Stringify state={state} />;
|
||||
23 | }
|
||||
24 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,10 +17,6 @@ function useFoo() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-hook-function-argument-mutates-local-variable.ts:5:10
|
||||
3 | function useFoo() {
|
||||
4 | const cache = new Map();
|
||||
> 5 | useHook(() => {
|
||||
@@ -28,23 +24,11 @@ error.invalid-hook-function-argument-mutates-local-variable.ts:5:10
|
||||
> 6 | cache.set('key', 'value');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | });
|
||||
| ^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^ InvalidReact: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead (5:7)
|
||||
|
||||
InvalidReact: The function modifies a local variable here (6:6)
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.invalid-hook-function-argument-mutates-local-variable.ts:6:4
|
||||
4 | const cache = new Map();
|
||||
5 | useHook(() => {
|
||||
> 6 | cache.set('key', 'value');
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
7 | });
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,49 +17,17 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 3 errors:
|
||||
Error: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)
|
||||
|
||||
`Date.now` is an impure function whose results may change on every call.
|
||||
|
||||
error.invalid-impure-functions-in-render.ts:4:15
|
||||
2 |
|
||||
3 | function Component() {
|
||||
> 4 | const date = Date.now();
|
||||
| ^^^^^^^^^^ Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)
|
||||
| ^^^^^^^^^^ InvalidReact: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent). `Date.now` is an impure function whose results may change on every call (4:4)
|
||||
|
||||
InvalidReact: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent). `performance.now` is an impure function whose results may change on every call (5:5)
|
||||
|
||||
InvalidReact: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent). `Math.random` is an impure function whose results may change on every call (6:6)
|
||||
5 | const now = performance.now();
|
||||
6 | const rand = Math.random();
|
||||
7 | return <Foo date={date} now={now} rand={rand} />;
|
||||
|
||||
|
||||
Error: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)
|
||||
|
||||
`performance.now` is an impure function whose results may change on every call.
|
||||
|
||||
error.invalid-impure-functions-in-render.ts:5:14
|
||||
3 | function Component() {
|
||||
4 | const date = Date.now();
|
||||
> 5 | const now = performance.now();
|
||||
| ^^^^^^^^^^^^^^^^^ Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)
|
||||
6 | const rand = Math.random();
|
||||
7 | return <Foo date={date} now={now} rand={rand} />;
|
||||
8 | }
|
||||
|
||||
|
||||
Error: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)
|
||||
|
||||
`Math.random` is an impure function whose results may change on every call.
|
||||
|
||||
error.invalid-impure-functions-in-render.ts:6:15
|
||||
4 | const date = Date.now();
|
||||
5 | const now = performance.now();
|
||||
> 6 | const rand = Math.random();
|
||||
| ^^^^^^^^^^^^^ Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)
|
||||
7 | return <Foo date={date} now={now} rand={rand} />;
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -50,21 +50,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
Found mutation of `i`.
|
||||
|
||||
error.invalid-jsx-captures-context-variable.ts:22:2
|
||||
20 | />
|
||||
21 | );
|
||||
> 22 | i = i + 1;
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX. Found mutation of `i` (22:22)
|
||||
23 | items.push(
|
||||
24 | <Stringify
|
||||
25 | key={i}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -25,19 +25,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-mutate-after-aliased-freeze.ts:13:2
|
||||
11 | // y is MaybeFrozen at this point, since it may alias to x
|
||||
12 | // (which is the above line freezes)
|
||||
> 13 | y.push(props.p2);
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (13:13)
|
||||
14 |
|
||||
15 | return <Component x={x} y={y} />;
|
||||
16 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,19 +19,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-mutate-after-freeze.ts:7:2
|
||||
5 |
|
||||
6 | // x is Frozen at this point
|
||||
> 7 | x.push(props.p2);
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (7:7)
|
||||
8 |
|
||||
9 | return <div>{_}</div>;
|
||||
10 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -24,21 +24,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating a value returned from 'useContext()', which should not be mutated
|
||||
|
||||
Found mutation of `FooContext`.
|
||||
|
||||
error.invalid-mutate-context-in-callback.ts:12:4
|
||||
10 | // independently
|
||||
11 | const onClick = () => {
|
||||
> 12 | FooContext.current = true;
|
||||
| ^^^^^^^^^^ Mutating a value returned from 'useContext()', which should not be mutated
|
||||
| ^^^^^^^^^^ InvalidReact: Mutating a value returned from 'useContext()', which should not be mutated. Found mutation of `FooContext` (12:12)
|
||||
13 | };
|
||||
14 | return <div onClick={onClick} />;
|
||||
15 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,19 +14,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating a value returned from 'useContext()', which should not be mutated
|
||||
|
||||
error.invalid-mutate-context.ts:3:2
|
||||
1 | function Component(props) {
|
||||
2 | const context = useContext(FooContext);
|
||||
> 3 | context.value = props.value;
|
||||
| ^^^^^^^ Mutating a value returned from 'useContext()', which should not be mutated
|
||||
| ^^^^^^^ InvalidReact: Mutating a value returned from 'useContext()', which should not be mutated (3:3)
|
||||
4 | return context.value;
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -25,21 +25,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
|
||||
Found mutation of `y`.
|
||||
|
||||
error.invalid-mutate-props-in-effect-fixpoint.ts:10:4
|
||||
8 | let y = x;
|
||||
9 | let mutateProps = () => {
|
||||
> 10 | y.foo = true;
|
||||
| ^ Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
| ^ InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead. Found mutation of `y` (10:10)
|
||||
11 | };
|
||||
12 | let mutatePropsIndirect = () => {
|
||||
13 | mutateProps();
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,19 +17,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
|
||||
error.invalid-mutate-props-via-for-of-iterator.ts:4:4
|
||||
2 | const items = [];
|
||||
3 | for (const x of props.items) {
|
||||
> 4 | x.modified = true;
|
||||
| ^ Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
| ^ InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead (4:4)
|
||||
5 | items.push(x);
|
||||
6 | }
|
||||
7 | return items;
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,21 +16,13 @@ function useInvalidMutation(options) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
|
||||
Found mutation of `options`.
|
||||
|
||||
error.invalid-mutation-in-closure.ts:4:4
|
||||
2 | function test() {
|
||||
3 | foo(options.foo); // error should not point on this line
|
||||
> 4 | options.foo = 'bar';
|
||||
| ^^^^^^^ Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
| ^^^^^^^ InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead. Found mutation of `options` (4:4)
|
||||
5 | }
|
||||
6 | return test;
|
||||
7 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,21 +19,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Writing to a variable defined outside a component or hook is not allowed. Consider using an effect
|
||||
|
||||
Found mutation of `x`.
|
||||
|
||||
error.invalid-mutation-of-possible-props-phi-indirect.ts:4:4
|
||||
2 | let x = cond ? someGlobal : props.foo;
|
||||
3 | const mutatePhiThatCouldBeProps = () => {
|
||||
> 4 | x.y = true;
|
||||
| ^ Writing to a variable defined outside a component or hook is not allowed. Consider using an effect
|
||||
| ^ InvalidReact: Writing to a variable defined outside a component or hook is not allowed. Consider using an effect. Found mutation of `x` (4:4)
|
||||
5 | };
|
||||
6 | const indirectMutateProps = () => {
|
||||
7 | mutatePhiThatCouldBeProps();
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -46,21 +46,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
|
||||
error.invalid-nested-function-reassign-local-variable-in-effect.ts:7:6
|
||||
5 | // Create the reassignment function inside another function, then return it
|
||||
6 | const reassignLocal = newValue => {
|
||||
> 7 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (7:7)
|
||||
8 | };
|
||||
9 | return reassignLocal;
|
||||
10 | };
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -24,21 +24,13 @@ function SomeComponent() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value returned from a hook is not allowed. Consider moving the mutation into the hook where the value is constructed
|
||||
|
||||
Found mutation of `sharedVal`.
|
||||
|
||||
error.invalid-non-imported-reanimated-shared-value-writes.ts:11:22
|
||||
9 | return (
|
||||
10 | <Button
|
||||
> 11 | onPress={() => (sharedVal.value = Math.random())}
|
||||
| ^^^^^^^^^ Updating a value returned from a hook is not allowed. Consider moving the mutation into the hook where the value is constructed
|
||||
| ^^^^^^^^^ InvalidReact: Updating a value returned from a hook is not allowed. Consider moving the mutation into the hook where the value is constructed. Found mutation of `sharedVal` (11:11)
|
||||
12 | title="Randomize"
|
||||
13 | />
|
||||
14 | );
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,12 +18,6 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Memoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected
|
||||
|
||||
The inferred dependency was `props.items.edges.nodes`, but the source dependencies were [props.items?.edges?.nodes]. Inferred different dependency than source.
|
||||
|
||||
error.invalid-optional-member-expression-as-memo-dep-non-optional-in-body.ts:3:23
|
||||
1 | // @validatePreserveExistingMemoizationGuarantees
|
||||
2 | function Component(props) {
|
||||
> 3 | const data = useMemo(() => {
|
||||
@@ -35,12 +29,10 @@ error.invalid-optional-member-expression-as-memo-dep-non-optional-in-body.ts:3:2
|
||||
> 6 | // deps are optional
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | }, [props.items?.edges?.nodes]);
|
||||
| ^^^^ React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected
|
||||
| ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `props.items.edges.nodes`, but the source dependencies were [props.items?.edges?.nodes]. Inferred different dependency than source (3:7)
|
||||
8 | return <Foo data={data} />;
|
||||
9 | }
|
||||
10 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -12,17 +12,11 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
|
||||
error.invalid-pass-hook-as-call-arg.ts:2:13
|
||||
1 | function Component(props) {
|
||||
> 2 | return foo(useFoo);
|
||||
| ^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
| ^^^^^^ InvalidReact: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values (2:2)
|
||||
3 | }
|
||||
4 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -12,17 +12,11 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
|
||||
error.invalid-pass-hook-as-prop.ts:2:21
|
||||
1 | function Component(props) {
|
||||
> 2 | return <Child foo={useFoo} />;
|
||||
| ^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values
|
||||
| ^^^^^^ InvalidReact: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values (2:2)
|
||||
3 | }
|
||||
4 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,30 +17,14 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-pass-mutable-function-as-prop.ts:7:18
|
||||
5 | cache.set('key', 'value');
|
||||
6 | };
|
||||
> 7 | return <Foo fn={fn} />;
|
||||
| ^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^ InvalidReact: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead (7:7)
|
||||
|
||||
InvalidReact: The function modifies a local variable here (5:5)
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.invalid-pass-mutable-function-as-prop.ts:5:4
|
||||
3 | const cache = new Map();
|
||||
4 | const fn = () => {
|
||||
> 5 | cache.set('key', 'value');
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
6 | };
|
||||
7 | return <Foo fn={fn} />;
|
||||
8 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,19 +15,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-pass-ref-to-function.ts:4:16
|
||||
2 | function Component(props) {
|
||||
3 | const ref = useRef(null);
|
||||
> 4 | const x = foo(ref);
|
||||
| ^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4)
|
||||
5 | return x.current;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,21 +18,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
|
||||
Found mutation of `props`.
|
||||
|
||||
error.invalid-prop-mutation-indirect.ts:3:4
|
||||
1 | function Component(props) {
|
||||
2 | const f = () => {
|
||||
> 3 | props.value = true;
|
||||
| ^^^^^ Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
| ^^^^^ InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead. Found mutation of `props` (3:3)
|
||||
4 | };
|
||||
5 | const g = () => {
|
||||
6 | f();
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,19 +16,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
|
||||
error.invalid-property-store-to-frozen-value.ts:5:2
|
||||
3 | // freeze
|
||||
4 | <div>{x}</div>;
|
||||
> 5 | x.y = true;
|
||||
| ^ Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX
|
||||
| ^ InvalidReact: Updating a value used previously in JSX is not allowed. Consider moving the mutation before the JSX (5:5)
|
||||
6 | return x;
|
||||
7 | }
|
||||
8 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,21 +18,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
|
||||
Found mutation of `props`.
|
||||
|
||||
error.invalid-props-mutation-in-effect-indirect.ts:3:4
|
||||
1 | function Component(props) {
|
||||
2 | const mutateProps = () => {
|
||||
> 3 | props.value = true;
|
||||
| ^^^^^ Mutating component props or hook arguments is not allowed. Consider using a local variable instead
|
||||
| ^^^^^ InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead. Found mutation of `props` (3:3)
|
||||
4 | };
|
||||
5 | const indirectMutateProps = () => {
|
||||
6 | mutateProps();
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,19 +14,13 @@ function Component({ref}) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-read-ref-prop-in-render-destructure.ts:3:16
|
||||
1 | // @validateRefAccessDuringRender @compilationMode:"infer"
|
||||
2 | function Component({ref}) {
|
||||
> 3 | const value = ref.current;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (3:3)
|
||||
4 | return <div>{value}</div>;
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,19 +14,13 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-read-ref-prop-in-render-property-load.ts:3:16
|
||||
1 | // @validateRefAccessDuringRender @compilationMode:"infer"
|
||||
2 | function Component(props) {
|
||||
> 3 | const value = props.ref.current;
|
||||
| ^^^^^^^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (3:3)
|
||||
4 | return <div>{value}</div>;
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -13,20 +13,12 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Cannot reassign a `const` variable
|
||||
|
||||
`x` is declared as const.
|
||||
|
||||
error.invalid-reassign-const.ts:3:2
|
||||
1 | function Component() {
|
||||
2 | const x = 0;
|
||||
> 3 | x = 1;
|
||||
| ^ Cannot reassign a `const` variable
|
||||
| ^ InvalidJS: Cannot reassign a `const` variable. `x` is declared as const (3:3)
|
||||
4 | }
|
||||
5 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,21 +15,13 @@ function useFoo() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `x` cannot be reassigned after render.
|
||||
|
||||
error.invalid-reassign-local-in-hook-return-value.ts:4:4
|
||||
2 | let x = 0;
|
||||
3 | return value => {
|
||||
> 4 | x = value;
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `x` cannot be reassigned after render (4:4)
|
||||
5 | };
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -25,21 +25,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable in an async function can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `value` cannot be reassigned after render.
|
||||
|
||||
error.invalid-reassign-local-variable-in-async-callback.ts:8:6
|
||||
6 | // after render, so this should error regardless of where this ends up
|
||||
7 | // getting called
|
||||
> 8 | value = result;
|
||||
| ^^^^^ Reassigning a variable in an async function can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ InvalidReact: Reassigning a variable in an async function can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `value` cannot be reassigned after render (8:8)
|
||||
9 | });
|
||||
10 | };
|
||||
11 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -47,21 +47,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
|
||||
error.invalid-reassign-local-variable-in-effect.ts:7:4
|
||||
5 |
|
||||
6 | const reassignLocal = newValue => {
|
||||
> 7 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (7:7)
|
||||
8 | };
|
||||
9 |
|
||||
10 | const onMount = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -48,21 +48,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
|
||||
error.invalid-reassign-local-variable-in-hook-argument.ts:8:4
|
||||
6 |
|
||||
7 | const reassignLocal = newValue => {
|
||||
> 8 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (8:8)
|
||||
9 | };
|
||||
10 |
|
||||
11 | const callback = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -41,21 +41,13 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
|
||||
error.invalid-reassign-local-variable-in-jsx-callback.ts:5:4
|
||||
3 |
|
||||
4 | const reassignLocal = newValue => {
|
||||
> 5 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (5:5)
|
||||
6 | };
|
||||
7 |
|
||||
8 | const onClick = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,18 +18,12 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-ref-in-callback-invoked-during-render.ts:8:33
|
||||
6 | return <Foo item={item} current={current} />;
|
||||
7 | };
|
||||
> 8 | return <Items>{props.items.map(item => renderItem(item))}</Items>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (8:8)
|
||||
9 | }
|
||||
10 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,18 +14,12 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-ref-value-as-props.ts:4:19
|
||||
2 | function Component(props) {
|
||||
3 | const ref = useRef(null);
|
||||
> 4 | return <Foo ref={ref.current} />;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4)
|
||||
5 | }
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,10 +19,6 @@ function useFoo() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-return-mutable-function-from-hook.ts:7:9
|
||||
5 | useHook(); // for inference to kick in
|
||||
6 | const cache = new Map();
|
||||
> 7 | return () => {
|
||||
@@ -30,23 +26,11 @@ error.invalid-return-mutable-function-from-hook.ts:7:9
|
||||
> 8 | cache.set('key', 'value');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 9 | };
|
||||
| ^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^ InvalidReact: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead (7:9)
|
||||
|
||||
InvalidReact: The function modifies a local variable here (8:8)
|
||||
10 | }
|
||||
11 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.invalid-return-mutable-function-from-hook.ts:8:4
|
||||
6 | const cache = new Map();
|
||||
7 | return () => {
|
||||
> 8 | cache.set('key', 'value');
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
9 | };
|
||||
10 | }
|
||||
11 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,30 +15,15 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-set-and-read-ref-during-render.ts:4:2
|
||||
2 | function Component(props) {
|
||||
3 | const ref = useRef(null);
|
||||
> 4 | ref.current = props.value;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4)
|
||||
|
||||
InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (5:5)
|
||||
5 | return ref.current;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-set-and-read-ref-during-render.ts:5:9
|
||||
3 | const ref = useRef(null);
|
||||
4 | ref.current = props.value;
|
||||
> 5 | return ref.current;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -15,30 +15,15 @@ function Component(props) {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-set-and-read-ref-nested-property-during-render.ts:4:2
|
||||
2 | function Component(props) {
|
||||
3 | const ref = useRef({inner: null});
|
||||
> 4 | ref.current.inner = props.value;
|
||||
| ^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
| ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4)
|
||||
|
||||
InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (5:5)
|
||||
5 | return ref.current.inner;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
Error: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
|
||||
error.invalid-set-and-read-ref-nested-property-during-render.ts:5:9
|
||||
3 | const ref = useRef({inner: null});
|
||||
4 | ref.current.inner = props.value;
|
||||
> 5 | return ref.current.inner;
|
||||
| ^^^^^^^^^^^^^^^^^ Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user