@@ -42,6 +42,10 @@ export type ClassFieldDeclSite = {
4242 * - Assignment to `this` in a static initialization block (static case)
4343 */
4444 path : NodePath < ClassProperty | ClassPrivateProperty | ClassMethod | ClassPrivateMethod | ClassAccessorProperty | TSDeclareMethod | AssignmentExpression > ;
45+ /**
46+ * Where is it referenced in?
47+ */
48+ owner : string | undefined ;
4549 /**
4650 * Type annotation, if any.
4751 *
@@ -65,6 +69,7 @@ export type ClassFieldExprSite = {
6569 * The node that accesses the field (both read and write)
6670 */
6771 path : NodePath < MemberExpression > ;
72+ owner : string | undefined ;
6873 typing : undefined ;
6974 init : undefined ;
7075 /**
@@ -112,7 +117,10 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
112117 const staticFields = new Map < string , ClassFieldAnalysis > ( ) ;
113118 const getStaticField = ( name : string ) => getOr ( staticFields , name , ( ) => ( { sites : [ ] } ) ) ;
114119 let constructor : NodePath < ClassMethod > | undefined = undefined ;
115- const bodies : NodePath [ ] = [ ] ;
120+ const bodies : {
121+ owner : string | undefined ,
122+ path : NodePath ,
123+ } [ ] = [ ] ;
116124 // 1st pass: look for class field definitions
117125 for ( const itemPath of path . get ( "body" ) . get ( "body" ) ) {
118126 if ( isNamedClassElement ( itemPath ) ) {
@@ -133,6 +141,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
133141 field . sites . push ( {
134142 type : "decl" ,
135143 path : itemPath ,
144+ owner : undefined ,
136145 typing : typeAnnotation_
137146 ? {
138147 type : "type_value" ,
@@ -145,7 +154,13 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
145154 } ) ;
146155 if ( valuePath ) {
147156 // Initializer should be analyzed in step 2 too (considered to be in the constructor)
148- bodies . push ( valuePath ) ;
157+ bodies . push ( {
158+ owner :
159+ valuePath . isFunctionExpression ( ) || valuePath . isArrowFunctionExpression ( )
160+ ? name
161+ : undefined ,
162+ path : valuePath ,
163+ } ) ;
149164 }
150165 } else if ( isClassMethodOrDecl ( itemPath ) ) {
151166 // Class method, constructor, getter/setter, or an accessor (those that will be introduced in the decorator proposal).
@@ -156,6 +171,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
156171 field . sites . push ( {
157172 type : "decl" ,
158173 path : itemPath ,
174+ owner : undefined ,
159175 // We put `typing` here only when it is type-only
160176 typing : itemPath . isTSDeclareMethod ( )
161177 ? {
@@ -172,9 +188,15 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
172188 // Analysis for step 2
173189 if ( isClassMethodLike ( itemPath ) ) {
174190 for ( const paramPath of itemPath . get ( "params" ) ) {
175- bodies . push ( paramPath ) ;
191+ bodies . push ( {
192+ owner : name ,
193+ path : paramPath ,
194+ } ) ;
176195 }
177- bodies . push ( itemPath . get ( "body" ) ) ;
196+ bodies . push ( {
197+ owner : name ,
198+ path : itemPath . get ( "body" ) ,
199+ } ) ;
178200 }
179201 } else if ( kind === "get" || kind === "set" ) {
180202 throw new AnalysisError ( `Not implemented yet: getter / setter` ) ;
@@ -262,6 +284,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
262284 field . sites . push ( {
263285 type : "decl" ,
264286 path : exprPath ,
287+ owner : undefined ,
265288 typing : undefined ,
266289 init : {
267290 type : "init_value" ,
@@ -270,12 +293,15 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
270293 hasWrite : undefined ,
271294 hasSideEffect : estimateSideEffect ( stmt . node . expression . right ) ,
272295 } ) ;
273- bodies . push ( exprPath . get ( "right" ) ) ;
296+ bodies . push ( {
297+ owner : name ,
298+ path : exprPath . get ( "right" ) ,
299+ } ) ;
274300 }
275301 }
276302
277303 // 2nd pass: look for uses within items
278- function traverseItem ( path : NodePath ) {
304+ function traverseItem ( owner : string | undefined , path : NodePath ) {
279305 traverseThis ( path , ( thisPath ) => {
280306 // Ensure this is part of `this.foo`
281307 const thisMemberPath = thisPath . parentPath ;
@@ -306,6 +332,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
306332
307333 field . sites . push ( {
308334 type : "expr" ,
335+ owner,
309336 path : thisMemberPath ,
310337 typing : undefined ,
311338 init : undefined ,
@@ -315,7 +342,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
315342 } ) ;
316343 }
317344 for ( const body of bodies ) {
318- traverseItem ( body ) ;
345+ traverseItem ( body . owner , body . path ) ;
319346 }
320347
321348 // Post validation
0 commit comments