Skip to content

Commit cf4d45e

Browse files
motiz88facebook-github-bot
authored andcommitted
Remove framesToPop from YellowBox
Summary: Removes the use of `framesToPop` to manage frame skipping in YellowBox and replaces it with support for the `collapse` field populated by Metro's [`customizeFrame`](facebook/metro#435) config option. `framesToPop` is a deprecated mechanism which will be removed in the future. Reviewed By: bvaughn Differential Revision: D17857057 fbshipit-source-id: 120383ba4aad877b7ca79c7cf9d5b7579a490577
1 parent df96de7 commit cf4d45e

6 files changed

+51
-59
lines changed

Libraries/YellowBox/Data/YellowBoxRegistry.js

-3
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,14 @@ function handleUpdate(): void {
6969
const YellowBoxRegistry = {
7070
add({
7171
args,
72-
framesToPop,
7372
}: $ReadOnly<{|
7473
args: $ReadOnlyArray<mixed>,
75-
framesToPop: number,
7674
|}>): void {
7775
if (typeof args[0] === 'string' && args[0].startsWith('(ADVICE)')) {
7876
return;
7977
}
8078
const {category, message, stack} = YellowBoxWarning.parse({
8179
args,
82-
framesToPop: framesToPop + 1,
8380
});
8481

8582
let warnings = registry.get(category);

Libraries/YellowBox/Data/YellowBoxSymbolication.js

+8
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,19 @@ const sanitize = (maybeStack: mixed): Stack => {
6666
if (typeof maybeFrame.methodName !== 'string') {
6767
throw new Error('Expected stack frame `methodName` to be a string.');
6868
}
69+
let collapse = false;
70+
if ('collapse' in maybeFrame) {
71+
if (typeof maybeFrame.collapse !== 'boolean') {
72+
throw new Error('Expected stack frame `collapse` to be a boolean.');
73+
}
74+
collapse = maybeFrame.collapse;
75+
}
6976
stack.push({
7077
column: maybeFrame.column,
7178
file: maybeFrame.file,
7279
lineNumber: maybeFrame.lineNumber,
7380
methodName: maybeFrame.methodName,
81+
collapse,
7482
});
7583
}
7684
return stack;

Libraries/YellowBox/Data/YellowBoxWarning.js

+2-9
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@ export type SymbolicationRequest = $ReadOnly<{|
2525
class YellowBoxWarning {
2626
static parse({
2727
args,
28-
framesToPop,
2928
}: $ReadOnly<{|
3029
args: $ReadOnlyArray<mixed>,
31-
framesToPop: number,
3230
|}>): {|
3331
category: Category,
3432
message: Message,
@@ -56,7 +54,8 @@ class YellowBoxWarning {
5654

5755
return {
5856
...YellowBoxCategory.parse(mutableArgs),
59-
stack: createStack({framesToPop: framesToPop + 1}),
57+
// TODO: Use Error.captureStackTrace on Hermes
58+
stack: parseErrorStack(new Error()),
6059
};
6160
}
6261

@@ -124,10 +123,4 @@ class YellowBoxWarning {
124123
}
125124
}
126125

127-
function createStack({framesToPop}: $ReadOnly<{|framesToPop: number|}>): Stack {
128-
const error: any = new Error();
129-
error.framesToPop = framesToPop + 1;
130-
return parseErrorStack(error);
131-
}
132-
133126
module.exports = YellowBoxWarning;

Libraries/YellowBox/Data/__tests__/YellowBoxRegistry-test.js

+36-36
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe('YellowBoxRegistry', () => {
3434
});
3535

3636
it('adds and deletes warnings', () => {
37-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
37+
YellowBoxRegistry.add({args: ['A']});
3838
const {category: categoryA} = YellowBoxCategory.parse(['A']);
3939

4040
expect(registry().size).toBe(1);
@@ -46,9 +46,9 @@ describe('YellowBoxRegistry', () => {
4646
});
4747

4848
it('clears all warnings', () => {
49-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
50-
YellowBoxRegistry.add({args: ['B'], framesToPop: 0});
51-
YellowBoxRegistry.add({args: ['C'], framesToPop: 0});
49+
YellowBoxRegistry.add({args: ['A']});
50+
YellowBoxRegistry.add({args: ['B']});
51+
YellowBoxRegistry.add({args: ['C']});
5252

5353
expect(registry().size).toBe(3);
5454

@@ -57,9 +57,9 @@ describe('YellowBoxRegistry', () => {
5757
});
5858

5959
it('sorts warnings in chronological order', () => {
60-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
61-
YellowBoxRegistry.add({args: ['B'], framesToPop: 0});
62-
YellowBoxRegistry.add({args: ['C'], framesToPop: 0});
60+
YellowBoxRegistry.add({args: ['A']});
61+
YellowBoxRegistry.add({args: ['B']});
62+
YellowBoxRegistry.add({args: ['C']});
6363

6464
const {category: categoryA} = YellowBoxCategory.parse(['A']);
6565
const {category: categoryB} = YellowBoxCategory.parse(['B']);
@@ -71,7 +71,7 @@ describe('YellowBoxRegistry', () => {
7171
categoryC,
7272
]);
7373

74-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
74+
YellowBoxRegistry.add({args: ['A']});
7575

7676
// Expect `A` to be hoisted to the end of the registry.
7777
expect(Array.from(registry().keys())).toEqual([
@@ -82,9 +82,9 @@ describe('YellowBoxRegistry', () => {
8282
});
8383

8484
it('ignores warnings matching patterns', () => {
85-
YellowBoxRegistry.add({args: ['A!'], framesToPop: 0});
86-
YellowBoxRegistry.add({args: ['B?'], framesToPop: 0});
87-
YellowBoxRegistry.add({args: ['C!'], framesToPop: 0});
85+
YellowBoxRegistry.add({args: ['A!']});
86+
YellowBoxRegistry.add({args: ['B?']});
87+
YellowBoxRegistry.add({args: ['C!']});
8888
expect(registry().size).toBe(3);
8989

9090
YellowBoxRegistry.addIgnorePatterns(['!']);
@@ -95,9 +95,9 @@ describe('YellowBoxRegistry', () => {
9595
});
9696

9797
it('ignores warnings matching regexs or pattern', () => {
98-
YellowBoxRegistry.add({args: ['There are 4 dogs'], framesToPop: 0});
99-
YellowBoxRegistry.add({args: ['There are 3 cats'], framesToPop: 0});
100-
YellowBoxRegistry.add({args: ['There are H cats'], framesToPop: 0});
98+
YellowBoxRegistry.add({args: ['There are 4 dogs']});
99+
YellowBoxRegistry.add({args: ['There are 3 cats']});
100+
YellowBoxRegistry.add({args: ['There are H cats']});
101101
expect(registry().size).toBe(3);
102102

103103
YellowBoxRegistry.addIgnorePatterns(['dogs']);
@@ -111,9 +111,9 @@ describe('YellowBoxRegistry', () => {
111111
});
112112

113113
it('ignores all warnings when disabled', () => {
114-
YellowBoxRegistry.add({args: ['A!'], framesToPop: 0});
115-
YellowBoxRegistry.add({args: ['B?'], framesToPop: 0});
116-
YellowBoxRegistry.add({args: ['C!'], framesToPop: 0});
114+
YellowBoxRegistry.add({args: ['A!']});
115+
YellowBoxRegistry.add({args: ['B?']});
116+
YellowBoxRegistry.add({args: ['C!']});
117117
expect(registry().size).toBe(3);
118118

119119
YellowBoxRegistry.setDisabled(true);
@@ -124,57 +124,57 @@ describe('YellowBoxRegistry', () => {
124124
});
125125

126126
it('groups warnings by simple categories', () => {
127-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
127+
YellowBoxRegistry.add({args: ['A']});
128128
expect(registry().size).toBe(1);
129129

130-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
130+
YellowBoxRegistry.add({args: ['A']});
131131
expect(registry().size).toBe(1);
132132

133-
YellowBoxRegistry.add({args: ['B'], framesToPop: 0});
133+
YellowBoxRegistry.add({args: ['B']});
134134
expect(registry().size).toBe(2);
135135
});
136136

137137
it('groups warnings by format string categories', () => {
138-
YellowBoxRegistry.add({args: ['%s', 'A'], framesToPop: 0});
138+
YellowBoxRegistry.add({args: ['%s', 'A']});
139139
expect(registry().size).toBe(1);
140140

141-
YellowBoxRegistry.add({args: ['%s', 'B'], framesToPop: 0});
141+
YellowBoxRegistry.add({args: ['%s', 'B']});
142142
expect(registry().size).toBe(1);
143143

144-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
144+
YellowBoxRegistry.add({args: ['A']});
145145
expect(registry().size).toBe(2);
146146

147-
YellowBoxRegistry.add({args: ['B'], framesToPop: 0});
147+
YellowBoxRegistry.add({args: ['B']});
148148
expect(registry().size).toBe(3);
149149
});
150150

151151
it('groups warnings with consideration for arguments', () => {
152-
YellowBoxRegistry.add({args: ['A', 'B'], framesToPop: 0});
152+
YellowBoxRegistry.add({args: ['A', 'B']});
153153
expect(registry().size).toBe(1);
154154

155-
YellowBoxRegistry.add({args: ['A', 'B'], framesToPop: 0});
155+
YellowBoxRegistry.add({args: ['A', 'B']});
156156
expect(registry().size).toBe(1);
157157

158-
YellowBoxRegistry.add({args: ['A', 'C'], framesToPop: 0});
158+
YellowBoxRegistry.add({args: ['A', 'C']});
159159
expect(registry().size).toBe(2);
160160

161-
YellowBoxRegistry.add({args: ['%s', 'A', 'A'], framesToPop: 0});
161+
YellowBoxRegistry.add({args: ['%s', 'A', 'A']});
162162
expect(registry().size).toBe(3);
163163

164-
YellowBoxRegistry.add({args: ['%s', 'B', 'A'], framesToPop: 0});
164+
YellowBoxRegistry.add({args: ['%s', 'B', 'A']});
165165
expect(registry().size).toBe(3);
166166

167-
YellowBoxRegistry.add({args: ['%s', 'B', 'B'], framesToPop: 0});
167+
YellowBoxRegistry.add({args: ['%s', 'B', 'B']});
168168
expect(registry().size).toBe(4);
169169
});
170170

171171
it('ignores warnings starting with "(ADVICE)"', () => {
172-
YellowBoxRegistry.add({args: ['(ADVICE) ...'], framesToPop: 0});
172+
YellowBoxRegistry.add({args: ['(ADVICE) ...']});
173173
expect(registry().size).toBe(0);
174174
});
175175

176176
it('does not ignore warnings formatted to start with "(ADVICE)"', () => {
177-
YellowBoxRegistry.add({args: ['%s ...', '(ADVICE)'], framesToPop: 0});
177+
YellowBoxRegistry.add({args: ['%s ...', '(ADVICE)']});
178178
expect(registry().size).toBe(1);
179179
});
180180

@@ -189,8 +189,8 @@ describe('YellowBoxRegistry', () => {
189189
const {observer} = observe();
190190
expect(observer.mock.calls.length).toBe(1);
191191

192-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
193-
YellowBoxRegistry.add({args: ['B'], framesToPop: 0});
192+
YellowBoxRegistry.add({args: ['A']});
193+
YellowBoxRegistry.add({args: ['B']});
194194
jest.runAllImmediates();
195195
expect(observer.mock.calls.length).toBe(2);
196196
});
@@ -207,7 +207,7 @@ describe('YellowBoxRegistry', () => {
207207
const {observer} = observe();
208208
expect(observer.mock.calls.length).toBe(1);
209209

210-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
210+
YellowBoxRegistry.add({args: ['A']});
211211
jest.runAllImmediates();
212212
expect(observer.mock.calls.length).toBe(2);
213213

@@ -226,7 +226,7 @@ describe('YellowBoxRegistry', () => {
226226
const {observer} = observe();
227227
expect(observer.mock.calls.length).toBe(1);
228228

229-
YellowBoxRegistry.add({args: ['A'], framesToPop: 0});
229+
YellowBoxRegistry.add({args: ['A']});
230230
jest.runAllImmediates();
231231
expect(observer.mock.calls.length).toBe(2);
232232

Libraries/YellowBox/UI/YellowBoxInspector.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ class YellowBoxInspector extends React.Component<Props, State> {
8686
/>
8787
</View>
8888
{warning.getAvailableStack().map((frame, index) => {
89-
const {file, lineNumber} = frame;
89+
const {file, lineNumber, collapse = false} = frame;
90+
if (collapse) {
91+
return null;
92+
}
9093
return (
9194
<YellowBoxInspectorStackFrame
9295
key={index}

Libraries/YellowBox/YellowBox.js

+1-10
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,7 @@ if (__DEV__) {
145145
};
146146

147147
const registerWarning = (...args): void => {
148-
// YellowBox should ignore the top 3-4 stack frames:
149-
// 1: registerWarning() itself
150-
// 2: YellowBox's own console override (in this file)
151-
// 3: React DevTools console.error override (to add component stack)
152-
// (The override feature may be disabled by a runtime preference.)
153-
// 4: The actual console method itself.
154-
// $FlowFixMe This prop is how the DevTools override is observable.
155-
const isDevToolsOvveride = !!console.warn
156-
.__REACT_DEVTOOLS_ORIGINAL_METHOD__;
157-
YellowBoxRegistry.add({args, framesToPop: isDevToolsOvveride ? 4 : 3});
148+
YellowBoxRegistry.add({args});
158149
};
159150
} else {
160151
YellowBox = class extends React.Component<Props, State> {

0 commit comments

Comments
 (0)