lenix 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +46 -2
- package/{bin → lint}/dist/lint.mjs +2 -2
- package/{bin/.eslint-preset.json → lint/lint-preset.json} +54 -18
- package/{bin → lint}/lint.mts +2 -2
- package/lua/LICENSE +21 -0
- package/lua/_dev/firstAttempt.lua +202 -0
- package/lua/_dev/secondAttempt.lua +166 -0
- package/lua/_dev/tests.lua +298 -0
- package/lua/index.lua +322 -0
- package/lua/lenix-0.1.0-1.rockspec +25 -0
- package/package.json +14 -10
- package/bin/Readme.md +0 -33
- /package/{bin → lint}/tsconfig.json +0 -0
- /package/{bin/mac-lua_modules.sh → lua/mac-lua-modules.sh} +0 -0
- /package/{dist → ts/dist}/fetch/index.d.ts +0 -0
- /package/{dist → ts/dist}/fetch/index.js +0 -0
- /package/{dist → ts/dist}/fxmanifest/fxmanifest.json +0 -0
- /package/{dist → ts/dist}/fxmanifest/index.d.ts +0 -0
- /package/{dist → ts/dist}/fxmanifest/index.js +0 -0
- /package/{dist → ts/dist}/index.d.ts +0 -0
- /package/{dist → ts/dist}/index.js +0 -0
- /package/{dist → ts/dist}/wait/index.d.ts +0 -0
- /package/{dist → ts/dist}/wait/index.js +0 -0
package/Readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# lenix
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Monorepo for the software engineering community
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|

