Basically, I have a list,
newtry of blocks, and I want to find a value of
catchtype that makes them all return true for
block.isCatchExtendable(newhandler, catchtype) or report an error if this can't be done.
block.isCatchExtendable returns two values, success and a new type to try on failure.
My current code works, but the control flow is very convoluted, with numerous breaks and elses. I was wondering if anyone could think of a better way to arrange things. Also, these are all my own functions, so I am free to change the interfaces, etc.
while 1: ct_changed = False for block in newtry: success, newcatchtype = block.isCatchExtendable(newhandler, catchtype) if not success: if catchtype == newcatchtype: #no success and no other types to try, so just break and fail break catchtype, ct_changed = newcatchtype, True else: if ct_changed: continue else: break error('Unable to extend try block completely')
def isCatchExtendable(self, newhandler, catchtype): return self.catchset.extendible(newhandler, catchtype, self.currentHandlers)
This then calls:
#If not extendible with current catchtype, returns suggested type as second arg def extendible(self, newhandler, catchtype, outerhs): if catchtype is None: temp = self.catchsets.get(newhandler) if temp is None: return True, None return False, temp.getSingleTType() proposed = ExceptionSet.fromTops(self.env, catchtype) inner = [h for h in self.handlers if h != newhandler and h not in outerhs] outer = [h for h in self.handlers if h in outerhs] sofar = ExceptionSet.fromTops(self.env) for h in inner: sofar = sofar | self.catchsets[h] if (proposed - sofar) != self.catchsets[newhandler]: #Get a suggsted catch type to try instead suggested = (self.catchsets[newhandler] | sofar).getSingleTType() suggested = objtypes.commonSupertype(self.env, suggested, (catchtype, 0)) assert(self.env.isSubClass(suggested, 'java/lang/Throwable')) return False, suggested for h in outer: if not proposed.isdisjoint(self.catchsets[h]): return False, catchtype return True, catchtype