UNPKG

jsii-pacmak

Version:

A code generation framework for jsii backend languages

236 lines 10.2 kB
"use strict"; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _GoInterface_parameterValidators; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoInterface = void 0; const comparators = require("../comparators"); const dependencies_1 = require("../dependencies"); const runtime_1 = require("../runtime"); const util_1 = require("../util"); const go_type_1 = require("./go-type"); const go_type_reference_1 = require("./go-type-reference"); const type_member_1 = require("./type-member"); class GoInterface extends go_type_1.GoType { constructor(pkg, type) { super(pkg, type); _GoInterface_parameterValidators.set(this, void 0); this.methods = type.ownMethods .map((method) => new InterfaceMethod(this, method)) .sort(comparators.byName); this.properties = type.ownProperties .map((prop) => new InterfaceProperty(this, prop)) .sort(comparators.byName); // If there is more than one base, and any ancestor (including transitive) // comes from a different assembly, we will re-implement all members on the // proxy struct, as otherwise we run the risk of un-promotable methods // caused by inheriting the same interface via multiple paths (since we have // to represent those as embedded types). if (type.interfaces.length > 1 && type .getInterfaces(true) .some((ancestor) => ancestor.assembly.fqn !== type.assembly.fqn)) { this.reimplementedMethods = type.allMethods .filter((method) => !method.static && method.definingType !== type) .map((method) => new InterfaceMethod(this, method)) .sort(comparators.byName); this.reimplementedProperties = type.allProperties .filter((property) => !property.static && property.definingType !== type) .map((property) => new InterfaceProperty(this, property)) .sort(comparators.byName); } else { this.reimplementedMethods = []; this.reimplementedProperties = []; } } get parameterValidators() { if (__classPrivateFieldGet(this, _GoInterface_parameterValidators, "f") == null) { __classPrivateFieldSet(this, _GoInterface_parameterValidators, [ ...this.methods.map((m) => m.validator).filter((v) => v != null), ...this.reimplementedMethods .map((m) => m.validator) .filter((v) => v != null), ...this.properties.map((p) => p.validator).filter((v) => v != null), ...this.reimplementedProperties .map((p) => p.validator) .filter((v) => v != null), ], "f"); } return __classPrivateFieldGet(this, _GoInterface_parameterValidators, "f"); } emit(context) { this.emitDocs(context); const { code } = context; code.openBlock(`type ${this.name} interface`); // embed extended interfaces for (const iface of this.extends) { code.line(new go_type_reference_1.GoTypeRef(this.pkg.root, iface.type.reference).scopedName(this.pkg)); } for (const method of this.methods) { method.emitDecl(context); } for (const prop of this.properties) { prop.emit(context); } code.closeBlock(); code.line(); code.line(`// The jsii proxy for ${this.name}`); code.openBlock(`type ${this.proxyName} struct`); if (this.extends.length === 0) { // Ensure this is not 0-width code.line('_ byte // padding'); } else { for (const base of this.extends) { code.line(this.pkg.resolveEmbeddedType(base).embed); } } code.closeBlock(); code.line(); for (const method of this.methods) { method.emit(context); } for (const method of this.reimplementedMethods) { method.emit(context); } for (const prop of this.properties) { prop.emitGetterProxy(context); if (!prop.immutable) { prop.emitSetterProxy(context); } } for (const prop of this.reimplementedProperties) { prop.emitGetterProxy(context); if (!prop.immutable) { prop.emitSetterProxy(context); } } } emitRegistration({ code }) { code.open(`${runtime_1.JSII_RT_ALIAS}.RegisterInterface(`); code.line(`"${this.fqn}",`); code.line(`reflect.TypeOf((*${this.name})(nil)).Elem(),`); const allMembers = [ ...this.type.allMethods .filter((method) => !method.static) .map((method) => new InterfaceMethod(this, method)), ...this.type.allProperties .filter((property) => !property.static) .map((property) => new type_member_1.GoProperty(this, property)), ].sort(comparators.byName); if (allMembers.length === 0) { code.line('nil, // no members'); } else { code.open(`[]${runtime_1.JSII_RT_ALIAS}.Member{`); for (const member of allMembers) { code.line(`${member.override},`); } code.close('},'); } this.emitProxyMakerFunction(code, this.extends); code.close(')'); } get specialDependencies() { return (0, dependencies_1.reduceSpecialDependencies)({ fmt: false, init: false, internal: this.extends.some((base) => this.pkg.isExternalType(base)), runtime: false, time: false, }, ...this.properties.map((p) => p.specialDependencies), ...this.reimplementedProperties.map((p) => p.specialDependencies), ...this.methods.map((m) => m.specialDependencies), ...this.reimplementedMethods.map((m) => m.specialDependencies)); } get extends() { return this.type.interfaces .map((iface) => this.pkg.root.findType(iface.fqn)) .sort(comparators.byName); } get extendsDependencies() { const packages = []; for (const ifaceRef of this.extends) { const pkg = ifaceRef.pkg; if (pkg) { packages.push(pkg); } } return packages; } get dependencies() { return [ ...this.extendsDependencies, ...(0, util_1.getMemberDependencies)(this.methods), ...(0, util_1.getMemberDependencies)(this.reimplementedMethods), ...(0, util_1.getMemberDependencies)(this.properties), ...(0, util_1.getMemberDependencies)(this.reimplementedProperties), ...(0, util_1.getParamDependencies)(this.methods), ...(0, util_1.getParamDependencies)(this.reimplementedMethods), ]; } } exports.GoInterface = GoInterface; _GoInterface_parameterValidators = new WeakMap(); class InterfaceProperty extends type_member_1.GoProperty { constructor(parent, property) { super(parent, property); this.parent = parent; this.property = property; } get returnType() { return this.reference.scopedReference(this.parent.pkg); } emit({ code, documenter }) { documenter.emit(this.property.docs, this.apiLocation); code.line(`${this.name}() ${this.returnType}`); if (!this.property.immutable) { // For setters, only emit the stability. Copying the documentation from // the getter might result in confusing documentation. This is an "okay" // middle-ground. documenter.emitStability(this.property.docs); code.line(`Set${this.name}(${this.name[0].toLowerCase()} ${this.returnType})`); } } } class InterfaceMethod extends type_member_1.GoMethod { constructor(parent, method) { super(parent, method); this.parent = parent; this.method = method; this.runtimeCall = new runtime_1.MethodCall(this); } emitDecl({ code, documenter }) { documenter.emit(this.method.docs, this.apiLocation); code.line(`${this.name}(${this.paramString()})${this.returnTypeString}`); } emit(context) { const name = this.name; const { code } = context; code.openBlock(`func (${this.instanceArg} *${this.parent.proxyName}) ${name}(${this.paramString()})${this.returnTypeString}`); this.runtimeCall.emit(context); code.closeBlock(); code.line(); } get specialDependencies() { return { fmt: false, init: false, internal: false, runtime: true, time: this.parameters.some((p) => p.reference.specialDependencies.time) || !!this.reference?.specialDependencies.time, }; } get returnTypeString() { return this.reference?.void ? '' : ` ${this.returnType}`; } } //# sourceMappingURL=interface.js.map