@amplitude/ampli
Version:
Amplitude CLI
219 lines (218 loc) • 6.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("lodash");
function parseVarRef(varRefArray) {
return {
type: varRefArray[0],
name: varRefArray[1],
location: varRefArray[2],
};
}
const NULL_NODE = {
type: '@null',
name: 'null',
};
const FALSE_NODE = {
type: '@false-value',
name: 'false',
};
function parseContainerNode(parent, containerNodeArray) {
const containerNode = {
type: containerNodeArray[0],
children: [],
parent,
};
const childArray = containerNodeArray[1];
let children;
try {
children = childArray.map((childNode) => parseNode(containerNode, childNode));
}
catch (e) {
children = [];
}
return Object.assign(Object.assign({}, containerNode), { children });
}
function flattenNestedArrays(array) {
function flatten(a) {
let flat = [];
if (a && a.length > 0) {
if (typeof a[0] === 'string') {
flat = [...a];
}
if (a[0] instanceof Array) {
a.forEach(item => {
if (typeof item[0] === 'string') {
flat.push(item);
}
else if (item[0] instanceof Array) {
flat = flat.concat(flattenNestedArrays(item));
}
});
return flat;
}
}
return flat;
}
return flatten(array);
}
function parseValueListNode(parent, containerNodeArray) {
const children = [];
const containerNode = {
type: containerNodeArray[0],
children: [],
parent,
};
for (let i = 1; i < containerNodeArray.length; i += 1) {
const childNode = containerNodeArray[i];
if (!lodash_1.isEmpty(childNode)) {
if (typeof childNode[0] === 'string') {
children.push(parseNode(containerNode, childNode));
}
else if (childNode[0] instanceof Array) {
const childNodeArray = childNode;
const flatKids = flattenNestedArrays(childNodeArray);
flatKids.forEach(c => {
children.push(parseNode(containerNode, c));
});
}
}
}
const valueListNode = Object.assign(Object.assign({}, containerNode), { children });
return valueListNode;
}
function parsePlaceholderNode(parent, node) {
return {
type: node[0],
parent,
};
}
function parseValueNode(parent, valueNodeArray) {
return {
type: valueNodeArray[0],
name: valueNodeArray[1],
location: {
row: valueNodeArray[2][0],
column: valueNodeArray[2][1],
},
parent,
};
}
function parseNode(parent, node) {
if (node === null || node === undefined) {
return Object.assign(Object.assign({}, NULL_NODE), { parent });
}
if (node === false) {
return Object.assign(Object.assign({}, FALSE_NODE), { parent });
}
let type;
if (typeof node[0] === 'string') {
[type] = node;
}
switch (type) {
case 'array':
case 'assoclist_from_args':
case 'bare_assoc_hash':
case 'bodystmt':
case 'program':
case 'string_embexpr':
return parseContainerNode(parent, node);
case 'aref':
case 'aref_field':
case 'arg_paren':
case 'args_add_star':
case 'args_add_block':
case 'assign':
case 'assoc_new':
case 'begin':
case 'block_var':
case 'brace_block':
case 'call':
case 'class':
case 'command':
case 'const_path_ref':
case 'const_ref':
case 'def':
case 'do_block':
case 'else':
case 'elsif':
case 'field':
case 'fcall':
case 'hash':
case 'if':
case 'if_mod':
case 'method_add_arg':
case 'method_add_block':
case 'mlhs':
case 'module':
case 'opassign':
case 'params':
case 'paren':
case 'regexp_literal':
case 'rescue_mod':
case 'string_literal':
case 'string_content':
case 'symbol':
case 'symbol_literal':
case 'var_field':
case 'var_ref':
case 'vcall':
return parseValueListNode(parent, node);
case 'binary':
case 'void_stmt':
case 'yield0':
return parsePlaceholderNode(parent, node);
case '@const':
case '@float':
case '@ident':
case '@int':
case '@ivar':
case '@kw':
case '@label':
case '@op':
case '@period':
case '@regexp_end':
case '@tstring_content':
return parseValueNode(parent, node);
default:
console.error(`RubyAst.parseNode: Unrecognized type: ${type}`);
}
return {
type: `Invalid ${type} node`,
};
}
class RubyAst {
constructor() {
this.astArrayToJson = (callArray) => {
const json = {
action: callArray[0],
};
for (let i = 1; i < callArray.length; i += 1) {
const key = callArray[i][0];
switch (key) {
case 'var_ref':
json.var_ref = parseVarRef(callArray[i][1]);
break;
case 'const_path_ref':
json.const_path_ref = {
var_ref: parseVarRef(callArray[i][1][1]),
const: parseVarRef(callArray[i][2]),
};
break;
case 'vcall':
json.vcall = parseVarRef(callArray[i][1]);
break;
case '@period':
json.period = parseVarRef(callArray[i]);
break;
case '@ident':
json.ident = parseVarRef(callArray[i]);
break;
case 'call':
default:
}
}
return json;
};
}
}
exports.default = RubyAst;