Skip to content
This repository was archived by the owner on Mar 8, 2019. It is now read-only.

Commit 954efdd

Browse files
authored
fix: add variable resolution in event doc
* test: add immediately resolved event name * extract resolve identifier * fix: add variable resolution in event doc #113
1 parent c4f1d52 commit 954efdd

File tree

4 files changed

+93
-57
lines changed

4 files changed

+93
-57
lines changed

src/script-handlers/__tests__/eventHandler.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as bt from '@babel/types'
12
import { NodePath } from 'ast-types'
23
import babylon from '../../babel-parser'
34
import { Documentation, EventDescriptor } from '../../Documentation'
@@ -6,9 +7,9 @@ import eventHandler from '../eventHandler'
67

78
jest.mock('../../Documentation')
89

9-
function parse(src: string): NodePath | undefined {
10+
function parse(src: string): { component: NodePath | undefined; ast: bt.File } {
1011
const ast = babylon().parse(src)
11-
return resolveExportedComponent(ast).get('default')
12+
return { component: resolveExportedComponent(ast).get('default'), ast }
1213
}
1314

1415
describe('eventHandler', () => {
@@ -38,8 +39,8 @@ describe('eventHandler', () => {
3839
}
3940
`
4041
const def = parse(src)
41-
if (def) {
42-
eventHandler(documentation, def)
42+
if (def.component) {
43+
eventHandler(documentation, def.component, def.ast)
4344
}
4445
const eventComp: EventDescriptor = {
4546
description: 'Describe the event',
@@ -73,8 +74,8 @@ describe('eventHandler', () => {
7374
}
7475
`
7576
const def = parse(src)
76-
if (def) {
77-
eventHandler(documentation, def)
77+
if (def.component) {
78+
eventHandler(documentation, def.component, def.ast)
7879
}
7980
const eventComp: EventDescriptor = {
8081
description: '',
@@ -93,4 +94,22 @@ describe('eventHandler', () => {
9394
expect(documentation.getEventDescriptor).toHaveBeenCalledWith('success')
9495
expect(mockEventDescriptor).toMatchObject(eventComp)
9596
})
97+
98+
it('should find events names stored in variables', () => {
99+
const src = `
100+
const successEventName = 'success';
101+
export default {
102+
methods: {
103+
testEmit() {
104+
this.$emit(successEventName, 1, 2)
105+
}
106+
}
107+
}
108+
`
109+
const def = parse(src)
110+
if (def.component) {
111+
eventHandler(documentation, def.component, def.ast)
112+
}
113+
expect(documentation.getEventDescriptor).toHaveBeenCalledWith('success')
114+
})
96115
})

src/script-handlers/eventHandler.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,17 @@ import {
1111
} from '../Documentation'
1212
import getDocblock from '../utils/getDocblock'
1313
import getDoclets from '../utils/getDoclets'
14+
import resolveIdentifier from '../utils/resolveIdentifier'
1415

1516
export interface TypedParamTag extends ParamTag {
1617
type: ParamType
1718
}
1819

19-
export default function eventHandler(documentation: Documentation, path: NodePath) {
20+
export default function eventHandler(
21+
documentation: Documentation,
22+
path: NodePath,
23+
astPath: bt.File,
24+
) {
2025
recast.visit(path.node, {
2126
visitCallExpression(pathExpression) {
2227
if (
@@ -30,12 +35,16 @@ export default function eventHandler(documentation: Documentation, path: NodePat
3035
return false
3136
}
3237

33-
const firstArg = args[0]
34-
if (!bt.isStringLiteral(firstArg)) {
38+
let firstArg = pathExpression.get('arguments', 0)
39+
if (bt.isIdentifier(firstArg.node)) {
40+
firstArg = resolveIdentifier(astPath, firstArg)
41+
}
42+
43+
if (!bt.isStringLiteral(firstArg.node)) {
3544
return false
3645
}
3746

38-
const eventName = firstArg.value
47+
const eventName = firstArg.node.value
3948

4049
// if this event is documented somewhere else leave it alone
4150
const evtDescriptor = documentation.getEventDescriptor(eventName)

src/utils/resolveExportedComponent.ts

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import recast from 'recast'
44
import Map from 'ts-map'
55
import isExportedAssignment from './isExportedAssignment'
66
import resolveExportDeclaration from './resolveExportDeclaration'
7+
import resolveIdentifier from './resolveIdentifier'
78

89
function ignore(): boolean {
910
return false
@@ -128,50 +129,3 @@ function normalizeComponentPath(path: NodePath): NodePath {
128129
}
129130
return path
130131
}
131-
132-
function resolveIdentifier(ast: bt.File, path: NodePath): NodePath | null {
133-
if (!bt.isIdentifier(path.node)) {
134-
return path
135-
}
136-
137-
const varName = path.node.name
138-
let comp: NodePath | null = null
139-
140-
recast.visit(ast.program, {
141-
// to look only at the root we ignore all traversing
142-
visitFunctionDeclaration: ignore,
143-
visitFunctionExpression: ignore,
144-
visitClassExpression: ignore,
145-
visitIfStatement: ignore,
146-
visitWithStatement: ignore,
147-
visitSwitchStatement: ignore,
148-
visitWhileStatement: ignore,
149-
visitDoWhileStatement: ignore,
150-
visitForStatement: ignore,
151-
visitForInStatement: ignore,
152-
153-
visitVariableDeclaration(variablePath) {
154-
if (!bt.isVariableDeclaration(variablePath.node)) {
155-
return false
156-
}
157-
const varID = variablePath.node.declarations[0].id
158-
if (!varID || !bt.isIdentifier(varID) || varID.name !== varName) {
159-
return false
160-
}
161-
162-
comp = variablePath.get('declarations', 0).get('init')
163-
return false
164-
},
165-
166-
visitClassDeclaration(classPath) {
167-
const classID = classPath.node.id
168-
if (!classID || !bt.isIdentifier(classID) || classID.name !== varName) {
169-
return false
170-
}
171-
172-
comp = classPath
173-
return false
174-
},
175-
})
176-
return comp
177-
}

src/utils/resolveIdentifier.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import * as bt from '@babel/types'
2+
import { NodePath } from 'ast-types'
3+
import recast from 'recast'
4+
5+
function ignore(): boolean {
6+
return false
7+
}
8+
9+
export default function resolveIdentifier(ast: bt.File, path: NodePath): NodePath | null {
10+
if (!bt.isIdentifier(path.node)) {
11+
return path
12+
}
13+
14+
const varName = path.node.name
15+
let comp: NodePath | null = null
16+
17+
recast.visit(ast.program, {
18+
// to look only at the root we ignore all traversing
19+
visitFunctionDeclaration: ignore,
20+
visitFunctionExpression: ignore,
21+
visitClassExpression: ignore,
22+
visitIfStatement: ignore,
23+
visitWithStatement: ignore,
24+
visitSwitchStatement: ignore,
25+
visitWhileStatement: ignore,
26+
visitDoWhileStatement: ignore,
27+
visitForStatement: ignore,
28+
visitForInStatement: ignore,
29+
30+
visitVariableDeclaration(variablePath) {
31+
if (!bt.isVariableDeclaration(variablePath.node)) {
32+
return false
33+
}
34+
const varID = variablePath.node.declarations[0].id
35+
if (!varID || !bt.isIdentifier(varID) || varID.name !== varName) {
36+
return false
37+
}
38+
39+
comp = variablePath.get('declarations', 0).get('init')
40+
return false
41+
},
42+
43+
visitClassDeclaration(classPath) {
44+
const classID = classPath.node.id
45+
if (!classID || !bt.isIdentifier(classID) || classID.name !== varName) {
46+
return false
47+
}
48+
49+
comp = classPath
50+
return false
51+
},
52+
})
53+
return comp
54+
}

0 commit comments

Comments
 (0)