wurstscript / WurstScript

Programming language and toolkit to create Warcraft III Maps
https://wurstlang.org
Apache License 2.0
225 stars 30 forks source link

Error in File compiled.j.txt line 2743: This is a bug in the Wurst Compiler. Please Report it. Pjass has found the following problem: Missing return #765

Closed Cokemonkey11 closed 5 years ago

Cokemonkey11 commented 5 years ago

image

map script:

https://bin.wurstlang.org/urulofoqoj.wurst

https://bin.wurstlang.org/axinepazow.wurst

https://bin.wurstlang.org/xiyuhelemi.wurst

Cokemonkey11 commented 5 years ago

And languageServer.log: https://bin.wurstlang.org/unekiyuyut.wurst

Cokemonkey11 commented 5 years ago

If you comment out these last lines it starts working:

    // doPeriodically(ANIMATION_PERIOD) cb ->
    //     let clean_queue = new LinkedList<UnitEffect>()
    //     for fx_pair in circles
    //         if fx_pair.u.getTypeId() != 0 and fx_pair.u.isAlive()
    //             fx_pair.fx.setPos(fx_pair.u.getPos())
    //         else
    //             clean_queue.add(fx_pair)

    //     clean_queue.forEach() itr ->
    //         circles.remove(itr)
    //         destroy itr
Cokemonkey11 commented 5 years ago

This issue seems to exist because of my implementation of ClosureTimersFork::CallbackSingle::setupDialogCallback

public abstract class SingleDialogUpdateFn
    protected abstract function call(CallbackSingle cb) returns dialog_update_fn_res

public abstract class CallbackSingle
    private timer t
    abstract function call()
    private SingleDialogUpdateFn update_fn = null
    private timerdialog dialg = null

    function start(real time)
        t = getTimer()
            ..setData(this castTo int)
            ..start(time, () -> staticCallback())

    private static function staticCallback()
        timer t = GetExpiredTimer()
        thistype cb = t.getData() castTo thistype
        cb.call()
        destroy cb

    function setupDialogCallback(SingleDialogUpdateFn update_fn)
        this.update_fn = update_fn
        this.dialg = CreateTimerDialog(this.t)
        let update_result = update_fn.call(this)
        TimerDialogDisplay(this.dialg, update_result.display)
        TimerDialogSetTitle(this.dialg, update_result.name)

    ondestroy
        t.release()
        if this.update_fn != null
            TimerDialogDisplay(this.dialg, false)
            DestroyTimerDialog(this.dialg)
            destroy this.update_fn

If I use doPeriodicallyTimed(z, 1) instead of doAfter(z), the issue goes away