UNPKG

2.85 kBJavaScriptView Raw
1'use strict';
2
3var syntax = require('estraverse').Syntax;
4
5function locationOf(currentNode, tokens) {
6 switch(currentNode.type) {
7 case syntax.MemberExpression:
8 return propertyLocationOf(currentNode, tokens);
9 case syntax.CallExpression:
10 if (currentNode.callee.type === syntax.MemberExpression) {
11 return propertyLocationOf(currentNode.callee, tokens);
12 }
13 break;
14 case syntax.BinaryExpression:
15 case syntax.LogicalExpression:
16 case syntax.AssignmentExpression:
17 return infixOperatorLocationOf(currentNode, tokens);
18 default:
19 break;
20 }
21 return currentNode.loc;
22}
23
24function propertyLocationOf(memberExpression, tokens) {
25 var prop = memberExpression.property,
26 token;
27 if (!memberExpression.computed) {
28 return prop.loc;
29 }
30 token = findLeftBracketTokenOf(memberExpression, tokens);
31 return token ? token.loc : prop.loc;
32}
33
34// calculate location of infix operator for BinaryExpression, AssignmentExpression and LogicalExpression.
35function infixOperatorLocationOf (expression, tokens) {
36 var token = findOperatorTokenOf(expression, tokens);
37 return token ? token.loc : expression.left.loc;
38}
39
40function findLeftBracketTokenOf(expression, tokens) {
41 var fromLine = expression.loc.start.line,
42 toLine = expression.property.loc.start.line,
43 fromColumn = expression.property.loc.start.column;
44 return searchToken(tokens, fromLine, toLine, function (token, index) {
45 var prevToken;
46 if (token.loc.start.column === fromColumn) {
47 prevToken = tokens[index - 1];
48 if (prevToken.type === 'Punctuator' && prevToken.value === '[') {
49 return prevToken;
50 }
51 }
52 return undefined;
53 });
54}
55
56function findOperatorTokenOf(expression, tokens) {
57 var fromLine = expression.left.loc.end.line,
58 toLine = expression.right.loc.start.line,
59 fromColumn = expression.left.loc.end.column,
60 toColumn = expression.right.loc.start.column;
61 return searchToken(tokens, fromLine, toLine, function (token, index) {
62 if (fromColumn < token.loc.start.column &&
63 token.loc.end.column < toColumn &&
64 token.type === 'Punctuator' &&
65 token.value === expression.operator) {
66 return token;
67 }
68 return undefined;
69 });
70}
71
72function searchToken(tokens, fromLine, toLine, predicate) {
73 var i, token, found;
74 for(i = 0; i < tokens.length; i += 1) {
75 token = tokens[i];
76 if (token.loc.start.line < fromLine) {
77 continue;
78 }
79 if (toLine < token.loc.end.line) {
80 break;
81 }
82 found = predicate(token, i);
83 if (found) {
84 return found;
85 }
86 }
87 return undefined;
88}
89
90module.exports = locationOf;