Skip to content

Commit 1c8cf4a

Browse files
Merge pull request #8 from IamKritika/master
finding function name through esprima library
2 parents df3fde3 + 91aa1fc commit 1c8cf4a

File tree

3 files changed

+99
-45
lines changed

3 files changed

+99
-45
lines changed

app/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@
7171
<script src="bower_components/error-stack-parser/error-stack-parser.js"></script>
7272
<script src="bower_components/stack-generator/stack-generator.js"></script>
7373
<script src="bower_components/stacktrace-gps/dist/stacktrace-gps.js"></script>
74-
<script src="bower_components/stacktrace-js/dist/stacktrace.js"></script>
74+
<script src="bower_components/stacktrace-js/stacktrace.js"></script>
75+
<script src="bower_components/esprima/esprima.js"></script>
7576
<!-- endbower -->
7677
<script src="bower_components/source-map/dist/source-map.js"></script>
7778

app/scripts/services/source-map-util.js

Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,85 @@
88
* Factory in the ui.logger.
99
*/
1010
(function(){
11+
function findNode(nodeList,lineNumber,ColumnNumber){
12+
var first = 0;
13+
var last = nodeList.length - 1;
14+
var nodeIndex;
15+
var middle = Math.floor((first+last)/2);
16+
while(first<=last){
17+
if(nodeList[middle].loc.start.line>lineNumber){
18+
last = middle -1;
19+
}
20+
else if((nodeList[middle].loc.start.line<=lineNumber) && (nodeList[middle].loc.end.line >=lineNumber) ){
21+
if(nodeList[middle].loc.start.line===lineNumber && nodeList[middle].loc.start.column >ColumnNumber ){
22+
last = middle -1;
23+
}else if(nodeList[middle].loc.end.line===lineNumber && nodeList[middle].loc.end.column < ColumnNumber){
24+
first = middle+1;
25+
}else{
26+
nodeIndex = middle;
27+
break;}
28+
}
29+
else {
30+
first = middle+1;
31+
}
32+
middle = Math.floor((first+last)/2);
33+
}
34+
if(first > last){
35+
return {};
36+
}
37+
else{
38+
39+
return nodeList[nodeIndex];
40+
}
41+
}
42+
43+
function switchNodeType(node,lineNumber,ColumnNumber){
44+
var type = node.type;
45+
var result={};
46+
switch(type) {
47+
case 'ExpressionStatement':
48+
result = switchNodeType(node.expression,lineNumber,ColumnNumber);
49+
break;
50+
case 'CallExpression':
51+
var argumentNode = findNode(node.arguments,lineNumber,ColumnNumber);
52+
if (!Object.keys(argumentNode).length) {
53+
result = switchNodeType(node.callee, lineNumber,ColumnNumber);
54+
}
55+
else {
56+
result = switchNodeType(argumentNode, lineNumber,ColumnNumber);
57+
}
58+
59+
break;
60+
case 'FunctionDeclaration':
61+
case 'FunctionExpression':
62+
var funcNode = findNode(node.body.body, lineNumber,ColumnNumber);
63+
result = switchNodeType(funcNode, lineNumber,ColumnNumber);
64+
if(result.id===undefined){
65+
result=node;
66+
}
67+
break;
68+
case 'ArrayExpression':
69+
var arrNode=findNode(node.elements, lineNumber,ColumnNumber);
70+
result = switchNodeType(arrNode, lineNumber,ColumnNumber);
71+
break;
72+
case 'VariableDeclaration':
73+
var declarationNode=findNode(node.declarations, lineNumber,ColumnNumber);
74+
var testNode=switchNodeType(declarationNode.init, lineNumber,ColumnNumber);
75+
if(testNode.type==='FunctionDeclaration'||testNode.type==='FunctionExpression'){
76+
result=declarationNode;
77+
}else{
78+
result = node;
79+
}
80+
break;
81+
case 'AssignmentExpression':
82+
result =switchNodeType(node.right, lineNumber,ColumnNumber);
83+
break;
84+
default :
85+
result = node;
86+
}
87+
return result;
88+
}
89+
1190
function _findSourceMappingURL(source) {
1291
var m = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)\s*$/.exec(source);
1392
if (m && m[1]) {
@@ -17,6 +96,7 @@
1796
function Configure(options) {
1897
angular.extend(this.options,options);
1998
}
99+
20100
function validURL(str) {
21101
var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
22102
return regexp.test(str);
@@ -29,46 +109,15 @@
29109
// }
30110
// return str;
31111
//}
32-
function _findFunctionName(source, lineNumber) {
33-
// function {name}({args}) m[1]=name m[2]=args
34-
var reFunctionDeclaration = /function+([^(]*?)\s*\(([^)]*)\)/;
35-
// {name} = function ({args})
36-
var reFunctionExpression = /['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*function\b/;
37-
// {name} = eval()
38-
var reFunctionEvaluation = /['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*(?:eval|new Function)\b/;
39-
var lines = source.split('\n');
40-
41-
// Walk backwards in the source lines until we find the line which matches one of the patterns above
42-
var code = '', line, maxLines = Math.min(lineNumber, 50), m, commentPos;
43-
for (var i = 0; i < maxLines; ++i) {
44-
// lineNo is 1-based, source[] is 0-based
45-
line = lines[lineNumber - i - 1];
46-
if(line){
47-
commentPos = line.indexOf('//');
48-
if (commentPos >= 0) {
49-
line = line.substr(0, commentPos);
50-
}
51-
}
52-
53-
54-
if (line) {
55-
code = line + code;
56-
m = reFunctionExpression.exec(code);
57-
if (m && m[1]) {
58-
return m[1];
59-
}
60-
m = reFunctionDeclaration.exec(code);
61-
if (m ) {
62-
if(m[1]!=='') {return m[1];}
63-
else { return undefined;}
64-
}
65-
m = reFunctionEvaluation.exec(code);
66-
if (m && m[1]) {
67-
return m[1];
68-
}
69-
}
112+
function _findFunctionName(syntaxTree,lineNumber,ColumnNumber) {
113+
var node= findNode(syntaxTree.body,lineNumber,ColumnNumber);
114+
var finalResult = switchNodeType(node,lineNumber,ColumnNumber);
115+
if(finalResult.id===null){
116+
return undefined;
117+
}
118+
else{
119+
return finalResult.id.name;
70120
}
71-
return undefined;
72121
}
73122
function Provider(sourceMap) {
74123
this.options={
@@ -104,7 +153,8 @@
104153
_cache[url]={
105154
exist:def1.promise,
106155
_map:{},
107-
_file:''
156+
_file:'',
157+
_syntaxTree:''
108158
};
109159
getSourceFileUrl(url).then(function(mapUrl){
110160
if(mapUrl && !validURL(mapUrl)){
@@ -117,15 +167,17 @@
117167
column: stack.columnNumber
118168
});
119169
if(_cache[url]._file){
120-
loc.name=_findFunctionName(_cache[url]._file,loc.line, loc.column);
170+
_cache[url]._syntaxTree = window.esprima.parse(_cache[url]._file,{loc:true});
171+
loc.name=_findFunctionName( _cache[url]._syntaxTree,loc.line, loc.column);
121172
_stack=new window.StackFrame(loc.name, stack.args, loc.source, loc.line, loc.column);
122173
def.resolve(_stack);
123174
}else{
124175
var sourceFileUlr=url.substring(0,url.lastIndexOf('/')+1)+loc.source;
125176
$.ajax(sourceFileUlr).then(function(content) {
126177
_cache[url]._file=content;
127178
def1.resolve(true);
128-
loc.name=_findFunctionName(_cache[url]._file,loc.line, loc.column);
179+
_cache[url]._syntaxTree = window.esprima.parse(_cache[url]._file,{loc:true});
180+
loc.name=_findFunctionName( _cache[url]._syntaxTree,loc.line, loc.column);
129181
_stack=new window.StackFrame(loc.name, stack.args, loc.source, loc.line, loc.column);
130182
def.resolve(_stack);
131183
}).fail(function() {
@@ -155,7 +207,7 @@
155207
line: stack.lineNumber,
156208
column: stack.columnNumber
157209
});
158-
loc.name=_findFunctionName(_cache[url]._file,loc.line, loc.column);
210+
loc.name=_findFunctionName( _cache[url]._syntaxTree,loc.line, loc.column);
159211
_stack=new window.StackFrame(loc.name, stack.args, loc.source, loc.line, loc.column);
160212
def.resolve(_stack);
161213
}

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"moment": "~2.10.6",
77
"stacktrace-js": "~1.0.1",
88
"source-map": "mozilla/source-map#0.5.1",
9-
"jquery": "~2.2.0"
9+
"jquery": "~2.2.0",
10+
"esprima":"2.0.0"
1011
},
1112
"main": [
1213
"dist/scripts/ui.logger.js"

0 commit comments

Comments
 (0)