@xtrek/ts-migrate-plugins
Version:
Set of codemods, which are doing transformation of js/jsx to ts/tsx
73 lines • 3.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jscodeshift_1 = __importDefault(require("jscodeshift"));
const type_guards_1 = require("../utils/type-guards");
const validateOptions_1 = require("../utils/validateOptions");
const j = jscodeshift_1.default.withParser('tsx');
const declareMissingClassPropertiesPlugin = {
name: 'declare-missing-class-properties',
async run({ text, fileName, getLanguageService, options }) {
const diagnostics = getLanguageService()
.getSemanticDiagnostics(fileName)
.filter(type_guards_1.isDiagnosticWithLinePosition)
.filter((diagnostic) => diagnostic.code === 2339 || diagnostic.code === 2551);
const root = j(text);
const toAdd = [];
diagnostics.forEach((diagnostic) => {
root
.find(j.Identifier)
.filter((path) => path.node.start === diagnostic.start &&
path.node.end === diagnostic.start + diagnostic.length &&
path.parentPath.node.type === 'MemberExpression' &&
path.parentPath.node.object.type === 'ThisExpression')
.forEach((path) => {
const classBody = findParentClassBody(path);
if (classBody) {
let item = toAdd.find((cur) => cur.classBody === classBody);
if (!item) {
item = { classBody, propertyNames: new Set() };
toAdd.push(item);
}
item.propertyNames.add(path.node.name);
}
});
});
toAdd.forEach(({ classBody, propertyNames: propertyNameSet }) => {
const propertyNames = Array.from(propertyNameSet)
.filter((propertyName) => {
const existingProperty = classBody.node.body.find((n) => n.type === 'ClassProperty' &&
n.key.type === 'Identifier' &&
n.key.name === propertyName);
return existingProperty == null;
})
.sort();
let index = -1;
for (let i = 0; i < classBody.node.body.length; i += 1) {
const node = classBody.node.body[i];
if (node.type === 'ClassProperty' && node.static) {
index = i;
}
}
classBody.node.body.splice(index + 1, 0, ...propertyNames.map((propertyName) => j.classProperty(j.identifier(propertyName), null, j.tsTypeAnnotation(options.anyAlias == null
? j.tsAnyKeyword()
: j.tsTypeReference(j.identifier(options.anyAlias))))));
});
return root.toSource();
},
validate: validateOptions_1.validateAnyAliasOptions,
};
exports.default = declareMissingClassPropertiesPlugin;
function findParentClassBody(path) {
let cur = path;
while (cur.node.type !== 'Program') {
if (cur.node.type === 'ClassBody') {
return cur;
}
cur = cur.parentPath;
}
return undefined;
}
//# sourceMappingURL=declare-missing-class-properties.js.map