UNPKG

11.3 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright Google Inc. All Rights Reserved.
4 *
5 * Use of this source code is governed by an MIT-style license that can be
6 * found in the LICENSE file at https://angular.io/license
7 */
8import { __spreadArrays } from "tslib";
9import { global, stringify } from '../facade/lang';
10import { Type, isType } from '../facade/type';
11/**
12 * Attention: This regex has to hold even if the code is minified!
13 */
14export var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
15var ReflectionCapabilities = /** @class */ (function () {
16 function ReflectionCapabilities(reflect) {
17 this._reflect = reflect || global['Reflect'];
18 }
19 ReflectionCapabilities.prototype.isReflectionEnabled = function () {
20 return true;
21 };
22 ReflectionCapabilities.prototype.factory = function (t) {
23 return function () {
24 var args = [];
25 for (var _i = 0; _i < arguments.length; _i++) {
26 args[_i] = arguments[_i];
27 }
28 return new (t.bind.apply(t, __spreadArrays([void 0], args)))();
29 };
30 };
31 /** @internal */
32 ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
33 var result;
34 if (typeof paramTypes === 'undefined') {
35 result = new Array(paramAnnotations.length);
36 }
37 else {
38 result = new Array(paramTypes.length);
39 }
40 for (var i = 0; i < result.length; i++) {
41 // TS outputs Object for parameters without types, while Traceur omits
42 // the annotations. For now we preserve the Traceur behavior to aid
43 // migration, but this can be revisited.
44 if (typeof paramTypes === 'undefined') {
45 result[i] = [];
46 // tslint:disable-next-line:triple-equals
47 }
48 else if (paramTypes[i] != Object) {
49 result[i] = [paramTypes[i]];
50 }
51 else {
52 result[i] = [];
53 }
54 if (paramAnnotations && paramAnnotations[i] != null) {
55 result[i] = result[i].concat(paramAnnotations[i]);
56 }
57 }
58 return result;
59 };
60 ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
61 // If we have no decorators, we only have function.length as metadata.
62 // In that case, to detect whether a child class declared an own constructor or not,
63 // we need to look inside of that constructor to check whether it is
64 // just calling the parent.
65 // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
66 // that sets 'design:paramtypes' to []
67 // if a class inherits from another class but has no ctor declared itself.
68 if (DELEGATE_CTOR.exec(type.toString())) {
69 return null;
70 }
71 // Prefer the direct API.
72 if (type.parameters && type.parameters !== parentCtor.parameters) {
73 return type.parameters;
74 }
75 // API of tsickle for lowering decorators to properties on the class.
76 var tsickleCtorParams = type.ctorParameters;
77 if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
78 // Newer tsickle uses a function closure
79 // Retain the non-function case for compatibility with older tsickle
80 var ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
81 var paramTypes = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
82 var paramAnnotations = ctorParameters.map(function (ctorParam) { return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators); });
83 return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
84 }
85 // API for metadata created by invoking the decorators.
86 if (this._reflect != null && this._reflect.getOwnMetadata != null) {
87 var paramAnnotations = this._reflect.getOwnMetadata('parameters', type);
88 var paramTypes = this._reflect.getOwnMetadata('design:paramtypes', type);
89 if (paramTypes || paramAnnotations) {
90 return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
91 }
92 }
93 // If a class has no decorators, at least create metadata
94 // based on function.length.
95 // Note: We know that this is a real constructor as we checked
96 // the content of the constructor above.
97 return new Array(type.length).fill(undefined);
98 };
99 ReflectionCapabilities.prototype.parameters = function (type) {
100 // Note: only report metadata if we have at least one class decorator
101 // to stay in sync with the static reflector.
102 if (!isType(type)) {
103 return [];
104 }
105 var parentCtor = getParentCtor(type);
106 var parameters = this._ownParameters(type, parentCtor);
107 if (!parameters && parentCtor !== Object) {
108 parameters = this.parameters(parentCtor);
109 }
110 return parameters || [];
111 };
112 ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
113 // Prefer the direct API.
114 if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
115 var annotations = typeOrFunc.annotations;
116 if (typeof annotations === 'function' && annotations.annotations) {
117 annotations = annotations.annotations;
118 }
119 return annotations;
120 }
121 // API of tsickle for lowering decorators to properties on the class.
122 if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
123 return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
124 }
125 // API for metadata created by invoking the decorators.
126 if (this._reflect && this._reflect.getOwnMetadata) {
127 return this._reflect.getOwnMetadata('annotations', typeOrFunc);
128 }
129 return null;
130 };
131 ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
132 if (!isType(typeOrFunc)) {
133 return [];
134 }
135 var parentCtor = getParentCtor(typeOrFunc);
136 var ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
137 var parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
138 return parentAnnotations.concat(ownAnnotations);
139 };
140 ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
141 // Prefer the direct API.
142 if (typeOrFunc.propMetadata && typeOrFunc.propMetadata !== parentCtor.propMetadata) {
143 var propMetadata = typeOrFunc.propMetadata;
144 if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
145 propMetadata = propMetadata.propMetadata;
146 }
147 return propMetadata;
148 }
149 // API of tsickle for lowering decorators to properties on the class.
150 if (typeOrFunc.propDecorators && typeOrFunc.propDecorators !== parentCtor.propDecorators) {
151 var propDecorators_1 = typeOrFunc.propDecorators;
152 var propMetadata_1 = {};
153 Object.keys(propDecorators_1).forEach(function (prop) {
154 propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
155 });
156 return propMetadata_1;
157 }
158 // API for metadata created by invoking the decorators.
159 if (this._reflect && this._reflect.getOwnMetadata) {
160 return this._reflect.getOwnMetadata('propMetadata', typeOrFunc);
161 }
162 return null;
163 };
164 ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
165 if (!isType(typeOrFunc)) {
166 return {};
167 }
168 var parentCtor = getParentCtor(typeOrFunc);
169 var propMetadata = {};
170 if (parentCtor !== Object) {
171 var parentPropMetadata_1 = this.propMetadata(parentCtor);
172 Object.keys(parentPropMetadata_1).forEach(function (propName) {
173 propMetadata[propName] = parentPropMetadata_1[propName];
174 });
175 }
176 var ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
177 if (ownPropMetadata) {
178 Object.keys(ownPropMetadata).forEach(function (propName) {
179 var decorators = [];
180 if (propMetadata.hasOwnProperty(propName)) {
181 decorators.push.apply(decorators, propMetadata[propName]);
182 }
183 decorators.push.apply(decorators, ownPropMetadata[propName]);
184 propMetadata[propName] = decorators;
185 });
186 }
187 return propMetadata;
188 };
189 ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
190 return type instanceof Type && lcProperty in type.prototype;
191 };
192 ReflectionCapabilities.prototype.getter = function (name) {
193 return new Function('o', 'return o.' + name + ';');
194 };
195 ReflectionCapabilities.prototype.setter = function (name) {
196 return new Function('o', 'v', 'return o.' + name + ' = v;');
197 };
198 ReflectionCapabilities.prototype.method = function (name) {
199 var functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n return o." + name + ".apply(o, args);";
200 return new Function('o', 'args', functionBody);
201 };
202 // There is not a concept of import uri in Js, but this is useful in developing Dart applications.
203 ReflectionCapabilities.prototype.importUri = function (type) {
204 // StaticSymbol
205 if (typeof type === 'object' && type['filePath']) {
206 return type['filePath'];
207 }
208 // Runtime type
209 return "./" + stringify(type);
210 };
211 ReflectionCapabilities.prototype.resourceUri = function (type) {
212 return "./" + stringify(type);
213 };
214 ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
215 return runtime;
216 };
217 ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) {
218 return enumIdentifier[name];
219 };
220 return ReflectionCapabilities;
221}());
222export { ReflectionCapabilities };
223function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
224 if (!decoratorInvocations) {
225 return [];
226 }
227 return decoratorInvocations.map(function (decoratorInvocation) {
228 var decoratorType = decoratorInvocation.type;
229 var annotationCls = decoratorType.annotationCls;
230 var annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
231 return new (annotationCls.bind.apply(annotationCls, __spreadArrays([void 0], annotationArgs)))();
232 });
233}
234function getParentCtor(ctor) {
235 if (!ctor.prototype) {
236 return Object;
237 }
238 var parentProto = Object.getPrototypeOf(ctor.prototype);
239 var parentCtor = parentProto ? parentProto.constructor : null;
240 // Note: We always use `Object` as the null value
241 // to simplify checking later on.
242 return parentCtor || Object;
243}
244//# sourceMappingURL=reflection_capabilities.js.map
\No newline at end of file