Skip to content
This repository was archived by the owner on Jun 9, 2019. It is now read-only.

Commit 3d887a9

Browse files
committed
move decorators/methods/ -> decorators/methods
1 parent 4966f8c commit 3d887a9

File tree

4 files changed

+126
-87
lines changed

4 files changed

+126
-87
lines changed

src/decorators/methods.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
const repository = new WeakMap();
2+
3+
function createValidator(methodname) {
4+
const config = {};
5+
6+
function validate(...args) {
7+
const header = `${this.constructor.name}#${config.methodname}()`;
8+
const argErrIndex = argscheck(args, config.parameters);
9+
10+
if (argErrIndex !== -1) {
11+
throw new TypeError(`${header}; argument(${argErrIndex}) should be a ${config.parameters[argErrIndex].validator.name}, but got: ${args[argErrIndex]}`);
12+
}
13+
14+
if (typeof config.precondition === "function") {
15+
try {
16+
this::config.precondition(...args);
17+
} catch (e) {
18+
e.message = `${header}; ${e.message}`;
19+
throw e;
20+
}
21+
}
22+
23+
const res = this::config.methodBody(...args);
24+
25+
if (typeof config.postcondition === "function") {
26+
try {
27+
this::config.postcondition(res);
28+
} catch (e) {
29+
e.message = `${header}; ${e.message}`;
30+
throw e;
31+
}
32+
}
33+
34+
if (config.returnValue) {
35+
if (!config.returnValue.test(res)) {
36+
throw new TypeError(`${header}; required a ${config.returnValue.name}, but got ${res}`);
37+
}
38+
}
39+
40+
return res;
41+
}
42+
43+
config.methodname = methodname;
44+
config.parameters = [];
45+
config.descriptor = {
46+
value: validate, enumerable: true, configurable: true
47+
};
48+
49+
return config;
50+
}
51+
52+
function argscheck(values, validators) {
53+
for (let i = 0; i < validators.length; i++) {
54+
if (validators[i].optional === true && values.length <= i) {
55+
break;
56+
}
57+
if (!validators[i].validator.test(values[i])) {
58+
return i;
59+
}
60+
}
61+
return -1;
62+
}
63+
64+
function getMethodConfig(target, methodname) {
65+
let classConfig = repository.get(target);
66+
67+
if (!classConfig) {
68+
repository.set(target, (classConfig = {}));
69+
}
70+
71+
if (!classConfig[methodname]) {
72+
classConfig[methodname] = createValidator(methodname);
73+
}
74+
75+
return classConfig[methodname];
76+
}
77+
78+
export function name($methodname) {
79+
return (target, methodname, descriptor) => {
80+
const methodConfig = getMethodConfig(target, methodname);
81+
82+
methodConfig.methodname = $methodname;
83+
methodConfig.methodBody = methodConfig.methodBody || descriptor.value;
84+
85+
return methodConfig.descriptor;
86+
};
87+
}
88+
89+
export function param(paramname, validator) {
90+
return (target, methodname, descriptor) => {
91+
const methodConfig = getMethodConfig(target, methodname);
92+
const optional = /^\[\s*\w+?\s*\]$/.test(paramname);
93+
94+
if (optional) {
95+
paramname = paramname.replace(/^\[|\]$/g, "").trim();
96+
}
97+
98+
methodConfig.parameters.unshift({ paramname, validator, optional });
99+
methodConfig.methodBody = methodConfig.methodBody || descriptor.value;
100+
101+
return methodConfig.descriptor;
102+
};
103+
}
104+
105+
export function returns(validator) {
106+
return (target, methodname, descriptor) => {
107+
const methodConfig = getMethodConfig(target, methodname);
108+
109+
methodConfig.returnValue = validator;
110+
methodConfig.methodBody = methodConfig.methodBody || descriptor.value;
111+
112+
return methodConfig.descriptor;
113+
};
114+
}
115+
116+
export function contract({ precondition, postcondition }) {
117+
return (target, methodname, descriptor) => {
118+
const methodConfig = getMethodConfig(target, methodname);
119+
120+
methodConfig.precondition = precondition;
121+
methodConfig.postcondition = postcondition;
122+
methodConfig.methodBody = methodConfig.methodBody || descriptor.value;
123+
124+
return methodConfig.descriptor;
125+
};
126+
}

src/decorators/methods/contract.js

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/decorators/methods/index.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/decorators/methods/param.js

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)