@jdeighan/coffee-utils 7.0.48 → 7.0.51

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,8 @@
1
1
  # debug_utils.coffee
2
2
 
3
3
  import {
4
- assert, undef, error, croak, warn, isString, isFunction, isBoolean,
4
+ assert, undef, error, croak, warn, defined,
5
+ isString, isFunction, isBoolean, sep_dash,
5
6
  OL, escapeStr, isNumber, isArray, words, pass,
6
7
  } from '@jdeighan/coffee-utils'
7
8
  import {blockToArray} from '@jdeighan/coffee-utils/block'
@@ -9,16 +10,15 @@ import {untabify} from '@jdeighan/coffee-utils/indent'
9
10
  import {slurp} from '@jdeighan/coffee-utils/fs'
10
11
  import {CallStack} from '@jdeighan/coffee-utils/stack'
11
12
  import {
12
- log, logItem, LOG, setStringifier, orderedStringify,
13
+ getPrefix, addArrow, removeLastVbar,
14
+ } from '@jdeighan/coffee-utils/arrow'
15
+ import {
16
+ log, logItem, LOG, shortEnough,
13
17
  } from '@jdeighan/coffee-utils/log'
14
18
 
15
- # --- These are saved/restored on the call stack
16
- export debugging = false
17
- shouldLogFunc = (func) -> debugging
18
- shouldLogString = (str) -> debugging
19
-
20
- stack = new CallStack()
19
+ callStack = new CallStack()
21
20
  doDebugDebug = false
21
+ shouldLog = undef # set in resetDebugging() and setDebugging()
22
22
 
23
23
  # ---------------------------------------------------------------------------
24
24
 
@@ -33,49 +33,47 @@ export debugDebug = (flag=true) ->
33
33
 
34
34
  resetDebugging = () ->
35
35
 
36
- debugging = false
37
36
  if doDebugDebug
38
- LOG "resetDebugging() - debugging = false"
39
- stack.reset()
40
- shouldLogFunc = (func) -> debugging
41
- shouldLogString = (str) -> debugging
37
+ LOG "resetDebugging()"
38
+ callStack.reset()
39
+ shouldLog = (type, str, stack) -> false
42
40
  return
43
41
 
44
42
  # ---------------------------------------------------------------------------
45
43
 
46
- export setDebugging = (funcDoDebug=undef, funcDoLog=undef) ->
44
+ export setDebugging = (option) ->
47
45
 
48
46
  resetDebugging()
49
- if isBoolean(funcDoDebug)
50
- debugging = funcDoDebug
51
- if doDebugDebug
52
- LOG "setDebugging(): debugging = #{funcDoDebug}"
53
- else if isString(funcDoDebug)
54
- debugging = false
55
- lFuncNames = words(funcDoDebug)
56
- assert isArray(lFuncNames), "words('#{funcDoDebug}') returned non-array"
57
- shouldLogFunc = (funcName) ->
58
- funcMatch(funcName, lFuncNames)
47
+ if isBoolean(option)
48
+ shouldLog = (type, str, stack) -> option
49
+ else if isString(option)
50
+ shouldLog = (type, str, stack) ->
51
+ lFuncs = words(option)
52
+ switch type
53
+ when 'enter'
54
+ return funcMatch(stack, lFuncs, str)
55
+ else
56
+ return funcMatch(stack, lFuncs)
59
57
  if doDebugDebug
60
- LOG "setDebugging FUNCS: #{lFuncNames.join(',')}, debugging = false"
61
- else if isFunction(funcDoDebug)
62
- shouldLogFunc = funcDoDebug
58
+ LOG "setDebugging FUNCS: #{option}"
59
+ else if isFunction(option)
60
+ shouldLog = option
63
61
  if doDebugDebug
64
62
  LOG "setDebugging to custom func"
65
63
  else
66
- croak "setDebugging(): bad parameter #{OL(funcDoDebug)}"
67
-
68
- if funcDoLog
69
- assert isFunction(funcDoLog), "setDebugging: arg 2 not a function"
70
- shouldLogString = funcDoLog
64
+ croak "setDebugging(): bad parameter #{OL(option)}"
71
65
  return
