Projekt

Obecné

Profil

Stáhnout (13 KB) Statistiky
| Větev: | Revize:
1
import toArray from "./toArray";
2
import toPropertyKey from "./toPropertyKey";
3
export default function _decorate(decorators, factory, superClass, mixins) {
4
  var api = _getDecoratorsApi();
5

    
6
  if (mixins) {
7
    for (var i = 0; i < mixins.length; i++) {
8
      api = mixins[i](api);
9
    }
10
  }
11

    
12
  var r = factory(function initialize(O) {
13
    api.initializeInstanceElements(O, decorated.elements);
14
  }, superClass);
15
  var decorated = api.decorateClass(_coalesceClassElements(r.d.map(_createElementDescriptor)), decorators);
16
  api.initializeClassElements(r.F, decorated.elements);
17
  return api.runClassFinishers(r.F, decorated.finishers);
18
}
19

    
20
function _getDecoratorsApi() {
21
  _getDecoratorsApi = function _getDecoratorsApi() {
22
    return api;
23
  };
24

    
25
  var api = {
26
    elementsDefinitionOrder: [["method"], ["field"]],
27
    initializeInstanceElements: function initializeInstanceElements(O, elements) {
28
      ["method", "field"].forEach(function (kind) {
29
        elements.forEach(function (element) {
30
          if (element.kind === kind && element.placement === "own") {
31
            this.defineClassElement(O, element);
32
          }
33
        }, this);
34
      }, this);
35
    },
36
    initializeClassElements: function initializeClassElements(F, elements) {
37
      var proto = F.prototype;
38
      ["method", "field"].forEach(function (kind) {
39
        elements.forEach(function (element) {
40
          var placement = element.placement;
41

    
42
          if (element.kind === kind && (placement === "static" || placement === "prototype")) {
43
            var receiver = placement === "static" ? F : proto;
44
            this.defineClassElement(receiver, element);
45
          }
46
        }, this);
47
      }, this);
48
    },
49
    defineClassElement: function defineClassElement(receiver, element) {
50
      var descriptor = element.descriptor;
51

    
52
      if (element.kind === "field") {
53
        var initializer = element.initializer;
54
        descriptor = {
55
          enumerable: descriptor.enumerable,
56
          writable: descriptor.writable,
57
          configurable: descriptor.configurable,
58
          value: initializer === void 0 ? void 0 : initializer.call(receiver)
59
        };
60
      }
61

    
62
      Object.defineProperty(receiver, element.key, descriptor);
63
    },
64
    decorateClass: function decorateClass(elements, decorators) {
65
      var newElements = [];
66
      var finishers = [];
67
      var placements = {
68
        "static": [],
69
        prototype: [],
70
        own: []
71
      };
72
      elements.forEach(function (element) {
73
        this.addElementPlacement(element, placements);
74
      }, this);
75
      elements.forEach(function (element) {
76
        if (!_hasDecorators(element)) return newElements.push(element);
77
        var elementFinishersExtras = this.decorateElement(element, placements);
78
        newElements.push(elementFinishersExtras.element);
79
        newElements.push.apply(newElements, elementFinishersExtras.extras);
80
        finishers.push.apply(finishers, elementFinishersExtras.finishers);
81
      }, this);
82

    
83
      if (!decorators) {
84
        return {
85
          elements: newElements,
86
          finishers: finishers
87
        };
88
      }
89

    
90
      var result = this.decorateConstructor(newElements, decorators);
91
      finishers.push.apply(finishers, result.finishers);
92
      result.finishers = finishers;
93
      return result;
94
    },
95
    addElementPlacement: function addElementPlacement(element, placements, silent) {
96
      var keys = placements[element.placement];
97

    
98
      if (!silent && keys.indexOf(element.key) !== -1) {
99
        throw new TypeError("Duplicated element (" + element.key + ")");
100
      }
101

    
102
      keys.push(element.key);
103
    },
104
    decorateElement: function decorateElement(element, placements) {
105
      var extras = [];
106
      var finishers = [];
107

    
108
      for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) {
109
        var keys = placements[element.placement];
110
        keys.splice(keys.indexOf(element.key), 1);
111
        var elementObject = this.fromElementDescriptor(element);
112
        var elementFinisherExtras = this.toElementFinisherExtras((0, decorators[i])(elementObject) || elementObject);
113
        element = elementFinisherExtras.element;
114
        this.addElementPlacement(element, placements);
115

    
116
        if (elementFinisherExtras.finisher) {
117
          finishers.push(elementFinisherExtras.finisher);
118
        }
119

    
120
        var newExtras = elementFinisherExtras.extras;
121

    
122
        if (newExtras) {
123
          for (var j = 0; j < newExtras.length; j++) {
124
            this.addElementPlacement(newExtras[j], placements);
125
          }
126

    
127
          extras.push.apply(extras, newExtras);
128
        }
129
      }
130

    
131
      return {
132
        element: element,
133
        finishers: finishers,
134
        extras: extras
135
      };
136
    },
137
    decorateConstructor: function decorateConstructor(elements, decorators) {
138
      var finishers = [];
139

    
140
      for (var i = decorators.length - 1; i >= 0; i--) {
141
        var obj = this.fromClassDescriptor(elements);
142
        var elementsAndFinisher = this.toClassDescriptor((0, decorators[i])(obj) || obj);
143

    
144
        if (elementsAndFinisher.finisher !== undefined) {
145
          finishers.push(elementsAndFinisher.finisher);
146
        }
147

    
148
        if (elementsAndFinisher.elements !== undefined) {
149
          elements = elementsAndFinisher.elements;
150

    
151
          for (var j = 0; j < elements.length - 1; j++) {
152
            for (var k = j + 1; k < elements.length; k++) {
153
              if (elements[j].key === elements[k].key && elements[j].placement === elements[k].placement) {
154
                throw new TypeError("Duplicated element (" + elements[j].key + ")");
155
              }
156
            }
157
          }
158
        }
159
      }
160

    
161
      return {
162
        elements: elements,
163
        finishers: finishers
164
      };
165
    },
166
    fromElementDescriptor: function fromElementDescriptor(element) {
167
      var obj = {
168
        kind: element.kind,
169
        key: element.key,
170
        placement: element.placement,
171
        descriptor: element.descriptor
172
      };
173
      var desc = {
174
        value: "Descriptor",
175
        configurable: true
176
      };
177
      Object.defineProperty(obj, Symbol.toStringTag, desc);
178
      if (element.kind === "field") obj.initializer = element.initializer;
179
      return obj;
180
    },
181
    toElementDescriptors: function toElementDescriptors(elementObjects) {
182
      if (elementObjects === undefined) return;
183
      return toArray(elementObjects).map(function (elementObject) {
184
        var element = this.toElementDescriptor(elementObject);
185
        this.disallowProperty(elementObject, "finisher", "An element descriptor");
186
        this.disallowProperty(elementObject, "extras", "An element descriptor");
187
        return element;
188
      }, this);
189
    },
190
    toElementDescriptor: function toElementDescriptor(elementObject) {
191
      var kind = String(elementObject.kind);
192

    
193
      if (kind !== "method" && kind !== "field") {
194
        throw new TypeError('An element descriptor\'s .kind property must be either "method" or' + ' "field", but a decorator created an element descriptor with' + ' .kind "' + kind + '"');
195
      }
196

    
197
      var key = toPropertyKey(elementObject.key);
198
      var placement = String(elementObject.placement);
199

    
200
      if (placement !== "static" && placement !== "prototype" && placement !== "own") {
201
        throw new TypeError('An element descriptor\'s .placement property must be one of "static",' + ' "prototype" or "own", but a decorator created an element descriptor' + ' with .placement "' + placement + '"');
202
      }
203

    
204
      var descriptor = elementObject.descriptor;
205
      this.disallowProperty(elementObject, "elements", "An element descriptor");
206
      var element = {
207
        kind: kind,
208
        key: key,
209
        placement: placement,
210
        descriptor: Object.assign({}, descriptor)
211
      };
212

    
213
      if (kind !== "field") {
214
        this.disallowProperty(elementObject, "initializer", "A method descriptor");
215
      } else {
216
        this.disallowProperty(descriptor, "get", "The property descriptor of a field descriptor");
217
        this.disallowProperty(descriptor, "set", "The property descriptor of a field descriptor");
218
        this.disallowProperty(descriptor, "value", "The property descriptor of a field descriptor");
219
        element.initializer = elementObject.initializer;
220
      }
221

    
222
      return element;
223
    },
224
    toElementFinisherExtras: function toElementFinisherExtras(elementObject) {
225
      var element = this.toElementDescriptor(elementObject);
226

    
227
      var finisher = _optionalCallableProperty(elementObject, "finisher");
228

    
229
      var extras = this.toElementDescriptors(elementObject.extras);
230
      return {
231
        element: element,
232
        finisher: finisher,
233
        extras: extras
234
      };
235
    },
236
    fromClassDescriptor: function fromClassDescriptor(elements) {
237
      var obj = {
238
        kind: "class",
239
        elements: elements.map(this.fromElementDescriptor, this)
240
      };
241
      var desc = {
242
        value: "Descriptor",
243
        configurable: true
244
      };
245
      Object.defineProperty(obj, Symbol.toStringTag, desc);
246
      return obj;
247
    },
248
    toClassDescriptor: function toClassDescriptor(obj) {
249
      var kind = String(obj.kind);
250

    
251
      if (kind !== "class") {
252
        throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"');
253
      }
254

    
255
      this.disallowProperty(obj, "key", "A class descriptor");
256
      this.disallowProperty(obj, "placement", "A class descriptor");
257
      this.disallowProperty(obj, "descriptor", "A class descriptor");
258
      this.disallowProperty(obj, "initializer", "A class descriptor");
259
      this.disallowProperty(obj, "extras", "A class descriptor");
260

    
261
      var finisher = _optionalCallableProperty(obj, "finisher");
262

    
263
      var elements = this.toElementDescriptors(obj.elements);
264
      return {
265
        elements: elements,
266
        finisher: finisher
267
      };
268
    },
269
    runClassFinishers: function runClassFinishers(constructor, finishers) {
270
      for (var i = 0; i < finishers.length; i++) {
271
        var newConstructor = (0, finishers[i])(constructor);
272

    
273
        if (newConstructor !== undefined) {
274
          if (typeof newConstructor !== "function") {
275
            throw new TypeError("Finishers must return a constructor.");
276
          }
277

    
278
          constructor = newConstructor;
279
        }
280
      }
281

    
282
      return constructor;
283
    },
284
    disallowProperty: function disallowProperty(obj, name, objectType) {
285
      if (obj[name] !== undefined) {
286
        throw new TypeError(objectType + " can't have a ." + name + " property.");
287
      }
288
    }
289
  };
