2
2
3
3
"use strict"
4
4
5
- var acorn = require ( "acorn" )
6
- if ( false ) {
7
- throw new Error ( ( "acorn-private-class-elements requires acorn@^6.1.0, not " + ( acorn . version ) ) )
5
+ var getPrototype = Object . getPrototypeOf || ( function ( o ) { return o . __proto__ ; } )
6
+
7
+ var getAcorn = function ( Parser ) {
8
+ if ( Parser . acorn ) { return Parser . acorn }
9
+
10
+ var acorn = require ( "acorn" )
11
+
12
+ if ( acorn . version . indexOf ( "6." ) != 0 && acorn . version . indexOf ( "6.0." ) == 0 && acorn . version . indexOf ( "7." ) != 0 ) {
13
+ throw new Error ( ( "acorn-private-class-elements requires acorn@^6.1.0 or acorn@7.0.0, not " + ( acorn . version ) ) )
14
+ }
15
+
16
+ // Make sure `Parser` comes from the same acorn as we `require`d,
17
+ // otherwise the comparisons fail.
18
+ for ( var cur = Parser ; cur && cur !== acorn . Parser ; cur = getPrototype ( cur ) ) {
19
+ if ( cur !== acorn . Parser ) {
20
+ throw new Error ( "acorn-private-class-elements does not support mixing different acorn copies" )
21
+ }
22
+ }
23
+ return acorn
8
24
}
9
- var tt = acorn . tokTypes
10
- var TokenType = acorn . TokenType
11
25
12
26
module . exports = function ( Parser ) {
13
27
// Only load this plugin once.
14
28
if ( Parser . prototype . parsePrivateName ) {
15
29
return Parser
16
30
}
17
31
18
- // Make sure `Parser` comes from the same acorn as our `tt`,
19
- // otherwise the comparisons fail.
20
- var cur = Parser
21
- while ( cur && cur !== acorn . Parser ) {
22
- cur = cur . __proto__
23
- }
24
- if ( cur !== acorn . Parser ) {
25
- throw new Error ( "acorn-private-class-elements does not support mixing different acorn copies" )
26
- }
32
+ var acorn = getAcorn ( Parser )
27
33
28
34
Parser = /*@__PURE__ */ ( function ( Parser ) {
29
35
function Parser_ ( ) {
@@ -49,12 +55,12 @@ module.exports = function(Parser) {
49
55
element . key = this . parsePrivateName ( )
50
56
if ( element . key . name == "constructor" ) { this . raise ( element . key . start , "Classes may not have a private element named constructor" ) }
51
57
var accept = { get : "set" , set : "get" } [ element . kind ]
52
- var privateBoundNames = this . _privateBoundNamesStack [ this . _privateBoundNamesStack . length - 1 ]
58
+ var privateBoundNames = this . _privateBoundNames
53
59
if ( Object . prototype . hasOwnProperty . call ( privateBoundNames , element . key . name ) && privateBoundNames [ element . key . name ] !== accept ) {
54
60
this . raise ( element . start , "Duplicate private element" )
55
61
}
56
62
privateBoundNames [ element . key . name ] = element . kind || true
57
- delete this . _unresolvedPrivateNamesStack [ this . _unresolvedPrivateNamesStack . length - 1 ] [ element . key . name ]
63
+ delete this . _unresolvedPrivateNames [ element . key . name ]
58
64
return element . key
59
65
} ;
60
66
@@ -79,37 +85,60 @@ module.exports = function(Parser) {
79
85
80
86
// Manage stacks and check for undeclared private names
81
87
Parser_ . prototype . parseClass = function parseClass ( node , isStatement ) {
82
- this . _privateBoundNamesStack = this . _privateBoundNamesStack || [ ]
83
- var privateBoundNames = Object . create ( this . _privateBoundNamesStack [ this . _privateBoundNamesStack . length - 1 ] || null )
84
- this . _privateBoundNamesStack . push ( privateBoundNames )
85
- this . _unresolvedPrivateNamesStack = this . _unresolvedPrivateNamesStack || [ ]
86
- var unresolvedPrivateNames = Object . create ( null )
87
- this . _unresolvedPrivateNamesStack . push ( unresolvedPrivateNames )
88
+ var oldOuterPrivateBoundNames = this . _outerPrivateBoundNames
89
+ this . _outerPrivateBoundNames = this . _privateBoundNames
90
+ this . _privateBoundNames = Object . create ( this . _privateBoundNames || null )
91
+ var oldOuterUnresolvedPrivateNames = this . _outerUnresolvedPrivateNames
92
+ this . _outerUnresolvedPrivateNames = this . _unresolvedPrivateNames
93
+ this . _unresolvedPrivateNames = Object . create ( null )
94
+
88
95
var _return = Parser . prototype . parseClass . call ( this , node , isStatement )
89
- this . _privateBoundNamesStack . pop ( )
90
- this . _unresolvedPrivateNamesStack . pop ( )
91
- if ( ! this . _unresolvedPrivateNamesStack . length ) {
96
+
97
+ var unresolvedPrivateNames = this . _unresolvedPrivateNames
98
+ this . _privateBoundNames = this . _outerPrivateBoundNames
99
+ this . _outerPrivateBoundNames = oldOuterPrivateBoundNames
100
+ this . _unresolvedPrivateNames = this . _outerUnresolvedPrivateNames
101
+ this . _outerUnresolvedPrivateNames = oldOuterUnresolvedPrivateNames
102
+ if ( ! this . _unresolvedPrivateNames ) {
92
103
var names = Object . keys ( unresolvedPrivateNames )
93
104
if ( names . length ) {
94
105
names . sort ( function ( n1 , n2 ) { return unresolvedPrivateNames [ n1 ] - unresolvedPrivateNames [ n2 ] ; } )
95
106
this . raise ( unresolvedPrivateNames [ names [ 0 ] ] , "Usage of undeclared private name" )
96
107
}
97
- } else { Object . assign ( this . _unresolvedPrivateNamesStack [ this . _unresolvedPrivateNamesStack . length - 1 ] , unresolvedPrivateNames ) }
108
+ } else { Object . assign ( this . _unresolvedPrivateNames , unresolvedPrivateNames ) }
109
+ return _return
110
+ } ;
111
+
112
+ // Class heritage is evaluated with outer private environment
113
+ Parser_ . prototype . parseClassSuper = function parseClassSuper ( node ) {
114
+ var privateBoundNames = this . _privateBoundNames
115
+ this . _privateBoundNames = this . _outerPrivateBoundNames
116
+ var unresolvedPrivateNames = this . _unresolvedPrivateNames
117
+ this . _unresolvedPrivateNames = this . _outerUnresolvedPrivateNames
118
+ var _return = Parser . prototype . parseClassSuper . call ( this , node )
119
+ this . _privateBoundNames = privateBoundNames
120
+ this . _unresolvedPrivateNames = unresolvedPrivateNames
98
121
return _return
99
122
} ;
100
123
101
124
// Parse private element access
102
125
Parser_ . prototype . parseSubscript = function parseSubscript ( base , startPos , startLoc , noCalls , maybeAsyncArrow ) {
103
- if ( ! this . eat ( tt . dot ) ) {
126
+ if ( ! this . eat ( acorn . tokTypes . dot ) ) {
104
127
return Parser . prototype . parseSubscript . call ( this , base , startPos , startLoc , noCalls , maybeAsyncArrow )
105
128
}
106
129
var node = this . startNodeAt ( startPos , startLoc )
107
130
node . object = base
108
131
node . computed = false
109
132
if ( this . type == this . privateNameToken ) {
133
+ if ( base . type == "Super" ) {
134
+ this . raise ( this . start , "Cannot access private element on super" )
135
+ }
110
136
node . property = this . parsePrivateName ( )
111
- if ( ! this . _privateBoundNamesStack . length || ! this . _privateBoundNamesStack [ this . _privateBoundNamesStack . length - 1 ] [ node . property . name ] ) {
112
- this . _unresolvedPrivateNamesStack [ this . _unresolvedPrivateNamesStack . length - 1 ] [ node . property . name ] = node . property . start
137
+ if ( ! this . _privateBoundNames || ! this . _privateBoundNames [ node . property . name ] ) {
138
+ if ( ! this . _unresolvedPrivateNames ) {
139
+ this . raise ( node . property . start , "Usage of undeclared private name" )
140
+ }
141
+ this . _unresolvedPrivateNames [ node . property . name ] = node . property . start
113
142
}
114
143
} else {
115
144
node . property = this . parseIdent ( true )
@@ -130,6 +159,6 @@ module.exports = function(Parser) {
130
159
131
160
return Parser_ ;
132
161
} ( Parser ) )
133
- Parser . prototype . privateNameToken = new TokenType ( "privateName" )
162
+ Parser . prototype . privateNameToken = new acorn . TokenType ( "privateName" )
134
163
return Parser
135
164
}
0 commit comments