|
8 | 8 | * Factory in the ui.logger. |
9 | 9 | */ |
10 | 10 | (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 | + |
11 | 90 | function _findSourceMappingURL(source) { |
12 | 91 | var m = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)\s*$/.exec(source); |
13 | 92 | if (m && m[1]) { |
|
17 | 96 | function Configure(options) { |
18 | 97 | angular.extend(this.options,options); |
19 | 98 | } |
| 99 | + |
20 | 100 | function validURL(str) { |
21 | 101 | var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; |
22 | 102 | return regexp.test(str); |
|
29 | 109 | // } |
30 | 110 | // return str; |
31 | 111 | //} |
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; |
70 | 120 | } |
71 | | - return undefined; |
72 | 121 | } |
73 | 122 | function Provider(sourceMap) { |
74 | 123 | this.options={ |
|
104 | 153 | _cache[url]={ |
105 | 154 | exist:def1.promise, |
106 | 155 | _map:{}, |
107 | | - _file:'' |
| 156 | + _file:'', |
| 157 | + _syntaxTree:'' |
108 | 158 | }; |
109 | 159 | getSourceFileUrl(url).then(function(mapUrl){ |
110 | 160 | if(mapUrl && !validURL(mapUrl)){ |
|
117 | 167 | column: stack.columnNumber |
118 | 168 | }); |
119 | 169 | 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); |
121 | 172 | _stack=new window.StackFrame(loc.name, stack.args, loc.source, loc.line, loc.column); |
122 | 173 | def.resolve(_stack); |
123 | 174 | }else{ |
124 | 175 | var sourceFileUlr=url.substring(0,url.lastIndexOf('/')+1)+loc.source; |
125 | 176 | $.ajax(sourceFileUlr).then(function(content) { |
126 | 177 | _cache[url]._file=content; |
127 | 178 | 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); |
129 | 181 | _stack=new window.StackFrame(loc.name, stack.args, loc.source, loc.line, loc.column); |
130 | 182 | def.resolve(_stack); |
131 | 183 | }).fail(function() { |
|
155 | 207 | line: stack.lineNumber, |
156 | 208 | column: stack.columnNumber |
157 | 209 | }); |
158 | | - loc.name=_findFunctionName(_cache[url]._file,loc.line, loc.column); |
| 210 | + loc.name=_findFunctionName( _cache[url]._syntaxTree,loc.line, loc.column); |
159 | 211 | _stack=new window.StackFrame(loc.name, stack.args, loc.source, loc.line, loc.column); |
160 | 212 | def.resolve(_stack); |
161 | 213 | } |
|
0 commit comments