@@ -3,6 +3,7 @@ import declaredScope from '../core/declaredScope'
3
3
4
4
module . exports = function ( context ) {
5
5
const deprecated = new Map ( )
6
+ , namespaces = new Map ( )
6
7
7
8
function checkSpecifiers ( node ) {
8
9
if ( node . source == null ) return // local export, ignore
@@ -21,30 +22,16 @@ module.exports = function (context) {
21
22
return
22
23
}
23
24
24
- function getDeprecation ( imported ) {
25
- const metadata = imports . named . get ( imported )
26
- if ( ! metadata || ! metadata . doc ) return
27
-
28
- let deprecation
29
- if ( metadata . doc . tags . some ( t => t . title === 'deprecated' && ( deprecation = t ) ) ) {
30
- return deprecation
31
- }
32
- }
33
-
34
25
node . specifiers . forEach ( function ( im ) {
35
26
let imported , local
36
27
switch ( im . type ) {
37
28
38
- // case 'ImportNamespaceSpecifier':{
39
- // const submap = new Map()
40
- // for (let name in imports.named) {
41
- // const deprecation = getDeprecation(name)
42
- // if (!deprecation) continue
43
- // submap.set(name, deprecation)
44
- // }
45
- // if (submap.size > 0) deprecated.set(im.local.name, submap)
46
- // return
47
- // }
29
+
30
+ case 'ImportNamespaceSpecifier' :{
31
+ if ( ! imports . named . size ) return
32
+ namespaces . set ( im . local . name , imports . named )
33
+ return
34
+ }
48
35
49
36
case 'ImportDefaultSpecifier' :
50
37
imported = 'default'
@@ -62,7 +49,11 @@ module.exports = function (context) {
62
49
// unknown thing can't be deprecated
63
50
if ( ! imports . named . has ( imported ) ) return
64
51
65
- const deprecation = getDeprecation ( imported )
52
+ // capture named import of deep namespace
53
+ const { namespace } = imports . named . get ( imported )
54
+ if ( namespace ) namespaces . set ( local , namespace )
55
+
56
+ const deprecation = getDeprecation ( imports . named . get ( imported ) )
66
57
if ( ! deprecation ) return
67
58
68
59
context . report ( { node : im , message : message ( deprecation ) } )
@@ -76,6 +67,10 @@ module.exports = function (context) {
76
67
'ImportDeclaration' : checkSpecifiers ,
77
68
78
69
'Identifier' : function ( node ) {
70
+ if ( node . parent . type === 'MemberExpression' && node . parent . property === node ) {
71
+ return // handled by MemberExpression
72
+ }
73
+
79
74
// ignore specifier identifiers
80
75
if ( node . parent . type . slice ( 0 , 6 ) === 'Import' ) return
81
76
@@ -87,9 +82,50 @@ module.exports = function (context) {
87
82
message : message ( deprecated . get ( node . name ) ) ,
88
83
} )
89
84
} ,
85
+
86
+ 'MemberExpression' : function ( dereference ) {
87
+ if ( dereference . object . type !== 'Identifier' ) return
88
+ if ( ! namespaces . has ( dereference . object . name ) ) return
89
+
90
+ if ( declaredScope ( context , dereference . object . name ) !== 'module' ) return
91
+
92
+ // go deep
93
+ var namespace = namespaces . get ( dereference . object . name )
94
+ var namepath = [ dereference . object . name ]
95
+ // while property is namespace and parent is member expression, keep validating
96
+ while ( namespace instanceof Map &&
97
+ dereference . type === 'MemberExpression' ) {
98
+
99
+ // ignore computed parts for now
100
+ if ( dereference . computed ) return
101
+
102
+ const metadata = namespace . get ( dereference . property . name )
103
+
104
+ if ( ! metadata ) break
105
+ const deprecation = getDeprecation ( metadata )
106
+
107
+ if ( deprecation ) {
108
+ context . report ( { node : dereference . property , message : message ( deprecation ) } )
109
+ }
110
+
111
+ // stash and pop
112
+ namepath . push ( dereference . property . name )
113
+ namespace = metadata . namespace
114
+ dereference = dereference . parent
115
+ }
116
+ } ,
90
117
}
91
118
}
92
119
93
120
function message ( deprecation ) {
94
121
return 'Deprecated' + ( deprecation . description ? ': ' + deprecation . description : '.' )
95
122
}
123
+
124
+ function getDeprecation ( metadata ) {
125
+ if ( ! metadata || ! metadata . doc ) return
126
+
127
+ let deprecation
128
+ if ( metadata . doc . tags . some ( t => t . title === 'deprecated' && ( deprecation = t ) ) ) {
129
+ return deprecation
130
+ }
131
+ }
0 commit comments