This repository has been archived by the owner on Sep 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ae-static.ts
162 lines (148 loc) · 5.25 KB
/
ae-static.ts
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import { Class } from '@proc7ts/primitives';
import { Amendment, AmendTarget } from '../base';
import { AeClass, AmendableClass } from '../class';
import { AeProp, AePropHost, AePropHostKind } from '../impl';
import { StaticAmendment } from './static-amendment';
/**
* An amended entity representing a static class member (static property) to amend.
*
* Used by {@link Amendment amendments} to modify the static member definition. I.e. its property descriptor.
*
* @typeParam TValue - Amended member value type.
* @typeParam TClass - A type of amended class.
* @typeParam TUpdate - Amended member update type accepted by its setter.
*/
export interface AeStatic<
TValue extends TUpdate,
TClass extends AmendableClass = Class,
TUpdate = TValue,
> extends AeClass<TClass> {
/**
* A key of the static member.
*
* Updates to this property are always ignored. The member key can not be changed.
*/
readonly key: string | symbol;
/**
* Whether the member is writable.
*
* Updates to this property are always ignored.
*
* Set to `true` when {@link get} property assigned. Set to `false` when {@link set} property assigned, while the
* {@link get} one is not. Remains unchanged when neither {@link get}, nor {@link set} properties assigned.
*/
readonly readable: boolean;
/**
* Whether the member is writable.
*
* Updates to this property are always ignored.
*
* Set to `true` when {@link set} property assigned. Set to `false` when {@link get} property assigned, while the
* {@link set} one is not. Remains unchanged when neither {@link get}, nor {@link set} properties assigned.
*/
readonly writable: boolean;
/**
* Whether the member is enumerable.
*/
readonly enumerable: boolean;
/**
* Whether the member is configurable.
*/
readonly configurable: boolean;
/**
* Reads the value of this static member in the target class constructor.
*
* Throws if the member is not {@link readable}.
*
* @param classConstructor - Target class constructor.
*
* @returns Member value.
*/
get(this: void, classConstructor: TClass): TValue;
/**
* Assigns the value of this static member in the target class constructor.
*
* Throw is the member is not {@link writable}.
*
* @param classConstructor - Target class constructor.
* @param update - Updated member value.
*/
set(this: void, classConstructor: TClass, update: TUpdate): void;
}
/**
* An amendment target representing a static class member (static property) to amend.
*
* @typeParam TValue - Amended member value type.
* @typeParam TClass - A type of amended class.
* @typeParam TUpdate - Amended member update type accepted by its setter.
* @typeParam TAmended - A type of the entity representing a static member to amend.
*/
export type AeStaticTarget<
TValue extends TUpdate,
TClass extends AmendableClass = Class,
TUpdate = TValue,
TAmended extends AeStatic<TValue, TClass, TUpdate> = AeStatic<TValue, TClass, TUpdate>,
> = AmendTarget<TAmended>;
/**
* An amended entity representing a class containing a static member to decorate.
*
* Contains a data required for static member {@link StaticAmendatory.decorateAmended decoration}.
*
* Contains a class to amend, as well as arbitrary amended entity data.
*
* @typeParam TClass - A type of amended class.
* @typeParam TAmended - A type of the entity representing a class to amend.
*/
export type DecoratedAeStatic<
TClass extends AmendableClass,
TAmended extends AeClass<TClass> = AeClass<TClass>,
> = DecoratedAeStatic.ForBase<AeClass<TClass>, AeStatic<any, TClass>, TClass, TAmended>;
export namespace DecoratedAeStatic {
export type ForBase<
TClassBase extends AeClass<TClass>,
TStaticBase extends AeStatic<any, TClass>,
TClass extends AmendableClass,
TAmended extends TClassBase,
> = {
[K in Exclude<keyof TAmended, keyof TStaticBase>]: TAmended[K];
} & {
readonly amendedClass: TClass;
} & {
[K in keyof AmendTarget.Core<TAmended>]?: AmendTarget.Core<TAmended>[K] | undefined;
};
}
/**
* Creates an amendment (and decorator) for the static class member.
*
* @typeParam TValue - Amended member value type.
* @typeParam TClass - A type of amended class.
* @typeParam TUpdate - Amended member update type accepted by its setter.
* @typeParam TAmended - A type of the entity representing a static member to amend.
* @param amendments - Amendments to apply.
*
* @returns - New static member amendment instance.
*/
export function AeStatic<
TValue extends TUpdate,
TClass extends AmendableClass = Class,
TUpdate = TValue,
TAmended extends AeStatic<TValue, TClass, TUpdate> = AeStatic<TValue, TClass, TUpdate>,
>(...amendments: Amendment<TAmended>[]): StaticAmendment<TValue, TClass, TUpdate, TAmended> {
return AeProp(AeStatic$createHost, AeStatic$hostClass, amendments);
}
const AeStatic$HostKind: AePropHostKind = {
pName: 'Static property',
vDesc: key => `staticOf(${String(key)}`,
};
function AeStatic$createHost<TClass extends AmendableClass>({
amendedClass,
}: AeClass<TClass>): AePropHost<TClass, TClass> {
return {
kind: AeStatic$HostKind,
cls: amendedClass,
host: amendedClass,
};
}
function AeStatic$hostClass<TClass extends AmendableClass>(classConstructor: TClass): TClass {
return classConstructor;
}