-
Notifications
You must be signed in to change notification settings - Fork 0
/
polymorphic-constructor.js
72 lines (61 loc) · 2.36 KB
/
polymorphic-constructor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
var extender = require('./assign-properties');
module.exports = extender.extend({
transformConstructor: function(Constructor) {
return function Class(options) {
options || (options = {});
// don't leak arguments
var args = new Array(arguments.length);
for (var i = arguments.length - 1; i >= 0; i--) {
args[i] = arguments[i];
}
var NewConstructor;
if (!options._polymophic_hasTransformed) {
NewConstructor = this.getPolymorphicClass.apply(this, args);
}
// Makes sure that a polymorphic class can't be infinitely recursive, only
// one transformation possible.
if (NewConstructor) {
options._polymophic_hasTransformed = true;
args[0] = options;
if (args.length === 0) {
return new NewConstructor();
} else if (args.length === 1) {
return new NewConstructor(args[0]);
} else if (args.length === 2) {
return new NewConstructor(args[0], args[1]);
} else if (args.length === 3) {
return new NewConstructor(args[0], args[1], args[2]);
} else if (args.length === 4) {
return new NewConstructor(args[0], args[1], args[2], args[3]);
} else if (args.length === 5) {
return new NewConstructor(args[0], args[1], args[2], args[3], args[4]);
} else if (args.length === 6) {
return new NewConstructor(args[0], args[1], args[2], args[3], args[4], args[5]);
} else if (args.length === 7) {
return new NewConstructor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
} else {
return new NewConstructor(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
}
} else {
return Constructor.apply(this, args);
}
};
},
properties: {
polymorphicKey: 'type',
getPolymorphicClass: function(options) {
options || (options = {});
var polymorphicKey = (typeof this.polymorphicKey === 'function') ? this.polymorphicKey(options) : this.polymorphicKey;
var type = options[polymorphicKey];
var classes;
if (typeof this.polymorphicTypes === 'function') {
classes = this.polymorphicTypes();
} else if (this.polymorphicTypes) {
classes = this.polymorphicTypes;
} else {
classes = {};
}
return classes[type];
}
}
});