Browse Source

typescript: support array and union types in generated bindings

Kira Boom 3 weeks ago
parent
commit
446ed23ad7
1 changed files with 37 additions and 7 deletions
  1. 37 7
      api/generators/typescript.lua

+ 37 - 7
api/generators/typescript.lua

@@ -23,7 +23,7 @@
 -- - lovr.graphics.getDevice() more specific return value and documentation
 -- - lovr.graphics.getDevice() more specific return value and documentation
 --   (available in .table field of return value)
 --   (available in .table field of return value)
 -- - global vector constructors documentation
 -- - global vector constructors documentation
--- - LuaTable specializations (e.g. arrays)
+-- - LuaTable specializations
 -- - enet
 -- - enet
 -- - http
 -- - http
 --
 --
@@ -264,21 +264,32 @@ return function (api)
     lightuserdata = 'any',
     lightuserdata = 'any',
     ['function'] = '(this: void, ...args: any[]) => any',
     ['function'] = '(this: void, ...args: any[]) => any',
     ['*'] = 'any',
     ['*'] = 'any',
-    ['Object'] = 'LovrObject'
+    ['Object'] = 'LovrObject',
+    ['nil'] = 'undefined'
   }
   }
 
 
   local convert_type
   local convert_type
 
 
   local function convert_table (table_fields)
   local function convert_table (table_fields)
     local result = '{ '
     local result = '{ '
-    for _, field in ipairs (table_fields) do
+    for i, field in ipairs (table_fields) do
       local optional = field.default and '?' or ''
       local optional = field.default and '?' or ''
-      result = result .. field.name .. optional .. ': ' .. convert_type(field.type, field.table) .. ', '
+      result = result .. field.name .. optional .. ': ' .. convert_type(field.type, field.table)
+      if i < #table_fields then
+        result = result .. ', '
+      end
     end
     end
     return result .. '}'
     return result .. '}'
   end
   end
 
 
-  function convert_type (t, table_fields)
+  local function make_array_type(t)
+    if t:match '|' then
+      t = '(' .. t .. ')'
+    end
+    return t .. '[]'
+  end
+
+  local function convert_individual_type (t, table_fields)
     if t == 'table' and table_fields then
     if t == 'table' and table_fields then
       return convert_table (table_fields)
       return convert_table (table_fields)
     else
     else
@@ -286,6 +297,25 @@ return function (api)
     end
     end
   end
   end
 
 
+  function convert_type(t, table_fields)
+    t = t:match('^%s*(.-)%s*$')
+    local array_pattern = '^{(.*)}$'
+    if t:match(array_pattern) then
+      local inner = t:match(array_pattern)
+      local converted = convert_type(inner)
+      return make_array_type(converted)
+    elseif t:match('|') then
+      local result
+      for subtype in t:gmatch('[^|]+') do
+        result = result and (result .. ' | ') or ''
+        result = result .. convert_type(subtype)
+      end
+      return result
+    else
+      return convert_individual_type(t, table_fields)
+    end
+  end
+
   local name_map = {
   local name_map = {
     ['*'] = 'rest',
     ['*'] = 'rest',
   }
   }
@@ -303,7 +333,7 @@ return function (api)
       if name == '...' then
       if name == '...' then
         name = name .. 'rest'
         name = name .. 'rest'
       end
       end
-      t = t .. '[]'
+      t = make_array_type(t)
     end
     end
     return name .. (optional and '?' or '') .. ': ' .. t
     return name .. (optional and '?' or '') .. ': ' .. t
   end
   end
@@ -321,7 +351,7 @@ return function (api)
           if name == '...' then
           if name == '...' then
             name = '...rest'
             name = '...rest'
           end
           end
-          t = t .. '[]'
+          t = make_array_type(t)
         end
         end
         ret = ret .. name .. ': ' .. t
         ret = ret .. name .. ': ' .. t
         if n < #returns then
         if n < #returns then