Wiki

Ticket #247 (assigned defect)

Opened 7 years ago

Last modified 5 years ago

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] 

Change History

Changed 7 years ago by Chuck

  • owner set to nevdelap
  • status changed from new to assigned

Please break this ticket into two tickets because it is two separate problems. Also, the 2nd problem can be distilled to:

class Test

	get two as int
		return 2

	def toString as String is override
		throw Exception('toString')
	
	def main
		try
			assert .two == 3
		catch exc as AssertException
			msg = exc.message  # run-time error: throws an exception, but we want it to be robust
			assert 'sourceSite' in msg
			assert 'for object' in msg
			assert '.two' in msg

Changed 5 years ago by hopscc

The second problem ( protecting stringifying for error display) seems to be corrected.

Note: See TracTickets for help on using tickets.