UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for static analysis and code manipulation.

176 lines (175 loc) 9.94 kB
"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: [] }); }