mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[validation] More detailed error diagnostics for validatePreserveExistingMemo
--- This should make it easier to grep through error diagnostics to understand state of the codebase: - no matching dependences -> likely that source is ignoring eslint failures - differences in ref.current access -> non-backwards compatible refs - subpath -> should be fixable in the compiler (unless source is ignore eslint failures)
This commit is contained in:
+56
-6
@@ -102,10 +102,41 @@ function prettyPrintScopeDependency(val: ReactiveScopeDependency): string {
|
||||
return `${rootStr}${val.path.length > 0 ? "." : ""}${val.path.join(".")}`;
|
||||
}
|
||||
|
||||
enum CompareDependencyResult {
|
||||
Ok = 0,
|
||||
RootDifference = 1,
|
||||
PathDifference = 2,
|
||||
Subpath = 3,
|
||||
RefAccessDifference = 4,
|
||||
}
|
||||
|
||||
function merge(
|
||||
a: CompareDependencyResult,
|
||||
b: CompareDependencyResult
|
||||
): CompareDependencyResult {
|
||||
return Math.max(a, b);
|
||||
}
|
||||
|
||||
function getCompareDependencyResultDescription(
|
||||
result: CompareDependencyResult
|
||||
): string {
|
||||
switch (result) {
|
||||
case CompareDependencyResult.Ok:
|
||||
return "dependencies equal";
|
||||
case CompareDependencyResult.RootDifference:
|
||||
case CompareDependencyResult.PathDifference:
|
||||
return "inferred different dependency than source";
|
||||
case CompareDependencyResult.RefAccessDifference:
|
||||
return "differences in ref.current access";
|
||||
case CompareDependencyResult.Subpath:
|
||||
return "inferred less specific property than source";
|
||||
}
|
||||
}
|
||||
|
||||
function compareDeps(
|
||||
inferred: ManualMemoDependency,
|
||||
source: ManualMemoDependency
|
||||
): boolean {
|
||||
): CompareDependencyResult {
|
||||
const rootsEqual =
|
||||
(inferred.root.kind === "Global" &&
|
||||
source.root.kind === "Global" &&
|
||||
@@ -114,7 +145,7 @@ function compareDeps(
|
||||
source.root.kind === "NamedLocal" &&
|
||||
inferred.root.value.identifier.id === source.root.value.identifier.id);
|
||||
if (!rootsEqual) {
|
||||
return false;
|
||||
return CompareDependencyResult.RootDifference;
|
||||
}
|
||||
|
||||
let isSubpath = true;
|
||||
@@ -131,9 +162,20 @@ function compareDeps(
|
||||
(inferred.path.length >= source.path.length &&
|
||||
!inferred.path.includes("current")))
|
||||
) {
|
||||
return true;
|
||||
return CompareDependencyResult.Ok;
|
||||
} else {
|
||||
return false;
|
||||
if (isSubpath) {
|
||||
if (
|
||||
source.path.includes("current") ||
|
||||
inferred.path.includes("current")
|
||||
) {
|
||||
return CompareDependencyResult.RefAccessDifference;
|
||||
} else {
|
||||
return CompareDependencyResult.Subpath;
|
||||
}
|
||||
} else {
|
||||
return CompareDependencyResult.PathDifference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,9 +239,13 @@ function validateInferredDep(
|
||||
return;
|
||||
}
|
||||
}
|
||||
let errorDiagnostic: CompareDependencyResult | null = null;
|
||||
for (const originalDep of validDepsInMemoBlock) {
|
||||
if (compareDeps(normalizedDep, originalDep)) {
|
||||
const compareResult = compareDeps(normalizedDep, originalDep);
|
||||
if (compareResult === CompareDependencyResult.Ok) {
|
||||
return;
|
||||
} else {
|
||||
errorDiagnostic = merge(errorDiagnostic ?? compareResult, compareResult);
|
||||
}
|
||||
}
|
||||
errorState.push({
|
||||
@@ -210,7 +256,11 @@ function validateInferredDep(
|
||||
dep
|
||||
)}\`, but the source dependencies were [${validDepsInMemoBlock
|
||||
.map((dep) => printManualMemoDependency(dep, true))
|
||||
.join(", ")}]`,
|
||||
.join(", ")}]. Detail: ${
|
||||
errorDiagnostic
|
||||
? getCompareDependencyResultDescription(errorDiagnostic)
|
||||
: "none"
|
||||
}`,
|
||||
loc: GeneratedSource,
|
||||
suggestions: null,
|
||||
});
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ function useHook(maybeRef) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `maybeRef.current`, but the source dependencies were [maybeRef]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `maybeRef.current`, but the source dependencies were [maybeRef]. Detail: differences in ref.current access
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ function useHook(maybeRef, shouldRead) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `maybeRef.current`, but the source dependencies were [shouldRead, maybeRef]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `maybeRef.current`, but the source dependencies were [shouldRead, maybeRef]. Detail: differences in ref.current access
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ function useHook(x) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `aliasedX`, but the source dependencies were [x, aliasedProp]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `aliasedX`, but the source dependencies were [x, aliasedProp]. Detail: inferred different dependency than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA, propB.x.y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA, propB.x.y]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ function Component({ propA, propB }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ function Component({ propA }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ function useHook(x) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `x`, but the source dependencies were [aliasedX, aliasedProp]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `x`, but the source dependencies were [aliasedX, aliasedProp]. Detail: inferred different dependency than source
|
||||
```
|
||||
|
||||
|
||||
+2
-2
@@ -24,9 +24,9 @@ function Component({ propA, propB }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA.a, propB.x.y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+2
-2
@@ -24,9 +24,9 @@ function Component({ propA, propB }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA.a, propB.x.y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propB`, but the source dependencies were [propA.a, propB.x.y]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ function Component({ propA }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ function Component({ propA }) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `propA`, but the source dependencies were [propA.x]. Detail: inferred less specific property than source
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ function useFoo(input1) {
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `input1`, but the source dependencies were [y]
|
||||
[ReactForget] Todo: Could not preserve manual memoization because an inferred dependency does not match the dependency list in source. The inferred dependency was `input1`, but the source dependencies were [y]. Detail: inferred different dependency than source
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user