Lua completions: __stub.lua is not valid Lua

I'm trying to build something which leverages __stub.lua and I ran into a handful of issues:

  1. Some lines are invalid Lua code: for example positional parameters are stubbed with names that are invalid identifiers, either with invalid characters ("-"), as reserved keywords (repeat, function, end):
104 function playdate.graphics.sprite.setBounds(upper-left-x, upper-left-y, width, height) end
296 function playdate.graphics.perlin(x, y, z, repeat, octaves, persistence) end
297 function playdate.graphics.perlinArray(count, x, dx, y, dy, z, dz, repeat, octaves, persistence) end
573 function playdate.sound.fileplayer.setLoopRange(start, end, loopCallback, arg) end
622 function playdate.sound.synth.setFinishCallback(function) end
650 function playdate.sound.envelope.setRateScaling(scaling, start, end) end

And setStencilPattern confuses a calling convention with the signature resulting in an invalid statement.

306 function playdate.graphics.setStencilPattern({ row1, row2, row3, row4, row5, row6, row7, row8 }) end
  1. Some function signatures have duplicated portions, for example 13 instances of "playdate.playdate.*" and others have missing/duplicated parts:
697 function playdate.sound.delayline.addTap(delay)(delay) end
698 function playdate.sound.delayline.setFeedback(level)(level) end
704 function playdate.sound.delaylinetap.setFlipChannels(flag)(flag) end
606 function playdate.sound.synth.new.waveform(waveform) end
607 function playdate.sound.synth.new.sample(sample, sustainStart, sustainEnd) end

playdate.crankIndicator.* (should be pladyate.ui.crankIndicator.*)
playdate.geometry.lineSegment.fast.intersection (should be fast_intersection)
playdate.gridView.* (should be playdate.ui.gridview)
playdate.gridview.* (should be playdate.ui.gridView and fix camelCase)
playdate.sound.synth.new.{waveform,sample} (should be playdate.sound.synth.new(...))
playdate.where (should be where())
playdate.printTable (should be printTable)
  1. Multiple issues with setSencialPattern. First playdate.graphics.sprite:setStencilPattern shows up as playdate.graphics.setStencilPattern You can see it wrong in the html docs too. (doc link). Also the stub mentioned above should be something like setStencilPattern(rowTable).

  2. Nearly all constructors are absent (e.g. notice __stub.lua has no rect.new, sprite.new, image.new, etc) and some are duplicated under the wrong name (playdate.timer.new2, playdate.graphics.animator.new1-5).

  3. Some (not all) of the playdate sub-namespaces are stubbed out as functions, which is incorrect. For example playdate.graphics is not a function and has things under its namespace and so should not have a stubbed function itself.

Which leads me my following suggestion: If you fix all the above issues __stub.lua becomes valid lua in the presence of a playdate global table including all the sub-namespaces. So you could add a test to your CI that would catch invalid identifiers or namespace typos introduced in the future:

lua -e 'playdate = {
    datastore={},
    display={},
    easingFunctions={},
    inputHandlers={},
    file={file={}},
    geometry={affineTransform={},arc={},lineSegment={},point={},polygon={},rect={},size={},vector2D={}},
    graphics={image={},imagetable={},sprite={},tilemap={},nineSlice={},animation={blinker={},loop={}},animator={},font={},video={}},
    keyboard={},
    math={},
    menu={item={}},
    pathfinder={graph={},node={}},
    simulator={},
    sound={sampleplayer={},fileplayer={},sample={},channel={},synth={},signal={},lfo={},envelope={},bitcrusher={},ringmod={},onepolefilter={},twopolefilter={},overdrive={},delayline={},delaylinetap={},sequence={},track={},instrument={},controlsignal={},micinput={}},
    string={},
    timer={},
    frameTimer={},
    ui={crankIndicator={},gridview={}},
}
table={}
json={}' ~/Developer/PlaydateSDK/CoreLibs/__stub.lua
  1. The signatures for all instance methods are incorrect. They should either use a colon or have self listed as the first parameter:
BAD: playdate.graphics.image.getSize()
 OK: playdate.graphics.image.getSize(self)
 OK: playdate.graphics.image:getSize()

As always, thanks for creating a truly great SDK! It's very much a pleasure to work with. :raised_hands:

2 Likes

Thank you for the detailed notes! I'll get this filed so we can take a look at getting your fixes integrated.

3 Likes

@notpeter Here's a new stub file with your corrections included. Can you let me know if it's good enough?

__stub.lua.zip (7.3 KB)

3 Likes

Thanks @james! I very much appreciate this and it's now compatible with my tooling. What you've done is a massive improvement.

Here's a couple more minor errors I noticed in your attached file:

-- 1. should be print not playdate.print; also probably print(...)
function playdate.print(string) end

-- 2. should be json.* not playdate.json.*
function playdate.json.decode(string) end
function playdate.json.encode(table) end
function playdate.json.encodePretty(table) end

-- 3. Should include a ... as last parameter:
function playdate.sound.lfo:setArpeggio(note1) end
function playdate.timer.new(duration, callback) end
function playdate.timer.performAfterDelay(delay, callback) end
function playdate.timer.keyRepeatTimer(callback) end
function playdate.timer.keyRepeatTimerWithDelay(delayAfterInitialFiring, delayAfterSecondFiring, callback) end

The last thing I wanted to point out is that class variables and instance variables:

function playdate.argv() end
function playdate.keyboard.text() end
function playdate.isSimulator() end
function playdate.ui.crankIndicator.clockwise() end
-- [snip] Many more too: playdate.timer.*, playdate.frameTimer.*, etc

Are incorrectly stubbed as functions. They are harmless for me and I don't have a great suggestion for how best to document them, but just figured I'd mention it before I forgot.

Thanks again for tackling this. Yes this is good enough. :smiley:

Morning @james. I've been taking a slightly different angle on this where I'm directly scraping the documentation to generate something like __stub.lua. This has way fewer errors.

Instead of having to create comments where I explain issues I found instead I generated a "more correct" stub file which I think should help y'all fix the typos in your asciidoc source material.

I only included functions (excluding public variables) but can generate the same file with playdate.variable = nil style variable placeholders if you prefer.

Yours: __stub.lua.zip (7.3 KB)
Mine: __stub.lua_notpeter.lua.zip (8.1 KB)
Diff : Side-by-side diff on GitHub.

I'm hoping this will make it easier fix the inconsistencies and converge on "more correct" stubs.

Thanks!

3 Likes

i noticed the class variables incorrectly stubbed as functions (playdate.graphics was styled in visual studio code like a function instead of like a variable) and it seems like it might be fixable by doing something like

playdate.graphics = nil

instead of function playdate.graphics() end.

i tried this and playdate.graphics was syntax highlighted as a class variable and showed up in intellisense, although there might be some problem i'm not aware of.

edit: looks like i forgot to read things and it seems like you figured this out already sorry

I'm directly scraping the documentation to generate something like __stub.lua. This has way fewer errors.

I've taken a similar approach, but I'm generating Lua annotations instead of stubs: Lua type annotation file for the SDK

Still waiting for permission to share it.