motoko
Version:
Compile and run Motoko smart contracts in Node.js or the browser.
120 lines • 3.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRawExp = getRawExp;
exports.setRootScope = setRootScope;
exports.getScope = getScope;
exports.asNode = asNode;
exports.simplifyAST = simplifyAST;
/**
* Retrieves the raw expression from a node (internal use only).
*/
function getRawExp(node) {
return node.rawExp;
}
/**
* Attaches a raw scope to a root node (internal use only).
*/
function setRootScope(node, scope) {
Object.defineProperty(node, 'rawScope', {
value: scope,
enumerable: false,
});
}
/**
* Retrieves the raw scope directly from a node (internal use only).
*/
function getScope(ast) {
return ast.rawScope;
}
function asNode(ast) {
if (ast && typeof ast === 'object' && !Array.isArray(ast)) {
return ast;
}
}
// Some nodes are "virtual" (generated by the serialization processs) and do not
// have proper properties. We set the parent properties to these, which also aid
// the language server.
const nodesThatNeedParentProperties = ['ID', 'ExpField'];
function simplifyAST(ast, parent) {
if (Array.isArray(ast)) {
return ast.map((a) => simplifyAST(a, parent));
}
if (typeof ast !== 'object') {
return ast;
}
if (ast.name === '@') {
const [start, end, subAst] = ast.args;
const node = typeof subAst === 'string'
? { name: subAst, parent }
: simplifyAST(subAst, parent);
node.start = [+start.args[1], +start.args[2]];
node.end = [+end.args[1], +end.args[2]];
const file = start.args[0];
if (file) {
node.file = file;
}
return node;
}
if (ast.name === '@@') {
const [file, start, end] = ast.args;
return {
name: 'Region',
file,
start: [+start.args[0], +start.args[1]],
end: [+end.args[0], +end.args[1]],
};
}
if (ast.name === ':') {
const [typeAst, type, typeRep] = ast.args;
const node = typeof typeAst === 'string'
? { name: typeAst, parent }
: simplifyAST(typeAst, parent);
node.type = type;
node.typeRep = simplifyAST(typeRep, parent);
return node;
}
if (ast.name === '*') {
const [doc, docAst] = ast.args;
const node = typeof docAst === 'string'
? { name: docAst, parent }
: simplifyAST(docAst, parent);
node.doc = doc;
return node;
}
const node = {
name: ast.name,
};
// Store rawExp as non-enumerable to hide from serialization/comparison
Object.defineProperty(node, 'rawExp', {
value: ast.rawExp,
enumerable: false,
});
Object.defineProperty(node, 'parent', {
value: parent,
enumerable: false,
});
node.args = simplifyAST(ast.args, node);
if (parent && nodesThatNeedParentProperties.includes(ast.name)) {
// Inherit properties from parent for convenience.
Object.defineProperty(node, 'type', {
get: () => parent.type,
set: (newType) => (parent.type = newType),
enumerable: true,
configurable: true,
});
Object.defineProperty(node, 'typeRep', {
get: () => parent.typeRep,
set: (newTypeRep) => (parent.typeRep = newTypeRep),
enumerable: true,
configurable: true,
});
Object.defineProperty(node, 'doc', {
get: () => parent.doc,
set: (newDoc) => (parent.doc = newDoc),
enumerable: true,
configurable: true,
});
}
return node;
}
//# sourceMappingURL=ast.js.map