UNPKG

@mcesystems/nbind

Version:

Magical headers that make your C++ library accessible from JavaScript

180 lines (179 loc) 7.41 kB
"use strict"; // This file is part of nbind, copyright (C) 2014-2016 BusFaster Ltd. // Released under the MIT license, see LICENSE. var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.Type = (_a = typeModule(typeModule), _a.Type), exports.makeType = _a.makeType, exports.structureList = _a.structureList; /* tslint:disable:no-shadowed-variable */ function typeModule(self) { // Parameter count and printable name of each StructureType. var structureList = [ [0, 1, 'X'], [1 /* isConst */, 1, 'const X'], [128 /* isPointer */, 1, 'X *'], [256 /* isReference */, 1, 'X &'], [384 /* isRvalueRef */, 1, 'X &&'], [512 /* isSharedPtr */, 1, 'std::shared_ptr<X>'], [640 /* isUniquePtr */, 1, 'std::unique_ptr<X>'], [5120 /* isVector */, 1, 'std::vector<X>'], [6144 /* isArray */, 2, 'std::array<X, Y>'], [9216 /* isCallback */, -1, 'std::function<X (Y)>'] ]; function applyStructure(outerName, outerFlags, innerName, innerFlags, param, flip) { if (outerFlags == 1 /* isConst */) { var ref = innerFlags & 896 /* refMask */; if (ref == 128 /* isPointer */ || ref == 256 /* isReference */ || ref == 384 /* isRvalueRef */) outerName = 'X const'; } var name; if (flip) { name = innerName.replace('X', outerName).replace('Y', param); } else { name = outerName.replace('X', innerName).replace('Y', param); } // Remove spaces between consecutive * and & characters. return (name.replace(/([*&]) (?=[*&])/g, '$1')); } function reportProblem(problem, id, kind, structureType, place) { throw (new Error(problem + ' type ' + kind.replace('X', id + '?') + (structureType ? ' with flag ' + structureType : '') + ' in ' + place)); } function getComplexType(id, constructType, getType, queryType, place, // C++ type name string built top-down, for printing helpful errors. kind, // tslint:disable-line // Outer type, used only for updating kind. prevStructure, // tslint:disable-line depth // tslint:disable-line ) { if (kind === void 0) { kind = 'X'; } if (depth === void 0) { depth = 1; } var result = getType(id); if (result) return (result); var query = queryType(id); var structureType = query.placeholderFlag; var structure = structureList[structureType]; if (prevStructure && structure) { kind = applyStructure(prevStructure[2], prevStructure[0], kind, structure[0], '?', true); } var problem; if (structureType == 0) problem = 'Unbound'; if (structureType >= 10 /* max */) problem = 'Corrupt'; if (depth > 20) problem = 'Deeply nested'; if (problem) reportProblem(problem, id, kind, structureType, place || '?'); var subId = query.paramList[0]; var subType = getComplexType(subId, constructType, getType, queryType, place, kind, structure, depth + 1); var srcSpec; var spec = { flags: structure[0], id: id, name: '', paramList: [subType] }; var argList = []; var structureParam = '?'; switch (query.placeholderFlag) { case 1 /* constant */: srcSpec = subType.spec; break; case 2 /* pointer */: if ((subType.flags & 15360 /* kindMask */) == 1024 /* isArithmetic */ && subType.spec.ptrSize == 1) { spec.flags = 7168 /* isCString */; break; } // tslint:disable-next-line:no-switch-case-fall-through case 3 /* reference */: // tslint:disable-next-line:no-switch-case-fall-through case 6 /* unique */: // tslint:disable-next-line:no-switch-case-fall-through case 5 /* shared */: srcSpec = subType.spec; if ((subType.flags & 15360 /* kindMask */) != 2048 /* isClass */) { // reportProblem('Unsupported', id, kind, structureType, place); } break; case 8 /* array */: structureParam = '' + query.paramList[1]; spec.paramList.push(query.paramList[1]); break; case 9 /* callback */: for (var _i = 0, _a = query.paramList[1]; _i < _a.length; _i++) { var paramId = _a[_i]; var paramType = getComplexType(paramId, constructType, getType, queryType, place, kind, structure, depth + 1); argList.push(paramType.name); spec.paramList.push(paramType); } structureParam = argList.join(', '); break; default: break; } spec.name = applyStructure(structure[2], structure[0], subType.name, subType.flags, structureParam); if (srcSpec) { for (var _b = 0, _c = Object.keys(srcSpec); _b < _c.length; _b++) { var key = _c[_b]; spec[key] = spec[key] || srcSpec[key]; } spec.flags |= srcSpec.flags; } return (makeType(constructType, spec)); } function makeType(constructType, spec) { var flags = spec.flags; var refKind = flags & 896 /* refMask */; var kind = flags & 15360 /* kindMask */; if (!spec.name && kind == 1024 /* isArithmetic */) { if (spec.ptrSize == 1) { spec.name = (flags & 16 /* isSignless */ ? '' : (flags & 8 /* isUnsigned */ ? 'un' : '') + 'signed ') + 'char'; } else { spec.name = ((flags & 8 /* isUnsigned */ ? 'u' : '') + (flags & 32 /* isFloat */ ? 'float' : 'int') + (spec.ptrSize * 8 + '_t')); } } if (spec.ptrSize == 8 && !(flags & 32 /* isFloat */)) kind = 64 /* isBig */; if (kind == 2048 /* isClass */) { if (refKind == 512 /* isSharedPtr */ || refKind == 640 /* isUniquePtr */) { kind = 4096 /* isSharedClassPtr */; } else if (refKind) kind = 3072 /* isClassPtr */; } return (constructType(kind, spec)); } var Type = /** @class */ (function () { function Type(spec) { this.id = spec.id; this.name = spec.name; this.flags = spec.flags; this.spec = spec; } Type.prototype.toString = function () { return (this.name); }; return Type; }()); var output = { Type: Type, getComplexType: getComplexType, makeType: makeType, structureList: structureList }; self.output = output; return (self.output || output); } exports.typeModule = typeModule;