namespace Cobra.Core class CobraFrame implements HasAppendNonPropertyKeyValues var _declClassName as String var _methodName as String var _fileName as String var _lineNum as int is public var _args as Object[] var _locals as Dictionary var _localNamesInOrder as List cue init(declClassName as String, methodName as String, fileName as String, lineNum as int, args as vari Object) """ args should have the arg names embedded: "x", x, "y", y """ base.init _declClassName = declClassName _methodName = methodName _fileName = fileName _lineNum = lineNum _args = sharp'(object[])args.Clone()' _locals = Dictionary() _localNamesInOrder = List() for j = 0 .. _args.length ++ 2 .setLocal(_args[j] to String, _args[j+1]) get args from var get declClassName from var get fileName from var get lineNum from var get methodName from var get locals from var get localNamesInOrder from var def setLocal(name as String, value as dynamic?) if not _locals.containsKey(name) _localNamesInOrder.add(name) _locals[name] = value def appendNonPropertyKeyValues(target as HasAppendKeyValue) args = .args argNames = Set() for j = 0 .. args.length ++ 2 name = args[j] to String target.appendKeyValue(name+' (arg)', args[j+1]) argNames.add(name) for name in .localNamesInOrder if name == 'this' or name in argNames, continue target.appendKeyValue(name+' (local)', .locals[name]) def dumpText(tw as TextWriter, i as int) nameWidth = 8 tw.writeLine('\n [i]. [this]') tw.writeLine(' args') for j = 0 .. _args.length ++ 2 tw.write(String.format(' {0} = ', (_args[j] to String).padRight(nameWidth))) try s = CobraCore.toTechString(_args[j+1]) catch e as Exception s = 'ToString() Exception: ' + e.message tw.writeLine(s) tw.writeLine(' locals') for name in _localNamesInOrder if name == 'this' continue tw.write(String.format(' {0} = ', name.padRight(nameWidth))) try s = CobraCore.toTechString(_locals[name]) catch e as Exception s = 'ToString() Exception: ' + e.message tw.writeLine(s) # TODO: move this to HtmlExceptionReportWriter as an extend CobraFrame def dumpHtml(tw as TextWriter, i as int, objects as ObjectCatalog, willDumpHtmlFor as WillDumpHtmlForMethod) # record objects for localValue in _locals.values if localValue is not nil and willDumpHtmlFor(localValue) objects.record(localValue to !) # write frame html tw.writeLine tw.writeLine(' [i]. [_declClassName].[_methodName] ') tw.writeLine('   at: [SourceSite.htmlForAtArgs(_fileName, _lineNum)] ') rowNum = 1 for j = 0 .. _args.length ++ 2 name = _args[j] to String value = _args[j+1] to dynamic? label = if(j==0, 'args:', '') tw.write('   [label] [name]  =  ') try s = CobraCore.htmlEncode(CobraCore.toTechString(value)) catch e as Exception s = 'ToString() Exception: ' + e.message if willDumpHtmlFor(value) s = '[s]' tw.writeLine(' [s] ') rowNum += 1 first = true for name in _localNamesInOrder if name == 'this' continue label = if(first, 'locals:', '') tw.write('   [label] [name]  =  ') value = _locals[name] try s = CobraCore.htmlEncode(CobraCore.toTechString(value)) catch e as Exception s = 'ToString() Exception: ' + e.message if willDumpHtmlFor(value) s = '[s]' tw.writeLine(' [s] ') first = false rowNum += 1 tw.writeLine('   ') def toString as String is override return 'def [_declClassName].[_methodName] at line [_lineNum]' def copy as CobraFrame return .memberwiseClone to CobraFrame