@@ -13,9 +13,16 @@ import { AnalysisError } from "./error.js";
1313 */
1414export type ClassFieldsAnalysis = {
1515 /** Access to instance fields (`this.foo`), indexed by their names. */
16- instanceFields : Map < string , ClassFieldSite [ ] > ;
16+ instanceFields : Map < string , ClassFieldAnalysis > ;
1717 /** Access to static fields (`C.foo`, where `C` is the class), indexed by their names. */
18- staticFields : Map < string , ClassFieldSite [ ] > ;
18+ staticFields : Map < string , ClassFieldAnalysis > ;
19+ } ;
20+
21+ /**
22+ * Result of class field analysis for each field name.
23+ */
24+ export type ClassFieldAnalysis = {
25+ sites : ClassFieldSite [ ] ;
1926} ;
2027
2128/**
@@ -100,10 +107,10 @@ export type FieldInit = {
100107 * - Static fields ... `C.foo`, where `C` is the class
101108 */
102109export function analyzeClassFields ( path : NodePath < ClassDeclaration > ) : ClassFieldsAnalysis {
103- const instanceFields = new Map < string , ClassFieldSite [ ] > ( ) ;
104- const getInstanceField = ( name : string ) => getOr ( instanceFields , name , ( ) => [ ] ) ;
105- const staticFields = new Map < string , ClassFieldSite [ ] > ( ) ;
106- const getStaticField = ( name : string ) => getOr ( staticFields , name , ( ) => [ ] ) ;
110+ const instanceFields = new Map < string , ClassFieldAnalysis > ( ) ;
111+ const getInstanceField = ( name : string ) => getOr ( instanceFields , name , ( ) => ( { sites : [ ] } ) ) ;
112+ const staticFields = new Map < string , ClassFieldAnalysis > ( ) ;
113+ const getStaticField = ( name : string ) => getOr ( staticFields , name , ( ) => ( { sites : [ ] } ) ) ;
107114 let constructor : NodePath < ClassMethod > | undefined = undefined ;
108115 const bodies : NodePath [ ] = [ ] ;
109116 // 1st pass: look for class field definitions
@@ -123,7 +130,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
123130 const valuePath = nonNullPath < Expression > ( itemPath . get ( "value" ) ) ;
124131 const typeAnnotation = itemPath . get ( "typeAnnotation" ) ;
125132 const typeAnnotation_ = typeAnnotation . isTSTypeAnnotation ( ) ? typeAnnotation : undefined ;
126- field . push ( {
133+ field . sites . push ( {
127134 type : "decl" ,
128135 path : itemPath ,
129136 typing : typeAnnotation_
@@ -146,7 +153,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
146153 // - In TS, it may lack the implementation (i.e. TSDeclareMethod)
147154 const kind = itemPath . node . kind ?? "method" ;
148155 if ( kind === "method" ) {
149- field . push ( {
156+ field . sites . push ( {
150157 type : "decl" ,
151158 path : itemPath ,
152159 // We put `typing` here only when it is type-only
@@ -252,7 +259,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
252259 // TODO: check for parameter/local variable reference
253260
254261 const field = getInstanceField ( name ) ! ;
255- field . push ( {
262+ field . sites . push ( {
256263 type : "decl" ,
257264 path : exprPath ,
258265 typing : undefined ,
@@ -297,7 +304,7 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
297304 argument : thisMemberPath . node ,
298305 } )
299306
300- field . push ( {
307+ field . sites . push ( {
301308 type : "expr" ,
302309 path : thisMemberPath ,
303310 typing : undefined ,
@@ -312,28 +319,28 @@ export function analyzeClassFields(path: NodePath<ClassDeclaration>): ClassField
312319 }
313320
314321 // Post validation
315- for ( const [ name , fieldSites ] of instanceFields ) {
316- if ( fieldSites . length === 0 ) {
322+ for ( const [ name , field ] of instanceFields ) {
323+ if ( field . sites . length === 0 ) {
317324 instanceFields . delete ( name ) ;
318325 }
319- const numInits = fieldSites . reduce ( ( n , site ) => n + Number ( ! ! site . init ) , 0 ) ;
326+ const numInits = field . sites . reduce ( ( n , site ) => n + Number ( ! ! site . init ) , 0 ) ;
320327 if ( numInits > 1 ) {
321328 throw new AnalysisError ( `${ name } is initialized more than once` ) ;
322329 }
323- const numTypes = fieldSites . reduce ( ( n , site ) => n + Number ( ! ! site . typing ) , 0 ) ;
330+ const numTypes = field . sites . reduce ( ( n , site ) => n + Number ( ! ! site . typing ) , 0 ) ;
324331 if ( numTypes > 1 ) {
325332 throw new AnalysisError ( `${ name } is declared more than once` ) ;
326333 }
327334 }
328- for ( const [ name , fieldSites ] of staticFields ) {
329- if ( fieldSites . length === 0 ) {
335+ for ( const [ name , field ] of staticFields ) {
336+ if ( field . sites . length === 0 ) {
330337 instanceFields . delete ( name ) ;
331338 }
332- const numInits = fieldSites . reduce ( ( n , site ) => n + Number ( ! ! site . init ) , 0 ) ;
339+ const numInits = field . sites . reduce ( ( n , site ) => n + Number ( ! ! site . init ) , 0 ) ;
333340 if ( numInits > 1 ) {
334341 throw new AnalysisError ( `static ${ name } is initialized more than once` ) ;
335342 }
336- const numTypes = fieldSites . reduce ( ( n , site ) => n + Number ( ! ! site . typing ) , 0 ) ;
343+ const numTypes = field . sites . reduce ( ( n , site ) => n + Number ( ! ! site . typing ) , 0 ) ;
337344 if ( numTypes > 1 ) {
338345 throw new AnalysisError ( `static ${ name } is declared more than once` ) ;
339346 }
0 commit comments