all files / src/util/ IdentGenerator.js

98.11% Statements 52/53
100% Branches 26/26
100% Functions 13/13
98.11% Lines 52/53
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114  8833×       4591× 4591× 4591×   4587× 78× 78×   4591× 4591×       137× 137× 137× 137× 137×     4515×   4513× 4513× 4513×     4513× 4513× 4513× 4591× 4591× 4509×     4513× 4513×                 78×         4513×         66× 66× 134×               197× 197× 196×                 118×                         78×      
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const FIRST_CHAR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const OTHER_CHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
const FIRST_CHAR_INSENSITIVE = "abcdefghijklmnopqrstuvwxyz";
const OTHER_CHAR_INSENSITIVE = "0123456789abcdefghijklmnopqrstuvwxyz-_";
function identChar(insensitive, c, i) {
    return i === 0
        ? (insensitive ? FIRST_CHAR_INSENSITIVE : FIRST_CHAR)[c]
        : (insensitive ? OTHER_CHAR_INSENSITIVE : OTHER_CHAR)[c];
}
function increment(insensitive, counters, i) {
    let c = counters[i] + 1;
    let carry = false;
    if (i === 0 && c === (insensitive ? 26 : 52)) {
        c = 0;
        carry = true;
    }
    else if (i > 0 && c === (insensitive ? 38 : 64)) {
        c = 0;
        carry = true;
    }
    counters[i] = c;
    return carry;
}
class IdentGenerator {
    constructor(caseInsensitive = false) {
        this.counters = [0];
        this.returnedIdents = [];
        this.reservedIdents = new Set();
        this.identChar = identChar.bind(null, caseInsensitive);
        this.increment = increment.bind(null, caseInsensitive);
    }
    nextIdent() {
        if (this.returnedIdents.length > 0) {
            return this.returnedIdents.pop();
        }
        let ident;
        while (this.isReserved(ident = this.generateNextIdent())) { }
        return this.lastIdent = ident;
    }
    generateNextIdent() {
        let nextIdent = this.counters.map(this.identChar).join("");
        let carry = false;
        for (let i = this.counters.length - 1; i >= 0; i--) {
            carry = this.increment(this.counters, i);
            if (!carry) {
                break;
            }
        }
        if (carry)
            this.counters.push(0);
        return nextIdent;
    }
    /**
     * When a generated ident is no longer in use, it should be returned
     * so it can be re-used.
     */
    returnIdent(ident) {
        this.returnedIdents.push(ident);
    }
    reserve(...idents) {
        for (let ident of idents) {
            this.reservedIdents.add(ident);
        }
    }
    isReserved(ident) {
        return this.reservedIdents.has(ident);
    }
}
exports.IdentGenerator = IdentGenerator;
class IdentGenerators {
    constructor(caseInsensitive, ...namespaces) {
        this.namespaces = {};
        namespaces.forEach(ns => {
            this.namespaces[ns] = new IdentGenerator(caseInsensitive);
        });
    }
    /**
     * Look up the ident generator for the given namespace. Raise an error if no
     * no such namespace exists.
     */
    get(namespace) {
        let generator = this.namespaces[namespace];
        if (generator) {
            return generator;
        }
        else {
            throw new Error("unknown ident namespace: " + namespace);
        }
    }
    /**
     * Generate an ident from the given namespace.
     */
    nextIdent(namespace) {
        return this.get(namespace).nextIdent();
    }
    /**
     * Return an ident to be generated for the next requested ident.
     */
    returnIdent(namespace, ident) {
        this.get(namespace).returnIdent(ident);
    }
    /**
     * Reserved idents are never output by the ident generator.
     * @param namespace The namespace that ident should come from.
     * @param idents The ident that should not be generated.
     */
    reserve(namespace, ...idents) {
        this.get(namespace).reserve(...idents);
    }
}
exports.IdentGenerators = IdentGenerators;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWRlbnRHZW5lcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbC9JZGVudEdlbmVyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU0sVUFBVSxHQUFHLHNEQUFzRCxDQUFDO0FBQzFFLE1BQU0sVUFBVSxHQUFHLGtFQUFrRSxDQUFDO0FBRXRGLE1BQU0sc0JBQXNCLEdBQUcsNEJBQTRCLENBQUM7QUFDNUQsTUFBTSxzQkFBc0IsR0FBRyx3Q0FBd0MsQ0FBQztBQUV4RSxtQkFBbUIsV0FBb0IsRUFBRSxDQUFTLEVBQUUsQ0FBUztJQUMzRCxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQ1osQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFFRCxtQkFBbUIsV0FBb0IsRUFBRSxRQUF1QixFQUFFLENBQVM7SUFDekUsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN4QixJQUFJLEtBQUssR0FBRyxLQUFLLENBQUM7SUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtRQUM1QyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ04sS0FBSyxHQUFHLElBQUksQ0FBQztLQUNkO1NBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMs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