290
  return api;
291
}
292

    
293
function _createElementDescriptor(def) {
294
  var key = toPropertyKey(def.key);
295
  var descriptor;
296

    
297
  if (def.kind === "method") {
298
    descriptor = {
299
      value: def.value,
300
      writable: true,
301
      configurable: true,
302
      enumerable: false
303
    };
304
  } else if (def.kind === "get") {
305
    descriptor = {
306
      get: def.value,
307
      configurable: true,
308
      enumerable: false
309
    };
310
  } else if (def.kind === "set") {
311
    descriptor = {
312
      set: def.value,
313
      configurable: true,
314
      enumerable: false
315
    };
316
  } else if (def.kind === "field") {
317
    descriptor = {
318
      configurable: true,
319
      writable: true,
320
      enumerable: true
321
    };
322
  }
323

    
324
  var element = {
325
    kind: def.kind === "field" ? "field" : "method",
326
    key: key,
327
    placement: def["static"] ? "static" : def.kind === "field" ? "own" : "prototype",
328
    descriptor: descriptor
329
  };
330
  if (def.decorators) element.decorators = def.decorators;
331
  if (def.kind === "field") element.initializer = def.value;
332
  return element;
333
}
334

    
335
function _coalesceGetterSetter(element, other) {
336
  if (element.descriptor.get !== undefined) {
337
    other.descriptor.get = element.descriptor.get;
338
  } else {
339
    other.descriptor.set = element.descriptor.set;
340
  }
341
}
342

    
343
function _coalesceClassElements(elements) {
344
  var newElements = [];
345

    
346
  var isSameElement = function isSameElement(other) {
347
    return other.kind === "method" && other.key === element.key && other.placement === element.placement;
348
  };
349

    
350
  for (var i = 0; i < elements.length; i++) {
351
    var element = elements[i];
352
    var other;
353

    
354
    if (element.kind === "method" && (other = newElements.find(isSameElement))) {
355
      if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {
356
        if (_hasDecorators(element) || _hasDecorators(other)) {
357
          throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated.");
358
        }
359

    
360
        other.descriptor = element.descriptor;
361
      } else {
362
        if (_hasDecorators(element)) {
363
          if (_hasDecorators(other)) {
364
            throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ").");
365
          }
366

    
367
          other.decorators = element.decorators;
368
        }
369

    
370
        _coalesceGetterSetter(element, other);
371
      }
372
    } else {
373
      newElements.push(element);
374
    }
375
  }
376

    
377
  return newElements;
378
}
379

    
380
function _hasDecorators(element) {
381
  return element.decorators && element.decorators.length;
382
}
383

    
384
function _isDataDescriptor(desc) {
385
  return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);
386
}
387

    
388
function _optionalCallableProperty(obj, name) {
389
  var value = obj[name];
390

    
391
  if (value !== undefined && typeof value !== "function") {
392
    throw new TypeError("Expected '" + name + "' to be a function");
393
  }
394

    
395
  return value;
396
}
(30-30/80)