123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- 'use strict';
- // https://github.com/eslint/espree/blob/6b7d0b8100537dcd5c84a7fb17bbe28edcabe05d/lib/token-translator.js#L20
- const tokenTypesNeedsSemicolon = new Set([
- 'String',
- 'Null',
- 'Boolean',
- 'Numeric',
- 'RegularExpression',
- ]);
- const charactersMightNeedsSemicolon = new Set([
- '[',
- '(',
- '/',
- '`',
- '+',
- '-',
- '*',
- ',',
- '.',
- ]);
- /**
- Determines if a semicolon needs to be inserted before `code`, in order to avoid a SyntaxError.
- @param {Token} tokenBefore Token before `code`.
- @param {SourceCode} sourceCode
- @param {String} [code] Code text to determine.
- @returns {boolean} `true` if a semicolon needs to be inserted before `code`.
- */
- function needsSemicolon(tokenBefore, sourceCode, code) {
- if (
- code === ''
- || (code && !charactersMightNeedsSemicolon.has(code.charAt(0)))
- ) {
- return false;
- }
- if (!tokenBefore) {
- return false;
- }
- const {type, value, range} = tokenBefore;
- const lastBlockNode = sourceCode.getNodeByRangeIndex(range[0]);
- if (type === 'Punctuator') {
- if (value === ';') {
- return false;
- }
- if (value === ']') {
- return true;
- }
- if (value === ')') {
- switch (lastBlockNode.type) {
- case 'IfStatement': {
- if (sourceCode.getTokenBefore(lastBlockNode.consequent) === tokenBefore) {
- return false;
- }
- break;
- }
- case 'ForStatement':
- case 'ForInStatement':
- case 'ForOfStatement':
- case 'WhileStatement':
- case 'DoWhileStatement':
- case 'WithStatement': {
- if (lastBlockNode.body && sourceCode.getTokenBefore(lastBlockNode.body) === tokenBefore) {
- return false;
- }
- break;
- }
- // No default
- }
- return true;
- }
- }
- if (tokenTypesNeedsSemicolon.has(type)) {
- return true;
- }
- if (type === 'Template') {
- return value.endsWith('`');
- }
- if (lastBlockNode.type === 'ObjectExpression') {
- return true;
- }
- if (type === 'Identifier') {
- // `for...of`
- if (value === 'of' && lastBlockNode.type === 'ForOfStatement') {
- return false;
- }
- // `await`
- if (value === 'await' && lastBlockNode.type === 'AwaitExpression') {
- return false;
- }
- return true;
- }
- return false;
- }
- module.exports = needsSemicolon;
|