From c6f4a5e34540651e06c903e9a3c0c3e9ba940e5a Mon Sep 17 00:00:00 2001 From: Ian Christian Myers Date: Thu, 16 Feb 2017 17:43:55 -0800 Subject: [PATCH] Fix error caused by templates in ConditionalExpressions (jsx-indent) Template strings are constructed differently from other tokens in espree. Other tokens are created by the Token class and are thus Token class objects. They look like this: ``` Token { type: 'String', value: '"bar"', start: 44, end: 49, loc: SourceLocation { start: Position { line: 4, column: 11 }, end: Position { line: 4, column: 16 } }, range: [ 44, 49 ] } ``` Template tokens, however, are constructed differently and end up as plain JavaScript objects, which look like this: ``` { type: 'Template', value: '`bar`', loc: { start: Position { line: 4, column: 11 }, end: Position { line: 4, column: 16 } }, range: [ 44, 49 ] } ``` See: [espree's token-translator.js](https://github.com/eslint/espree/blob/58f75be6b89d8904b6366ed368045cb02c4a4e33/lib/token-translator.js#L43) As a result of this different construction, the `start` and `end` properties are not present on the template token object. To correct this I've changed to using the `range` property, which I infer to be more proper given the method it is being passed into is called `getNodeByRangeIndex`. I also think we can safely rely on `range` being present on all token types. Fixes #1061 --- lib/rules/jsx-indent.js | 3 ++- tests/lib/rules/jsx-indent.js | 41 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/rules/jsx-indent.js b/lib/rules/jsx-indent.js index 5d1cfda332..773e979de1 100644 --- a/lib/rules/jsx-indent.js +++ b/lib/rules/jsx-indent.js @@ -275,7 +275,8 @@ module.exports = { do { prevToken = sourceCode.getTokenBefore(prevToken); } while (prevToken.type === 'Punctuator'); - prevToken = sourceCode.getNodeByRangeIndex(prevToken.start); + prevToken = sourceCode.getNodeByRangeIndex(prevToken.range[0]); + while (prevToken.parent && prevToken.parent.type !== 'ConditionalExpression') { prevToken = prevToken.parent; } diff --git a/tests/lib/rules/jsx-indent.js b/tests/lib/rules/jsx-indent.js index 20e07641c7..737fdf45b2 100644 --- a/tests/lib/rules/jsx-indent.js +++ b/tests/lib/rules/jsx-indent.js @@ -410,6 +410,47 @@ ruleTester.run('jsx-indent', rule, { ].join('\n'), options: [4, {indentLogicalExpressions: true}], parserOptions: parserOptions + }, { + code: [ + '', + ' {condition ?', + ' :', + ' ', + ' }', + '' + ].join('\n'), + options: [2], + parserOptions: parserOptions + }, { + code: [ + '', + ' {condition ?', + ' :', + ' ', + ' }', + '' + ].join('\n'), + options: [2], + parserOptions: parserOptions + }, { + code: [ + 'function foo() {', + ' ', + ' {condition ?', + ' :', + ' ', + ' }', + ' ', + '}' + ].join('\n'), + options: [2], + parserOptions: parserOptions }], invalid: [{