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]