- Added Grid Layout - Removed Flexbox this will make it easy to apply layouts on all container types.
278 lines
9.6 KiB
Lua
278 lines
9.6 KiB
Lua
local function findClassName(content)
|
|
return content:match("%-%-%-@class%s+(%w+)")
|
|
end
|
|
|
|
local function findParentClass(content)
|
|
return content:match("%-%-%-@class%s+%w+%s*:%s*(%w+)")
|
|
end
|
|
|
|
local function parseProperties(content)
|
|
local properties = {}
|
|
for line in content:gmatch("[^\r\n]+") do
|
|
local name, type, default, desc = line:match("%-%-%-@property%s+(%w+)%s+(%w+)%s+(.-)%s+(.*)")
|
|
if name and type then
|
|
properties[#properties + 1] = {
|
|
name = name,
|
|
type = type,
|
|
default = default,
|
|
description = desc
|
|
}
|
|
end
|
|
end
|
|
return properties
|
|
end
|
|
|
|
local function parseCombinedProperty(content)
|
|
local combinedProperties = {}
|
|
for line in content:gmatch("[^\r\n]+") do
|
|
local name, props, desc = line:match("%-%-%-@combinedProperty%s+(%w+)%s+{(.-)%}%s+(.*)")
|
|
if name and props then
|
|
local propList = {}
|
|
for prop, typ in props:gmatch("(%w+)%s*(%w*)")do
|
|
table.insert(propList, {
|
|
name = prop,
|
|
type = typ ~= "" and typ or "any"
|
|
})
|
|
end
|
|
|
|
combinedProperties[#combinedProperties + 1] = {
|
|
name = name,
|
|
properties = propList,
|
|
description = desc
|
|
}
|
|
end
|
|
end
|
|
return combinedProperties
|
|
end
|
|
|
|
local function parseEvents(content)
|
|
local events = {}
|
|
for line in content:gmatch("[^\r\n]+") do
|
|
local name, description = line:match("%-%-%-@event%s+([%w_]+)%s+(.+)")
|
|
if name then
|
|
-- Entferne das "on" Präfix falls vorhanden
|
|
local baseName = name:match("^on(.+)") or name
|
|
-- Konvertiere erste Buchstabe zu Großbuchstaben
|
|
local functionName = "on" .. baseName:sub(1,1):upper() .. baseName:sub(2)
|
|
|
|
events[#events + 1] = {
|
|
name = name,
|
|
functionName = functionName,
|
|
description = description
|
|
}
|
|
end
|
|
end
|
|
return events
|
|
end
|
|
|
|
local function collectAllClassNames(folder)
|
|
local classes = {}
|
|
for file in io.popen('ls "' .. folder .. '"'):lines() do
|
|
if file:match("%.lua$") then
|
|
local f = io.open(folder .. "/" .. file, "r")
|
|
if f then
|
|
local content = f:read("*a")
|
|
f:close()
|
|
|
|
local className = findClassName(content)
|
|
if className and className ~= "BaseFrame" then
|
|
table.insert(classes, className)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return classes
|
|
end
|
|
|
|
local function getParentProperties(parentClass, allClasses)
|
|
local properties = {}
|
|
if parentClass then
|
|
for _, classContent in pairs(allClasses) do
|
|
if classContent.name == parentClass then
|
|
for _, prop in ipairs(classContent.properties) do
|
|
table.insert(properties, prop)
|
|
end
|
|
if classContent.parent then
|
|
local parentProps = getParentProperties(classContent.parent, allClasses)
|
|
for _, prop in ipairs(parentProps) do
|
|
table.insert(properties, prop)
|
|
end
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
return properties
|
|
end
|
|
|
|
local function generateClassContent(className, properties, combinedProperties, events, allClasses)
|
|
local parentClass = findParentClass(content)
|
|
local inheritedProps = getParentProperties(parentClass, allClasses)
|
|
for _, prop in ipairs(inheritedProps) do
|
|
table.insert(properties, prop)
|
|
end
|
|
|
|
if #properties == 0 and #events == 0 and className ~= "Container" then
|
|
return nil
|
|
end
|
|
|
|
local content = {}
|
|
table.insert(content, string.format("---@class %s", className))
|
|
|
|
for _, prop in ipairs(properties) do
|
|
table.insert(content, string.format("---@field %s %s", prop.name, prop.type))
|
|
end
|
|
|
|
table.insert(content, string.format("local %s = {}", className))
|
|
table.insert(content, "")
|
|
|
|
for _, prop in ipairs(properties) do
|
|
table.insert(content, string.format("--- Gets the %s", prop.description))
|
|
table.insert(content, string.format("---@generic Element: %s", className))
|
|
table.insert(content, "---@param self Element")
|
|
table.insert(content, string.format("---@return %s", prop.type))
|
|
table.insert(content, string.format("function %s:get%s()",
|
|
className,
|
|
prop.name:sub(1,1):upper() .. prop.name:sub(2)
|
|
))
|
|
table.insert(content, string.format(" return self.%s", prop.name))
|
|
table.insert(content, "end")
|
|
table.insert(content, "")
|
|
|
|
table.insert(content, string.format("--- Sets the %s", prop.description))
|
|
table.insert(content, string.format("---@generic Element: %s", className))
|
|
table.insert(content, "---@param self Element")
|
|
table.insert(content, string.format("---@param %s %s", prop.name, prop.type))
|
|
table.insert(content, "---@return Element")
|
|
table.insert(content, string.format("function %s:set%s(%s)",
|
|
className,
|
|
prop.name:sub(1,1):upper() .. prop.name:sub(2),
|
|
prop.name
|
|
))
|
|
table.insert(content, string.format(" self.%s = %s", prop.name, prop.name))
|
|
table.insert(content, " return self")
|
|
table.insert(content, "end")
|
|
table.insert(content, "")
|
|
end
|
|
|
|
for _, combinedProp in ipairs(combinedProperties) do
|
|
table.insert(content, string.format("--- Gets the %s", combinedProp.description))
|
|
table.insert(content, string.format("---@generic Element: %s", className))
|
|
table.insert(content, "---@param self Element")
|
|
for _, prop in ipairs(combinedProp.properties) do
|
|
table.insert(content, string.format("---@return %s %s", prop.type, prop.name))
|
|
end
|
|
table.insert(content, string.format("function %s:get%s()",
|
|
className,
|
|
combinedProp.name:sub(1,1):upper() .. combinedProp.name:sub(2)
|
|
))
|
|
local returnValues = {}
|
|
for _, prop in ipairs(combinedProp.properties) do
|
|
table.insert(returnValues, "self." .. prop.name)
|
|
end
|
|
table.insert(content, string.format(" return %s", table.concat(returnValues, ", ")))
|
|
table.insert(content, "end")
|
|
table.insert(content, "")
|
|
|
|
table.insert(content, string.format("--- Sets the %s", combinedProp.description))
|
|
table.insert(content, string.format("---@generic Element: %s", className))
|
|
table.insert(content, "---@param self Element")
|
|
for _, prop in ipairs(combinedProp.properties) do
|
|
table.insert(content, string.format("---@param %s %s", prop.name, prop.type))
|
|
end
|
|
table.insert(content, "---@return Element")
|
|
|
|
local params = {}
|
|
for _, prop in ipairs(combinedProp.properties) do
|
|
table.insert(params, prop.name)
|
|
end
|
|
table.insert(content, string.format("function %s:set%s(%s)",
|
|
className,
|
|
combinedProp.name:sub(1,1):upper() .. combinedProp.name:sub(2),
|
|
table.concat(params, ", ")
|
|
))
|
|
|
|
for _, prop in ipairs(combinedProp.properties) do
|
|
table.insert(content, string.format(" self.%s = %s", prop.name, prop.name))
|
|
end
|
|
table.insert(content, " return self")
|
|
table.insert(content, "end")
|
|
table.insert(content, "")
|
|
end
|
|
|
|
for _, event in ipairs(events) do
|
|
table.insert(content, string.format([[
|
|
--- %s
|
|
---@generic Element: %s
|
|
---@param self Element
|
|
---@param callback function
|
|
---@return Element
|
|
function %s:%s(callback)
|
|
return self
|
|
end]], event.description, className, className, event.functionName))
|
|
table.insert(content, "")
|
|
end
|
|
|
|
if className == "Container" then
|
|
for _, cls in ipairs(allClasses) do
|
|
table.insert(content, string.format([[
|
|
--- Adds a new %s to the container
|
|
---@generic Element: Container
|
|
---@param self Element
|
|
---@return %s
|
|
function Container:add%s()
|
|
return self
|
|
end
|
|
|
|
--- Adds a new delayed %s to the container
|
|
---@generic Element: Container
|
|
---@param self Element
|
|
---@return %s
|
|
function Container:addDelayed%s()
|
|
return self
|
|
end]], cls, cls, cls, cls, cls, cls))
|
|
table.insert(content, "")
|
|
end
|
|
end
|
|
|
|
return table.concat(content, "\n")
|
|
end
|
|
|
|
local function parseFolder(folder, destinationFile)
|
|
local allClasses = collectAllClassNames(folder)
|
|
local allContent = {}
|
|
|
|
for file in io.popen('ls "' .. folder .. '"'):lines() do
|
|
if file:match("%.lua$") then
|
|
local f = io.open(folder .. "/" .. file, "r")
|
|
if f then
|
|
local content = f:read("*a")
|
|
f:close()
|
|
|
|
local className = findClassName(content)
|
|
if className then
|
|
local properties = parseProperties(content)
|
|
local combinedProperties = parseCombinedProperty(content)
|
|
local events = parseEvents(content)
|
|
local classContent = generateClassContent(className, properties, combinedProperties, events, allClasses)
|
|
if classContent then
|
|
table.insert(allContent, classContent)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local f = io.open(destinationFile, "w")
|
|
if f then
|
|
f:write(table.concat(allContent, "\n\n"))
|
|
f:close()
|
|
end
|
|
end
|
|
|
|
local args = {...}
|
|
if #args == 2 then
|
|
parseFolder(args[1], args[2])
|
|
else
|
|
print("Usage: annotationParser <sourceFolder> <destinationFile>")
|
|
end |