<@script name="TraceMgr" also="Window Fields" hide="y"> Implements the %STUDIO% trace manager (c) SAP AG 2003-2006. All rights reserved. <@func name="TRACE_FN"> Invoke at the beginning of a function to trace the function invocations The function arguments Use this function in conjunction with conditional JavaScript compilation to trace a function: \@set \@trace=true; ... function myFunc() { \@if (\@trace) TRACE_FN(arguments) \@end; ... } ... function TRACE_FN(args) { try { var func=args.callee; if (!func.funcName) { var arr=func.toString().match(/^function\s+([^(]+)/); if (!arr) return; func.funcName = arr[1]; func.className = 'Global'; } __TRACER_OBJ.traceCall(null, args); } catch (e) {} } <@func name="TRACE_MT" also="TRACE_CLASS"> Invoke at the beginning of a method to trace the method invocations The traced object The method arguments Use this function in conjunction with conditional JavaScript compilation to trace a method: \@set \@trace=true; ... Circle.prototype.paint = function() { \@if (\@trace) TRACE_MT(this, arguments) \@end; ... } ... function TRACE_MT(obj, args) { try { __TRACER_OBJ.traceCall(obj, args); } catch (e) {} } <@func name="TRACE_CLASS" also="TRACE_MT"> Invoke at the end of a class definition to enable tracing the class methods The class constructor The class name Use this function in conjunction with conditional JavaScript compilation to enable class tracing: \@set \@trace=true; ... // constructor function Circle(x, y, radius) { \@if (\@trace) TRACE_MT(this, arguments) \@end; Shape.call(this, x, y); ... } Circle.prototype = new Shape; Circle.prototype.constructor = Circle; Circle.superclass = Shape; ... // methods Circle.prototype.paint = function() {} Circle.prototype.erase = function() {} Circle.prototype.move = function() {} ... \@if (\@trace) TRACE_CLASS(Circle, 'Circle') \@end; function TRACE_CLASS(cls, name) { var proto=cls.prototype; cls.funcName = 'constructor'; cls.className = name; proto.className = name; for (var k in proto) { if (!proto.hasOwnProperty(k) || typeof(proto[k]) != 'function') continue; proto[k].funcName = k; proto[k].className = name; } } ///////////////////////////////////////////////////////////////// // TRACER Object function __TRACER() { this.totalClasses = 0; // Total classes this.totalMethods = 0; // Total methods this.totalCalls = 0; // Total method calls this.minCallsPerFunc = 99999999; this.maxCallsPerFunc = 0; this.classKeys = {}; // table of class keys, indexed by class name this.classes = [], // per class: {name:String, total:int} this.methodKeys = {}; // table of method keys, indexed by full method name this.methods = []; // per method: {name:String, className:String, funcName:String, total:int} } __TRACER.reset = function() { __TRACER_OBJ = new __TRACER(); } __TRACER.prototype.traceCall = function(obj, args) { var f1=args.callee; if (!f1.funcName) return; var nc1=f1.className, kc1=this.classKeys[nc1]; var nm1=nc1+'.'+f1.funcName, km1=this.methodKeys[nm1]; if (kc1 == undefined) { kc1=this.totalClasses++; this.classKeys[nc1]=kc1; } if (km1 == undefined) { km1=this.totalMethods++; this.methodKeys[nm1]=km1; } if (this.classes[kc1] == undefined) this.classes[kc1] = {name:nc1, total:0}; if (this.methods[km1] == undefined) this.methods[km1] = {name:nm1, className:nc1, funcName:f1.funcName, total:0}; var c1=this.classes[kc1], m1=this.methods[km1]; c1.total++; m1.total++; this.totalCalls++; } __TRACER.prototype.getMethods = function() { for (var i=0, A=this.methods, B=[], len=A.length; i