-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
105 lines (78 loc) · 2.47 KB
/
index.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* @flow */
import type {Realm} from "../";
export class TypedObject {
}
import {$isType, $ValueType} from "../symbols";
/**
* Make the TypeClass meta-class for the given realm.
*/
export function make (realm: Realm): Function {
/**
* TypeClass meta-class.
*/
function TypeClass (name: string, inititalizer: Function) {
function define (...args) {
let config = inititalizer(...args);
if (config instanceof TypeClass) {
// @flowIssue 1138
Object.setPrototypeOf(config, define.prototype);
return config;
}
let constructor;
function Target () {
return constructor.apply(this, arguments);
}
if (typeof config === 'function') {
config = config(Target);
}
if (config[$isType]) {
if (config.name && config.id) {
realm.registry.add(config);
}
return config;
}
const source = config.prototype || {};
// @flowIssue 1138
if (!TypedObject.prototype.isPrototypeOf(source) && isSimplePrototype(Object.getPrototypeOf(source))) {
// @flowIssue 1138
Object.setPrototypeOf(source, TypedObject.prototype);
}
constructor = typeof config.constructor === 'function' ? config.constructor : function (input) {
if (!(this instanceof Target)) {
return input;
}
};
Target.prototype = Object.create(source);
Target.prototype.constructor = Target;
Object.defineProperty(Target.prototype, $ValueType, { value: Target });
// @flowIssue 1138
Object.setPrototypeOf(Target, define.prototype);
Object.keys(config).filter(name => name !== 'prototype' && name !== 'constructor').forEach(name => {
Object.defineProperty(Target, name, {
value: config[name]
});
});
Object.defineProperty(Target, $isType, { value: true });
if (Target.name && Target.id) {
realm.registry.add(Target);
}
return Target;
}
// @flowIssue 1138
Object.setPrototypeOf(define, TypeClass.prototype);
// @flowIssue 1138
Object.setPrototypeOf(define.prototype, Function.prototype);
Object.defineProperties(define, {
name: {
value: name
}
});
return define;
}
// @flowIssue 1138
Object.setPrototypeOf(TypeClass.prototype, Function.prototype);
return TypeClass;
}
function isSimplePrototype (prototype: Object): boolean {
return prototype == null || prototype === Object.prototype;
}