PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/tcomb/lib
Просмотр файла: isSubsetOf.js
var assert = require('./assert');
var decompose = require('./decompose');
var isType = require('./isType');
var Any = require('./Any');
var Array = require('./Array');
var Function = require('./Function');
var Nil = require('./Nil');
var tObject = require('./Object');
function leqList(As, Bs) {
return ( As.length === Bs.length ) && As.every(function (A, i) {
return recurse(A, Bs[i]);
});
}
function leqPredicates(ps1, ps2) {
return ps2.length <= ps1.length && ps2.every(function (p) {
return ps1.indexOf(p) !== -1;
});
}
var index = [];
function find(A, B) {
for (var i = 0, len = index.length ; i < len ; i++) {
var item = index[i];
if (item.A === A && item.B === B) {
return item;
}
}
}
function leq(A, B) {
// Fast results
// (1) if B === t.Any then A <= B for all A
// (2) if B === A then A <= B for all A
if (A === B || B === Any) {
return true;
}
var kindA = A.meta.kind;
var kindB = B.meta.kind;
// Reductions
// (3) if B = maybe(C) and A is not a maybe then A <= B if and only if A === t.Nil or A <= C
if (kindB === 'maybe' && kindA !== 'maybe') {
return ( A === Nil ) || recurse(A, B.meta.type);
}
function gte(type) {
return recurse(A, type);
}
// (4) if B is a union then A <= B if exists B' in B.meta.types such that A <= B'
if (kindB === 'union') {
if (B.meta.types.some(gte)) {
return true;
}
}
// (5) if B is an intersection then A <= B if A <= B' for all B' in B.meta.types
if (kindB === 'intersection') {
if (B.meta.types.every(gte)) {
return true;
}
}
// Let A be a struct then A <= B if B === t.Object
if (kindA === 'struct') {
return B === tObject;
}
// Let A be a maybe then A <= B if B is a maybe and A.meta.type <= B.meta.type
else if (kindA === 'maybe') {
return ( kindB === 'maybe' ) && recurse(A.meta.type, B.meta.type);
}
// Let A be an union then A <= B if A' <= B for all A' in A.meta.types
else if (kindA === 'union') {
return A.meta.types.every(function (T) {
return recurse(T, B);
});
}
// Let A be an intersection then A <= B if exists A' in A.meta.types such that A' <= B
else if (kindA === 'intersection') {
return A.meta.types.some(function (T) {
return recurse(T, B);
});
}
// Let A be irreducible then A <= B if B is irreducible and A.is === B.is
else if (kindA === 'irreducible') {
return ( kindB === 'irreducible' ) && ( A.meta.predicate === B.meta.predicate );
}
// Let A be an enum then A <= B if and only if B.is(a) === true for all a in keys(A.meta.map)
else if (kindA === 'enums') {
return Object.keys(A.meta.map).every(B.is);
}
// Let A be a refinement then A <= B if decompose(A) <= decompose(B)
else if (kindA === 'subtype') {
var dA = decompose(A);
var dB = decompose(B);
return leqPredicates(dA.predicates, dB.predicates) && recurse(dA.unrefinedType, dB.unrefinedType);
}
// Let A be a list then A <= B if one of the following holds:
else if (kindA === 'list') {
// B === t.Array
if (B === Array) {
return true;
}
// B is a list and A.meta.type <= B.meta.type
return ( kindB === 'list' ) && recurse(A.meta.type, B.meta.type);
}
// Let A be a list then A <= B if one of the following holds:
else if (kindA === 'dict') {
// B === t.Object
if (B === tObject) {
return true;
}
// B is a dictionary and [A.meta.domain, A.meta.codomain] <= [B.meta.domain, B.meta.codomain]
return ( kindB === 'dict' ) && recurse(A.meta.domain, B.meta.domain) && recurse(A.meta.codomain, B.meta.codomain);
}
// Let A be a tuple then A <= B if one of the following holds:
else if (kindA === 'tuple') {
// B === t.Array
if (B === Array) {
return true;
}
// B is a tuple and A.meta.types <= B.meta.types
return ( kindB === 'tuple' ) && leqList(A.meta.types, B.meta.types);
}
// Let A be a function then then A <= B if one of the following holds:
else if (kindA === 'func') {
// B === t.Function
if (B === Function) {
return true;
}
// B is a function and [A.meta.domain, A.meta.codomain] <= [B.meta.domain, B.meta.codomain]
return ( kindB === 'func' ) && recurse(A.meta.codomain, B.meta.codomain) && leqList(A.meta.domain, B.meta.domain);
}
// Let A be an interface then A <= B if one of the following holds:
else if (kindA === 'interface') {
// B === t.Object
if (B === tObject) {
return true;
}
if (kindB === 'interface') {
var keysB = Object.keys(B.meta.props);
var compatible = keysB.every(function (k) {
return A.meta.props.hasOwnProperty(k) && recurse(A.meta.props[k], B.meta.props[k]);
});
// B is an interface, B.meta.strict === false, keys(B.meta.props) <= keys(A.meta.props) and A.meta.props[k] <= B.meta.props[k] for all k in keys(B.meta.props)
if (B.meta.strict === false) {
return compatible;
}
// B is an interface, B.meta.strict === true, A.meta.strict === true, keys(B.meta.props) = keys(A.meta.props) and A.meta.props[k] <= B.meta.props[k] for all k in keys(B.meta.props)
return compatible && ( A.meta.strict === true ) && ( keysB.length === Object.keys(A.meta.props).length );
}
}
return false;
}
function recurse(A, B) {
// handle recursive types
var hit = find(A, B);
if (hit) {
return hit.leq;
}
hit = { A: A, B: B, leq: true };
index.push(hit);
return ( hit.leq = leq(A, B) );
}
function isSubsetOf(A, B) {
if (process.env.NODE_ENV !== 'production') {
assert(isType(A), function () { return 'Invalid argument subset ' + assert.stringify(A) + ' supplied to isSubsetOf(subset, superset) (expected a type)'; });
assert(isType(B), function () { return 'Invalid argument superset ' + assert.stringify(B) + ' supplied to isSubsetOf(subset, superset) (expected a type)'; });
}
return recurse(A, B);
}
module.exports = isSubsetOf;Выполнить команду
Для локальной разработки. Не используйте в интернете!