Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2a62cd0

Browse files
committed
feat: add WTF tracing
- $digest - $digest#asyncQueue - $digest#postDigestQueue - $eval - $watcher - $compile#compile - $compile#link - $timeout Show events (ng-click, etc.) expressions. Show watched expressions. Show $timeout callbacks. Show reslving/rejecting promises details.
1 parent 550ba01 commit 2a62cd0

File tree

7 files changed

+164
-1
lines changed

7 files changed

+164
-1
lines changed

src/Angular.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@
103103
* <div doc-module-components="ng"></div>
104104
*/
105105

106+
var WTF_ENABLED = WTF && WTF.PRESENT;
107+
106108
var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
107109

108110
// The name of a form control's ValidityState property.

src/ng/compile.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,12 +1024,23 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10241024
*/
10251025
function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
10261026
previousCompileContext) {
1027+
var wtfScope, wtfHtml;
1028+
1029+
if (WTF_ENABLED) {
1030+
wtfScope = WTF.trace.enterScope('$compile#compile');
1031+
wtfHtml = '';
1032+
}
1033+
10271034
var linkFns = [],
10281035
attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;
10291036

10301037
for (var i = 0; i < nodeList.length; i++) {
10311038
attrs = new Attributes();
10321039

1040+
if (WTF_ENABLED) {
1041+
wtfHtml += (nodeList[i].outerHTML || '');
1042+
}
1043+
10331044
// we must always refer to nodeList[i] since the nodes can be replaced underneath us.
10341045
directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,
10351046
ignoreDirective);
@@ -1062,12 +1073,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10621073
previousCompileContext = null;
10631074
}
10641075

1076+
if (WTF_ENABLED) {
1077+
WTF.trace.appendScopeData('html', wtfHtml);
1078+
WTF.trace.leaveScope(wtfScope);
1079+
}
1080+
10651081
// return a linking function if we have found anything, null otherwise
10661082
return linkFnFound ? compositeLinkFn : null;
10671083

10681084
function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
10691085
var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;
10701086
var stableNodeList;
1087+
var wtfLinkScope;
10711088

10721089

10731090
if (nodeLinkFnFound) {
@@ -1090,6 +1107,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10901107
nodeLinkFn = linkFns[i++];
10911108
childLinkFn = linkFns[i++];
10921109

1110+
if (WTF_ENABLED) {
1111+
wtfLinkScope = WTF.trace.enterScope('$compile#link');
1112+
WTF.trace.appendScopeData('html', node.outerHTML || node.textContent);
1113+
}
1114+
10931115
if (nodeLinkFn) {
10941116
if (nodeLinkFn.scope) {
10951117
childScope = scope.$new();
@@ -1118,6 +1140,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
11181140
} else if (childLinkFn) {
11191141
childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);
11201142
}
1143+
1144+
if (WTF_ENABLED) {
1145+
WTF.trace.leaveScope(wtfLinkScope);
1146+
}
11211147
}
11221148
}
11231149
}

