Skip to content

Commit 1a1177e

Browse files
authoredJul 3, 2020
fix: incorrect typedef parsing for interfaces (#24192)
* fix: incorrect typedef parsing for interfaces Wasn't finding typedefs for interfaces with the same name as the typed thing; e.g. ```ts interface Foo {} const Foo: Foo ``` Also adds a guard and more helpful error when unavoidable loops occur due to type naming * test: add tests
1 parent baddf58 commit 1a1177e

File tree

4 files changed

+41
-16
lines changed

4 files changed

+41
-16
lines changed
 

‎packages/gatsby-transformer-documentationjs/src/__tests__/__snapshots__/gatsby-node.js.snap

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`transformer-react-doc-gen: onCreateNode Complex example should handle members should handle type unions 1`] = `
3+
exports[`gatsby-transformer-documentationjs: onCreateNode Complex example should handle members should handle type unions 1`] = `
44
Object {
55
"elements": Array [
66
Object {
@@ -18,7 +18,7 @@ Object {
1818
}
1919
`;
2020

21-
exports[`transformer-react-doc-gen: onCreateNode Complex example should handle typedefs should handle type applications 1`] = `
21+
exports[`gatsby-transformer-documentationjs: onCreateNode Complex example should handle typedefs should handle type applications 1`] = `
2222
Object {
2323
"children": Array [
2424
"documentationJS documentationJS node_1 path #[{\\"name\\":\\"ObjectType\\",\\"kind\\":\\"typedef\\"}] line 12 path #[{\\"name\\":\\"ObjectType\\",\\"kind\\":\\"typedef\\"},{\\"fieldName\\":\\"properties\\",\\"fieldIndex\\":0}] line 3--DocumentationJSComponentDescription--comment.description",
@@ -52,12 +52,12 @@ Object {
5252
}
5353
`;
5454

55-
exports[`transformer-react-doc-gen: onCreateNode Simple example should extract out a description, params, and examples: description content 1`] = `
55+
exports[`gatsby-transformer-documentationjs: onCreateNode Simple example should extract out a description, params, and examples: description content 1`] = `
5656
"A pretty cool jsdoc example
5757
"
5858
`;
5959

60-
exports[`transformer-react-doc-gen: onCreateNode Simple example should extract out a description, params, and examples: example 1`] = `
60+
exports[`gatsby-transformer-documentationjs: onCreateNode Simple example should extract out a description, params, and examples: example 1`] = `
6161
Object {
6262
"description": "const apple = require('apple')
6363
apple()",
@@ -68,9 +68,9 @@ apple()",
6868
}
6969
`;
7070
71-
exports[`transformer-react-doc-gen: onCreateNode Simple example should extract out a description, params, and examples: param description 1`] = `
71+
exports[`gatsby-transformer-documentationjs: onCreateNode Simple example should extract out a description, params, and examples: param description 1`] = `
7272
"A nice crispy apple
7373
"
7474
`;
7575
76-
exports[`transformer-react-doc-gen: onCreateNode Simple example should extract out a description, params, and examples: param name 1`] = `"paramName"`;
76+
exports[`gatsby-transformer-documentationjs: onCreateNode Simple example should extract out a description, params, and examples: param name 1`] = `"paramName"`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
/**
3+
* The actual type
4+
*/
5+
export declare interface Foo {
6+
(props: any): JSX.Element | null;
7+
}
8+
9+
/**
10+
* The Main Thing here
11+
*/
12+
const Foo: Foo = () => null;
13+
14+

‎packages/gatsby-transformer-documentationjs/src/__tests__/gatsby-node.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import groupBy from "lodash/groupBy"
22
import path from "path"
33
import gatsbyNode from "../gatsby-node"
44

5-
describe(`transformer-react-doc-gen: onCreateNode`, () => {
5+
describe(`gatsby-transformer-documentationjs: onCreateNode`, () => {
66
let createdNodes, updatedNodes
77
const createNodeId = jest.fn(id => id)
88
const createContentDigest = jest.fn().mockReturnValue(`content-digest`)
@@ -361,4 +361,8 @@ describe(`transformer-react-doc-gen: onCreateNode`, () => {
361361
expect(createdNodes.length).toBeGreaterThan(0)
362362
})
363363
})
364+
365+
it(`doesn't cause a stack overflow for nodes of the same name`, () => {
366+
expect(run(getFileNode(`same-name.ts`))).resolves.toBeUndefined()
367+
})
364368
})

‎packages/gatsby-transformer-documentationjs/src/gatsby-node.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,25 @@ exports.onCreateNode = async ({ node, actions, ...helpers }) => {
218218
const handledDocs = new WeakMap()
219219
const typeDefs = new Map()
220220

221-
const getNodeIDForType = typeName => {
221+
const getNodeIDForType = (typeName, parent) => {
222222
if (typeDefs.has(typeName)) {
223223
return typeDefs.get(typeName)
224224
}
225225

226226
const index = documentationJson.findIndex(
227227
docsJson =>
228228
docsJson.name === typeName &&
229-
[`typedef`, `constant`].includes(docsJson.kind)
229+
[`interface`, `typedef`, `constant`].includes(docsJson.kind)
230230
)
231231

232-
if (index !== -1) {
232+
const isCycle = parent === documentationJson[index]
233+
if (isCycle) {
234+
helpers.reporter.warn(
235+
`Unexpected cycle detected creating DocumentationJS nodes for file:\n\n\t${node.absolutePath}\n\nFor type: ${typeName}`
236+
)
237+
}
238+
239+
if (index !== -1 && !isCycle) {
233240
return prepareNodeForDocs(documentationJson[index], {
234241
commentNumber: index,
235242
}).node.id
@@ -238,21 +245,21 @@ exports.onCreateNode = async ({ node, actions, ...helpers }) => {
238245
return null
239246
}
240247

241-
const tryToAddTypeDef = type => {
248+
const tryToAddTypeDef = (type, parent) => {
242249
if (type.applications) {
243-
type.applications.forEach(tryToAddTypeDef)
250+
type.applications.forEach(t => tryToAddTypeDef(t, parent))
244251
}
245252

246253
if (type.expression) {
247-
tryToAddTypeDef(type.expression)
254+
tryToAddTypeDef(type.expression, parent)
248255
}
249256

250257
if (type.elements) {
251-
type.elements.forEach(tryToAddTypeDef)
258+
type.elements.forEach(t => tryToAddTypeDef(t, parent))
252259
}
253260

254261
if (type.type === `NameExpression` && type.name) {
255-
type.typeDef___NODE = getNodeIDForType(type.name)
262+
type.typeDef___NODE = getNodeIDForType(type.name, parent)
256263
}
257264
}
258265

@@ -334,7 +341,7 @@ exports.onCreateNode = async ({ node, actions, ...helpers }) => {
334341
picked.type = picked.type.expression
335342
}
336343

337-
tryToAddTypeDef(picked.type)
344+
tryToAddTypeDef(picked.type, docsJson)
338345
}
339346

340347
const mdFields = [`description`, `deprecated`]

0 commit comments

Comments
 (0)
Please sign in to comment.