You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.4 KiB
JavaScript
81 lines
2.4 KiB
JavaScript
6 years ago
|
'use strict';
|
||
|
|
||
|
var syntax = require('estraverse').Syntax;
|
||
|
|
||
|
function locationOf(currentNode, tokens) {
|
||
|
switch(currentNode.type) {
|
||
|
case syntax.MemberExpression:
|
||
|
return propertyLocationOf(currentNode, tokens);
|
||
|
case syntax.CallExpression:
|
||
|
if (currentNode.callee.type === syntax.MemberExpression) {
|
||
|
return propertyLocationOf(currentNode.callee, tokens);
|
||
|
}
|
||
|
break;
|
||
|
case syntax.BinaryExpression:
|
||
|
case syntax.LogicalExpression:
|
||
|
case syntax.AssignmentExpression:
|
||
|
return infixOperatorLocationOf(currentNode, tokens);
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return currentNode.range;
|
||
|
}
|
||
|
|
||
|
function propertyLocationOf(memberExpression, tokens) {
|
||
|
var prop = memberExpression.property;
|
||
|
var token;
|
||
|
if (!memberExpression.computed) {
|
||
|
return prop.range;
|
||
|
}
|
||
|
token = findLeftBracketTokenOf(memberExpression, tokens);
|
||
|
return token ? token.range : prop.range;
|
||
|
}
|
||
|
|
||
|
// calculate location of infix operator for BinaryExpression, AssignmentExpression and LogicalExpression.
|
||
|
function infixOperatorLocationOf (expression, tokens) {
|
||
|
var token = findOperatorTokenOf(expression, tokens);
|
||
|
return token ? token.range : expression.left.range;
|
||
|
}
|
||
|
|
||
|
function findLeftBracketTokenOf(expression, tokens) {
|
||
|
var fromColumn = expression.property.range[0];
|
||
|
return searchToken(tokens, function (token, index) {
|
||
|
var prevToken;
|
||
|
if (token.range[0] === fromColumn) {
|
||
|
prevToken = tokens[index - 1];
|
||
|
// if (prevToken.type === 'Punctuator' && prevToken.value === '[') { // esprima
|
||
|
if (prevToken.type.label === '[') { // acorn
|
||
|
return prevToken;
|
||
|
}
|
||
|
}
|
||
|
return undefined;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function findOperatorTokenOf(expression, tokens) {
|
||
|
var fromColumn = expression.left.range[1];
|
||
|
var toColumn = expression.right.range[0];
|
||
|
return searchToken(tokens, function (token, index) {
|
||
|
if (fromColumn < token.range[0] &&
|
||
|
token.range[1] < toColumn &&
|
||
|
token.value === expression.operator) {
|
||
|
return token;
|
||
|
}
|
||
|
return undefined;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function searchToken(tokens, predicate) {
|
||
|
var i, token, found;
|
||
|
for(i = 0; i < tokens.length; i += 1) {
|
||
|
token = tokens[i];
|
||
|
found = predicate(token, i);
|
||
|
if (found) {
|
||
|
return found;
|
||
|
}
|
||
|
}
|
||
|
return undefined;
|
||
|
}
|
||
|
|
||
|
module.exports = locationOf;
|