lenix 1.3.3 → 1.3.4
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/lua/LICENSE +21 -0
- package/lua/src/_dev/firstAttempt.lua +202 -0
- package/lua/src/_dev/secondAttempt.lua +166 -0
- package/lua/src/_dev/tests.lua +298 -0
- package/lua/src/index.lua +322 -0
- package/lua/src/lenix-0.1.0-1.rockspec +25 -0
- package/package.json +3 -3
- package/lint/src/lint-preset.json +0 -370
- package/lint/src/lint.mts +0 -322
- package/lint/src/tsconfig.json +0 -10
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
assert(_VERSION == "Lua 5.4", "THIS MODULE REQUIRES Lua 5.4")
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
---@alias MemberKey string | "get" | "set" | "constructor"
|
|
5
|
+
---@alias Member ShorthandedMemberValue | MemberEntries | Getter | Setter | Constructor
|
|
6
|
+
---@alias ShorthandedMemberValue number | string | boolean | fun(self: unknown, ...: unknown): unknown?
|
|
7
|
+
---@alias MemberEntries {[1]: MemberValue, [2]?: MemberFlag, [3]?: MemberFlag, [4]?: MemberFlag, [5]?: MemberFlag, [6]?: MemberFlag}
|
|
8
|
+
---@alias MemberValue number | string | boolean | table | nil | fun(self: unknown, ...: unknown): unknown
|
|
9
|
+
---@alias MemberFlag boolean | nil
|
|
10
|
+
---@alias Getter fun(self: unknown): unknown
|
|
11
|
+
---@alias Setter fun(self: unknown, value: unknown): nil
|
|
12
|
+
---@alias Constructor fun(self: unknown, super: fun(...: any): unknown, ...: unknown): unknown
|
|
13
|
+
---@alias Members table<string, PropertyFlags>
|
|
14
|
+
---@alias MembersValues table<string, MemberValue>
|
|
15
|
+
---@alias RawMembers table<MemberKey, Member>
|
|
16
|
+
|
|
17
|
+
---@class PropertyFlags
|
|
18
|
+
---@field private MemberFlag
|
|
19
|
+
---@field static MemberFlag
|
|
20
|
+
---@field final MemberFlag
|
|
21
|
+
---@field virtual MemberFlag
|
|
22
|
+
---@field override MemberFlag
|
|
23
|
+
|
|
24
|
+
---@param Members RawMembers
|
|
25
|
+
---@param Parent? unknown
|
|
26
|
+
local class<const> = function (Members, Parent)
|
|
27
|
+
---@type Members
|
|
28
|
+
local members<const> = {}
|
|
29
|
+
---@type MembersValues
|
|
30
|
+
local membersValues<const> = {}
|
|
31
|
+
local default<const> = function(existingValue, defaultValue)
|
|
32
|
+
if existingValue ~= nil then
|
|
33
|
+
return existingValue
|
|
34
|
+
else return defaultValue end
|
|
35
|
+
end
|
|
36
|
+
---@type table<string, Getter>
|
|
37
|
+
local getters<const> = {}
|
|
38
|
+
---@type table<string, Setter>
|
|
39
|
+
local setters<const> = {}
|
|
40
|
+
|
|
41
|
+
for memberKey, member in pairs(Members) do
|
|
42
|
+
assert(member ~= nil, ("syntax error: expected member, got `%s`"):format(type(member)))
|
|
43
|
+
if memberKey == "constructor" then
|
|
44
|
+
if type(member) ~= "function" then error(("syntax error: constructor expected `function`, got `%s`"):format(type(member))) end
|
|
45
|
+
elseif memberKey == "get" then
|
|
46
|
+
if type(member) ~= "table" then error(("syntax error: get expected `table`, got `%s`"):format(type(member))) end
|
|
47
|
+
---@cast member table<string, Getter>
|
|
48
|
+
for getterKey, getter in pairs(member) do
|
|
49
|
+
if type(getter) ~= "function" then error(("syntax error: the getters(`%s`) can be only a `function`, got `%s`"):format(getterKey, type(getter))) end
|
|
50
|
+
local getterInfo<const> = debug.getinfo(getter, "u")
|
|
51
|
+
if getterInfo.nparams ~= 1 then error(("syntax error: the getters(`%s`) can not have parameters (excluding `self`)"):format(getterKey)) end
|
|
52
|
+
getters[getterKey] = getter
|
|
53
|
+
end
|
|
54
|
+
elseif memberKey == "set" then
|
|
55
|
+
if type(member) ~= "table" then error(("syntax error: set expected `table`, got `%s`"):format(type(member))) end
|
|
56
|
+
---@cast member table<string, Setter>
|
|
57
|
+
for setterKey, setter in pairs(member) do
|
|
58
|
+
if type(setter) ~= "function" then error(("syntax error: the setters(`%s`) can be only a `function`, got `%s`"):format(setterKey, type(setter))) end
|
|
59
|
+
local getterInfo<const> = debug.getinfo(setter, "u")
|
|
60
|
+
if getterInfo.nparams ~= 2 then error(("syntax error: the setters(`%s`) must have exactly one parameter (excluding `self`)"):format(setterKey)) end
|
|
61
|
+
setters[setterKey] = setter
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
members[memberKey] = {}
|
|
65
|
+
if type(member) == "table" then
|
|
66
|
+
membersValues[memberKey] = member[1]
|
|
67
|
+
members[memberKey] = {
|
|
68
|
+
private = default(member[2], true),
|
|
69
|
+
static = default(member[3], false),
|
|
70
|
+
final = default(member[4], false),
|
|
71
|
+
virtual = default(member[5], false),
|
|
72
|
+
override = default(member[6], true),
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
membersValues[memberKey] = member
|
|
76
|
+
members[memberKey] = {
|
|
77
|
+
private = true,
|
|
78
|
+
static = false,
|
|
79
|
+
final = true,
|
|
80
|
+
virtual = false,
|
|
81
|
+
override = false,
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
for memberKey, member in pairs(members) do
|
|
88
|
+
if member.override then
|
|
89
|
+
if not Parent or not Parent.__extended then
|
|
90
|
+
error(("cannot override `%s`: no parent class was derived"):format(memberKey))
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
local parentMember<const> = Parent.__extended.members[memberKey]
|
|
94
|
+
if not parentMember then
|
|
95
|
+
error(("override failed: no such `%s` parent method"):format(memberKey))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if not parentMember.virtual then
|
|
99
|
+
error(("override denied: the parent method `%s` is not virtual"):format(memberKey))
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if Parent and Parent.__extended then
|
|
105
|
+
for memberKey, member in pairs(Parent.__extended.members) do
|
|
106
|
+
if not members[memberKey] then
|
|
107
|
+
members[memberKey] = member
|
|
108
|
+
membersValues[memberKey] = Parent.__extended.membersValues[memberKey]
|
|
109
|
+
else
|
|
110
|
+
if not members[memberKey].override then
|
|
111
|
+
error(("method `%s` already exists in parent, did you mean to use the override flag"):format(memberKey))
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
for getterKey, getter in pairs(Parent.__extended.getters) do
|
|
117
|
+
if not getters[getterKey] then
|
|
118
|
+
getters[getterKey] = getter
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
for setterKey, setter in pairs(Parent.__extended.setters) do
|
|
123
|
+
if not setters[setterKey] then
|
|
124
|
+
setters[setterKey] = setter
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
return setmetatable({
|
|
130
|
+
__extended = {
|
|
131
|
+
members = members,
|
|
132
|
+
membersValues = membersValues,
|
|
133
|
+
getters = getters,
|
|
134
|
+
setters = setters
|
|
135
|
+
},
|
|
136
|
+
new = function(self, ...)
|
|
137
|
+
---@type MembersValues
|
|
138
|
+
local instance<const> = {}
|
|
139
|
+
for memberKey, member in pairs(members) do
|
|
140
|
+
if not member.static then
|
|
141
|
+
instance[memberKey] = membersValues[memberKey]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
if Members.constructor and not Parent then
|
|
146
|
+
Members.constructor(instance, nil, ...)
|
|
147
|
+
elseif Members.constructor and Parent then
|
|
148
|
+
local super<const> = function(...)
|
|
149
|
+
local parentInstance<const> = Parent:new(...)
|
|
150
|
+
|
|
151
|
+
local parentMetatable<const> = debug.getmetatable(parentInstance)
|
|
152
|
+
if parentMetatable and parentMetatable.__instance then
|
|
153
|
+
for memberKey, memberValue in pairs(parentMetatable.__instance) do
|
|
154
|
+
local parentMember<const> = Parent.__extended.members[memberKey]
|
|
155
|
+
if members[memberKey] and members[memberKey].override then
|
|
156
|
+
elseif parentMember and not parentMember.private then
|
|
157
|
+
instance[memberKey] = memberValue
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
return parentInstance
|
|
163
|
+
end
|
|
164
|
+
Members.constructor(instance, super, ...)
|
|
165
|
+
else error("no constructor was provided") end
|
|
166
|
+
|
|
167
|
+
for memberKey, member in pairs(members) do
|
|
168
|
+
if not instance[memberKey] and not member.static and not member.private then
|
|
169
|
+
error(("the `%s` was not instantiated in constructor"):format(memberKey))
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if Parent and Parent.__extended then
|
|
174
|
+
for memberKey, member in pairs(Parent.__extended.members) do
|
|
175
|
+
if not instance[memberKey] and not member.static and not member.private then
|
|
176
|
+
error(("derived member `%s` was not instantiated"):format(memberKey))
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
return setmetatable({}, {
|
|
182
|
+
__metatable = "access denied",
|
|
183
|
+
__instance = instance,
|
|
184
|
+
__index = function(_, memberKey)
|
|
185
|
+
local member<const> = members[memberKey]
|
|
186
|
+
if not member then
|
|
187
|
+
if getters[memberKey] then
|
|
188
|
+
return getters[memberKey](instance)
|
|
189
|
+
elseif Parent and Parent.__extended then
|
|
190
|
+
local parentMember<const> = Parent.__extended.members[memberKey]
|
|
191
|
+
if parentMember then
|
|
192
|
+
if parentMember.private then
|
|
193
|
+
error(("`%s` is not a public member"):format(memberKey))
|
|
194
|
+
end
|
|
195
|
+
return instance[memberKey]
|
|
196
|
+
end
|
|
197
|
+
elseif setters[memberKey] then
|
|
198
|
+
error(("`%s` setter can not be accessed"):format(memberKey))
|
|
199
|
+
end
|
|
200
|
+
error(("`%s` does not exist"):format(memberKey))
|
|
201
|
+
end
|
|
202
|
+
assert(not member.private, ("`%s` is not a public member"):format(memberKey))
|
|
203
|
+
assert(not member.static, ("`%s` is a static member"):format(memberKey))
|
|
204
|
+
|
|
205
|
+
local value<const> = instance[memberKey]
|
|
206
|
+
if type(value) == "function" then
|
|
207
|
+
return function(_, ...)
|
|
208
|
+
return value(instance, ...)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
return value
|
|
213
|
+
end,
|
|
214
|
+
__newindex = function(_, memberKey, memberValue)
|
|
215
|
+
if setters[memberKey] then
|
|
216
|
+
setters[memberKey](instance, memberValue)
|
|
217
|
+
return
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
local member = members[memberKey]
|
|
221
|
+
|
|
222
|
+
if not member and Parent and Parent.__extended then
|
|
223
|
+
member = Parent.__extended.members[memberKey]
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
if not member then
|
|
227
|
+
if getters[memberKey] then
|
|
228
|
+
error(("getters can not be modified: at `%s`"):format(memberKey))
|
|
229
|
+
end
|
|
230
|
+
error(("`%s` does not exist"):format(memberKey))
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
assert(not member.private, ("`%s` is not a public member"):format(memberKey))
|
|
234
|
+
assert(not member.static, ("`%s` is a static member"):format(memberKey))
|
|
235
|
+
assert(not member.final, ("`%s` is a readonly member"):format(memberKey))
|
|
236
|
+
|
|
237
|
+
instance[memberKey] = memberValue
|
|
238
|
+
end
|
|
239
|
+
})
|
|
240
|
+
end
|
|
241
|
+
}, {
|
|
242
|
+
__metatable = "access denied",
|
|
243
|
+
__index = function(self, memberKey)
|
|
244
|
+
local member<const> = members[memberKey]
|
|
245
|
+
if not member then
|
|
246
|
+
if getters[memberKey] then
|
|
247
|
+
return getters[memberKey](membersValues)
|
|
248
|
+
elseif Parent then
|
|
249
|
+
return Parent[memberKey]
|
|
250
|
+
elseif setters[memberKey] then
|
|
251
|
+
error(("setters can not be accessed: at `%s`"):format(memberKey))
|
|
252
|
+
end
|
|
253
|
+
error(("`%s` does not exist"):format(memberKey))
|
|
254
|
+
end
|
|
255
|
+
assert(not member.private, ("`%s` is not a public member"):format(memberKey))
|
|
256
|
+
assert(member.static, ("`%s` is not a static member"):format(memberKey))
|
|
257
|
+
local value<const> = membersValues[memberKey]
|
|
258
|
+
|
|
259
|
+
if type(value) == "function" then
|
|
260
|
+
return function(...)
|
|
261
|
+
return value(membersValues, ...)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
return value
|
|
266
|
+
end,
|
|
267
|
+
__newindex = function(self, memberKey, memberValue)
|
|
268
|
+
local member<const> = members[memberKey]
|
|
269
|
+
if not member then
|
|
270
|
+
if setters[memberKey] then
|
|
271
|
+
setters[memberKey](membersValues, memberValue)
|
|
272
|
+
return
|
|
273
|
+
elseif Parent then
|
|
274
|
+
Parent[memberKey] = memberValue
|
|
275
|
+
return
|
|
276
|
+
elseif getters[memberKey] then
|
|
277
|
+
error(("getters can not be modified: at `%s`"):format(memberKey))
|
|
278
|
+
end
|
|
279
|
+
error(("`%s` does not exist"):format(memberKey))
|
|
280
|
+
end
|
|
281
|
+
assert(not member.private, ("`%s` is not a public member"):format(memberKey))
|
|
282
|
+
assert(member.static, ("`%s` is not a static member"):format(memberKey))
|
|
283
|
+
assert(not member.final, ("`%s` is a readonly member"):format(memberKey))
|
|
284
|
+
membersValues[memberKey] = memberValue
|
|
285
|
+
end
|
|
286
|
+
})
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
-- annotation tests section
|
|
291
|
+
local private<const>, static<const>, final<const>, virtual<const>, override<const> = true, true, true, true, true
|
|
292
|
+
class({
|
|
293
|
+
property1 = 10,
|
|
294
|
+
property4 = {10},
|
|
295
|
+
property7 = {10, private, false, final, false, override},
|
|
296
|
+
property2 = "hello",
|
|
297
|
+
property5 = {"hello"},
|
|
298
|
+
property8 = {"hello", false, static, false, virtual, false},
|
|
299
|
+
property3 = true,
|
|
300
|
+
property6 = {true},
|
|
301
|
+
property9 = {true, private, false, final, false, override},
|
|
302
|
+
property10 = nil, -- SYNTAX ERROR
|
|
303
|
+
property11 = {nil},
|
|
304
|
+
property12 = {nil, false, static, false, virtual, false},
|
|
305
|
+
method1 = function(self) end,
|
|
306
|
+
method2 = {function(self) end},
|
|
307
|
+
method3 = {function(self) end, private, false, final, false, override},
|
|
308
|
+
get = {
|
|
309
|
+
getter1 = function(self)
|
|
310
|
+
return self.property1
|
|
311
|
+
end,
|
|
312
|
+
},
|
|
313
|
+
set = {
|
|
314
|
+
setter1 = function(self, value)
|
|
315
|
+
self.property1 = value
|
|
316
|
+
end,
|
|
317
|
+
},
|
|
318
|
+
constructor = function(self, super, value)
|
|
319
|
+
super(value)
|
|
320
|
+
self.property1 = value
|
|
321
|
+
end
|
|
322
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package = "lenix"
|
|
2
|
+
version = "0.1.0-1"
|
|
3
|
+
|
|
4
|
+
source = {
|
|
5
|
+
url = "git+https://github.com/lenixdev/lenix.git",
|
|
6
|
+
tag = "v0.1.0"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
description = {
|
|
10
|
+
summary = "Lua OOP class module similar to TypeScript/JavaScript/Java/C++ classes",
|
|
11
|
+
detailed = "Lua object oriented programming class module with support for constructors, getters, setters, inheritance, static members, private members, final members, and virtual/override methods.",
|
|
12
|
+
homepage = "https://github.com/lenixdev/lenix/lua",
|
|
13
|
+
license = "MIT"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
dependencies = {
|
|
17
|
+
"lua == 5.4"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
build = {
|
|
21
|
+
type = "builtin",
|
|
22
|
+
modules = {
|
|
23
|
+
lenix = "index.lua"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lenix",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "The Monorepo for the software engineering community",
|
|
5
5
|
"author": "Lenix",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"ts/dist",
|
|
34
|
-
"lua
|
|
35
|
-
"lint"
|
|
34
|
+
"lua",
|
|
35
|
+
"lint/dist"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@eslint/js": "^10.0.1",
|