@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