uqbar-project / wollok

Wollok Programming Language
GNU General Public License v3.0
60 stars 16 forks source link

NullPointerException when instantiating an exception with a message #644

Closed fdodino closed 8 years ago

fdodino commented 8 years ago

Steps to reproduce it. Create a Wollok Object:

class UserException inherits wollok.lang.Exception {
    constructor(mensaje) {
        super(mensaje)
    }
}

object monedero {
    var plata = 500

    method plata() = return plata

    method poner(cantidad) {
        if (cantidad < 0) {
            throw new UserException("La cantidad debe ser positiva")
        } 
        plata += cantidad
    }

    method sacar(cantidad) { plata -= cantidad }
}

Then start a REPL console and type:

monedero.poner(-2)

you get

monedero.poner(-2)     WVM Error in line  (1): monedero.poner(-2):
          WVM Error in line  (10): {
        if (cantidad < 0) {
            throw new UserException("La cantidad debe ser positiva")
        } 
        plata += cantidad
    }:
                WVM Error in line  (11): if (cantidad < 0) {
            throw new UserException("La cantidad debe ser positiva")
        }:
                    WVM Error in line  (11): {
            throw new UserException("La cantidad debe ser positiva")
        }:
WVM Error in line  (12): throw new UserException("La cantidad debe ser positiva"):
                         WVM Error in line  (12): new UserException("La cantidad debe ser positiva"):
WVM Error in line  (1): super(mensaje):
java.lang.NullPointerException
    at org.uqbar.project.wollok.model.WMethodContainerExtensions._feature(WMethodContainerExtensions.java:864)
    at org.uqbar.project.wollok.model.WMethodContainerExtensions.feature(WMethodContainerExtensions.java:1199)
    at org.uqbar.project.wollok.interpreter.WollokInterpreterEvaluator._evaluate(WollokInterpreterEvaluator.java:809)
    at org.uqbar.project.wollok.launch.WollokLauncherInterpreterEvaluator.evaluate(WollokLauncherInterpreterEvaluator.java:210)
    at org.uqbar.project.wollok.interpreter.WollokInterpreterEvaluator.evaluate(WollokInterpreterEvaluator.java:1)
    at org.uqbar.project.wollok.interpreter.WollokInterpreter.eval(WollokInterpreter.java:236)
    at org.uqbar.project.wollok.interpreter.WollokInterpreterEvaluator.eval(WollokInterpreterEvaluator.java:131)
fdodino commented 8 years ago

Problem is here:

class UserException inherits wollok.lang.Exception {
    constructor(mensaje) {
        super(mensaje)
    }
}

If I do

class UserException inherits wollok.lang.Exception {
    constructor(mensaje) = super(mensaje)
}

problem is solved. But I should be able to write it both ways.

matifreyre commented 8 years ago

I'm not sure how it should behave, but I'm sure that those 2 syntaxes are not exactly equivalent. The second one has an implicit return, the first one doesn't. In order to be exactly equivalent, it should be:

class UserException inherits wollok.lang.Exception {
    constructor(mensaje) {
        return super(mensaje)
    }
}
fdodino commented 8 years ago

Ok, but you cannot define a return inside a constructor, otherwise you get an error: "you cannot return a value in constructor"

fdodino commented 8 years ago

Nice-to-have: I would prefer not to redefine the constructor,if I can inherit it from Exception. But it doesn't work, I get "Wrong number of arguments. Should be new UserException"

javierfernandes commented 8 years ago

They are not the same. Wollok doesn't have constructor delegation as part of the constructor's body. This shouldn't compile

constructor(mensaje) {
        super(mensaje)
    }

There's only one way to delegate and it is outside the body, before it, and after a = symbol

constructor(mensaje) = super(mensaje) {
   ...
    }

Seems like we missed an static check to forbid writing super() within any constructor

This syntax is more similar to C# than to Java.