Skip to content

Commit 367d99e

Browse files
committed
Remove and partially deprecate Node's custom inspect funtion
1 parent c5f18a8 commit 367d99e

File tree

9 files changed

+33
-123
lines changed

9 files changed

+33
-123
lines changed

src/jsutils/__tests__/inspect-test.js

+15-30
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { describe, it } from 'mocha';
33

44
import inspect from '../inspect';
55
import invariant from '../invariant';
6-
import nodejsCustomInspectSymbol from '../nodejsCustomInspectSymbol';
76

87
describe('inspect', () => {
98
it('undefined', () => {
@@ -84,54 +83,40 @@ describe('inspect', () => {
8483
expect(inspect(map)).to.equal('{ a: true, b: null }');
8584
});
8685

87-
it('custom inspect', () => {
86+
it('use toJSON if provided', () => {
8887
const object = {
89-
inspect() {
90-
return '<custom inspect>';
88+
toJSON() {
89+
return '<json value>';
9190
},
9291
};
9392

94-
expect(inspect(object)).to.equal('<custom inspect>');
93+
expect(inspect(object)).to.equal('<json value>');
9594
});
9695

97-
it('custom inspect that return `this` should work', () => {
96+
it('handles toJSON that return `this` should work', () => {
9897
const object = {
99-
inspect() {
98+
toJSON() {
10099
return this;
101100
},
102101
};
103102

104-
expect(inspect(object)).to.equal('{ inspect: [function inspect] }');
103+
expect(inspect(object)).to.equal('{ toJSON: [function toJSON] }');
105104
});
106105

107-
it('custom symbol inspect is take precedence', () => {
106+
it('handles toJSON returning object values', () => {
108107
const object = {
109-
// istanbul ignore next (Never called and use just as a placeholder)
110-
inspect() {
111-
invariant(false);
112-
},
113-
[String(nodejsCustomInspectSymbol)]() {
114-
return '<custom symbol inspect>';
115-
},
116-
};
117-
118-
expect(inspect(object)).to.equal('<custom symbol inspect>');
119-
});
120-
121-
it('custom inspect returning object values', () => {
122-
const object = {
123-
inspect() {
124-
return { custom: 'inspect' };
108+
toJSON() {
109+
return { json: 'value' };
125110
},
126111
};
127112

128-
expect(inspect(object)).to.equal('{ custom: "inspect" }');
113+
expect(inspect(object)).to.equal('{ json: "value" }');
129114
});
130115

131-
it('custom inspect function that uses this', () => {
116+
it('handles toJSON function that uses this', () => {
132117
const object = {
133118
str: 'Hello World!',
134-
inspect() {
119+
toJSON() {
135120
return this.str;
136121
},
137122
};
@@ -160,11 +145,11 @@ describe('inspect', () => {
160145
expect(inspect(mixed)).to.equal('{ array: [[Circular]] }');
161146

162147
const customA = {
163-
inspect: () => customB,
148+
toJSON: () => customB,
164149
};
165150

166151
const customB = {
167-
inspect: () => customA,
152+
toJSON: () => customA,
168153
};
169154

170155
expect(inspect(customA)).to.equal('[Circular]');

src/jsutils/defineInspect.js

-19
This file was deleted.

src/jsutils/inspect.js

+6-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable flowtype/no-weak-types */
2-
import nodejsCustomInspectSymbol from './nodejsCustomInspectSymbol';
32

43
const MAX_ARRAY_LENGTH = 10;
54
const MAX_RECURSIVE_DEPTH = 2;
@@ -36,16 +35,15 @@ function formatObjectValue(
3635
}
3736

3837
const seenValues = [...previouslySeenValues, value];
39-
const customInspectFn = getCustomFn(value);
4038

41-
if (customInspectFn !== undefined) {
42-
const customValue = customInspectFn.call(value);
39+
if (typeof value.toJSON === 'function') {
40+
const jsonValue = value.toJSON(value);
4341

4442
// check for infinite recursion
45-
if (customValue !== value) {
46-
return typeof customValue === 'string'
47-
? customValue
48-
: formatValue(customValue, seenValues);
43+
if (jsonValue !== value) {
44+
return typeof jsonValue === 'string'
45+
? jsonValue
46+
: formatValue(jsonValue, seenValues);
4947
}
5048
} else if (Array.isArray(value)) {
5149
return formatArray(value, seenValues);
@@ -98,18 +96,6 @@ function formatArray(array: Array<mixed>, seenValues: Array<mixed>): string {
9896
return '[' + items.join(', ') + ']';
9997
}
10098

101-
function getCustomFn(object: Object) {
102-
const customInspectFn = object[String(nodejsCustomInspectSymbol)];
103-
104-
if (typeof customInspectFn === 'function') {
105-
return customInspectFn;
106-
}
107-
108-
if (typeof object.inspect === 'function') {
109-
return object.inspect;
110-
}
111-
}
112-
11399
function getObjectTag(object: Object): string {
114100
const tag = Object.prototype.toString
115101
.call(object)

src/jsutils/nodejsCustomInspectSymbol.js

-7
This file was deleted.

src/language/__tests__/lexer-test.js

-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// eslint-disable-next-line import/no-nodejs-modules
2-
import { inspect as nodeInspect } from 'util';
3-
41
import { expect } from 'chai';
52
import { describe, it } from 'mocha';
63

@@ -121,9 +118,6 @@ describe('Lexer', () => {
121118
expect(JSON.stringify(token)).to.equal(
122119
'{"kind":"Name","value":"foo","line":1,"column":1}',
123120
);
124-
expect(nodeInspect(token)).to.equal(
125-
"{ kind: 'Name', value: 'foo', line: 1, column: 1 }",
126-
);
127121
expect(inspect(token)).to.equal(
128122
'{ kind: "Name", value: "foo", line: 1, column: 1 }',
129123
);

src/language/__tests__/parser-test.js

-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// eslint-disable-next-line import/no-nodejs-modules
2-
import { inspect as nodeInspect } from 'util';
3-
41
import { expect } from 'chai';
52
import { describe, it } from 'mocha';
63

@@ -379,7 +376,6 @@ describe('Parser', () => {
379376
const result = parse('{ id }');
380377

381378
expect(JSON.stringify(result.loc)).to.equal('{"start":0,"end":6}');
382-
expect(nodeInspect(result.loc)).to.equal('{ start: 0, end: 6 }');
383379
expect(inspect(result.loc)).to.equal('{ start: 0, end: 6 }');
384380
});
385381

src/language/ast.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import defineInspect from '../jsutils/defineInspect';
2-
31
import type { Source } from './source';
42
import type { TokenKindEnum } from './tokenKind';
53

@@ -44,10 +42,13 @@ export class Location {
4442
toJSON(): {| start: number, end: number |} {
4543
return { start: this.start, end: this.end };
4644
}
47-
}
4845

49-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
50-
defineInspect(Location);
46+
// @deprecated: Will be removed in v17
47+
// $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet
48+
[Symbol.for('nodejs.util.inspect.custom')](): mixed {
49+
return this.toJSON();
50+
}
51+
}
5152

5253
/**
5354
* Represents a range of characters represented by a lexical token
@@ -124,10 +125,13 @@ export class Token {
124125
column: this.column,
125126
};
126127
}
127-
}
128128

129-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
130-
defineInspect(Token);
129+
// @deprecated: Will be removed in v17
130+
// $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet
131+
[Symbol.for('nodejs.util.inspect.custom')](): mixed {
132+
return this.toJSON();
133+
}
134+
}
131135

132136
/**
133137
* @internal

src/type/definition.js

-25
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import instanceOf from '../jsutils/instanceOf';
1717
import didYouMean from '../jsutils/didYouMean';
1818
import isObjectLike from '../jsutils/isObjectLike';
1919
import identityFunc from '../jsutils/identityFunc';
20-
import defineInspect from '../jsutils/defineInspect';
2120
import suggestionList from '../jsutils/suggestionList';
2221

2322
import { GraphQLError } from '../error/GraphQLError';
@@ -370,9 +369,6 @@ export class GraphQLList<+T: GraphQLType> {
370369
}
371370
}
372371

373-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
374-
defineInspect(GraphQLList);
375-
376372
/**
377373
* Non-Null Type Wrapper
378374
*
@@ -419,9 +415,6 @@ export class GraphQLNonNull<+T: GraphQLNullableType> {
419415
}
420416
}
421417

422-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
423-
defineInspect(GraphQLNonNull);
424-
425418
/**
426419
* These types wrap and modify other types
427420
*/
@@ -638,9 +631,6 @@ export class GraphQLScalarType {
638631
}
639632
}
640633
641-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
642-
defineInspect(GraphQLScalarType);
643-
644634
export type GraphQLScalarSerializer<TExternal> = (
645635
outputValue: mixed,
646636
) => ?TExternal;
@@ -782,9 +772,6 @@ export class GraphQLObjectType {
782772
}
783773
}
784774

785-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
786-
defineInspect(GraphQLObjectType);
787-
788775
function defineInterfaces(
789776
config: $ReadOnly<
790777
| GraphQLObjectTypeConfig<mixed, mixed>
@@ -1100,9 +1087,6 @@ export class GraphQLInterfaceType {
11001087
}
11011088
}
11021089

1103-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
1104-
defineInspect(GraphQLInterfaceType);
1105-
11061090
export type GraphQLInterfaceTypeConfig<TSource, TContext> = {|
11071091
name: string,
11081092
description?: ?string,
@@ -1207,9 +1191,6 @@ export class GraphQLUnionType {
12071191
}
12081192
}
12091193

1210-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
1211-
defineInspect(GraphQLUnionType);
1212-
12131194
function defineTypes(
12141195
config: $ReadOnly<GraphQLUnionTypeConfig<mixed, mixed>>,
12151196
): Array<GraphQLObjectType> {
@@ -1385,9 +1366,6 @@ export class GraphQLEnumType /* <T> */ {
13851366
}
13861367
}
13871368

1388-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
1389-
defineInspect(GraphQLEnumType);
1390-
13911369
function didYouMeanEnumValue(
13921370
enumType: GraphQLEnumType,
13931371
unknownValueStr: string,
@@ -1536,9 +1514,6 @@ export class GraphQLInputObjectType {
15361514
}
15371515
}
15381516

1539-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
1540-
defineInspect(GraphQLInputObjectType);
1541-
15421517
function defineInputFieldMap(
15431518
config: $ReadOnly<GraphQLInputObjectTypeConfig>,
15441519
): GraphQLInputFieldMap {

src/type/directives.js

-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import toObjMap from '../jsutils/toObjMap';
66
import devAssert from '../jsutils/devAssert';
77
import instanceOf from '../jsutils/instanceOf';
88
import isObjectLike from '../jsutils/isObjectLike';
9-
import defineInspect from '../jsutils/defineInspect';
109

1110
import type { DirectiveDefinitionNode } from '../language/ast';
1211
import type { DirectiveLocationEnum } from '../language/directiveLocation';
@@ -114,9 +113,6 @@ export class GraphQLDirective {
114113
}
115114
}
116115

117-
// Print a simplified form when appearing in `inspect` and `util.inspect`.
118-
defineInspect(GraphQLDirective);
119-
120116
export type GraphQLDirectiveConfig = {|
121117
name: string,
122118
description?: ?string,

0 commit comments

Comments
 (0)