6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import { NodePath , PluginObj , types } from '@babel/core' ;
9
+ import type { NodePath , PluginObj } from '@babel/core' ;
10
10
11
11
/**
12
12
* The name of the Angular class metadata function created by the Angular compiler.
@@ -30,9 +30,19 @@ const SET_CLASS_DEBUG_INFO_NAME = 'ɵsetClassDebugInfo';
30
30
* @returns An a string iterable containing one or more keywords.
31
31
*/
32
32
export function getKeywords ( ) : Iterable < string > {
33
- return [ SET_CLASS_METADATA_NAME , SET_CLASS_METADATA_ASYNC_NAME , SET_CLASS_DEBUG_INFO_NAME ] ;
33
+ return Object . keys ( angularMetadataFunctions ) ;
34
34
}
35
35
36
+ /**
37
+ * An object map of function names and related value checks for discovery of Angular generated
38
+ * metadata calls.
39
+ */
40
+ const angularMetadataFunctions : Record < string , ( args : NodePath [ ] ) => boolean > = {
41
+ [ SET_CLASS_METADATA_NAME ] : isSetClassMetadataCall ,
42
+ [ SET_CLASS_METADATA_ASYNC_NAME ] : isSetClassMetadataAsyncCall ,
43
+ [ SET_CLASS_DEBUG_INFO_NAME ] : isSetClassDebugInfoCall ,
44
+ } ;
45
+
36
46
/**
37
47
* A babel plugin factory function for eliding the Angular class metadata function (`ɵsetClassMetadata`).
38
48
*
@@ -41,24 +51,25 @@ export function getKeywords(): Iterable<string> {
41
51
export default function ( ) : PluginObj {
42
52
return {
43
53
visitor : {
44
- CallExpression ( path : NodePath < types . CallExpression > ) {
45
- const callee = path . node . callee ;
46
- const callArguments = path . node . arguments ;
54
+ CallExpression ( path ) {
55
+ const callee = path . get ( 'callee' ) ;
47
56
48
57
// The function being called must be the metadata function name
49
58
let calleeName ;
50
- if ( types . isMemberExpression ( callee ) && types . isIdentifier ( callee . property ) ) {
51
- calleeName = callee . property . name ;
52
- } else if ( types . isIdentifier ( callee ) ) {
53
- calleeName = callee . name ;
59
+ if ( callee . isMemberExpression ( ) ) {
60
+ const calleeProperty = callee . get ( 'property' ) ;
61
+ if ( calleeProperty . isIdentifier ( ) ) {
62
+ calleeName = calleeProperty . node . name ;
63
+ }
64
+ } else if ( callee . isIdentifier ( ) ) {
65
+ calleeName = callee . node . name ;
66
+ }
67
+
68
+ if ( ! calleeName ) {
69
+ return ;
54
70
}
55
71
56
- if (
57
- calleeName !== undefined &&
58
- ( isRemoveClassMetadataCall ( calleeName , callArguments ) ||
59
- isRemoveClassmetadataAsyncCall ( calleeName , callArguments ) ||
60
- isSetClassDebugInfoCall ( calleeName , callArguments ) )
61
- ) {
72
+ if ( angularMetadataFunctions [ calleeName ] ?.( path . get ( 'arguments' ) ) ) {
62
73
// The metadata function is always emitted inside a function expression
63
74
const parent = path . getFunctionParent ( ) ;
64
75
@@ -74,47 +85,41 @@ export default function (): PluginObj {
74
85
}
75
86
76
87
/** Determines if a function call is a call to `setClassMetadata`. */
77
- function isRemoveClassMetadataCall ( name : string , args : types . CallExpression [ 'arguments' ] ) : boolean {
88
+ function isSetClassMetadataCall ( callArguments : NodePath [ ] ) : boolean {
78
89
// `setClassMetadata` calls have to meet the following criteria:
79
90
// * First must be an identifier
80
91
// * Second must be an array literal
81
92
return (
82
- name === SET_CLASS_METADATA_NAME &&
83
- args . length === 4 &&
84
- types . isIdentifier ( args [ 0 ] ) &&
85
- types . isArrayExpression ( args [ 1 ] )
93
+ callArguments . length === 4 &&
94
+ callArguments [ 0 ] . isIdentifier ( ) &&
95
+ callArguments [ 1 ] . isArrayExpression ( )
86
96
) ;
87
97
}
88
98
89
99
/** Determines if a function call is a call to `setClassMetadataAsync`. */
90
- function isRemoveClassmetadataAsyncCall (
91
- name : string ,
92
- args : types . CallExpression [ 'arguments' ] ,
93
- ) : boolean {
100
+ function isSetClassMetadataAsyncCall ( callArguments : NodePath [ ] ) : boolean {
94
101
// `setClassMetadataAsync` calls have to meet the following criteria:
95
102
// * First argument must be an identifier.
96
103
// * Second argument must be an inline function.
97
104
// * Third argument must be an inline function.
98
105
return (
99
- name === SET_CLASS_METADATA_ASYNC_NAME &&
100
- args . length === 3 &&
101
- types . isIdentifier ( args [ 0 ] ) &&
102
- isInlineFunction ( args [ 1 ] ) &&
103
- isInlineFunction ( args [ 2 ] )
106
+ callArguments . length === 3 &&
107
+ callArguments [ 0 ] . isIdentifier ( ) &&
108
+ isInlineFunction ( callArguments [ 1 ] ) &&
109
+ isInlineFunction ( callArguments [ 2 ] )
104
110
) ;
105
111
}
106
112
107
113
/** Determines if a function call is a call to `setClassDebugInfo`. */
108
- function isSetClassDebugInfoCall ( name : string , args : types . CallExpression [ 'arguments' ] ) : boolean {
114
+ function isSetClassDebugInfoCall ( callArguments : NodePath [ ] ) : boolean {
109
115
return (
110
- name === SET_CLASS_DEBUG_INFO_NAME &&
111
- args . length === 2 &&
112
- types . isIdentifier ( args [ 0 ] ) &&
113
- types . isObjectExpression ( args [ 1 ] )
116
+ callArguments . length === 2 &&
117
+ callArguments [ 0 ] . isIdentifier ( ) &&
118
+ callArguments [ 1 ] . isObjectExpression ( )
114
119
) ;
115
120
}
116
121
117
122
/** Determines if a node is an inline function expression. */
118
- function isInlineFunction ( node : types . Node ) : boolean {
119
- return types . isFunctionExpression ( node ) || types . isArrowFunctionExpression ( node ) ;
123
+ function isInlineFunction ( path : NodePath ) : boolean {
124
+ return path . isFunctionExpression ( ) || path . isArrowFunctionExpression ( ) ;
120
125
}
0 commit comments