72
66
 
73
67
  # ---------------------------------------------------------------------------
74
68
  # --- export only to allow unit tests
75
69
 
76
- export funcMatch = (curFunc, lFuncNames) ->
70
+ export funcMatch = (stack, lFuncNames, enteringFunc=undef) ->
71
+
72
+ if defined(enteringFunc) && (enteringFunc in lFuncNames)
73
+ return true
77
74
 
78
- assert isString(curFunc), "funcMatch(): not a string"
75
+ curFunc = stack.curFunc()
76
+ assert isString(curFunc), "funcMatch(): not a string #{OL(curFunc)}"
79
77
  assert isArray(lFuncNames), "funcMatch(): bad array #{lFuncNames}"
80
78
  if lFuncNames.includes(curFunc)
81
79
  return true
@@ -87,120 +85,116 @@ export funcMatch = (curFunc, lFuncNames) ->
87
85
  return false
88
86
 
89
87
  # ---------------------------------------------------------------------------
90
- # 1. adjust call stack on 'enter' or 'return from'
91
- # 2. adjust debugging flag
92
- # 3. return [mainPrefix, auxPrefix, hEnv] - hEnv can be undef
93
- # 4. disable logging by setting mainPrefix to undef
88
+ # --- type is one of: 'enter', 'return', 'string', 'object'
94
89
 
95
- adjustStack = (str) ->
90
+ export getType = (str, nObjects) ->
96
91
 
