UNPKG

@cosmology/ast

Version:
244 lines (219 loc) 6.53 kB
import * as t from "@babel/types"; import { ProtoField } from "@cosmology/types"; import { ProtoParseContext } from "../encoding"; const BILLION = t.numericLiteral(1_000_000_000); BILLION.extra = { raw: "1_000_000_000", rawValue: 1000000000 }; export { BILLION }; export const cleanComment = (str) => { return str.replace(/\*\//g, "*\\/"); }; const ensureOneSpace = (str) => { if (/^[\s\n\t]+/.test(str)) return str; return ` ${str}`; }; export const makeCommentBlock = (comment: string): t.CommentBlock => { if (!/[\n]+/.test(comment)) { return { type: "CommentBlock", value: `* ${cleanComment(comment)} `, start: null, end: null, loc: null, }; } let lines = comment.split("\n"); lines = ["*", ...lines, " "]; const comments = lines.map((line, i) => { if (i == 0) return line; if (i == 1) return ` *${ensureOneSpace(cleanComment(line))}`; if (i == lines.length - 1) return cleanComment(line); return ` *${ensureOneSpace(cleanComment(line))}`; }); return { type: "CommentBlock", value: comments.join("\n"), start: null, end: null, loc: null, }; }; export const renderNameSafely = (name) => { return name .split("_") .map((str) => { const parts = str.split("."); str = parts[parts.length - 1]; return str; }) .join("_"); }; export const getProtoFieldTypeName = ( context: ProtoParseContext, field: ProtoField ) => { let name = context.getTypeName(field); return renderNameSafely(name); }; export const recursiveNamespace = (names, moduleBlockBody) => { if (!names || !names.length) return moduleBlockBody; const name = names.pop(); const body = [ t.exportNamedDeclaration( t.tsModuleDeclaration( t.identifier(name), t.tsModuleBlock(recursiveNamespace(names, moduleBlockBody)) ) ), ]; return body; }; export const bindMethod = (name: string) => { return t.expressionStatement( t.assignmentExpression( "=", t.memberExpression(t.thisExpression(), t.identifier(name)), t.callExpression( t.memberExpression( t.memberExpression(t.thisExpression(), t.identifier(name)), t.identifier("bind") ), [t.thisExpression()] ) ) ); }; export const shorthandProperty = (prop: string) => { return t.objectProperty( t.identifier(prop), t.identifier(prop), false, true ); }; export const importStmt = (names: string[], path: string) => { return t.importDeclaration( names.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)) ), t.stringLiteral(path) ); }; export const memberExpressionOrIdentifier = (names) => { if (names.length === 1) { return t.identifier(names[0]); } if (names.length === 2) { const [b, a] = names; return t.memberExpression(t.identifier(a), t.identifier(b)); } const [name, ...rest] = names; return t.memberExpression( memberExpressionOrIdentifier(rest), t.identifier(name) ); }; export const memberExpressionOrIdentifierAminoCasing = ( names, aminoCasingFn: Function ) => { if (names.length === 1) { return t.identifier(aminoCasingFn(names[0])); } if (names.length === 2) { const [b, a] = names; return t.memberExpression( t.identifier(aminoCasingFn(a)), t.identifier(aminoCasingFn(b)) ); } const [name, ...rest] = names; return t.memberExpression( memberExpressionOrIdentifierAminoCasing(rest, aminoCasingFn), t.identifier(aminoCasingFn(name)) ); }; export const memberExpressionOrIdentifierAminoCaseField = ( fields: ProtoField[], aminoCaseFunc: Function, useNullHandling: boolean = false ) => { if (fields.length === 1) { return t.identifier(aminoCaseFunc(fields[0])); } if (fields.length === 2) { const [b, a] = fields; return useNullHandling ? t.memberExpression( t.identifier(aminoCaseFunc(a)), t.identifier(aminoCaseFunc(b)), false, true ) : t.memberExpression( t.identifier(aminoCaseFunc(a)), t.identifier(aminoCaseFunc(b)) ); } const [field, ...rest] = fields; return useNullHandling ? t.memberExpression( memberExpressionOrIdentifierAminoCaseField( rest, aminoCaseFunc, useNullHandling ), t.identifier(aminoCaseFunc(field)), false, true ) : t.memberExpression( memberExpressionOrIdentifierAminoCaseField( rest, aminoCaseFunc, useNullHandling ), t.identifier(aminoCaseFunc(field)) ); }; export const promiseTypeAnnotation = (name) => { return t.tsTypeAnnotation( t.tsTypeReference( t.identifier("Promise"), t.tsTypeParameterInstantiation([ t.tsTypeReference(t.identifier(name)), ]) ) ); }; export const getAcceptedInterfacesTypes = ( context: ProtoParseContext, lookupInterface: string ) => { return lookupInterface ? context.store._symbols.filter( (s) => s.implementsType === lookupInterface && s.ref === context.ref.filename ) : []; }; export const getSdkFieldName = (fieldName: string, field: ProtoField) => { return field.options?.["(telescope:orig)"] ?? fieldName; }; export const getAminoFieldName = ( fieldName: string, field: ProtoField, interfaceName: string, context: ProtoParseContext ) => { const orig = field.options?.["(telescope:orig)"] ?? fieldName; if ( interfaceName === "Any" && context.ref.proto.package === "google.protobuf" && (orig === "type_url" || orig === "typeUrl") ) { // type_url => type for amino return "type"; } return orig; };