-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathexport.js
91 lines (75 loc) · 2.45 KB
/
export.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import ExportMap, { recursivePatternCapture } from '../ExportMap'
import docsUrl from '../docsUrl'
import includes from 'array-includes'
module.exports = {
meta: {
type: 'problem',
docs: {
url: docsUrl('export'),
},
},
create: function (context) {
const named = new Map()
function addNamed(name, node, type) {
const key = type ? `${type}:${name}` : name
let nodes = named.get(key)
if (nodes == null) {
nodes = new Set()
named.set(key, nodes)
}
nodes.add(node)
}
return {
'ExportDefaultDeclaration': (node) => addNamed('default', node),
'ExportSpecifier': function (node) {
addNamed(node.exported.name, node.exported)
},
'ExportNamedDeclaration': function (node) {
if (node.declaration == null) return
if (node.declaration.id != null) {
if (includes([
'TSTypeAliasDeclaration',
'TSInterfaceDeclaration',
], node.declaration.type)) {
addNamed(node.declaration.id.name, node.declaration.id, 'type')
} else {
addNamed(node.declaration.id.name, node.declaration.id)
}
}
if (node.declaration.declarations != null) {
for (let declaration of node.declaration.declarations) {
recursivePatternCapture(declaration.id, v => addNamed(v.name, v))
}
}
},
'ExportAllDeclaration': function (node) {
if (node.source == null) return // not sure if this is ever true
const remoteExports = ExportMap.get(node.source.value, context)
if (remoteExports == null) return
if (remoteExports.errors.length) {
remoteExports.reportErrors(context, node)
return
}
let any = false
remoteExports.forEach((v, name) =>
name !== 'default' &&
(any = true) && // poor man's filter
addNamed(name, node))
if (!any) {
context.report(node.source,
`No named exports found in module '${node.source.value}'.`)
}
},
'Program:exit': function () {
for (let [name, nodes] of named) {
if (nodes.size <= 1) continue
for (let node of nodes) {
if (name === 'default') {
context.report(node, 'Multiple default exports.')
} else context.report(node, `Multiple exports of name '${name}'.`)
}
}
},
}
},
}