diff --git a/init.lua b/init.lua index 2930f0c..bca5386 100644 --- a/init.lua +++ b/init.lua @@ -3,18 +3,35 @@ local M = {} -- Extracts public/private surface from Lua source code. --- Convention: `M. = function(...)` is public; `M._ = ...` is private. +-- Convention: M. public; M._ private. +-- Supports both explicit assignment (`M.foo = function`) and syntax sugar +-- (`function M.foo`) — Lua treats them semantically identical. -- Returns: { public = ["foo","bar",...], private = ["_baz",...] } function M.parse_lua_surface(source_string) local public = {} local private = {} - for name in string.gmatch(source_string, "M%.([_%w]+)%s*=%s*function") do + local seen = {} + + local function classify(name) + if seen[name] then return end + seen[name] = true if string.sub(name, 1, 1) == "_" then table.insert(private, name) else table.insert(public, name) end end + + -- Form 1: M.foo = function(...) + for name in string.gmatch(source_string, "M%.([_%w]+)%s*=%s*function") do + classify(name) + end + + -- Form 2: function M.foo(...) + for name in string.gmatch(source_string, "function%s+M%.([_%w]+)") do + classify(name) + end + return { public = public, private = private } end