Skip to content

Commit bdf2a9b

Browse files
yungsterszpao
authored andcommitted
Use invariant in react/utils
Just some therapeutic cleanup.
1 parent 8d48610 commit bdf2a9b

10 files changed

Lines changed: 147 additions & 221 deletions

src/utils/OrderedMap.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ function OrderedMapImpl(normalizedObj, computedLength) {
8585
* Validates a "public" key - that is, one that the public facing API supplies.
8686
* The key is then normalized for internal storage. In order to be considered
8787
* valid, all keys must be non-empty, defined, non-null strings or numbers.
88-
* Since this already costs a function invocation, will avoid additional call to
89-
* `throwIf`.
9088
*
9189
* @param {string?} key Validates that the key is suitable for use in a
9290
* `OrderedMap`.

src/utils/Transaction.js

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,7 @@
1818

1919
"use strict";
2020

21-
var throwIf = require('throwIf');
22-
23-
var DUAL_TRANSACTION = 'DUAL_TRANSACTION';
24-
var MISSING_TRANSACTION = 'MISSING_TRANSACTION';
25-
if (__DEV__) {
26-
DUAL_TRANSACTION =
27-
'Cannot initialize transaction when there is already an outstanding ' +
28-
'transaction. Common causes of this are trying to render a component ' +
29-
'when you are already rendering a component or attempting a state ' +
30-
'transition while in a render function. Another possibility is that ' +
31-
'you are rendering new content (or state transitioning) in a ' +
32-
'componentDidRender callback. If this is not the case, please report the ' +
33-
'issue immediately.';
34-
35-
MISSING_TRANSACTION =
36-
'Cannot close transaction when there is none open.';
37-
}
21+
var invariant = require('invariant');
3822

3923
/**
4024
* `Transaction` creates a black box that is able to wrap any method such that
@@ -156,26 +140,33 @@ var Mixin = {
156140
* @return Return value from `method`.
157141
*/
158142
perform: function(method, scope, a, b, c, d, e, f) {
159-
throwIf(this.isInTransaction(), DUAL_TRANSACTION);
143+
invariant(
144+
!this.isInTransaction(),
145+
'Transaction.perform(...): Cannot initialize a transaction when there ' +
146+
'is already an outstanding transaction.'
147+
);
160148
var memberStart = Date.now();
161-
var err = null;
149+
var errorToThrow = null;
162150
var ret;
163151
try {
164152
this.initializeAll();
165153
ret = method.call(scope, a, b, c, d, e, f);
166-
} catch (ie_requires_catch) {
167-
err = ie_requires_catch;
154+
} catch (error) {
155+
// IE8 requires `catch` in order to use `finally`.
156+
errorToThrow = error;
168157
} finally {
169158
var memberEnd = Date.now();
170159
this.methodInvocationTime += (memberEnd - memberStart);
171160
try {
172161
this.closeAll();
173-
} catch (closeAllErr) {
174-
err = err || closeAllErr;
162+
} catch (closeError) {
163+
// If `method` throws, prefer to show that stack trace over any thrown
164+
// by invoking `closeAll`.
165+
errorToThrow = errorToThrow || closeError;
175166
}
176167
}
177-
if (err) {
178-
throw err;
168+
if (errorToThrow) {
169+
throw errorToThrow;
179170
}
180171
return ret;
181172
},
@@ -184,24 +175,26 @@ var Mixin = {
184175
this._isInTransaction = true;
185176
var transactionWrappers = this.transactionWrappers;
186177
var wrapperInitTimes = this.timingMetrics.wrapperInitTimes;
187-
var err = null;
178+
var errorToThrow = null;
188179
for (var i = 0; i < transactionWrappers.length; i++) {
189180
var initStart = Date.now();
190181
var wrapper = transactionWrappers[i];
191182
try {
192-
this.wrapperInitData[i] =
193-
wrapper.initialize ? wrapper.initialize.call(this) : null;
194-
} catch (initErr) {
195-
err = err || initErr; // Remember the first error.
183+
this.wrapperInitData[i] = wrapper.initialize ?
184+
wrapper.initialize.call(this) :
185+
null;
186+
} catch (initError) {
187+
// Prefer to show the stack trace of the first error.
188+
errorToThrow = errorToThrow || initError;
196189
this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
197190
} finally {
198191
var curInitTime = wrapperInitTimes[i];
199192
var initEnd = Date.now();
200193
wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart);
201194
}
202195
}
203-
if (err) {
204-
throw err;
196+
if (errorToThrow) {
197+
throw errorToThrow;
205198
}
206199
},
207200

@@ -212,10 +205,13 @@ var Mixin = {
212205
* invoked).
213206
*/
214207
closeAll: function() {
215-
throwIf(!this.isInTransaction(), MISSING_TRANSACTION);
208+
invariant(
209+
this.isInTransaction(),
210+
'Transaction.closeAll(): Cannot close transaction when none are open.'
211+
);
216212
var transactionWrappers = this.transactionWrappers;
217213
var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes;
218-
var err = null;
214+
var errorToThrow = null;
219215
for (var i = 0; i < transactionWrappers.length; i++) {
220216
var wrapper = transactionWrappers[i];
221217
var closeStart = Date.now();
@@ -224,8 +220,9 @@ var Mixin = {
224220
if (initData !== Transaction.OBSERVED_ERROR) {
225221
wrapper.close && wrapper.close.call(this, initData);
226222
}
227-
} catch (closeErr) {
228-
err = err || closeErr; // Remember the first error.
223+
} catch (closeError) {
224+
// Prefer to show the stack trace of the first error.
225+
errorToThrow = errorToThrow || closeError;
229226
} finally {
230227
var closeEnd = Date.now();
231228
var curCloseTime = wrapperCloseTimes[i];
@@ -234,14 +231,16 @@ var Mixin = {
234231
}
235232
this.wrapperInitData.length = 0;
236233
this._isInTransaction = false;
237-
if (err) {
238-
throw err;
234+
if (errorToThrow) {
235+
throw errorToThrow;
239236
}
240237
}
241238
};
242239

243240
var Transaction = {
241+
244242
Mixin: Mixin,
243+
245244
/**
246245
* Token to look for to determine if an error occured.
247246
*/

src/utils/accumulate.js

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,34 @@
1818

1919
"use strict";
2020

21-
var throwIf = require('throwIf');
22-
23-
var INVALID_ARGS = 'INVALID_ACCUM_ARGS';
24-
25-
if (__DEV__) {
26-
INVALID_ARGS =
27-
'accumulate requires non empty (non-null, defined) next ' +
28-
'values. All arrays accumulated must not contain any empty items.';
29-
}
21+
var invariant = require('invariant');
3022

3123
/**
32-
* Accumulates items that must never be empty, into a result in a manner that
33-
* conserves memory - avoiding allocation of arrays until they are needed. The
34-
* accumulation may start and/or end up being a single element or an array
35-
* depending on the total count (if greater than one, an array is allocated).
36-
* Handles most common case first (starting with an empty current value and
37-
* acquiring one).
38-
* @return {Accumulation} An accumulation which is either a single item or an
39-
* Array of items.
24+
* Accumulates items that must not be null or undefined.
25+
*
26+
* This is used to conserve memory by avoiding array allocations.
27+
*
28+
* @return {*|array<*>} An accumulation of items.
4029
*/
41-
function accumulate(cur, next) {
42-
var curValIsEmpty = cur == null; // Will test for emptiness (null/undef)
43-
var nextValIsEmpty = next === null;
44-
if (__DEV__) {
45-
throwIf(nextValIsEmpty, INVALID_ARGS);
46-
}
47-
if (nextValIsEmpty) {
48-
return cur;
30+
function accumulate(current, next) {
31+
invariant(
32+
next != null,
33+
'accumulate(...): Accumulated items must be not be null or undefined.'
34+
);
35+
if (current == null) {
36+
return next;
4937
} else {
50-
if (curValIsEmpty) {
51-
return next;
38+
// Both are not empty. Warning: Never call x.concat(y) when you are not
39+
// certain that x is an Array (x could be a string with concat method).
40+
var currentIsArray = Array.isArray(current);
41+
var nextIsArray = Array.isArray(next);
42+
if (currentIsArray) {
43+
return current.concat(next);
5244
} else {
53-
// Both are not empty. Warning: Never call x.concat(y) when you are not
54-
// certain that x is an Array (x could be a string with concat method).
55-
var curIsArray = Array.isArray(cur);
56-
var nextIsArray = Array.isArray(next);
57-
if (curIsArray) {
58-
return cur.concat(next);
45+
if (nextIsArray) {
46+
return [current].concat(next);
5947
} else {
60-
if (nextIsArray) {
61-
return [cur].concat(next);
62-
} else {
63-
return [cur, next];
64-
}
48+
return [current, next];
6549
}
6650
}
6751
}

src/utils/escapeTextForBrowser.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,12 @@
1414
* limitations under the License.
1515
*
1616
* @providesModule escapeTextForBrowser
17+
* @typechecks static-only
1718
*/
1819

1920
"use strict";
2021

21-
var throwIf = require('throwIf');
22-
23-
var ESCAPE_TYPE_ERR;
24-
25-
if (__DEV__) {
26-
ESCAPE_TYPE_ERR =
27-
'The React core has attempted to escape content that is of a ' +
28-
'mysterious type (object etc) Escaping only works on numbers and strings';
29-
}
22+
var invariant = require('invariant');
3023

3124
var ESCAPE_LOOKUP = {
3225
"&": "&amp;",
@@ -41,13 +34,19 @@ function escaper(match) {
4134
return ESCAPE_LOOKUP[match];
4235
}
4336

44-
var escapeTextForBrowser = function (text) {
37+
/**
38+
* Escapes text to prevent scripting attacks.
39+
*
40+
* @param {number|string} text Text value to escape.
41+
* @return {string} An escaped string.
42+
*/
43+
function escapeTextForBrowser(text) {
4544
var type = typeof text;
46-
var invalid = type === 'object';
47-
if (__DEV__) {
48-
throwIf(invalid, ESCAPE_TYPE_ERR);
49-
}
50-
if (text === '' || invalid) {
45+
invariant(
46+
type !== 'object',
47+
'escapeTextForBrowser(...): Attempted to escape an object.'
48+
);
49+
if (text === '') {
5150
return '';
5251
} else {
5352
if (type === 'string') {
@@ -56,6 +55,6 @@ var escapeTextForBrowser = function (text) {
5655
return (''+text).replace(/[&><"'\/]/g, escaper);
5756
}
5857
}
59-
};
58+
}
6059

6160
module.exports = escapeTextForBrowser;

src/utils/flattenChildren.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
"use strict";
2020

21-
var throwIf = require('throwIf');
21+
var invariant = require('invariant');
2222
var traverseAllChildren = require('traverseAllChildren');
2323

2424
/**
@@ -27,14 +27,14 @@ var traverseAllChildren = require('traverseAllChildren');
2727
* @param {!string} name String name of key path to child.
2828
*/
2929
function flattenSingleChildIntoContext(traverseContext, child, name) {
30-
// We found a component instance
30+
// We found a component instance.
3131
var result = traverseContext;
32-
if (__DEV__) {
33-
throwIf(
34-
result.hasOwnProperty(name),
35-
traverseAllChildren.DUPLICATE_KEY_ERROR
36-
);
37-
}
32+
invariant(
33+
!result.hasOwnProperty(name),
34+
'flattenChildren(...): Encountered two children with the same key, `%s`. ' +
35+
'Children keys must be unique.',
36+
name
37+
);
3838
result[name] = child;
3939
}
4040

@@ -43,7 +43,7 @@ function flattenSingleChildIntoContext(traverseContext, child, name) {
4343
* @return {!object} flattened children keyed by name.
4444
*/
4545
function flattenChildren(children) {
46-
if (children === null || children === undefined) {
46+
if (children == null) {
4747
return children;
4848
}
4949
var result = {};

src/utils/keyMirror.js

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,38 @@
1414
* limitations under the License.
1515
*
1616
* @providesModule keyMirror
17+
* @typechecks static-only
1718
*/
1819

1920
"use strict";
2021

21-
var throwIf = require('throwIf');
22-
23-
var NOT_OBJECT_ERROR = 'NOT_OBJECT_ERROR';
24-
if (__DEV__) {
25-
NOT_OBJECT_ERROR = 'keyMirror only works on objects';
26-
}
22+
var invariant = require('invariant');
2723

2824
/**
29-
* Utility for constructing enums with keys being equal to the associated
30-
* values, even when using advanced key crushing. This is useful for debugging,
31-
* but also for using the values themselves as lookups into the enum.
32-
* Example:
33-
* var COLORS = keyMirror({blue: null, red: null});
34-
* var myColor = COLORS.blue;
35-
* var isColorValid = !!COLORS[myColor]
25+
* Constructs an enumeration with keys equal to their value.
26+
*
27+
* For example:
28+
*
29+
* var COLORS = keyMirror({blue: null, red: null});
30+
* var myColor = COLORS.blue;
31+
* var isColorValid = !!COLORS[myColor];
32+
*
3633
* The last line could not be performed if the values of the generated enum were
3734
* not equal to their keys.
38-
* Input: {key1: val1, key2: val2}
39-
* Output: {key1: key1, key2: key2}
35+
*
36+
* Input: {key1: val1, key2: val2}
37+
* Output: {key1: key1, key2: key2}
38+
*
39+
* @param {object} obj
40+
* @return {object}
4041
*/
4142
var keyMirror = function(obj) {
4243
var ret = {};
4344
var key;
44-
45-
throwIf(!(obj instanceof Object) || Array.isArray(obj), NOT_OBJECT_ERROR);
46-
45+
invariant(
46+
obj instanceof Object && !Array.isArray(obj),
47+
'keyMirror(...): Argument must be an object.'
48+
);
4749
for (key in obj) {
4850
if (!obj.hasOwnProperty(key)) {
4951
continue;

0 commit comments

Comments
 (0)