'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;