ts-simple-ast
Version:
TypeScript compiler wrapper for static analysis and code manipulation.
176 lines (175 loc) • 9.94 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var utils_1 = require("../../../utils");
var base_1 = require("../base");
var callBaseSet_1 = require("../callBaseSet");
var module_1 = require("../module");
var statement_1 = require("../statement");
var callBaseGetStructure_1 = require("../callBaseGetStructure");
var base_2 = require("./base");
var common_1 = require("../common");
exports.ClassDeclarationBase = base_1.ChildOrderableNode(module_1.NamespaceChildableNode(base_1.AmbientableNode(base_1.ExportableNode(base_2.ClassLikeDeclarationBase(statement_1.Statement)))));
var ClassDeclaration = /** @class */ (function (_super) {
tslib_1.__extends(ClassDeclaration, _super);
function ClassDeclaration() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Sets the node from a structure.
* @param structure - Structure to set the node with.
*/
ClassDeclaration.prototype.set = function (structure) {
callBaseSet_1.callBaseSet(exports.ClassDeclarationBase.prototype, this, structure);
if (structure.extends != null)
this.setExtends(structure.extends);
else if (structure.hasOwnProperty("extends"))
this.removeExtends();
if (structure.ctors != null) {
this.getConstructors().forEach(function (c) { return c.remove(); });
this.addConstructors(structure.ctors);
}
if (structure.properties != null) {
this.getProperties().forEach(function (p) { return p.remove(); });
this.addProperties(structure.properties);
}
if (structure.getAccessors != null) {
this.getGetAccessors().forEach(function (a) { return a.remove(); });
this.addGetAccessors(structure.getAccessors);
}
if (structure.setAccessors != null) {
this.getSetAccessors().forEach(function (a) { return a.remove(); });
this.addSetAccessors(structure.setAccessors);
}
if (structure.methods != null) {
this.getMethods().forEach(function (m) { return m.remove(); });
this.addMethods(structure.methods);
}
return this;
};
/**
* Gets the structure equivalent to this node.
*/
ClassDeclaration.prototype.getStructure = function () {
var getExtends = this.getExtends();
var isAmbient = this.isAmbient();
return callBaseGetStructure_1.callBaseGetStructure(exports.ClassDeclarationBase.prototype, this, {
ctors: this.getConstructors().filter(function (ctor) { return isAmbient || !ctor.isOverload(); }).map(function (ctor) { return ctor.getStructure(); }),
methods: this.getMethods().filter(function (method) { return isAmbient || !method.isOverload(); }).map(function (method) { return method.getStructure(); }),
properties: this.getProperties().map(function (property) { return property.getStructure(); }),
extends: getExtends ? getExtends.getText() : undefined,
getAccessors: this.getGetAccessors().map(function (getAccessor) { return getAccessor.getStructure(); }),
setAccessors: this.getSetAccessors().map(function (accessor) { return accessor.getStructure(); })
});
};
/**
* Extracts an interface declaration structure from the class.
* @param name - Name of the interface. Falls back to the same name as the class and then the filepath's base name.
*/
ClassDeclaration.prototype.extractInterface = function (name) {
var _a = getExtractedClassDetails(this, false), constructors = _a.constructors, properties = _a.properties, methods = _a.methods, accessors = _a.accessors;
var parameterProperties = utils_1.ArrayUtils.flatten(constructors.map(function (c) { return c.getParameters().filter(function (p) { return p.isParameterProperty(); }); }))
.filter(function (p) { return p.getName() != null && p.getScope() === common_1.Scope.Public; });
return {
name: getDefaultExtractedName(name, this),
docs: this.getJsDocs().map(function (d) { return d.getStructure(); }),
typeParameters: this.getTypeParameters().map(function (p) { return p.getStructure(); }),
properties: tslib_1.__spread(parameterProperties.map(function (p) {
var jsDocComment = utils_1.ArrayUtils.flatten(p.getParentOrThrow().getJsDocs().map(function (j) { return j.getTags(); }))
.filter(utils_1.TypeGuards.isJSDocParameterTag)
.filter(function (t) { return t.getTagName() === "param" && t.getName() === p.getName() && t.getComment() != null; })
.map(function (t) { return t.getComment().trim(); })[0];
return {
docs: jsDocComment == null ? [] : [{ description: jsDocComment }],
name: p.getName(),
type: p.getType().getText(p),
hasQuestionToken: p.hasQuestionToken(),
isReadonly: p.isReadonly()
};
}), properties.map(getExtractedInterfacePropertyStructure), accessors.map(getExtractedInterfaceAccessorStructure)),
methods: methods.map(getExtractedInterfaceMethodStructure)
};
};
/**
* Extracts an interface declaration structure from the static part of the class.
* @param name - Name of the interface.
*/
ClassDeclaration.prototype.extractStaticInterface = function (name) {
var _a = getExtractedClassDetails(this, true), constructors = _a.constructors, properties = _a.properties, methods = _a.methods, accessors = _a.accessors;
var instanceName = getDefaultExtractedName(undefined, this);
return {
name: name,
properties: tslib_1.__spread(properties.map(getExtractedInterfacePropertyStructure), accessors.map(getExtractedInterfaceAccessorStructure)),
methods: methods.map(getExtractedInterfaceMethodStructure),
constructSignatures: constructors.map(function (c) { return ({
docs: c.getJsDocs().map(function (d) { return d.getStructure(); }),
parameters: c.getParameters().map(function (p) { return (tslib_1.__assign({}, getExtractedInterfaceParameterStructure(p), { scope: undefined, isReadonly: false })); }),
returnType: instanceName
}); })
};
};
return ClassDeclaration;
}(exports.ClassDeclarationBase));
exports.ClassDeclaration = ClassDeclaration;
function getExtractedClassDetails(classDec, isStatic) {
var constructors = utils_1.ArrayUtils.flatten(classDec.getConstructors().map(function (c) { return c.getOverloads().length > 0 ? c.getOverloads() : [c]; }));
var properties = classDec.getProperties().filter(function (p) { return p.isStatic() === isStatic && p.getScope() === common_1.Scope.Public; });
var methods = utils_1.ArrayUtils.flatten(classDec.getMethods()
.filter(function (p) { return p.isStatic() === isStatic && p.getScope() === common_1.Scope.Public; })
.map(function (m) { return m.getOverloads().length > 0 ? m.getOverloads() : [m]; }));
return { constructors: constructors, properties: properties, methods: methods, accessors: getAccessors() };
function getAccessors() {
var e_1, _a;
var result = new utils_1.KeyValueCache();
try {
for (var _b = tslib_1.__values(tslib_1.__spread(classDec.getGetAccessors(), classDec.getSetAccessors())), _c = _b.next(); !_c.done; _c = _b.next()) {
var accessor = _c.value;
if (accessor.isStatic() === isStatic && accessor.getScope() === common_1.Scope.Public)
result.getOrCreate(accessor.getName(), function () { return []; }).push(accessor);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return result.getValuesAsArray();
}
}
function getDefaultExtractedName(name, classDec) {
name = utils_1.StringUtils.isNullOrWhitespace(name) ? undefined : name;
return name || classDec.getName() || classDec.getSourceFile().getBaseNameWithoutExtension().replace(/[^a-zA-Z0-9_$]/g, "");
}
function getExtractedInterfacePropertyStructure(prop) {
return {
docs: prop.getJsDocs().map(function (d) { return d.getStructure(); }),
name: prop.getName(),
type: prop.getType().getText(prop),
hasQuestionToken: prop.hasQuestionToken(),
isReadonly: prop.isReadonly()
};
}
function getExtractedInterfaceAccessorStructure(getAndSet) {
return {
docs: getAndSet[0].getJsDocs().map(function (d) { return d.getStructure(); }),
name: getAndSet[0].getName(),
type: getAndSet[0].getType().getText(getAndSet[0]),
hasQuestionToken: false,
isReadonly: getAndSet.every(utils_1.TypeGuards.isGetAccessorDeclaration)
};
}
function getExtractedInterfaceMethodStructure(method) {
return {
docs: method.getJsDocs().map(function (d) { return d.getStructure(); }),
name: method.getName(),
hasQuestionToken: method.hasQuestionToken(),
returnType: method.getReturnType().getText(method),
parameters: method.getParameters().map(getExtractedInterfaceParameterStructure),
typeParameters: method.getTypeParameters().map(function (p) { return p.getStructure(); })
};
}
function getExtractedInterfaceParameterStructure(param) {
return tslib_1.__assign({}, param.getStructure(), { decorators: [] });
}