97
- if (lMatches = str.match(///^
92
+ if lMatches = str.match(///^
98
93
  \s*
99
94
  enter
100
95
  \s+
101
96
  ([A-Za-z_][A-Za-z0-9_\.]*)
102
- ///))
103
- curFunc = lMatches[1]
104
- hEnv = {
105
- debugging
106
- shouldLogFunc
107
- shouldLogString
108
- }
109
- debugging = shouldLogFunc(curFunc)
110
- if doDebugDebug
111
- trans = "#{hEnv.debugging} => #{debugging}"
112
- LOG " ENTER #{curFunc}, debugging: #{trans}"
113
- [mainPre, auxPre, _] = stack.call(curFunc, hEnv, debugging)
114
- return [
115
- mainPre
116
- auxPre
117
- undef
118
- if shouldLogFunc(curFunc) then 'enter' else undef
119
- ]
120
- else if (lMatches = str.match(///^
97
+ ///)
98
+
99
+ # --- We are entering function curFunc
100
+ return ['enter', lMatches[1]]
101
+
102
+ else if lMatches = str.match(///^
121
103
  \s*
122
104
  return
123
105
  .+
124
106
  from
125
107
  \s+
126
108
  ([A-Za-z_][A-Za-z0-9_\.]*)
127
- ///))
128
- curFunc = lMatches[1]
129
- [mainPre, auxPre, hEnv] = stack.returnFrom(curFunc)
130
- if doDebugDebug
131
- LOG " RETURN FROM #{curFunc}"
132
- return [
133
- mainPre
134
- auxPre
135
- hEnv
136
- if shouldLogFunc(curFunc) then 'return' else undef
137
- ]
109
+ ///)
110
+ return ['return', lMatches[1]]
111
+
112
+ else if (nObjects > 0)
113
+ return ['objects', undef]
138
114
  else
139
- [mainPre, auxPre, _] = stack.logStr()
140
- return [
141
- mainPre
142
- auxPre
143
- undef
144
- if shouldLogString(str) then 'string' else undef
145
- ]
115
+ return ['string', undef]
146
116
 
147
117
  # ---------------------------------------------------------------------------
148
118
 
149
- export debug = (lArgs...) ->
119
+ export debug = (label, lObjects...) ->
150
120
 
151
- # --- We want to allow item to be undef. Therefore, we need to
152
- # distinguish between 1 arg sent vs. 2 args sent
153
- nArgs = lArgs.length
154
- assert (nArgs==1) || (nArgs==2), "debug(): #{nArgs} args"
155
- [label, item] = lArgs
156
- assert isString(label),
157
- "debug(): 1st arg #{OL(label)} should be a string"
121
+ assert isString(label), "1st arg #{OL(label)} should be a string"
158
122
 
159
- if doDebugDebug
160
- if nArgs==1
161
- LOG "debug('#{escapeStr(label)}') - 1 arg"
162
- else
163
- LOG "debug('#{escapeStr(label)}', #{typeof item}) - 2 args"
164
-
165
- # --- We always need to manipulate the stack when we encounter
166
- # either "enter X" or "return from X", so we can't short-circuit
167
- # when debugging is off
168
-
169
- lResult = adjustStack(label)
170
- if doDebugDebug
171
- LOG 'lResult', lResult
172
- [mainPre, auxPre, hEnv, type] = lResult
173
- if doDebugDebug && (type == undef)
174
- LOG "type is undef - NOT LOGGING"
175
-
176
- hOptions = {
177
- prefix: mainPre
178
- itemPrefix: auxPre
179
- }
123
+ # --- We want to allow objects to be undef. Therefore, we need to
124
+ # distinguish between 1 arg sent vs. 2 or more args sent
125
+ nObjects = lObjects.length
180
126
 
127
+ # --- funcName is only set for types 'enter' and 'return'
128
+ [type, funcName] = getType(label, nObjects)
181
129
  switch type
182
130
  when 'enter'
183
- log label, hOptions
184
- if (nArgs==2)
185
- # --- don't repeat the label
186
- logItem undef, item, hOptions
131
+ doLog = shouldLog(type, funcName, callStack)
132
+
133
+ # --- If we won't be logging when funcName is activated
134
+ # then change 'enter' to 'call'
135
+ callStack.enter funcName # add to call stack
136
+ if ! shouldLog('string', 'abc', callStack)
137
+ label = label.replace('enter', 'call')
138
+ callStack.returnFrom funcName # remove from call stack
187
139
  when 'return'
188
- log label, hOptions
189
- if (nArgs==2)
190
- # --- don't repeat the label
191
- logItem undef, item, hOptions
140
+ doLog = shouldLog(type, funcName, callStack)
192
141
  when 'string'
193
- if (nArgs==2)
194
- logItem label, item, hOptions
195
- else
196
- log label, hOptions
142
+ doLog = shouldLog(type, label, callStack)
143
+ assert (nObjects == 0),
144
+ "multiple objects only not allowed for #{OL(type)}"
145
+ when 'objects'
146
+ doLog = shouldLog(type, label, callStack)
147
+ assert (nObjects > 0),
148
+ "multiple objects only not allowed for #{OL(type)}"
149
+
150
+ if doDebugDebug
151
+ if nObjects == 0
152
+ LOG "debug(#{OL(label)}) - 1 arg"
153
+ else
154
+ LOG "debug(#{OL(label)}), #{nObjects} args"
155
+ LOG "doLog = #{OL(doLog)}"
156
+ LOG "type = #{OL(type)}"
157
+ LOG "funcName = #{OL(funcName)}"
158
+
159
+ if doLog
160
+ level = callStack.getLevel()
161
+ prefix = getPrefix(level)
197
162
 
198
- if hEnv
199
- orgDebugging = debugging
200
- {debugging, shouldLogFunc, shouldLogString} = hEnv
201
163
  if doDebugDebug
202
- trans = "#{orgDebugging} => #{debugging}"
203
- LOG " Restore hEnv: debugging: #{trans}"
164
+ LOG "callStack", callStack
165
+ LOG "level = #{OL(level)}"
166
+ LOG "prefix = #{OL(prefix)}"
167
+
168
+ switch type
169
+ when 'enter'
170
+ log label, {prefix}
171
+ for obj,i in lObjects
172
+ if (i > 0)
173
+ log sep_dash, {prefix: removeLastVbar(prefix)}
174
+ logItem undef, obj, {prefix: removeLastVbar(prefix)}
175
+ when 'return'
176
+ log label, {prefix: addArrow(prefix)}
177
+ for obj,i in lObjects
178
+ if (i > 0)
179
+ log sep_dash, {prefix: removeLastVbar(prefix)}
180
+ logItem undef, obj, {prefix: removeLastVbar(prefix)}
181
+ when 'string'
182
+ log label, {prefix}
183
+ when 'objects'
184
+ if (nObjects==1) && shortEnough(label, lObjects[0])
185
+ logItem label, lObjects[0], {prefix}
186
+ else
187
+ if (label.indexOf(':') != label.length - 1)
188
+ label += ':'
189
+ log label, {prefix}
190
+ for obj in lObjects
191
+ logItem undef, obj, {prefix}
192
+
193
+ if (type == 'enter')
194
+ callStack.enter funcName, doLog
195
+ else if (type == 'return')
196
+ callStack.returnFrom funcName
197
+
204
198
  return true # allow use in boolean expressions
205
199
 
206
200
  # ---------------------------------------------------------------------------
@@ -1,6 +1,7 @@
1
1
  // Generated by CoffeeScript 2.7.0
2
- // debug_utils.coffee
3
- var adjustStack, doDebugDebug, reMethod, resetDebugging, shouldLogFunc, shouldLogString, stack;
2
+ // debug_utils.coffee
3
+ var callStack, doDebugDebug, reMethod, resetDebugging, shouldLog,
4
+ indexOf = [].indexOf;
4
5
 
5
6
  import {
6
7
  assert,
@@ -8,9 +9,11 @@ import {
8
9
  error,
9
10
  croak,
10
11
  warn,
12
+ defined,
11
13
  isString,
12
14
  isFunction,
13
15
  isBoolean,
16
+ sep_dash,
14
17
  OL,
15
18
  escapeStr,
16
19
  isNumber,
@@ -35,28 +38,25 @@ import {
35
38
  CallStack
36
39
  } from '@jdeighan/coffee-utils/stack';
37
40
 
41
+ import {
42
+ getPrefix,
43
+ addArrow,
44
+ removeLastVbar
45
+ } from '@jdeighan/coffee-utils/arrow';
46
+
38
47
  import {
39
48
  log,
40
49
  logItem,
41
50
  LOG,
42
- setStringifier,
43
- orderedStringify
51
+ shortEnough
44
52
  } from '@jdeighan/coffee-utils/log';
45
53
 
46
- // --- These are saved/restored on the call stack
47
- export var debugging = false;
54
+ callStack = new CallStack();
48
55
 
49
- shouldLogFunc = function(func) {
50
- return debugging;
51
- };
52
-
53
- shouldLogString = function(str) {
54
- return debugging;
55
- };
56
+ doDebugDebug = false;
56
57
 
57
- stack = new CallStack();
58
+ shouldLog = undef; // set in resetDebugging() and setDebugging()
58
59
 
59
- doDebugDebug = false;
60
60
 
61
61
  // ---------------------------------------------------------------------------
62
62
  export var debugDebug = function(flag = true) {
@@ -68,57 +68,55 @@ export var debugDebug = function(flag = true) {
68
68
 
69
69
  // ---------------------------------------------------------------------------
70
70
  resetDebugging = function() {
71
- debugging = false;
72
71
  if (doDebugDebug) {
73
- LOG("resetDebugging() - debugging = false");
72
+ LOG("resetDebugging()");
74
73
  }
75
- stack.reset();
76
- shouldLogFunc = function(func) {
77
- return debugging;
78
- };
79
- shouldLogString = function(str) {
80
- return debugging;
74
+ callStack.reset();
75
+ shouldLog = function(type, str, stack) {
76
+ return false;
81
77
  };
82
78
  };
83
79
 
84
80
  // ---------------------------------------------------------------------------
85
- export var setDebugging = function(funcDoDebug = undef, funcDoLog = undef) {
86
- var lFuncNames;
81
+ export var setDebugging = function(option) {
87
82
  resetDebugging();
88
- if (isBoolean(funcDoDebug)) {
89
- debugging = funcDoDebug;
90
- if (doDebugDebug) {
91
- LOG(`setDebugging(): debugging = ${funcDoDebug}`);
92
- }
93
- } else if (isString(funcDoDebug)) {
94
- debugging = false;
95
- lFuncNames = words(funcDoDebug);
96
- assert(isArray(lFuncNames), `words('${funcDoDebug}') returned non-array`);
97
- shouldLogFunc = function(funcName) {
98
- return funcMatch(funcName, lFuncNames);
83
+ if (isBoolean(option)) {
84
+ shouldLog = function(type, str, stack) {
85
+ return option;
86
+ };
87
+ } else if (isString(option)) {
88
+ shouldLog = function(type, str, stack) {
89
+ var lFuncs;
90
+ lFuncs = words(option);
91
+ switch (type) {
92
+ case 'enter':
93
+ return funcMatch(stack, lFuncs, str);
94
+ default:
95
+ return funcMatch(stack, lFuncs);
96
+ }
99
97
  };
100
98
  if (doDebugDebug) {
101
- LOG(`setDebugging FUNCS: ${lFuncNames.join(',')}, debugging = false`);
99
+ LOG(`setDebugging FUNCS: ${option}`);
102
100
  }
103
- } else if (isFunction(funcDoDebug)) {
104
- shouldLogFunc = funcDoDebug;
101
+ } else if (isFunction(option)) {
102
+ shouldLog = option;
105
103
  if (doDebugDebug) {
106
104
  LOG("setDebugging to custom func");
107
105
  }
108
106
  } else {
109
- croak(`setDebugging(): bad parameter ${OL(funcDoDebug)}`);
110
- }
111
- if (funcDoLog) {
112
- assert(isFunction(funcDoLog), "setDebugging: arg 2 not a function");
113
- shouldLogString = funcDoLog;
107
+ croak(`setDebugging(): bad parameter ${OL(option)}`);
114
108
  }
115
109
  };
116
110
 
117
111
  // ---------------------------------------------------------------------------
118
112
  // --- export only to allow unit tests
119
- export var funcMatch = function(curFunc, lFuncNames) {
120
- var _, cls, lMatches, meth;
121
- assert(isString(curFunc), "funcMatch(): not a string");
113
+ export var funcMatch = function(stack, lFuncNames, enteringFunc = undef) {
114
+ var _, cls, curFunc, lMatches, meth;
115
+ if (defined(enteringFunc) && (indexOf.call(lFuncNames, enteringFunc) >= 0)) {
116
+ return true;
117
+ }
118
+ curFunc = stack.curFunc();
119
+ assert(isString(curFunc), `funcMatch(): not a string ${OL(curFunc)}`);
122
120
  assert(isArray(lFuncNames), `funcMatch(): bad array ${lFuncNames}`);
123
121
  if (lFuncNames.includes(curFunc)) {
124
122
  return true;
@@ -130,95 +128,123 @@ export var funcMatch = function(curFunc, lFuncNames) {
130
128
  };
131
129
 
132
130
  // ---------------------------------------------------------------------------
133
- // 1. adjust call stack on 'enter' or 'return from'
134
- // 2. adjust debugging flag
135
- // 3. return [mainPrefix, auxPrefix, hEnv] - hEnv can be undef
136
- // 4. disable logging by setting mainPrefix to undef
137
- adjustStack = function(str) {
138
- var _, auxPre, curFunc, hEnv, lMatches, mainPre, trans;
139
- if ((lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
140
- curFunc = lMatches[1];
141
- hEnv = {debugging, shouldLogFunc, shouldLogString};
142
- debugging = shouldLogFunc(curFunc);
143
- if (doDebugDebug) {
144
- trans = `${hEnv.debugging} => ${debugging}`;
145
- LOG(` ENTER ${curFunc}, debugging: ${trans}`);
146
- }
147
- [mainPre, auxPre, _] = stack.call(curFunc, hEnv, debugging);
148
- return [mainPre, auxPre, undef, shouldLogFunc(curFunc) ? 'enter' : undef];
149
- } else if ((lMatches = str.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
150
- curFunc = lMatches[1];
151
- [mainPre, auxPre, hEnv] = stack.returnFrom(curFunc);
152
- if (doDebugDebug) {
153
- LOG(` RETURN FROM ${curFunc}`);
154
- }
155
- return [mainPre, auxPre, hEnv, shouldLogFunc(curFunc) ? 'return' : undef];
131
+ // --- type is one of: 'enter', 'return', 'string', 'object'
132
+ export var getType = function(str, nObjects) {
133
+ var lMatches;
134
+ if (lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
135
+ // --- We are entering function curFunc
136
+ return ['enter', lMatches[1]];
137
+ } else if (lMatches = str.match(/^\s*return.+from\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
138
+ return ['return', lMatches[1]];
139
+ } else if (nObjects > 0) {
140
+ return ['objects', undef];
156
141
  } else {
157
- [mainPre, auxPre, _] = stack.logStr();
158
- return [mainPre, auxPre, undef, shouldLogString(str) ? 'string' : undef];
142
+ return ['string', undef];
159
143
  }
160
144
  };
161
145
 
162
146
  // ---------------------------------------------------------------------------
163
- export var debug = function(...lArgs) {
164
- var auxPre, hEnv, hOptions, item, lResult, label, mainPre, nArgs, orgDebugging, trans, type;
165
- // --- We want to allow item to be undef. Therefore, we need to
166
- // distinguish between 1 arg sent vs. 2 args sent
167
- nArgs = lArgs.length;
168
- assert((nArgs === 1) || (nArgs === 2), `debug(): ${nArgs} args`);
169
- [label, item] = lArgs;
170
- assert(isString(label), `debug(): 1st arg ${OL(label)} should be a string`);
171
- if (doDebugDebug) {
172
- if (nArgs === 1) {
173
- LOG(`debug('${escapeStr(label)}') - 1 arg`);
174
- } else {
175
- LOG(`debug('${escapeStr(label)}', ${typeof item}) - 2 args`);
176
- }
177
- }
178
- // --- We always need to manipulate the stack when we encounter
179
- // either "enter X" or "return from X", so we can't short-circuit
180
- // when debugging is off
181
- lResult = adjustStack(label);
182
- if (doDebugDebug) {
183
- LOG('lResult', lResult);
184
- }
185
- [mainPre, auxPre, hEnv, type] = lResult;
186
- if (doDebugDebug && (type === undef)) {
187
- LOG("type is undef - NOT LOGGING");
188
- }
189
- hOptions = {
190
- prefix: mainPre,
191
- itemPrefix: auxPre
192
- };
147
+ export var debug = function(label, ...lObjects) {
148
+ var doLog, funcName, i, j, k, l, len1, len2, len3, level, nObjects, obj, prefix, type;
149
+ assert(isString(label), `1st arg ${OL(label)} should be a string`);
150
+ // --- We want to allow objects to be undef. Therefore, we need to
151
+ // distinguish between 1 arg sent vs. 2 or more args sent
152
+ nObjects = lObjects.length;
153
+ // --- funcName is only set for types 'enter' and 'return'
154
+ [type, funcName] = getType(label, nObjects);
193
155
  switch (type) {
194
156
  case 'enter':
195
- log(label, hOptions);
196
- if (nArgs === 2) {
197
- // --- don't repeat the label
198
- logItem(undef, item, hOptions);
157
+ doLog = shouldLog(type, funcName, callStack);
158
+ // --- If we won't be logging when funcName is activated
159
+ // then change 'enter' to 'call'
160
+ callStack.enter(funcName); // add to call stack
161
+ if (!shouldLog('string', 'abc', callStack)) {
162
+ label = label.replace('enter', 'call');
199
163
  }
164
+ callStack.returnFrom(funcName); // remove from call stack
200
165
  break;
201
166
  case 'return':
202
- log(label, hOptions);
203
- if (nArgs === 2) {
204
- // --- don't repeat the label
205
- logItem(undef, item, hOptions);
206
- }
167
+ doLog = shouldLog(type, funcName, callStack);
207
168
  break;
208
169
  case 'string':
209
- if (nArgs === 2) {
210
- logItem(label, item, hOptions);
211
- } else {
212
- log(label, hOptions);
213
- }
170
+ doLog = shouldLog(type, label, callStack);
171
+ assert(nObjects === 0, `multiple objects only not allowed for ${OL(type)}`);
172
+ break;
173
+ case 'objects':
174
+ doLog = shouldLog(type, label, callStack);
175
+ assert(nObjects > 0, `multiple objects only not allowed for ${OL(type)}`);
214
176
  }
215
- if (hEnv) {
216
- orgDebugging = debugging;
217
- ({debugging, shouldLogFunc, shouldLogString} = hEnv);
177
+ if (doDebugDebug) {
178
+ if (nObjects === 0) {
179
+ LOG(`debug(${OL(label)}) - 1 arg`);
180
+ } else {
181
+ LOG(`debug(${OL(label)}), ${nObjects} args`);
182
+ }
183
+ LOG(`doLog = ${OL(doLog)}`);
184
+ LOG(`type = ${OL(type)}`);
185
+ LOG(`funcName = ${OL(funcName)}`);
186
+ }
187
+ if (doLog) {
188
+ level = callStack.getLevel();
189
+ prefix = getPrefix(level);
218
190
  if (doDebugDebug) {
219
- trans = `${orgDebugging} => ${debugging}`;
220
- LOG(` Restore hEnv: debugging: ${trans}`);
191
+ LOG("callStack", callStack);
192
+ LOG(`level = ${OL(level)}`);
193
+ LOG(`prefix = ${OL(prefix)}`);
221
194
  }
195
+ switch (type) {
196
+ case 'enter':
197
+ log(label, {prefix});
198
+ for (i = j = 0, len1 = lObjects.length; j < len1; i = ++j) {
199
+ obj = lObjects[i];
200
+ if (i > 0) {
201
+ log(sep_dash, {
202
+ prefix: removeLastVbar(prefix)
203
+ });
204
+ }
205
+ logItem(undef, obj, {
206
+ prefix: removeLastVbar(prefix)
207
+ });
208
+ }
209
+ break;
210
+ case 'return':
211
+ log(label, {
212
+ prefix: addArrow(prefix)
213
+ });
214
+ for (i = k = 0, len2 = lObjects.length; k < len2; i = ++k) {
215
+ obj = lObjects[i];
216
+ if (i > 0) {
217
+ log(sep_dash, {
218
+ prefix: removeLastVbar(prefix)
219
+ });
220
+ }
221
+ logItem(undef, obj, {
222
+ prefix: removeLastVbar(prefix)
223
+ });
224
+ }
225
+ break;
226
+ case 'string':
227
+ log(label, {prefix});
228
+ break;
229
+ case 'objects':
230
+ if ((nObjects === 1) && shortEnough(label, lObjects[0])) {
231
+ logItem(label, lObjects[0], {prefix});
232
+ } else {
233
+ if (label.indexOf(':') !== label.length - 1) {
234
+ label += ':';
235
+ }
236
+ log(label, {prefix});
237
+ for (l = 0, len3 = lObjects.length; l < len3; l++) {
238
+ obj = lObjects[l];
239
+ logItem(undef, obj, {prefix});
240
+ }
241
+ }
242
+ }
243
+ }
244
+ if (type === 'enter') {
245
+ callStack.enter(funcName, doLog);
246
+ } else if (type === 'return') {
247
+ callStack.returnFrom(funcName);
222
248
  }
223
249
  return true; // allow use in boolean expressions
224
250
  };
@@ -229,12 +255,12 @@ reMethod = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/;
229
255
 
230
256
  // ---------------------------------------------------------------------------
231
257
  export var checkTrace = function(block) {
232
- var funcName, i, lMatches, lStack, len, len1, line, ref;
258
+ var funcName, j, lMatches, lStack, len, len1, line, ref;
233
259
  // --- export only to allow unit tests
234
260
  lStack = [];
235
261
  ref = blockToArray(block);
236
- for (i = 0, len1 = ref.length; i < len1; i++) {
237
- line = ref[i];
262
+ for (j = 0, len1 = ref.length; j < len1; j++) {
263
+ line = ref[j];
238
264
  if (lMatches = line.match(/enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
239
265
  funcName = lMatches[1];
240
266
  lStack.push(funcName);