8
8
9
9
import { Type } from '../interface/type' ;
10
10
11
+ import { noSideEffects } from './closure' ;
12
+
13
+
14
+
11
15
/**
12
16
* An interface implemented by all Angular type decorators, which allows them to be used as
13
17
* decorators as well as Angular syntax.
@@ -44,39 +48,41 @@ export function makeDecorator<T>(
44
48
additionalProcessing ?: ( type : Type < T > ) => void ,
45
49
typeFn ?: ( type : Type < T > , ...args : any [ ] ) => void ) :
46
50
{ new ( ...args : any [ ] ) : any ; ( ...args : any [ ] ) : any ; ( ...args : any [ ] ) : ( cls : any ) => any ; } {
47
- const metaCtor = makeMetadataCtor ( props ) ;
48
-
49
- function DecoratorFactory (
50
- this : unknown | typeof DecoratorFactory , ...args : any [ ] ) : ( cls : Type < T > ) => any {
51
- if ( this instanceof DecoratorFactory ) {
52
- metaCtor . call ( this , ...args ) ;
53
- return this as typeof DecoratorFactory ;
54
- }
51
+ return noSideEffects ( ( ) => {
52
+ const metaCtor = makeMetadataCtor ( props ) ;
53
+
54
+ function DecoratorFactory (
55
+ this : unknown | typeof DecoratorFactory , ...args : any [ ] ) : ( cls : Type < T > ) => any {
56
+ if ( this instanceof DecoratorFactory ) {
57
+ metaCtor . call ( this , ...args ) ;
58
+ return this as typeof DecoratorFactory ;
59
+ }
55
60
56
- const annotationInstance = new ( DecoratorFactory as any ) ( ...args ) ;
57
- return function TypeDecorator ( cls : Type < T > ) {
58
- if ( typeFn ) typeFn ( cls , ...args ) ;
59
- // Use of Object.defineProperty is important since it creates non-enumerable property which
60
- // prevents the property is copied during subclassing.
61
- const annotations = cls . hasOwnProperty ( ANNOTATIONS ) ?
62
- ( cls as any ) [ ANNOTATIONS ] :
63
- Object . defineProperty ( cls , ANNOTATIONS , { value : [ ] } ) [ ANNOTATIONS ] ;
64
- annotations . push ( annotationInstance ) ;
61
+ const annotationInstance = new ( DecoratorFactory as any ) ( ...args ) ;
62
+ return function TypeDecorator ( cls : Type < T > ) {
63
+ if ( typeFn ) typeFn ( cls , ...args ) ;
64
+ // Use of Object.defineProperty is important since it creates non-enumerable property which
65
+ // prevents the property is copied during subclassing.
66
+ const annotations = cls . hasOwnProperty ( ANNOTATIONS ) ?
67
+ ( cls as any ) [ ANNOTATIONS ] :
68
+ Object . defineProperty ( cls , ANNOTATIONS , { value : [ ] } ) [ ANNOTATIONS ] ;
69
+ annotations . push ( annotationInstance ) ;
65
70
66
71
67
- if ( additionalProcessing ) additionalProcessing ( cls ) ;
72
+ if ( additionalProcessing ) additionalProcessing ( cls ) ;
68
73
69
- return cls ;
70
- } ;
71
- }
74
+ return cls ;
75
+ } ;
76
+ }
72
77
73
- if ( parentClass ) {
74
- DecoratorFactory . prototype = Object . create ( parentClass . prototype ) ;
75
- }
78
+ if ( parentClass ) {
79
+ DecoratorFactory . prototype = Object . create ( parentClass . prototype ) ;
80
+ }
76
81
77
- DecoratorFactory . prototype . ngMetadataName = name ;
78
- ( DecoratorFactory as any ) . annotationCls = DecoratorFactory ;
79
- return DecoratorFactory as any ;
82
+ DecoratorFactory . prototype . ngMetadataName = name ;
83
+ ( DecoratorFactory as any ) . annotationCls = DecoratorFactory ;
84
+ return DecoratorFactory as any ;
85
+ } ) ;
80
86
}
81
87
82
88
function makeMetadataCtor ( props ?: ( ...args : any [ ] ) => any ) : any {
@@ -92,77 +98,82 @@ function makeMetadataCtor(props?: (...args: any[]) => any): any {
92
98
93
99
export function makeParamDecorator (
94
100
name : string , props ?: ( ...args : any [ ] ) => any , parentClass ?: any ) : any {
95
- const metaCtor = makeMetadataCtor ( props ) ;
96
- function ParamDecoratorFactory (
97
- this : unknown | typeof ParamDecoratorFactory , ...args : any [ ] ) : any {
98
- if ( this instanceof ParamDecoratorFactory ) {
99
- metaCtor . apply ( this , args ) ;
100
- return this ;
101
- }
102
- const annotationInstance = new ( < any > ParamDecoratorFactory ) ( ...args ) ;
103
-
104
- ( < any > ParamDecorator ) . annotation = annotationInstance ;
105
- return ParamDecorator ;
106
-
107
- function ParamDecorator ( cls : any , unusedKey : any , index : number ) : any {
108
- // Use of Object.defineProperty is important since it creates non-enumerable property which
109
- // prevents the property is copied during subclassing.
110
- const parameters = cls . hasOwnProperty ( PARAMETERS ) ?
111
- ( cls as any ) [ PARAMETERS ] :
112
- Object . defineProperty ( cls , PARAMETERS , { value : [ ] } ) [ PARAMETERS ] ;
113
-
114
- // there might be gaps if some in between parameters do not have annotations.
115
- // we pad with nulls.
116
- while ( parameters . length <= index ) {
117
- parameters . push ( null ) ;
101
+ return noSideEffects ( ( ) => {
102
+ const metaCtor = makeMetadataCtor ( props ) ;
103
+ function ParamDecoratorFactory (
104
+ this : unknown | typeof ParamDecoratorFactory , ...args : any [ ] ) : any {
105
+ if ( this instanceof ParamDecoratorFactory ) {
106
+ metaCtor . apply ( this , args ) ;
107
+ return this ;
108
+ }
109
+ const annotationInstance = new ( < any > ParamDecoratorFactory ) ( ...args ) ;
110
+
111
+ ( < any > ParamDecorator ) . annotation = annotationInstance ;
112
+ return ParamDecorator ;
113
+
114
+ function ParamDecorator ( cls : any , unusedKey : any , index : number ) : any {
115
+ // Use of Object.defineProperty is important since it creates non-enumerable property which
116
+ // prevents the property is copied during subclassing.
117
+ const parameters = cls . hasOwnProperty ( PARAMETERS ) ?
118
+ ( cls as any ) [ PARAMETERS ] :
119
+ Object . defineProperty ( cls , PARAMETERS , { value : [ ] } ) [ PARAMETERS ] ;
120
+
121
+ // there might be gaps if some in between parameters do not have annotations.
122
+ // we pad with nulls.
123
+ while ( parameters . length <= index ) {
124
+ parameters . push ( null ) ;
125
+ }
126
+
127
+ ( parameters [ index ] = parameters [ index ] || [ ] ) . push ( annotationInstance ) ;
128
+ return cls ;
118
129
}
119
-
120
- ( parameters [ index ] = parameters [ index ] || [ ] ) . push ( annotationInstance ) ;
121
- return cls ;
122
130
}
123
- }
124
- if ( parentClass ) {
125
- ParamDecoratorFactory . prototype = Object . create ( parentClass . prototype ) ;
126
- }
127
- ParamDecoratorFactory . prototype . ngMetadataName = name ;
128
- ( < any > ParamDecoratorFactory ) . annotationCls = ParamDecoratorFactory ;
129
- return ParamDecoratorFactory ;
131
+ if ( parentClass ) {
132
+ ParamDecoratorFactory . prototype = Object . create ( parentClass . prototype ) ;
133
+ }
134
+ ParamDecoratorFactory . prototype . ngMetadataName = name ;
135
+ ( < any > ParamDecoratorFactory ) . annotationCls = ParamDecoratorFactory ;
136
+ return ParamDecoratorFactory ;
137
+ } ) ;
130
138
}
131
139
132
140
export function makePropDecorator (
133
141
name : string , props ?: ( ...args : any [ ] ) => any , parentClass ?: any ,
134
142
additionalProcessing ?: ( target : any , name : string , ...args : any [ ] ) => void ) : any {
135
- const metaCtor = makeMetadataCtor ( props ) ;
143
+ return noSideEffects ( ( ) => {
144
+ const metaCtor = makeMetadataCtor ( props ) ;
145
+
146
+ function PropDecoratorFactory (
147
+ this : unknown | typeof PropDecoratorFactory , ...args : any [ ] ) : any {
148
+ if ( this instanceof PropDecoratorFactory ) {
149
+ metaCtor . apply ( this , args ) ;
150
+ return this ;
151
+ }
136
152
137
- function PropDecoratorFactory ( this : unknown | typeof PropDecoratorFactory , ...args : any [ ] ) : any {
138
- if ( this instanceof PropDecoratorFactory ) {
139
- metaCtor . apply ( this , args ) ;
140
- return this ;
141
- }
153
+ const decoratorInstance = new ( < any > PropDecoratorFactory ) ( ...args ) ;
142
154
143
- const decoratorInstance = new ( < any > PropDecoratorFactory ) ( ...args ) ;
155
+ function PropDecorator ( target : any , name : string ) {
156
+ const constructor = target . constructor ;
157
+ // Use of Object.defineProperty is important since it creates non-enumerable property which
158
+ // prevents the property is copied during subclassing.
159
+ const meta = constructor . hasOwnProperty ( PROP_METADATA ) ?
160
+ ( constructor as any ) [ PROP_METADATA ] :
161
+ Object . defineProperty ( constructor , PROP_METADATA , { value : { } } ) [ PROP_METADATA ] ;
162
+ meta [ name ] = meta . hasOwnProperty ( name ) && meta [ name ] || [ ] ;
163
+ meta [ name ] . unshift ( decoratorInstance ) ;
144
164
145
- function PropDecorator ( target : any , name : string ) {
146
- const constructor = target . constructor ;
147
- // Use of Object.defineProperty is important since it creates non-enumerable property which
148
- // prevents the property is copied during subclassing.
149
- const meta = constructor . hasOwnProperty ( PROP_METADATA ) ?
150
- ( constructor as any ) [ PROP_METADATA ] :
151
- Object . defineProperty ( constructor , PROP_METADATA , { value : { } } ) [ PROP_METADATA ] ;
152
- meta [ name ] = meta . hasOwnProperty ( name ) && meta [ name ] || [ ] ;
153
- meta [ name ] . unshift ( decoratorInstance ) ;
165
+ if ( additionalProcessing ) additionalProcessing ( target , name , ...args ) ;
166
+ }
154
167
155
- if ( additionalProcessing ) additionalProcessing ( target , name , ... args ) ;
168
+ return PropDecorator ;
156
169
}
157
170
158
- return PropDecorator ;
159
- }
160
-
161
- if ( parentClass ) {
162
- PropDecoratorFactory . prototype = Object . create ( parentClass . prototype ) ;
163
- }
171
+ if ( parentClass ) {
172
+ PropDecoratorFactory . prototype = Object . create ( parentClass . prototype ) ;
173
+ }
164
174
165
- PropDecoratorFactory . prototype . ngMetadataName = name ;
166
- ( < any > PropDecoratorFactory ) . annotationCls = PropDecoratorFactory ;
167
- return PropDecoratorFactory ;
175
+ PropDecoratorFactory . prototype . ngMetadataName = name ;
176
+ ( < any > PropDecoratorFactory ) . annotationCls = PropDecoratorFactory ;
177
+ return PropDecoratorFactory ;
178
+ } ) ;
168
179
}
0 commit comments