@@ -9,7 +9,7 @@ import { willPathCastToBoolean, findOutermostTransparentParent } from "./util";
9
9
const { ast } = template . expression ;
10
10
11
11
function isSimpleMemberExpression (
12
- expression : t . Expression ,
12
+ expression : t . Expression | t . Super ,
13
13
) : expression is t . Identifier | t . Super | t . MemberExpression {
14
14
expression = skipTransparentExprWrapperNodes ( expression ) ;
15
15
return (
@@ -102,6 +102,7 @@ export function transform(
102
102
}
103
103
}
104
104
105
+ // todo: Improve replacementPath typings
105
106
let replacementPath : NodePath < any > = path ;
106
107
if ( parentPath . isUnaryExpression ( { operator : "delete" } ) ) {
107
108
replacementPath = parentPath ;
@@ -139,8 +140,8 @@ export function transform(
139
140
t . cloneNode ( ref ) ,
140
141
// Here `chainWithTypes` MUST NOT be cloned because it could be
141
142
// updated when generating the memoised context of a call
142
- // expression
143
- chainWithTypes ,
143
+ // expression. It must be an Expression when `ref` is an identifier
144
+ chainWithTypes as t . Expression ,
144
145
) ;
145
146
146
147
isCall ? ( node . callee = ref ) : ( node . object = ref ) ;
@@ -160,13 +161,17 @@ export function transform(
160
161
// Otherwise, we need to memoize the context object, and change the call into a Function#call.
161
162
// `a.?b.?()` translates roughly to `(_b = _a.b) != null && _b.call(_a)`
162
163
const { object } = chain ;
163
- let context : t . Expression = scope . maybeGenerateMemoised ( object ) ;
164
- if ( context ) {
165
- chain . object = t . assignmentExpression ( "=" , context , object ) ;
166
- } else if ( t . isSuper ( object ) ) {
164
+ let context : t . Expression ;
165
+ if ( t . isSuper ( object ) ) {
167
166
context = t . thisExpression ( ) ;
168
167
} else {
169
- context = object ;
168
+ const memoized = scope . maybeGenerateMemoised ( object ) ;
169
+ if ( memoized ) {
170
+ context = memoized ;
171
+ chain . object = t . assignmentExpression ( "=" , memoized , object ) ;
172
+ } else {
173
+ context = object ;
174
+ }
170
175
}
171
176
172
177
node . arguments . unshift ( t . cloneNode ( context ) ) ;
@@ -181,7 +186,10 @@ export function transform(
181
186
// i.e. `?.b` in `(a?.b.c)()`
182
187
if ( i === 0 && parentIsCall ) {
183
188
// `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()`
184
- const object = skipTransparentExprWrapperNodes ( replacement . object ) ;
189
+ // object must not be Super as super?.foo is invalid
190
+ const object = skipTransparentExprWrapperNodes (
191
+ replacement . object ,
192
+ ) as t . Expression ;
185
193
let baseRef ;
186
194
if ( ! pureGetters || ! isSimpleMemberExpression ( object ) ) {
187
195
// memoize the context object when getters are not always pure
0 commit comments