ts-unused-exports
Version:
ts-unused-exports finds unused exported symbols in your Typescript project
165 lines • 6.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDynamicImports = exports.mayContainDynamicImports = void 0;
var ts = require("typescript");
var common_1 = require("./common");
var util_1 = require("./util");
var blacklists_1 = require("./blacklists");
// Parse Dynamic Imports
exports.mayContainDynamicImports = function (node) {
return !blacklists_1.namespaceBlacklist.includes(node.kind) && node.getText().includes('import(');
};
function isWithExpressionBoolean(node) {
var myInterface = node;
return !!myInterface.expression;
}
function isWithExpression(node) {
return isWithExpressionBoolean(node);
}
var parseDereferencedLambdaParamsToTypes = function (paramName, lambda) {
var types = [];
var usagePrefix = paramName + ".";
util_1.recurseIntoChildren(lambda, function (child) {
if (child.getText().startsWith(usagePrefix)) {
var usage = child.getText().substring(usagePrefix.length);
types.push(usage);
}
return true;
});
return types;
};
var hasBracesLike = function (paramList, openBrace, closeBrace) {
return paramList.startsWith(openBrace) && paramList.endsWith(closeBrace);
};
var parseDestructuredLambdaParamsToTypes = function (paramList) {
if (hasBracesLike(paramList, '{', '}')) {
var names = paramList.substring(1, paramList.length - 1);
return names
.split(',')
.map(function (n) { return (n.includes(':') ? n.split(':')[0] : n); })
.map(function (n) { return n.trim(); });
}
return [paramList];
};
/* Handle lambdas where the content uses imported types, via dereferencing.
* example:
* A_imported => {
* console.log(A_imported.A);
* }
*/
var findLambdasWithDereferencing = function (node) {
var what = [];
var processLambda = function (lambda) {
if (lambda.getChildCount() === 3) {
var paramName = lambda.getChildren()[0].getText();
parseDereferencedLambdaParamsToTypes(paramName, lambda).forEach(function (t) {
return what.push(t);
});
}
else if (lambda.getChildCount() === 5 &&
lambda.getChildAt(1).kind == ts.SyntaxKind.SyntaxList) {
var paramNames = lambda.getChildren()[1].getText();
parseDestructuredLambdaParamsToTypes(paramNames).forEach(function (p) {
what.push(p);
parseDereferencedLambdaParamsToTypes(p, lambda).forEach(function (t) {
return what.push(t);
});
});
}
};
var firstArrow = util_1.findFirstChildOfKind(node, ts.SyntaxKind.ArrowFunction);
if (firstArrow) {
processLambda(firstArrow);
}
return what;
};
var addImportViaLambda = function (node, from, addImport) {
var whatFromLambda = findLambdasWithDereferencing(node);
var what = ['default'].concat(whatFromLambda);
addImport({
from: common_1.getFromText(from),
what: what,
});
return whatFromLambda.length !== 0;
};
var tryParseImportExpression = function (expr, addImport) {
var callExpression = util_1.findFirstChildOfKind(expr, ts.SyntaxKind.CallExpression);
if (!(callExpression === null || callExpression === void 0 ? void 0 : callExpression.getText().startsWith('import'))) {
return false;
}
var syntaxListWithFrom = util_1.findFirstChildOfKind(callExpression, ts.SyntaxKind.SyntaxList);
if (!syntaxListWithFrom) {
return false;
}
var from = syntaxListWithFrom.getText();
return addImportViaLambda(expr, from, addImport);
};
var tryParseExpression = function (expr, addImport) {
if (expr.getText().startsWith('import')) {
return tryParseImportExpression(expr, addImport);
}
// Handle complex expressions, where the 'import' is buried in a tree.
// Example: see test with Promise.all[]
util_1.recurseIntoChildren(expr, function (node) {
if (isWithExpressionBoolean(node) && node.getText().startsWith('import')) {
tryParseImportExpression(node, addImport);
}
return true;
});
return false;
};
// note: JSX Attributes do not show up as children.
var handleImportWithJsxAttributes = function (attributes, addImport) {
attributes.properties.forEach(function (prop) {
if (ts.isJsxAttribute(prop)) {
if (prop.initializer &&
ts.isJsxExpression(prop.initializer) &&
prop.initializer.expression) {
tryParseExpression(prop.initializer.expression, addImport);
}
}
});
};
var handleImportWithinExpression = function (node, addImport) {
var expression1 = null;
if (node.kind === ts.SyntaxKind.CallExpression)
expression1 = node;
else if (isWithExpression(node))
expression1 = node.expression;
while (!!expression1) {
if (!tryParseExpression(expression1, addImport)) {
if (ts.isJsxElement(expression1) || ts.isJsxFragment(expression1)) {
var jsxExpressions = util_1.findAllChildrenOfKind(expression1, ts.SyntaxKind.JsxExpression);
jsxExpressions.forEach(function (j) {
var jsxExpr = j;
if (jsxExpr.expression) {
tryParseExpression(jsxExpr.expression, addImport);
}
});
}
var selfClosingElements = util_1.findAllChildrenOfKind(expression1, ts.SyntaxKind.JsxSelfClosingElement);
selfClosingElements.forEach(function (elem) {
if (ts.isJsxSelfClosingElement(elem)) {
handleImportWithJsxAttributes(elem.attributes, addImport);
}
});
}
if (isWithExpression(expression1)) {
expression1 = expression1.expression;
}
else {
break;
}
}
};
exports.addDynamicImports = function (node, addImport) {
var addImportsInAnyExpression = function (node) {
if (isWithExpression(node)) {
handleImportWithinExpression(node, addImport); // can be a ParenthesizedExpression with a JSX element inside it
}
return true;
};
// Recurse, since dynamic imports can occur at nested levels within the code
util_1.recurseIntoChildren(node, addImportsInAnyExpression);
};
//# sourceMappingURL=dynamic.js.map