@effectful/transducers-loose
Version:
@effectful/transducers built with faster generators
499 lines (497 loc) • 15.8 kB
JavaScript
"use strict";
exports.__esModule = true;
exports.assignmentProperty = exports.assignmentPattern = exports.assignmentOpEq = exports.assignmentOpDefault = exports.arrayPattern = exports.arrayAssignmentPattern = exports.TypeInfo = exports.Tag = void 0;
exports.fieldInfo = fieldInfo;
exports.invariant = invariant;
exports.isNode = isNode;
exports.isSymbol = void 0;
exports.isSynthetic = isSynthetic;
exports.newSymbol = void 0;
exports.nodeInfo = nodeInfo;
exports.symInfo = exports.restElementAssignment = exports.restElement = exports.objectProperty = exports.objectPattern = exports.objectAssignmentPattern = void 0;
exports.symKind = symKind;
exports.symbolDefFor = exports.symbol = exports.symName = void 0;
exports.typeInfo = typeInfo;
var _types = require("@babel/types");
var _visitor_keys = require("./visitor_keys.js");
exports.VISITOR_KEYS = _visitor_keys.VISITOR_KEYS;
var M = require("@effectful/es-rt/opts/loose");
const SYMBOLS_IMPL = "sym";
const GLOBAL_SYMBOLS = SYMBOLS_IMPL === "sym";
const OBJ_SYMBOLS = SYMBOLS_IMPL === "obj";
const STR_SYMBOLS = SYMBOLS_IMPL === "str";
const NUM_SYMBOLS = SYMBOLS_IMPL === "num";
let nameCount = 0;
const symbols = NUM_SYMBOLS ? [] : new Map();
//TODO: fields used only with a single type
// const fieldTypes = new Map()
let defaultSymbol;
const symInfo = exports.symInfo = OBJ_SYMBOLS ? function symInfo(sym) {
return sym;
} : NUM_SYMBOLS ? function symInfo(sym) {
return symbols[sym] || defaultSymbol;
} : function symInfo(sym) {
return symbols.get(sym) || defaultSymbol;
};
const isSymbol = exports.isSymbol = OBJ_SYMBOLS ? function (sym) {
return sym && sym.kind != null;
} : NUM_SYMBOLS ? function (sym) {
return typeof sym === "number";
} : STR_SYMBOLS ? function (sym) {
return sym.substr != null;
} : function (sym) {
return typeof sym === "symbol";
};
function typeInfo(i) {
return i.typeInfo || (i.typeInfo = symInfo(i.type));
}
const symName = exports.symName = OBJ_SYMBOLS ? function symName(s) {
return s.name;
} : STR_SYMBOLS ? function symName(s) {
return s;
} : GLOBAL_SYMBOLS ? Symbol.keyFor : function symName(s) {
return symInfo(s).name;
};
const symDict = {};
const newSymbol = exports.newSymbol = OBJ_SYMBOLS ? function newSymbol(n) {
return symDict[n] || (symDict[n] = {
sym: null,
name: null,
kind: null,
x: null,
prop: null
});
} : STR_SYMBOLS ? function (v) {
return v;
} : NUM_SYMBOLS ? function (n) {
const x = ++nameCount;
return (symDict[n] || (symDict[n] = {
sym: x,
name: null,
kind: null,
x,
prop: null
})).sym;
} : GLOBAL_SYMBOLS ? Symbol.for : Symbol;
function nodeInfo(node) {
return symInfo(Tag[node.type]);
}
function symKind(sym) {
return symInfo(sym).kind;
}
function fieldInfo(type, field) {
const e = symInfo(type);
if (e == null || e.fieldsMap == null) return null;
return e.fieldsMap.get(field);
}
const symbol = exports.symbol = OBJ_SYMBOLS ? function symbol(name, kind = "ctrl") {
const res = {
sym: null,
name,
kind,
x: ++nameCount,
prop: null
};
res.sym = res;
return symDict[name] = res;
} : NUM_SYMBOLS ? function symbol(name, kind = "ctrl") {
const res = newSymbol(name);
symbols[res] = {
sym: res,
name,
kind,
x: res,
prop: null
};
return res;
} : function symbol(name, kind = "ctrl") {
const res = newSymbol(name);
symbols.set(res, {
sym: res,
name,
kind,
x: ++nameCount,
prop: null
});
return res;
};
const symbolDefFor = exports.symbolDefFor = OBJ_SYMBOLS ? function symbolDefFor(name, kind) {
let sym = Tag[name];
if (sym == null) {
Tag[name] = sym = symDict[name] = {
sym,
name,
kind,
x: ++nameCount,
expr: false,
block: false,
key: false,
lval: false,
decl: false,
func: false
};
if (kind === "node") sym.esType = name;
sym.sym = sym;
}
return sym;
} : NUM_SYMBOLS ? function symbolDefFor(name, kind) {
let sym = Tag[name],
def;
if (sym == null) {
Tag[name] = sym = newSymbol(name);
def = {
sym,
name,
kind,
x: sym,
expr: false,
block: false,
key: false,
lval: false,
decl: false,
func: false
};
if (kind === "node") def.esType = name;
symbols[sym] = def;
} else {
def = symInfo(sym);
}
return def;
} : function symbolDefFor(name, kind) {
let sym = Tag[name],
def;
if (sym == null) {
Tag[name] = sym = newSymbol(name);
def = {
sym,
name,
kind,
x: ++nameCount,
expr: false,
block: false,
key: false,
lval: false,
decl: false,
func: false
};
if (kind === "node") def.esType = name;
symbols.set(sym, def);
} else {
def = symInfo(sym);
}
return def;
};
const TypeInfo = exports.TypeInfo = {};
const Tag = exports.Tag = {
push: symbol("push", "pos"),
top: symbol("top", "pos"),
Array: symbol("Array", "array"),
Node: symbol("Node", "node"),
Null: symbol("Null", "null"),
Empty: symbol("Empty", "empty"),
root: symbol("root", "pos"),
Root: symbol("Root", "ctrl")
};
for (const i in _visitor_keys.VISITOR_KEYS) {
TypeInfo[i] = symbolDefFor(i, "node");
var loop = M.iterator(_visitor_keys.VISITOR_KEYS[i]);
for (; !(loop = loop.step()).done;) {
const j = loop.value;
symbolDefFor(j, "pos").visitor = true;
}
var _loop = M.iterator(_types.BUILDER_KEYS[i]);
for (; !(_loop = _loop.step()).done;) {
const j = _loop.value;
symbolDefFor(j, "pos").builder = true;
}
}
for (const i in _types.ALIAS_KEYS) {
const def = symbolDefFor(i, "node");
const aliases = def.aliases || (def.aliases = new Set());
const aliasKeys = _types.ALIAS_KEYS[i];
if (aliasKeys != null) {
var loop1 = M.iterator(aliasKeys);
for (; !(loop1 = loop1.step()).done;) {
const j = loop1.value;
const adef = symbolDefFor(j, "alias");
(adef.instances || (adef.instances = new Set())).add(def.sym);
aliases.add(adef.sym);
}
}
}
{
const idDef = symInfo(Tag.Identifier);
idDef.fieldsMap = new Map([[Tag.name, {
atomicType: "string",
nodeTypes: new Set(),
nillable: false,
enumValues: null,
default: null
}]]);
const meDef = symInfo(Tag.MemberExpression);
meDef.fieldsMap = new Map([[Tag.property, {
atimicType: null,
nodeTypes: new Set([Tag.Identifier]),
nillable: false,
enumValues: null,
default: null
}]]);
}
for (const i in _visitor_keys.VISITOR_KEYS) {
const nodeFields = _types.NODE_FIELDS[i];
const pos = Tag[i];
const def = symInfo(pos);
if (nodeFields != null) {
const fieldsMap = def.fieldsMap || (def.fieldsMap = new Map());
for (const j in nodeFields) {
const jdef = nodeFields[j];
const fdef = symbolDefFor(j, "pos");
if (fieldsMap.has(fdef.sym)) continue;
const info = getTy(jdef.validate, fdef.sym);
info.default = jdef.default;
fieldsMap.set(fdef.sym, info);
}
}
function getTy(ty, pos) {
let enumValues = null,
nt = new Set(),
atomicType = null,
nillable = false;
if (ty != null && ty.chainOf != null) {
let chain = ty.chainOf.filter(i => i.type != null || i.oneOf != null || i.each != null || i.oneOfNodeTypes != null || i.oneOfNodeOrValueTypes != null);
if (chain.length === 1) {
ty = chain[0];
} else if (chain.length === 2) {
if (chain[0].type === "array") {
const elem = getTy(chain[1].each);
if (pos === Tag.params) elem.declVar = true;
return {
array: true,
elem: elem,
fieldsMap: new Map([[Tag.push, elem]])
};
} else if (chain[0].type === "string") {
if (chain[1].oneOf) enumValues = chain[1].oneOf;
atomicType = "string";
ty = null;
} else {
ty = chain[0];
// throw new Error("not implemented");
}
}
}
if (ty != null) {
if (ty.type != null) {
atomicType = ty.type;
} else if (ty.oneOfNodeTypes != null) {
var loop = M.iterator(ty.oneOfNodeTypes);
for (; !(loop = loop.step()).done;) {
const k = loop.value;
const p = Tag[k];
if (p) nt.add(p);
}
} else if (ty.oneOf != null) {
const first = ty.oneOf.filter(i => i != null)[0];
if (first.substr) {
enumValues = ty.oneOf;
atomicType = "string";
} else if (first === true || first === false) {
atomicType = "bool";
}
} else if (ty.oneOfNodeOrValueTypes != null) {
nt = new Set();
var _loop = M.iterator(ty.oneOfNodeOrValueTypes);
for (; !(_loop = _loop.step()).done;) {
const k = _loop.value;
if (k === "null") {
nillable = true;
} else {
const p = Tag[k];
if (p) nt.add(p);
}
}
} else {
atomicType = "any";
}
}
if (enumValues != null) {
nillable = nillable || enumValues.indexOf(null) !== -1;
enumValues = enumValues.filter(i => i != null);
}
const expr = nt.has(Tag.Expression),
lval = nt.has(Tag.LVal) || nt.has(Tag.PatternLike) || pos === Tag.local;
return {
atomicType,
nodeTypes: nt,
nillable,
enumValues,
expr,
stmt: nt.has(Tag.Statement),
block: nt.has(Tag.BlockStatement) && !nt.has(Tag.Statement),
key: nt.has(Tag.Identifier) && !expr && !lval,
lval,
decl: nt.has(Tag.VariableDeclaration) || nt.has(Tag.Declaration),
mod: lval,
declVar: pos === Tag.id
};
}
}
for (const i in _visitor_keys.VISITOR_KEYS) {
const def = symInfo(Tag[i]);
const aliases = def.aliases;
def.func = aliases.has(Tag.Function);
def.scope = aliases.has(Tag.FunctionParent);
def.expr = aliases.has(Tag.Expression);
def.decl = aliases.has(Tag.Declaration);
def.stmt = aliases.has(Tag.BlockStatement) || aliases.has(Tag.Statement);
def.block = aliases.has(Tag.BlockStatement) && !aliases.has(Tag.Statement);
def.blockScope = false;
def.funcScope = false;
def.loopScope = false;
def.declConstr = false;
def.classDecl = false;
}
for (const i in Tag) {
Tag[Tag[i]] = Tag[i];
}
function setComputed(sym, prop) {
const me = symInfo(sym);
me.propAlt = Object.assign({}, me, {
fieldsMap: new Map(me.fieldsMap).set(prop, {
atomicType: null,
nillable: false,
enumValues: null,
expr: true,
stmt: false,
block: false,
lval: false,
decl: false,
mod: false,
declVar: false,
nodeTypes: new Set([Tag.Expression])
})
});
me.prop = Tag.computed;
}
setComputed(Tag.ObjectProperty, Tag.key);
symInfo(Tag.CatchClause).fieldsMap.get(Tag.param).declVar = true;
{
var loop2 = M.iterator([Tag.ImportNamespaceSpecifier, Tag.ImportSpecifier, Tag.ImportDefaultSpecifier]);
for (; !(loop2 = loop2.step()).done;) {
const i = loop2.value;
symInfo(i).fieldsMap.get(Tag.local).declVar = true;
}
}
setComputed(Tag.MemberExpression, Tag.property);
setComputed(Tag.ObjectMethod, Tag.key);
setComputed(Tag.ClassProperty, Tag.key);
setComputed(Tag.ClassMethod, Tag.key);
symInfo(Tag.UpdateExpression).fieldsMap.get(Tag.argument).mod = true;
symInfo(Tag.BlockStatement).block = true;
symInfo(Tag.SpreadElement).expr = true;
symInfo(Tag.VariableDeclaration).decl = true;
symInfo(Tag.FunctionDeclaration).decl = true;
symInfo(Tag.ClassDeclaration).decl = true;
const assignmentOpEq = exports.assignmentOpEq = symInfo(Tag.AssignmentExpression);
const assignmentOpDefault = exports.assignmentOpDefault = Object.assign({}, assignmentOpEq, {
fieldsMap: new Map(assignmentOpEq.fieldsMap).set(Tag.left, Object.assign({}, assignmentOpEq.fieldsMap.get(Tag.left), {
expr: true
}))
});
{
const me = symInfo(Tag.AssignmentExpression);
me.propAlt = Object.assign({}, me, {
fieldsMap: new Map(me.fieldsMap).set(Tag.left, Object.assign({}, me.fieldsMap.get(Tag.left), {
expr: true
}))
});
me.prop = Tag.operator;
}
const assignmentPattern = exports.assignmentPattern = symInfo(Tag.AssignmentPattern);
const objectProperty = exports.objectProperty = symInfo(Tag.ObjectProperty);
const keyProperty = objectProperty.fieldsMap.get(Tag.key);
objectProperty.fieldsMap.set(Tag.key, Object.assign({}, keyProperty, {
expr: false
}));
const assignmentProperty = exports.assignmentProperty = symbolDefFor("AssignmentProperty", "node");
const objectAssignmentPattern = exports.objectAssignmentPattern = symInfo(Tag.ObjectPattern);
const objectPattern = exports.objectPattern = Object.assign({}, objectAssignmentPattern, {
fieldsMap: new Map(objectAssignmentPattern.fieldsMap)
});
{
const prop = objectAssignmentPattern.fieldsMap.get(Tag.properties);
const elem = Object.assign({}, prop.elem, {
declVar: true
});
prop.elem.declVar = false;
objectPattern.fieldsMap.set(Tag.properties, Object.assign({}, prop, {
elem,
fieldsMap: new Map([[Tag.push, elem]])
}));
}
const arrayAssignmentPattern = exports.arrayAssignmentPattern = symInfo(Tag.ArrayPattern);
const arrayPattern = exports.arrayPattern = Object.assign({}, arrayAssignmentPattern, {
fieldsMap: new Map(arrayAssignmentPattern.fieldsMap)
});
{
const prop = arrayAssignmentPattern.fieldsMap.get(Tag.elements);
const elem = Object.assign({}, prop.elem, {
declVar: true
});
prop.elem.declVar = false;
arrayPattern.fieldsMap.set(Tag.elements, Object.assign({}, prop, {
elem,
fieldsMap: new Map([[Tag.push, elem]])
}));
}
const patField = symInfo(Tag.VariableDeclarator).fieldsMap.get(Tag.id);
{
assignmentPattern.fieldsMap.get(Tag.left).declVar = true;
assignmentProperty.esType = "ObjectProperty";
assignmentProperty.fieldsMap = new Map(objectProperty.fieldsMap);
assignmentProperty.fieldsMap.set(Tag.value, patField);
}
const restElementAssignment = exports.restElementAssignment = symInfo(Tag.RestElement);
const restElement = exports.restElement = Object.assign({}, restElementAssignment, {
fieldsMap: new Map(restElementAssignment.fieldsMap)
});
restElement.fieldsMap.set(Tag.argument, patField);
// babel 7.10 broke this
const binaryExpression = symInfo(Tag.BinaryExpression);
binaryExpression.fieldsMap.set(Tag.left, binaryExpression.fieldsMap.get(Tag.right));
function isNode(node) {
if (node == null) return false;
return typeof node === "object" && typeof node.type === "string";
}
function invariant(value) {
if (!value) throw new Error("INTERNAL: invariant");
}
function isSynthetic(node) {
return !node || node.loc == null;
}
defaultSymbol = symbolDefFor("unkn", "ctrl");
var loop3 = M.iterator([Tag.FunctionExpression, Tag.File, Tag.ArrowFunctionExpression, Tag.FunctionDeclaration, Tag.ClassMethod, Tag.ClassPrivateMethod, Tag.ObjectMethod]);
for (; !(loop3 = loop3.step()).done;) {
const i = loop3.value;
symInfo(i).funcScope = true;
}
var loop4 = M.iterator([Tag.BlockStatement, Tag.Program, Tag.ForOfStatement, Tag.ForInStatement, Tag.ForStatement, Tag.SwitchStatement, Tag.CatchClause]);
for (; !(loop4 = loop4.step()).done;) {
const i = loop4.value;
symInfo(i).blockScope = true;
}
var loop5 = M.iterator([Tag.WhileStatement, Tag.DoWhileStatement, Tag.ForStatement, Tag.ForInStatement, Tag.ForOfStatement]);
for (; !(loop5 = loop5.step()).done;) {
const i = loop5.value;
symInfo(i).loopScope = true;
}
var loop6 = M.iterator([Tag.ClassExpression, Tag.ClassDeclaration, Tag.FunctionExpression, Tag.FunctionDeclaration, Tag.VariableDeclaration]);
for (; !(loop6 = loop6.step()).done;) {
const i = loop6.value;
symInfo(i).declConstr = true;
}
var loop7 = M.iterator([Tag.ClassExpression, Tag.ClassDeclaration]);
for (; !(loop7 = loop7.step()).done;) {
const i = loop7.value;
symInfo(i).classDecl = true;
}