Ticket #247 (assigned defect)
init for base class called before preconditions on derived class init are tested & compile not protecting it's calls to toString
| Reported by: | nevdelap | Owned by: | nevdelap |
|---|---|---|---|
| Priority: | medium | Milestone: | |
| Component: | Cobra Compiler | Version: | 0.8.0 |
| Keywords: | Cc: |
Description
This shows that that's the case.
class A
cue init
base.init
throw Exception() # Something fails
class B inherits A
var _s as String
cue init(s as String)
require
s <> 'a' # This should have failed first.
body
base.init
_s = s
def toString as String is override
return _s
class P
def main is shared
print B('a')
Expected result: Unhandled Exception: Cobra.Lang.RequireException?: blaa
Actual result: Unhandled Exception: System.Exception: Exception of type 'System.Exception' was thrown.
This shows up this further problem.
class A
cue init
base.init
# The difference is it's now throwing here.
class B inherits A
var _s as String
cue init(s as String)
require
s <> 'a'
body
base.init
_s = s
def toString as String is override
return _s
class P
def main is shared
print B('a')
Expected result: Same as above.
Actual result: It should never have started constructing, but since it has the compiler stringifies the object to print diagnostics, and since the object hasn't finished constructing and isn't ready to have it's methods called, we get this...
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object at Cobra.Lang.CobraImp.ToTechString (System.Object x) [0x00000] at Cobra.Lang.CobraCore.ToTechString (System.Object x) [0x00000] at Cobra.Lang.SourceSite.ToString () [0x00000] at Cobra.Lang.StringMaker.ObjectToString (System.Object obj) [0x00000] at Cobra.Lang.StringMaker._makeString (System.Object x) [0x00000] at Cobra.Lang.StringMaker.MakeString (System.Object x) [0x00000] at (wrapper synchronized) Cobra.Lang.StringMaker:MakeString (object) at Cobra.Lang.AssertException.get_Message () [0x00000] at System.Exception.ToString () [0x00000]
So the second problem is that when the compiler is putting out diagnostics it should have a catch around stringifying objects so that if the toString throws it can keep going and produce meaningful output, and maybe replace the name with something, I don't know what. In this cause if it replaced it with 'BOOM!' (just for sake of this example) it would produce this, instead of the above.
Unhandled Exception: Cobra.Lang.RequireException:
sourceSite = /home/nev/Temp/cobra/test.cobra:12 in B.cue.init for object BOOM!
info = nil
this = BOOM!
(s <> 'a') = false
s = 'a'
at B..ctor (System.String s) [0x00000]
at P.Main () [0x00000]