src/ng/directive/ngEventDirs.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ forEach(
6262
var callback = function() {
6363
fn(scope, {$event:event});
6464
};
65+
66+
if (WTF_ENABLED) {
67+
callback.toString = function() {
68+
return 'ng-' + name + '="' + attr[directiveName] + '"';
69+
};
70+
}
71+
6572
if (forceAsyncEvents[eventName] && scope.$$phase) {
6673
scope.$evalAsync(callback);
6774
} else {

src/ng/parse.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,11 @@ function $ParseProvider() {
11171117
// initial value is defined (for bind-once)
11181118
return isDefined(value) ? result : value;
11191119
};
1120+
1121+
if (WTF_ENABLED) {
1122+
fn.exp = parsedExpression;
1123+
}
1124+
11201125
fn.$$watchDelegate = parsedExpression.$$watchDelegate;
11211126
return fn;
11221127
}

src/ng/q.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,28 @@ function qFactory(nextTick, exceptionHandler) {
325325
function scheduleProcessQueue(state) {
326326
if (state.processScheduled || !state.pending) return;
327327
state.processScheduled = true;
328-
nextTick(function() { processQueue(state); });
328+
329+
var fn = function() { processQueue(state); };
330+
331+
if (WTF_ENABLED) {
332+
var pending = state.pending;
333+
334+
fn.toString = function() {
335+
var callbacks = state.pending.map(function(p) {
336+
return p[state.status];
337+
}).filter(function(callback) {
338+
return !!callback;
339+
}).map(function(callback) {
340+
return callback.name || callback.toString();
341+
});
342+
343+
return (state.status === 1 ? 'resolving' : 'rejecting') + ' promise\n' +
344+
'callbacks (' + callbacks.length + '):\n' + callbacks.join('\n\n') + '\n\n' +
345+
'value: ' + toJson(state.value, true);
346+
};
347+
}
348+
349+
nextTick(fn);
329350
}
330351

331352
function Deferred() {

src/ng/rootScope.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,11 @@ function $RootScopeProvider(){
622622
}
623623
}
624624

625+
if (WTF_ENABLED) {
626+
$watchCollectionAction.exp = listener;
627+
changeDetector.exp = obj;
628+
}
629+
625630
return this.$watch(changeDetector, $watchCollectionAction);
626631
},
627632

@@ -687,6 +692,15 @@ function $RootScopeProvider(){
687692
watchLog = [],
688693
logIdx, logMsg, asyncTask;
689694

695+
var wtfDigestScope, wtfDigestCycleScope, wtfDigestCycleCount, wtfAsyncQueueScope,
696+
wtfAsyncQueueCount, wtfWatcherScope;
697+
698+
if (WTF_ENABLED) {
699+
wtfDigestScope = WTF.trace.enterScope('$digest');
700+
wtfDigestCycleCount = 0;
701+
wtfAsyncQueueCount = 0;
702+
}
703+
690704
beginPhase('$digest');
691705
// Check for changes to browser url that happened in sync before the call to $digest
692706
$browser.$$checkUrlChange();
@@ -704,8 +718,17 @@ function $RootScopeProvider(){
704718
dirty = false;
705719
current = target;
706720

721+
if (WTF_ENABLED) {
722+
wtfDigestCycleCount++;
723+
wtfDigestCycleScope = WTF.trace.enterScope('$digest#' + wtfDigestCycleCount);
724+
wtfAsyncQueueScope = WTF.trace.enterScope('$digest#asyncQueue');
725+
}
726+
707727
while(asyncQueue.length) {
708728
try {
729+
if (WTF_ENABLED) {
730+
wtfAsyncQueueCount++
731+
}
709732
asyncTask = asyncQueue.shift();
710733
asyncTask.scope.$eval(asyncTask.expression);
711734
} catch (e) {
@@ -714,6 +737,11 @@ function $RootScopeProvider(){
714737
lastDirtyWatch = null;
715738
}
716739

740+
if (WTF_ENABLED) {
741+
WTF.trace.appendScopeData('length', wtfAsyncQueueCount);
742+
WTF.trace.leaveScope(wtfAsyncQueueScope);
743+
}
744+
717745
traverseScopesLoop:
718746
do { // "traverse the scopes" loop
719747
if ((watchers = current.$$watchers)) {
@@ -733,7 +761,33 @@ function $RootScopeProvider(){
733761
dirty = true;
734762
lastDirtyWatch = watch;
735763
watch.last = watch.eq ? copy(value, null) : value;
764+
765+
if (WTF_ENABLED) {
766+
wtfWatcherScope = WTF.trace.enterScope('watcher');
767+
if (watch.exp) {
768+
// interpolation watch.exp.exp
769+
// parse watch.exp
770+
if (watch.exp.exp) {
771+
WTF.trace.appendScopeData('exp', watch.exp.exp.toString());
772+
} else if (Object.hasOwnProperty.call(watch.exp, 'toString')) {
773+
WTF.trace.appendScopeData('exp', watch.exp.toString());
774+
} else {
775+
WTF.trace.appendScopeData('exp', watch.exp.name || watch.exp.toString());
776+
}
777+
}
778+
779+
WTF.trace.appendScopeData('get', (watch.get.name || watch.get.toString()));
780+
WTF.trace.appendScopeData('fn', (watch.fn.name || watch.fn.toString()));
781+
WTF.trace.appendScopeData('previous', toJson(last));
782+
WTF.trace.appendScopeData('current', toJson(value));
783+
}
784+
736785
watch.fn(value, ((last === initWatchVal) ? value : last), current);
786+
787+
if (WTF_ENABLED) {
788+
WTF.trace.leaveScope(wtfWatcherScope);
789+
}
790+
737791
if (ttl < 5) {
738792
logIdx = 4 - ttl;
739793
if (!watchLog[logIdx]) watchLog[logIdx] = [];
@@ -777,17 +831,41 @@ function $RootScopeProvider(){
777831
TTL, toJson(watchLog));
778832
}
779833

834+
if (WTF_ENABLED) {
835+
WTF.trace.leaveScope(wtfDigestCycleScope);
836+
}
837+
780838
} while (dirty || asyncQueue.length);
781839

840+
if (WTF_ENABLED) {
841+
WTF.trace.appendScopeData('cycles', wtfDigestCycleCount);
842+
WTF.trace.leaveScope(wtfDigestScope);
843+
}
844+
782845
clearPhase();
783846

847+
var wtfPostDigestQueueScope, wtfPostDigestQueueCount;
848+
849+
if (WTF_ENABLED) {
850+
wtfPostDigestQueueScope = WTF.trace.enterScope('$digest#postDigestQueue');
851+
wtfPostDigestQueueCount = 0;
852+
}
853+
784854
while(postDigestQueue.length) {
785855
try {
856+
if (WTF_ENABLED) {
857+
wtfPostDigestQueueCount++;
858+
}
786859
postDigestQueue.shift()();
787860
} catch (e) {
788861
$exceptionHandler(e);
789862
}
790863
}
864+
865+
if (WTF_ENABLED) {
866+
WTF.trace.appendScopeData('length', wtfPostDigestQueueCount);
867+
WTF.trace.leaveScope(wtfPostDigestQueueScope);
868+
}
791869
},
792870

793871

@@ -895,6 +973,20 @@ function $RootScopeProvider(){
895973
* @returns {*} The result of evaluating the expression.
896974
*/
897975
$eval: function(expr, locals) {
976+
if (WTF_ENABLED) {
977+
var wtfScope = WTF.trace.enterScope('$eval');
978+
979+
if (expr) {
980+
WTF.trace.appendScopeData('expression', Object.hasOwnProperty.call(expr, 'toString') ? expr.toString() : (expr.name || expr.toString()));
981+
}
982+
983+
var result = $parse(expr)(this, locals);
984+
985+
WTF.trace.leaveScope(wtfScope);
986+
987+
return result;
988+
}
989+
898990
return $parse(expr)(this, locals);
899991
},
900992

src/ng/timeout.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ function $TimeoutProvider() {
3939
timeoutId;
4040

4141
timeoutId = $browser.defer(function() {
42+
var wtfScope;
43+
44+
if (WTF_ENABLED) {
45+
wtfScope = WTF.trace.enterScope('$timeout');
46+
WTF.trace.appendScopeData('fn', fn.name || fn.toString());
47+
}
48+
4249
try {
4350
deferred.resolve(fn());
4451
} catch(e) {
@@ -50,6 +57,9 @@ function $TimeoutProvider() {
5057
}
5158

5259
if (!skipApply) $rootScope.$apply();
60+
if (WTF_ENABLED) {
61+
WTF.trace.leaveScope(wtfScope);
62+
}
5363
}, delay);
5464

5565
promise.$$timeoutId = timeoutId;

0 commit comments

Comments
 (0)