mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[compiler] Support default imports for autodep config (#31657)
## Summary Allows us to add deps for things like `import useWrapperEffect from 'useWrapperEffect'` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31657). * __->__ #31657 * #31652
This commit is contained in:
@@ -660,6 +660,13 @@ const testComplexConfigDefaults: PartialEnvironmentConfig = {
|
||||
},
|
||||
numRequiredArgs: 2,
|
||||
},
|
||||
{
|
||||
function: {
|
||||
source: 'useEffectWrapper',
|
||||
importSpecifierName: 'default',
|
||||
},
|
||||
numRequiredArgs: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1147,3 +1154,5 @@ export function tryParseExternalFunction(
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
|
||||
export const DEFAULT_EXPORT = 'default';
|
||||
|
||||
+12
@@ -16,6 +16,7 @@ import {
|
||||
Place,
|
||||
ReactiveScopeDependencies,
|
||||
} from '../HIR';
|
||||
import {DEFAULT_EXPORT} from '../HIR/Environment';
|
||||
import {
|
||||
createTemporaryPlace,
|
||||
fixScopeAndIdentifierRanges,
|
||||
@@ -97,6 +98,17 @@ export function inferEffectDependencies(fn: HIRFunction): void {
|
||||
autodepFnLoads.set(lvalue.identifier.id, numRequiredArgs);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
value.kind === 'LoadGlobal' &&
|
||||
value.binding.kind === 'ImportDefault'
|
||||
) {
|
||||
const moduleTargets = autodepFnConfigs.get(value.binding.module);
|
||||
if (moduleTargets != null) {
|
||||
const numRequiredArgs = moduleTargets.get(DEFAULT_EXPORT);
|
||||
if (numRequiredArgs != null) {
|
||||
autodepFnLoads.set(lvalue.identifier.id, numRequiredArgs);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
/*
|
||||
* TODO: Handle method calls
|
||||
|
||||
+18
-1
@@ -4,6 +4,7 @@
|
||||
```javascript
|
||||
// @inferEffectDependencies
|
||||
import {useEffect, useRef} from 'react';
|
||||
import useEffectWrapper from 'useEffectWrapper';
|
||||
|
||||
const moduleNonReactive = 0;
|
||||
|
||||
@@ -39,6 +40,10 @@ function Component({foo, bar}) {
|
||||
|
||||
// No inferred dep array, the argument is not a lambda
|
||||
useEffect(f);
|
||||
|
||||
useEffectWrapper(() => {
|
||||
console.log(foo);
|
||||
});
|
||||
}
|
||||
|
||||
```
|
||||
@@ -48,11 +53,12 @@ function Component({foo, bar}) {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
|
||||
import { useEffect, useRef } from "react";
|
||||
import useEffectWrapper from "useEffectWrapper";
|
||||
|
||||
const moduleNonReactive = 0;
|
||||
|
||||
function Component(t0) {
|
||||
const $ = _c(12);
|
||||
const $ = _c(14);
|
||||
const { foo, bar } = t0;
|
||||
|
||||
const ref = useRef(0);
|
||||
@@ -125,6 +131,17 @@ function Component(t0) {
|
||||
const f = t5;
|
||||
|
||||
useEffect(f);
|
||||
let t6;
|
||||
if ($[12] !== foo) {
|
||||
t6 = () => {
|
||||
console.log(foo);
|
||||
};
|
||||
$[12] = foo;
|
||||
$[13] = t6;
|
||||
} else {
|
||||
t6 = $[13];
|
||||
}
|
||||
useEffectWrapper(t6, [foo]);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
// @inferEffectDependencies
|
||||
import {useEffect, useRef} from 'react';
|
||||
import useEffectWrapper from 'useEffectWrapper';
|
||||
|
||||
const moduleNonReactive = 0;
|
||||
|
||||
@@ -35,4 +36,8 @@ function Component({foo, bar}) {
|
||||
|
||||
// No inferred dep array, the argument is not a lambda
|
||||
useEffect(f);
|
||||
|
||||
useEffectWrapper(() => {
|
||||
console.log(foo);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -297,6 +297,8 @@ function getEvaluatorPresets(
|
||||
arg.value = './shared-runtime';
|
||||
} else if (arg.value === 'ReactForgetFeatureFlag') {
|
||||
arg.value = './ReactForgetFeatureFlag';
|
||||
} else if (arg.value === 'useEffectWrapper') {
|
||||
arg.value = './useEffectWrapper';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/* This file is used to test the effect auto-deps configuration, which
|
||||
* allows you to specify functions that should have dependencies added to
|
||||
* callsites.
|
||||
*/
|
||||
import {useEffect} from 'react';
|
||||
|
||||
export default function useEffectWrapper(f: () => void | (() => void)): void {
|
||||
useEffect(() => {
|
||||
f();
|
||||
}, [f]);
|
||||
}
|
||||
+3
-3
@@ -6,14 +6,14 @@
|
||||
*/
|
||||
|
||||
// v0.17.1
|
||||
declare module "hermes-parser" {
|
||||
declare module 'hermes-parser' {
|
||||
type HermesParserOptions = {
|
||||
allowReturnOutsideFunction?: boolean;
|
||||
babel?: boolean;
|
||||
flow?: "all" | "detect";
|
||||
flow?: 'all' | 'detect';
|
||||
enableExperimentalComponentSyntax?: boolean;
|
||||
sourceFilename?: string;
|
||||
sourceType?: "module" | "script" | "unambiguous";
|
||||
sourceType?: 'module' | 'script' | 'unambiguous';
|
||||
tokens?: boolean;
|
||||
};
|
||||
export function parse(code: string, options: Partial<HermesParserOptions>);
|
||||
|
||||
Reference in New Issue
Block a user