UNPKG

alm

Version:

The best IDE for TypeScript

106 lines (105 loc) 4.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function isBinaryAddition(node) { return (node.kind == ts.SyntaxKind.BinaryExpression && node.operatorToken.kind == ts.SyntaxKind.PlusToken); } function isStringExpression(node, typeChecker) { var type = typeChecker.getTypeAtLocation(node); var flags = type.getFlags(); return !!(flags & ts.TypeFlags.String); } /** Returns the root (binary +) node if there is some otherwise returns undefined */ function isAPartOfAChainOfStringAdditions(node, typeChecker) { // We are looking for the `largestSumNode`. Its set once we find one up our tree var largestSumNode = undefined; while (true) { // Whenever we find a binary expression of type sum that evaluates to a string if (isBinaryAddition(node) && isStringExpression(node, typeChecker)) { largestSumNode = node; } // We've gone too far up if (node.kind == ts.SyntaxKind.SourceFile) { return largestSumNode; } // Next look at the parent to find a larger sum node node = node.parent; } } var StringConcatToTemplate = /** @class */ (function () { function StringConcatToTemplate() { this.key = StringConcatToTemplate.name; } StringConcatToTemplate.prototype.canProvideFix = function (info) { // Algo // Can provide a quick fix if we are part of an expression that // is a part of a binary + expression // and when these binary +es end we come to an expression which is of type `string` // Based on algo we do not care about what the current thing is as long as its a part of a sum of additions var strRoot = isAPartOfAChainOfStringAdditions(info.positionNode, info.typeChecker); if (strRoot) { return { display: 'String concatenations to a template string' }; } }; StringConcatToTemplate.prototype.provideFix = function (info) { var strRoot = isAPartOfAChainOfStringAdditions(info.positionNode, info.typeChecker); var finalOutput = []; var current = strRoot; var backTickCharacter = '`'; var backTick = new RegExp(backTickCharacter, 'g'); var $regex = /\$/g; var appendToFinal = function (node) { // Each string literal needs : // to be checked that it doesn't contain (`) and those need to be escaped. // Also `$` needs escaping // Also the quote characters at the limits need to be removed if (node.kind == ts.SyntaxKind.StringLiteral) { var text = node.getText(); var quoteCharacter = text.trim()[0]; var quoteRegex = new RegExp(quoteCharacter, 'g'); var escapedQuoteRegex = new RegExp("\\\\" + quoteCharacter, 'g'); var newText_1 = text .replace(backTick, "\\" + backTickCharacter) .replace(escapedQuoteRegex, quoteCharacter) .replace($regex, '\\$'); newText_1 = newText_1.substr(1, newText_1.length - 2); finalOutput.unshift(newText_1); } else if (node.kind == ts.SyntaxKind.TemplateExpression || node.kind == ts.SyntaxKind.NoSubstitutionTemplateLiteral) { var text = node.getText(); text = text.trim(); text = text.substr(1, text.length - 2); finalOutput.unshift(text); } else { finalOutput.unshift('${' + node.getText() + '}'); } }; // We pop of each left node one by one while (true) { // if we are still in some sequence of additions if (current.kind == ts.SyntaxKind.BinaryExpression) { var binary = current; appendToFinal(binary.right); // Continue with left current = binary.left; } else { appendToFinal(current); break; } } var newText = backTickCharacter + finalOutput.join('') + backTickCharacter; var refactoring = { span: { start: strRoot.getStart(), length: strRoot.end - strRoot.getStart() }, newText: newText, filePath: info.filePath }; return [refactoring]; }; return StringConcatToTemplate; }()); exports.StringConcatToTemplate = StringConcatToTemplate;