Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inspect stack not returning all ancestors #693

Merged
merged 14 commits into from
Nov 22, 2024
Merged
109 changes: 67 additions & 42 deletions packages/vscode-extension/lib/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,43 @@ export function AppWrapper({ children, initialProps, ..._rest }) {
[openPreview, closePreview, requestNavigationChange]
);

const getInspectorDataForInstance = (node) => {
km1chno marked this conversation as resolved.
Show resolved Hide resolved
const renderers = Array.from(window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.values());

if (!renderers) {
return {};
}

for (const renderer of renderers) {
if (renderer.rendererConfig?.getInspectorDataForInstance) {
const data = renderer.rendererConfig.getInspectorDataForInstance(node);
return data ?? {};
}
}

return {};
};

useAgentListener(
devtoolsAgent,
"RNIDE_inspect",
(payload) => {
const getInspectorDataForViewAtPoint = RNInternals.getInspectorDataForViewAtPoint;
const { width, height } = Dimensions.get("screen");
const { requestStack } = payload;

const createStackElement = (
frame, name, source
) => (
{
componentName: name,
source: {
fileName: source.fileName,
line0Based: source.lineNumber - 1,
column0Based: source.columnNumber - 1,
},
frame,
});

getInspectorDataForViewAtPoint(
mainContainerRef.current,
Expand All @@ -190,53 +221,47 @@ export function AppWrapper({ children, initialProps, ..._rest }) {
x: frame.left / width,
y: frame.top / height,
width: frame.width / width,
height: frame.height / height,
height: frame.height / height
};
let stackPromise = Promise.resolve(undefined);
if (payload.requestStack) {
stackPromise = Promise.all(
viewData.hierarchy.reverse().map((item) => {
const inspectorData = item.getInspectorData((arg) => findNodeHandle(arg));
const framePromise = new Promise((resolve, reject) => {
try {
inspectorData.measure((_x, _y, viewWidth, viewHeight, pageX, pageY) => {
resolve({
x: pageX / width,
y: pageY / height,
width: viewWidth / width,
height: viewHeight / height,
});
});
} catch (e) {
reject(e);
}
});

return framePromise
.catch(() => undefined)
.then((frame) => {
return inspectorData.source
? {
componentName: item.name,
source: {
fileName: inspectorData.source.fileName,
line0Based: inspectorData.source.lineNumber - 1,
column0Based: inspectorData.source.columnNumber - 1,
},
frame,
}
: undefined;
});
})
).then((stack) => stack?.filter(Boolean));
}
stackPromise.then((stack) => {

if (!requestStack) {
devtoolsAgent._bridge.send("RNIDE_inspectData", {
id: payload.id,
frame: scaledFrame,
stack: stack,
});
});
return;
}

const inspectNode = (node, stack) => {
// Optimization: we break after reaching fiber node corresponding to OffscreenComponent (with tag 22).
if (!node || node.tag === 22) {
km1chno marked this conversation as resolved.
Show resolved Hide resolved
devtoolsAgent._bridge.send("RNIDE_inspectData", {
id: payload.id,
frame: scaledFrame,
stack: Array.from(stack).filter(Boolean)
});
km1chno marked this conversation as resolved.
Show resolved Hide resolved
} else {
const data = getInspectorDataForInstance(node);
const item = data.hierarchy[data.hierarchy.length - 1];
const inspectorData = item.getInspectorData((arg) => findNodeHandle(arg));

inspectorData.measure((_x, _y, viewWidth, viewHeight, pageX, pageY) => {
const stackElementFrame = {
x: pageX / width,
y: pageY / height,
width: viewWidth / width,
height: viewHeight / height
};

const element = (inspectorData.source) ?
createStackElement(stackElementFrame, item.name, inspectorData.source) : undefined;

inspectNode(node.return, [...stack, element]);
km1chno marked this conversation as resolved.
Show resolved Hide resolved
});
}
};

inspectNode(viewData.closestInstance, []);
km1chno marked this conversation as resolved.
Show resolved Hide resolved
}
);
},
Expand Down