@@ -111,6 +111,7 @@ export class RenderParser {
111
111
private usedEvents = new Set < string > ( )
112
112
private customComponentNames : Set < string >
113
113
private loopCalleeId = new Set < t . Identifier > ( )
114
+ private usedThisProperties = new Set < t . Identifier > ( )
114
115
115
116
private renderPath : NodePath < t . ClassMethod >
116
117
private methods : ClassMethodsMap
@@ -737,48 +738,78 @@ export class RenderParser {
737
738
this . addRefIdentifier ( path , path . node )
738
739
}
739
740
} ,
740
- MemberExpression : ( path ) => {
741
- if ( ! isChildrenOfJSXAttr ( path ) ) {
742
- return
743
- }
744
- if ( ! path . isReferencedMemberExpression ( ) || path . parentPath . isMemberExpression ( ) ) {
745
- return
746
- }
747
- const { object, property } = path . node
748
- if (
749
- t . isMemberExpression ( object ) &&
750
- t . isThisExpression ( object . object ) &&
751
- t . isIdentifier ( object . property , { name : 'state' } )
752
- ) {
753
- if ( t . isIdentifier ( property ) ) {
754
- this . usedThisState . add ( property . name )
755
- } else if ( t . isMemberExpression ( property ) ) {
756
- const id = findFirstIdentifierFromMemberExpression ( property )
757
- if ( id && this . renderScope . hasBinding ( id . name ) ) {
758
- this . usedThisState . add ( id . name )
741
+ MemberExpression : {
742
+ exit : ( path : NodePath < t . MemberExpression > ) => {
743
+ const { object, property } = path . node
744
+ if ( ! path . isReferencedMemberExpression ( ) ) {
745
+ return
746
+ }
747
+ if ( ! t . isThisExpression ( object ) ) {
748
+ return
749
+ }
750
+ const reserves = new Set ( [
751
+ 'state' ,
752
+ 'props' ,
753
+ ...this . methods . keys ( )
754
+ ] )
755
+ if ( t . isIdentifier ( property ) || t . isMemberExpression ( property ) ) {
756
+ const id = t . isIdentifier ( property ) ? property : findFirstIdentifierFromMemberExpression ( property )
757
+ if ( reserves . has ( id . name ) ) {
758
+ return
759
+ }
760
+ const jsxAttr = path . findParent ( p => p . isJSXAttribute ( ) ) as NodePath < t . JSXAttribute >
761
+ if ( jsxAttr && t . isJSXIdentifier ( jsxAttr . node . name ) && jsxAttr . node . name . name . startsWith ( 'on' ) ) {
762
+ return
763
+ }
764
+ if ( t . isIdentifier ( id ) ) {
765
+ this . referencedIdentifiers . add ( id )
766
+ this . usedThisProperties . add ( id )
759
767
}
760
768
}
761
- return
762
- }
763
- const code = generate ( path . node ) . code
764
- if ( code . includes ( 'this.$router.params' ) && t . isIdentifier ( property ) ) {
765
- const name = this . renderScope . generateUid ( property . name )
766
- const dcl = buildConstVariableDeclaration ( name , path . node )
767
- this . renderPath . node . body . body . unshift ( dcl )
768
- path . replaceWith ( t . identifier ( name ) )
769
- }
770
- const parentPath = path . parentPath
771
- const id = findFirstIdentifierFromMemberExpression ( path . node )
772
- if ( t . isThisExpression ( id ) ) {
773
- return
774
- }
775
- if (
776
- parentPath . isConditionalExpression ( ) ||
777
- parentPath . isLogicalExpression ( ) ||
778
- parentPath . isJSXExpressionContainer ( ) ||
779
- ( this . renderScope . hasOwnBinding ( id . name ) )
780
- ) {
781
- this . addRefIdentifier ( path , id )
769
+ } ,
770
+ enter : ( path ) => {
771
+ if ( ! isChildrenOfJSXAttr ( path ) ) {
772
+ return
773
+ }
774
+ if ( ! path . isReferencedMemberExpression ( ) || path . parentPath . isMemberExpression ( ) ) {
775
+ return
776
+ }
777
+ const { object, property } = path . node
778
+ if (
779
+ t . isMemberExpression ( object ) &&
780
+ t . isThisExpression ( object . object ) &&
781
+ t . isIdentifier ( object . property , { name : 'state' } )
782
+ ) {
783
+ if ( t . isIdentifier ( property ) ) {
784
+ this . usedThisState . add ( property . name )
785
+ } else if ( t . isMemberExpression ( property ) ) {
786
+ const id = findFirstIdentifierFromMemberExpression ( property )
787
+ if ( id && this . renderScope . hasBinding ( id . name ) ) {
788
+ this . usedThisState . add ( id . name )
789
+ }
790
+ }
791
+ return
792
+ }
793
+ const code = generate ( path . node ) . code
794
+ if ( code . includes ( 'this.$router.params' ) && t . isIdentifier ( property ) ) {
795
+ const name = this . renderScope . generateUid ( property . name )
796
+ const dcl = buildConstVariableDeclaration ( name , path . node )
797
+ this . renderPath . node . body . body . unshift ( dcl )
798
+ path . replaceWith ( t . identifier ( name ) )
799
+ }
800
+ const parentPath = path . parentPath
801
+ const id = findFirstIdentifierFromMemberExpression ( path . node )
802
+ if ( t . isThisExpression ( id ) ) {
803
+ return
804
+ }
805
+ if (
806
+ parentPath . isConditionalExpression ( ) ||
807
+ parentPath . isLogicalExpression ( ) ||
808
+ parentPath . isJSXExpressionContainer ( ) ||
809
+ ( this . renderScope . hasOwnBinding ( id . name ) )
810
+ ) {
811
+ this . addRefIdentifier ( path , id )
812
+ }
782
813
}
783
814
} ,
784
815
ArrowFunctionExpression : ( path ) => {
@@ -1256,7 +1287,19 @@ export class RenderParser {
1256
1287
1257
1288
this . renderPath . node . body . body . unshift (
1258
1289
template ( `this.__state = arguments[0] || this.state || {};` ) ( ) ,
1259
- template ( `this.__props = arguments[1] || this.props || {};` ) ( )
1290
+ template ( `this.__props = arguments[1] || this.props || {};` ) ( ) ,
1291
+ t . variableDeclaration (
1292
+ 'const' ,
1293
+ [
1294
+ t . variableDeclarator (
1295
+ t . objectPattern ( Array . from ( this . usedThisProperties ) . map ( p => t . objectProperty (
1296
+ t . identifier ( p . name ) ,
1297
+ t . identifier ( p . name )
1298
+ ) as any ) ) ,
1299
+ t . thisExpression ( )
1300
+ )
1301
+ ]
1302
+ )
1260
1303
)
1261
1304
1262
1305
if ( t . isIdentifier ( this . renderPath . node . key ) ) {
0 commit comments