|
|
@@ -32,7 +32,7 @@ yarn add lenix
|
|
|
32
32
|
[](https://github.com/lenixdev/lenix)
|
|
33
33
|
|
|
34
34
|
## 🗺️ Roadmap
|
|
35
|
-
- [ ]
|
|
35
|
+
- [ ] fix the lint tsconfig.json file creation when no file is found
|
|
36
36
|
|
|
37
37
|
## 🧾License
|
|
38
38
|

|
|
@@ -43,3 +43,47 @@ yarn add lenix
|
|
|
43
43
|
## 💻 Build with
|
|
44
44
|

|
|
45
45
|

|
|
46
|
+
|
|
47
|
+
# Lua Object Oriented Programming Class Module
|
|
48
|
+
|
|
49
|
+
Lua object oriented programming class module allow you to use oop similar to the TypeScript/JavaScript/Java/C++ Classes
|
|
50
|
+
|
|
51
|
+
## 🗺️ Roadmap
|
|
52
|
+
- [ ] Implement the complete annotation
|
|
53
|
+
- [ ] Provide Documentation
|
|
54
|
+
- [ ] Clearify the installation steps
|
|
55
|
+
|
|
56
|
+
## Lua Modules Setup
|
|
57
|
+
|
|
58
|
+
Auto-configure Lua to use `./lua_modules` (like `node_modules`) instead of unorganized directories.
|
|
59
|
+
|
|
60
|
+
### Install
|
|
61
|
+
- MAC
|
|
62
|
+
```bash
|
|
63
|
+
npx mac-lua-modules
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Usage
|
|
67
|
+
```bash
|
|
68
|
+
# Install Lua packages
|
|
69
|
+
luarocks install --tree ./lua_modules inspect
|
|
70
|
+
|
|
71
|
+
# Use in code (no setup needed)
|
|
72
|
+
local inspect = require('inspect')
|
|
73
|
+
print(inspect({name = "Lenix"}))
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### What it does
|
|
77
|
+
|
|
78
|
+
Adds environment variables to your shell config (for mac users: `~/.zshrc` or `~/.bashrc`) to automatically change your Lua modules configurations to `./lua_modules` instead of hidden nested directories.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## ESLINT Usage
|
|
82
|
+
### Build your own linter
|
|
83
|
+
```zsh
|
|
84
|
+
npx lenix --lint
|
|
85
|
+
```
|
|
86
|
+
### Clone a preset lint
|
|
87
|
+
```zsh
|
|
88
|
+
npx lenix --lint --preset
|
|
89
|
+
```
|
|
@@ -6,7 +6,7 @@ import eslintJs from '@eslint/js';
|
|
|
6
6
|
import tseslint from 'typescript-eslint';
|
|
7
7
|
const [, , cmd, ...args] = process.argv;
|
|
8
8
|
if (cmd !== '--lint') {
|
|
9
|
-
process.stdout.write('Usage: lenix --lint [--preset]
|
|
9
|
+
process.stdout.write('Usage: lenix --lint [--preset]\n');
|
|
10
10
|
process.exit(0);
|
|
11
11
|
}
|
|
12
12
|
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
@@ -207,7 +207,7 @@ if (preset) {
|
|
|
207
207
|
const config = generateConfig(data.rules);
|
|
208
208
|
fs.writeFileSync('eslint.config.mts', config, 'utf8');
|
|
209
209
|
process.stdout.write(`${tag('done', c.green)} Written to ${bold('eslint.config.mts')}\n`);
|
|
210
|
-
process.stdout.write(`${tag('notice', c.cyan)} Run:
|
|
210
|
+
process.stdout.write(`${tag('notice', c.cyan)} Run: ${bold('npm add -D @eslint/js globals typescript-eslint')}\n`);
|
|
211
211
|
fs.closeSync(ttyFd);
|
|
212
212
|
process.exit(0);
|
|
213
213
|
}
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
"consistent-return": "warn",
|
|
13
13
|
"consistent-this": "warn",
|
|
14
14
|
"constructor-super": "warn",
|
|
15
|
-
"curly":
|
|
15
|
+
"curly": [
|
|
16
|
+
"error",
|
|
17
|
+
"multi"
|
|
18
|
+
],
|
|
16
19
|
"default-case": "error",
|
|
17
20
|
"default-case-last": "error",
|
|
18
21
|
"default-param-last": "error",
|
|
@@ -26,14 +29,21 @@
|
|
|
26
29
|
"grouped-accessor-pairs": "error",
|
|
27
30
|
"guard-for-in": "warn",
|
|
28
31
|
"id-denylist": "warn",
|
|
29
|
-
"id-length":
|
|
32
|
+
"id-length": [
|
|
33
|
+
"error",
|
|
34
|
+
{
|
|
35
|
+
"exceptions": [
|
|
36
|
+
"_"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
30
40
|
"id-match": "error",
|
|
31
41
|
"init-declarations": "error",
|
|
32
42
|
"logical-assignment-operators": "error",
|
|
33
43
|
"max-classes-per-file": "error",
|
|
34
44
|
"max-depth": "error",
|
|
35
45
|
"max-lines": "error",
|
|
36
|
-
"max-lines-per-function": "
|
|
46
|
+
"max-lines-per-function": "warn",
|
|
37
47
|
"max-nested-callbacks": "error",
|
|
38
48
|
"max-params": "error",
|
|
39
49
|
"max-statements": "error",
|
|
@@ -48,7 +58,7 @@
|
|
|
48
58
|
"no-class-assign": "error",
|
|
49
59
|
"no-compare-neg-zero": "error",
|
|
50
60
|
"no-cond-assign": "warn",
|
|
51
|
-
"no-console": "
|
|
61
|
+
"no-console": "warn",
|
|
52
62
|
"no-const-assign": "error",
|
|
53
63
|
"no-constant-binary-expression": "warn",
|
|
54
64
|
"no-constant-condition": "warn",
|
|
@@ -96,7 +106,18 @@
|
|
|
96
106
|
"no-lonely-if": "error",
|
|
97
107
|
"no-loop-func": "warn",
|
|
98
108
|
"no-loss-of-precision": "error",
|
|
99
|
-
"no-magic-numbers":
|
|
109
|
+
"no-magic-numbers": [
|
|
110
|
+
"error",
|
|
111
|
+
{
|
|
112
|
+
"detectObjects": true,
|
|
113
|
+
"enforceConst": true,
|
|
114
|
+
"ignore": [
|
|
115
|
+
0,
|
|
116
|
+
1
|
|
117
|
+
],
|
|
118
|
+
"ignoreReadonlyClassProperties": true
|
|
119
|
+
}
|
|
120
|
+
],
|
|
100
121
|
"no-misleading-character-class": "warn",
|
|
101
122
|
"no-multi-assign": "error",
|
|
102
123
|
"no-multi-str": "error",
|
|
@@ -136,9 +157,9 @@
|
|
|
136
157
|
"no-this-before-super": "error",
|
|
137
158
|
"no-throw-literal": "error",
|
|
138
159
|
"no-unassigned-vars": "error",
|
|
139
|
-
"no-undef": "
|
|
160
|
+
"no-undef": "error",
|
|
140
161
|
"no-undef-init": "error",
|
|
141
|
-
"no-undefined": "
|
|
162
|
+
"no-undefined": "off",
|
|
142
163
|
"no-underscore-dangle": "warn",
|
|
143
164
|
"no-unexpected-multiline": "error",
|
|
144
165
|
"no-unmodified-loop-condition": "warn",
|
|
@@ -168,7 +189,7 @@
|
|
|
168
189
|
"no-warning-comments": "warn",
|
|
169
190
|
"no-with": "error",
|
|
170
191
|
"object-shorthand": "error",
|
|
171
|
-
"one-var": "
|
|
192
|
+
"one-var": "off",
|
|
172
193
|
"operator-assignment": "warn",
|
|
173
194
|
"prefer-arrow-callback": "error",
|
|
174
195
|
"prefer-const": "error",
|
|
@@ -189,8 +210,8 @@
|
|
|
189
210
|
"require-await": "error",
|
|
190
211
|
"require-unicode-regexp": "warn",
|
|
191
212
|
"require-yield": "error",
|
|
192
|
-
"sort-imports": "
|
|
193
|
-
"sort-keys": "
|
|
213
|
+
"sort-imports": "off",
|
|
214
|
+
"sort-keys": "off",
|
|
194
215
|
"sort-vars": "error",
|
|
195
216
|
"strict": "error",
|
|
196
217
|
"symbol-description": "error",
|
|
@@ -211,9 +232,9 @@
|
|
|
211
232
|
"@typescript-eslint/consistent-type-definitions": "error",
|
|
212
233
|
"@typescript-eslint/consistent-type-imports": "error",
|
|
213
234
|
"@typescript-eslint/default-param-last": "warn",
|
|
214
|
-
"@typescript-eslint/explicit-function-return-type": "
|
|
235
|
+
"@typescript-eslint/explicit-function-return-type": "off",
|
|
215
236
|
"@typescript-eslint/explicit-member-accessibility": "warn",
|
|
216
|
-
"@typescript-eslint/explicit-module-boundary-types": "
|
|
237
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
217
238
|
"@typescript-eslint/init-declarations": "error",
|
|
218
239
|
"@typescript-eslint/max-params": "error",
|
|
219
240
|
"@typescript-eslint/member-ordering": "error",
|
|
@@ -231,7 +252,7 @@
|
|
|
231
252
|
"@typescript-eslint/no-inferrable-types": "error",
|
|
232
253
|
"@typescript-eslint/no-invalid-void-type": "error",
|
|
233
254
|
"@typescript-eslint/no-loop-func": "error",
|
|
234
|
-
"@typescript-eslint/no-magic-numbers": "
|
|
255
|
+
"@typescript-eslint/no-magic-numbers": "off",
|
|
235
256
|
"@typescript-eslint/no-misused-new": "error",
|
|
236
257
|
"@typescript-eslint/no-namespace": "error",
|
|
237
258
|
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "warn",
|
|
@@ -266,7 +287,17 @@
|
|
|
266
287
|
"@typescript-eslint/consistent-return": "error",
|
|
267
288
|
"@typescript-eslint/consistent-type-exports": "error",
|
|
268
289
|
"@typescript-eslint/dot-notation": "error",
|
|
269
|
-
"@typescript-eslint/naming-convention":
|
|
290
|
+
"@typescript-eslint/naming-convention": [
|
|
291
|
+
"warn",
|
|
292
|
+
{
|
|
293
|
+
"selector": "variable",
|
|
294
|
+
"format": [
|
|
295
|
+
"camelCase",
|
|
296
|
+
"UPPER_CASE",
|
|
297
|
+
"PascalCase"
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
],
|
|
270
301
|
"@typescript-eslint/no-array-delete": "error",
|
|
271
302
|
"@typescript-eslint/no-base-to-string": "warn",
|
|
272
303
|
"@typescript-eslint/no-confusing-void-expression": "error",
|
|
@@ -279,14 +310,14 @@
|
|
|
279
310
|
"@typescript-eslint/no-misused-promises": "error",
|
|
280
311
|
"@typescript-eslint/no-misused-spread": "error",
|
|
281
312
|
"@typescript-eslint/no-mixed-enums": "error",
|
|
282
|
-
"@typescript-eslint/no-redundant-type-constituents": "
|
|
313
|
+
"@typescript-eslint/no-redundant-type-constituents": "error",
|
|
283
314
|
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
|
|
284
315
|
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
285
316
|
"@typescript-eslint/no-unnecessary-qualifier": "warn",
|
|
286
317
|
"@typescript-eslint/no-unnecessary-template-expression": "error",
|
|
287
318
|
"@typescript-eslint/no-unnecessary-type-arguments": "error",
|
|
288
319
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
289
|
-
"@typescript-eslint/no-unnecessary-type-conversion": "
|
|
320
|
+
"@typescript-eslint/no-unnecessary-type-conversion": "error",
|
|
290
321
|
"@typescript-eslint/no-unnecessary-type-parameters": "error",
|
|
291
322
|
"@typescript-eslint/no-unsafe-argument": "error",
|
|
292
323
|
"@typescript-eslint/no-unsafe-assignment": "error",
|
|
@@ -306,7 +337,12 @@
|
|
|
306
337
|
"@typescript-eslint/prefer-optional-chain": "error",
|
|
307
338
|
"@typescript-eslint/prefer-promise-reject-errors": "error",
|
|
308
339
|
"@typescript-eslint/prefer-readonly": "error",
|
|
309
|
-
"@typescript-eslint/prefer-readonly-parameter-types":
|
|
340
|
+
"@typescript-eslint/prefer-readonly-parameter-types": [
|
|
341
|
+
"error",
|
|
342
|
+
{
|
|
343
|
+
"ignoreInferredTypes": true
|
|
344
|
+
}
|
|
345
|
+
],
|
|
310
346
|
"@typescript-eslint/prefer-reduce-type-parameter": "error",
|
|
311
347
|
"@typescript-eslint/prefer-regexp-exec": "warn",
|
|
312
348
|
"@typescript-eslint/prefer-return-this-type": "error",
|
|
@@ -319,7 +355,7 @@
|
|
|
319
355
|
"@typescript-eslint/restrict-template-expressions": "error",
|
|
320
356
|
"@typescript-eslint/return-await": "error",
|
|
321
357
|
"@typescript-eslint/strict-boolean-expressions": "error",
|
|
322
|
-
"@typescript-eslint/strict-void-return": "
|
|
358
|
+
"@typescript-eslint/strict-void-return": "off",
|
|
323
359
|
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
|
324
360
|
"@typescript-eslint/unbound-method": "warn",
|
|
325
361
|
"@typescript-eslint/use-unknown-in-catch-callback-variable": "error"
|
package/{bin → lint}/lint.mts
RENAMED
|
@@ -11,7 +11,7 @@ import type { ESLint } from 'eslint'
|
|
|
11
11
|
|
|
12
12
|
const [,, cmd, ...args] = process.argv
|
|
13
13
|
if (cmd !== '--lint') {
|
|
14
|
-
process.stdout.write('Usage: lenix --lint [--preset]
|
|
14
|
+
process.stdout.write('Usage: lenix --lint [--preset]\n')
|
|
15
15
|
process.exit(0)
|
|
16
16
|
}
|
|
17
17
|
process.argv = [process.argv[0], process.argv[1], ...args]
|
|
@@ -236,7 +236,7 @@ if (preset) {
|
|
|
236
236
|
const config = generateConfig(data.rules)
|
|
237
237
|
fs.writeFileSync('eslint.config.mts', config, 'utf8')
|
|
238
238
|
process.stdout.write(`${tag('done', c.green)} Written to ${bold('eslint.config.mts')}\n`)
|
|
239
|
-
process.stdout.write(`${tag('notice', c.cyan)} Run:
|
|
239
|
+
process.stdout.write(`${tag('notice', c.cyan)} Run: ${bold('npm add -D @eslint/js globals typescript-eslint')}\n`)
|
|
240
240
|
fs.closeSync(ttyFd)
|
|
241
241
|
process.exit(0)
|
|
242
242
|
}
|
package/lua/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lenix
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
local class<const> = function (fields)
|
|
2
|
+
local defined<const> = {}
|
|
3
|
+
local private<const> = fields.private or {}
|
|
4
|
+
local getter<const> = fields.get or {}
|
|
5
|
+
local setter<const> = fields.set or {}
|
|
6
|
+
local accessor<const> = fields.accessor or {}
|
|
7
|
+
local privates<const> = { static = {}, instance = {} }
|
|
8
|
+
local setProperties<const> = { static = {}, instance = {} }
|
|
9
|
+
local getProperties<const> = { static = {}, instance = {} }
|
|
10
|
+
|
|
11
|
+
local isVariableEligible<const> = function (variable, valueType, value)
|
|
12
|
+
if defined[variable] then
|
|
13
|
+
print(("`%s` is already defined"):format(variable))
|
|
14
|
+
return
|
|
15
|
+
elseif type(value) ~= valueType and valueType ~= "any" then
|
|
16
|
+
print(("type mismatch for `%s`, expected `%s`, got `%s`"):format(variable, valueType, type(value)))
|
|
17
|
+
return
|
|
18
|
+
end
|
|
19
|
+
defined[variable] = true
|
|
20
|
+
if valueType == "any" then
|
|
21
|
+
print(("variable `%s` implicitly has type `%s`"):format(variable, valueType, type(value)))
|
|
22
|
+
end
|
|
23
|
+
return true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
local fieldPairs<const> = {
|
|
27
|
+
{private, privates},
|
|
28
|
+
{getter, getProperties},
|
|
29
|
+
{setter, setProperties},
|
|
30
|
+
{accessor, nil}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for _, pair in ipairs(fieldPairs) do
|
|
34
|
+
local source, target = pair[1], pair[2]
|
|
35
|
+
for variable, values in pairs(source) do
|
|
36
|
+
-- getPropertyValue
|
|
37
|
+
local value<const> = type(values) == "table" and values[1]
|
|
38
|
+
-- getPropertyType
|
|
39
|
+
local valueType<const> = type(values) == "table" and values[2] or "any"
|
|
40
|
+
local staticValue<const> = values and values[3] or false
|
|
41
|
+
if isVariableEligible(variable, valueType, value) then
|
|
42
|
+
-- fill table with keys and values
|
|
43
|
+
if target then
|
|
44
|
+
if staticValue then
|
|
45
|
+
target["static"][variable] = value
|
|
46
|
+
else
|
|
47
|
+
target["instance"][variable] = value
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
if staticValue then
|
|
51
|
+
getProperties["static"][variable] = value
|
|
52
|
+
setProperties["static"][variable] = value
|
|
53
|
+
else
|
|
54
|
+
getProperties["instance"][variable] = value
|
|
55
|
+
setProperties["instance"][variable] = value
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
return setmetatable({
|
|
63
|
+
new = function (self, ...)
|
|
64
|
+
local newInstanceArgs = {...}
|
|
65
|
+
print(self)
|
|
66
|
+
local constructor<const> = fields.constructor
|
|
67
|
+
constructor(self, nil, ...)
|
|
68
|
+
return setmetatable({}, {
|
|
69
|
+
__index = function (_, variableKey)
|
|
70
|
+
if getter["instance"][variableKey] then
|
|
71
|
+
return getProperties["instance"][variableKey]
|
|
72
|
+
elseif accessor["instance"][variableKey] then
|
|
73
|
+
return getProperties["instance"][variableKey]
|
|
74
|
+
end
|
|
75
|
+
end,
|
|
76
|
+
})
|
|
77
|
+
end
|
|
78
|
+
}, {
|
|
79
|
+
__index = function(_, variableKey)
|
|
80
|
+
assert(defined[variableKey], ("property `%s` not found"):format(variableKey))
|
|
81
|
+
-- isPropertyExist
|
|
82
|
+
if getter[variableKey] ~= nil then
|
|
83
|
+
if isStatic(getter, variableKey, "get") then
|
|
84
|
+
-- returnPropertyValue
|
|
85
|
+
return getProperties["static"][variableKey]
|
|
86
|
+
end
|
|
87
|
+
elseif accessor[variableKey] ~= nil then
|
|
88
|
+
if isStatic(accessor, variableKey, "accessor") then
|
|
89
|
+
return getProperties["static"][variableKey]
|
|
90
|
+
end
|
|
91
|
+
elseif private[variableKey] ~= nil then
|
|
92
|
+
print(("cannot read the private property `%s`"):format(variableKey))
|
|
93
|
+
elseif setter[variableKey] ~= nil then
|
|
94
|
+
print(("the setter only property `%s` can not be accessed"):format(variableKey))
|
|
95
|
+
else print(("something went wrong when trying to access `%s`"):format(variableKey)) end
|
|
96
|
+
end,
|
|
97
|
+
__newindex = function (_, variableKey, variableValue)
|
|
98
|
+
assert(defined[variableKey], ("property `%s` not found"):format(variableKey))
|
|
99
|
+
if setter[variableKey] ~= nil then
|
|
100
|
+
if not isStatic(setter, variableKey, "set") then
|
|
101
|
+
local valueType = setter[variableKey][2] or "any"
|
|
102
|
+
if type(variableValue) ~= valueType and valueType ~= "any" then
|
|
103
|
+
print(("cannot assign `%s` to `%s` on `%s`"):format(type(variableValue), valueType, variableKey))
|
|
104
|
+
return
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
getProperties["static"][variableKey] = variableValue
|
|
108
|
+
elseif accessor[variableKey] ~= nil then
|
|
109
|
+
if not isStatic(accessor, variableKey, "accessor") then
|
|
110
|
+
local valueType = accessor[variableKey][2] or "any"
|
|
111
|
+
if type(variableValue) ~= valueType and valueType ~= "any" then
|
|
112
|
+
print(("cannot assign `%s` to `%s` on `%s`"):format(type(variableValue), valueType, variableKey))
|
|
113
|
+
return
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
getProperties["static"][variableKey] = variableValue
|
|
117
|
+
elseif getter[variableKey] ~= nil then
|
|
118
|
+
print(("the getter only property `%s `can not be set"):format(variableKey))
|
|
119
|
+
else print(("something went wrong when trying to access `%s`"):format(variableKey)) end
|
|
120
|
+
end
|
|
121
|
+
})
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
myClass = class({
|
|
125
|
+
private = {
|
|
126
|
+
height = {197, "number"},
|
|
127
|
+
},
|
|
128
|
+
get = {
|
|
129
|
+
blood = {"O+", "any"},
|
|
130
|
+
},
|
|
131
|
+
set = {
|
|
132
|
+
date = {2005, "number"},
|
|
133
|
+
},
|
|
134
|
+
accessor = {
|
|
135
|
+
age = {20, "number"},
|
|
136
|
+
name = {"Lenix", "string"},
|
|
137
|
+
getBlood = {function(self) return self end, "function"}
|
|
138
|
+
},
|
|
139
|
+
constructor = function(self, super, name, age)
|
|
140
|
+
self.name = name
|
|
141
|
+
self.age = age
|
|
142
|
+
end
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
local Person = myClass:new("Dev", 21)
|
|
147
|
+
print(Person.name, Person.age)
|
|
148
|
+
-- Person.date = 2005
|
|
149
|
+
-- print(Person.date)
|
|
150
|
+
-- print(Person.age)
|
|
151
|
+
-- Person.age = 21
|
|
152
|
+
|
|
153
|
+
-- print(myClass.height)
|
|
154
|
+
-- print(myClass.blood)
|
|
155
|
+
-- myClass.date = 2026
|
|
156
|
+
-- print(myClass.age)
|
|
157
|
+
-- myClass.age = 21
|
|
158
|
+
-- print(myClass.age)
|
|
159
|
+
-- print(myClass.name)
|
|
160
|
+
-- myClass.name = "Dev"
|
|
161
|
+
-- print(myClass.name)
|
|
162
|
+
-- print(myClass.getBlood())
|
|
163
|
+
-- myClass.getBlood = function() return true end
|
|
164
|
+
-- print(myClass.getBlood())
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
__index = function(_, variableKey)
|
|
170
|
+
assert(defined[variableKey], ("property `%s` not found"):format(variableKey))
|
|
171
|
+
-- isPropertyExist
|
|
172
|
+
if getter[variableKey] ~= nil then
|
|
173
|
+
-- returnPropertyValue
|
|
174
|
+
return getProperties[variableKey]
|
|
175
|
+
elseif accessor[variableKey] ~= nil then
|
|
176
|
+
return getProperties[variableKey]
|
|
177
|
+
elseif private[variableKey] ~= nil then
|
|
178
|
+
print(("cannot read the private property `%s`"):format(variableKey))
|
|
179
|
+
elseif setter[variableKey] ~= nil then
|
|
180
|
+
print(("the setter only property `%s` are forbidden to be accessed"):format(variableKey))
|
|
181
|
+
else print(("something went wrong when trying to access `%s`"):format(variableKey)) end
|
|
182
|
+
end,
|
|
183
|
+
__newindex = function (_, variableKey, variableValue)
|
|
184
|
+
assert(defined[variableKey], ("property `%s` not found"):format(variableKey))
|
|
185
|
+
if setter[variableKey] ~= nil then
|
|
186
|
+
local valueType = setter[variableKey][2] or "any"
|
|
187
|
+
if type(variableValue) ~= valueType and valueType ~= "any" then
|
|
188
|
+
print(("cannot assign `%s` to `%s` on `%s`"):format(type(variableValue), valueType, variableKey))
|
|
189
|
+
return
|
|
190
|
+
end
|
|
191
|
+
getProperties[variableKey] = variableValue
|
|
192
|
+
elseif accessor[variableKey] ~= nil then
|
|
193
|
+
local valueType = accessor[variableKey][2] or "any"
|
|
194
|
+
if type(variableValue) ~= valueType and valueType ~= "any" then
|
|
195
|
+
print(("cannot assign `%s` to `%s` on `%s`"):format(type(variableValue), valueType, variableKey))
|
|
196
|
+
return
|
|
197
|
+
end
|
|
198
|
+
getProperties[variableKey] = variableValue
|
|
199
|
+
elseif getter[variableKey] ~= nil then
|
|
200
|
+
print(("the getter only property `%s `can not be set"):format(variableKey))
|
|
201
|
+
else print(("something went wrong when trying to access `%s`"):format(variableKey)) end
|
|
202
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
assert(_VERSION == "Lua 5.4", "THIS MODULE REQUIRES Lua 5.4")
|
|
2
|
+
|
|
3
|
+
local class<const> = function (fields)
|
|
4
|
+
local definedProperties<const> = {}
|
|
5
|
+
local promisedToBeConstructed<const> = {}
|
|
6
|
+
local private<const> = fields.private or {}
|
|
7
|
+
local getter<const> = fields.get or {}
|
|
8
|
+
local setter<const> = fields.set or {}
|
|
9
|
+
local accessor<const> = fields.accessor or {}
|
|
10
|
+
local privates<const> = {}
|
|
11
|
+
local setProperties<const> = {}
|
|
12
|
+
local getProperties<const> = {}
|
|
13
|
+
|
|
14
|
+
local isVariableEligible<const> = function (propertyKey, propertyType, propertyValue)
|
|
15
|
+
if definedProperties[propertyKey] then
|
|
16
|
+
print(("`%s` is already defined"):format(propertyKey))
|
|
17
|
+
return
|
|
18
|
+
elseif type(propertyValue) ~= propertyType and propertyType ~= "any" and propertyValue ~= nil then
|
|
19
|
+
error(("type mismatch for `%s`, defined `%s`, appointed `%s`"):format(propertyKey, propertyType, type(propertyValue)))
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
definedProperties[propertyKey] = true
|
|
23
|
+
if propertyType == "any" then
|
|
24
|
+
print(("variable `%s` implicitly has type `%s`"):format(propertyKey, propertyType, type(propertyValue)))
|
|
25
|
+
end
|
|
26
|
+
if propertyValue == nil and propertyType ~= "nil" then
|
|
27
|
+
promisedToBeConstructed[propertyKey] = true
|
|
28
|
+
end
|
|
29
|
+
return true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
local fieldPairs<const> = {
|
|
33
|
+
{private, privates},
|
|
34
|
+
{getter, getProperties},
|
|
35
|
+
{setter, setProperties},
|
|
36
|
+
{accessor, nil}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
for _, pair in ipairs(fieldPairs) do
|
|
40
|
+
local field<const>, properties<const> = pair[1], pair[2]
|
|
41
|
+
for propertyKey, propertyValues in pairs(field) do
|
|
42
|
+
-- getPropertyValue
|
|
43
|
+
local propertyValue<const> = type(propertyValues) == "table" and propertyValues[1]
|
|
44
|
+
-- getPropertyType
|
|
45
|
+
assert(type(propertyValues) == 'table', ("syntax error at `%s`, expected `%s`, got `%s`"):format(propertyKey, "table", type(propertyValues)))
|
|
46
|
+
local propertyType<const> = propertyValues[2]
|
|
47
|
+
if isVariableEligible(propertyKey, propertyType, propertyValue) then
|
|
48
|
+
-- fill table with keys and values
|
|
49
|
+
if properties then
|
|
50
|
+
properties[propertyKey] = propertyValue
|
|
51
|
+
else
|
|
52
|
+
-- for the accessor, filling the get and set permission
|
|
53
|
+
getProperties[propertyKey], setProperties[propertyKey] = propertyValue, propertyValue
|
|
54
|
+
setter[propertyKey], getter[propertyKey] = accessor[propertyKey], accessor[propertyKey]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
local get<const> = function (self, propertyKey)
|
|
61
|
+
if definedProperties[propertyKey] then
|
|
62
|
+
if getter[propertyKey] then
|
|
63
|
+
if type(self[propertyKey]) == 'function' then
|
|
64
|
+
return function(...) return self[propertyKey](self, ...) end
|
|
65
|
+
end
|
|
66
|
+
return self[propertyKey]
|
|
67
|
+
elseif private[propertyKey] then
|
|
68
|
+
print(("private property `%s` is not allowed to be accessed"):format(propertyKey))
|
|
69
|
+
else print(("tried to get the `%s` set-only property"):format(propertyKey)) end
|
|
70
|
+
else
|
|
71
|
+
print(("`%s` property does not exist"):format(propertyKey))
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
local set<const> = function (self, propertyKey, propertyValue)
|
|
75
|
+
if definedProperties[propertyKey] then
|
|
76
|
+
if setter[propertyKey] then
|
|
77
|
+
if type(propertyValue) == setter[propertyKey][2] or setter[propertyKey][2] == "any" then
|
|
78
|
+
self[propertyKey] = propertyValue
|
|
79
|
+
else print(("`%s` is not assignable to `%s`: on `%s`"):format(type(propertyValue), setter[propertyKey][2], propertyKey)) end
|
|
80
|
+
elseif private[propertyKey] then
|
|
81
|
+
print(("private property `%s` is not allowed to be assigned"):format(propertyKey))
|
|
82
|
+
else print(("tried to set the `%s` get-only property"):format(propertyKey)) end
|
|
83
|
+
else
|
|
84
|
+
print(("`%s` property does not exist"):format(propertyKey))
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
return setmetatable({
|
|
89
|
+
new = function(self, ...)
|
|
90
|
+
local instance<const> = {}
|
|
91
|
+
|
|
92
|
+
for _, pair in pairs(fieldPairs) do
|
|
93
|
+
for propertyKey, propertyValue in pairs(pair[2] or {}) do
|
|
94
|
+
instance[propertyKey] = propertyValue
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
setmetatable(instance, getmetatable(self))
|
|
99
|
+
|
|
100
|
+
if fields.constructor then
|
|
101
|
+
fields.constructor(instance, nil, ...)
|
|
102
|
+
else error('no constructor was provided') end
|
|
103
|
+
|
|
104
|
+
-- Constructor has finished, now validate
|
|
105
|
+
for propertyKey in pairs(promisedToBeConstructed) do
|
|
106
|
+
if instance[propertyKey] == nil then
|
|
107
|
+
error(('the `%s` was not instantiated in constructor as promised'):format(propertyKey))
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
return setmetatable({}, {
|
|
112
|
+
__index = function(_, propertyKey)
|
|
113
|
+
return get(instance, propertyKey)
|
|
114
|
+
end,
|
|
115
|
+
__newindex = function(_, propertyKey, varValue)
|
|
116
|
+
set(instance, propertyKey, varValue)
|
|
117
|
+
end
|
|
118
|
+
})
|
|
119
|
+
end
|
|
120
|
+
}, { })
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
local myClass<const> = class({
|
|
124
|
+
private = {
|
|
125
|
+
height = {nil, "number"},
|
|
126
|
+
},
|
|
127
|
+
get = {
|
|
128
|
+
blood = {nil, "string"},
|
|
129
|
+
getHeight = {function(self, new)
|
|
130
|
+
self.setHeight(self, new)
|
|
131
|
+
return self.height
|
|
132
|
+
end, "function"}
|
|
133
|
+
},
|
|
134
|
+
set = {
|
|
135
|
+
setHeight = {
|
|
136
|
+
function(new)
|
|
137
|
+
self.height = new
|
|
138
|
+
end, "function"
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
accessor = {
|
|
142
|
+
name = {nil, "string"},
|
|
143
|
+
age = {nil, "number"},
|
|
144
|
+
},
|
|
145
|
+
constructor = function(self, super, name, age, height, blood)
|
|
146
|
+
self.name = name
|
|
147
|
+
self.age = age
|
|
148
|
+
self.height = height
|
|
149
|
+
self.blood = blood
|
|
150
|
+
end
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
local Class<const> = myClass:new("Lenix", 20, 197, "O+")
|
|
155
|
+
Class.setHeight = function(self, new)
|
|
156
|
+
self.height = new
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
print(Class.getHeight(198))
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|