github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/js/src/solts/lib/syntax.ts (about)

     1  import ts, { ConciseBody, factory, MethodDeclaration, TypeNode } from 'typescript';
     2  
     3  export const ErrorType = factory.createTypeReferenceNode('Error');
     4  export const VoidType = factory.createTypeReferenceNode('void', undefined);
     5  export const StringType = factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
     6  export const NumberType = factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
     7  export const BooleanType = factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
     8  export const UnknownType = factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
     9  export const UndefinedType = factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword);
    10  export const Uint8ArrayType = factory.createTypeReferenceNode('Uint8Array');
    11  export const MaybeUint8ArrayType = factory.createUnionTypeNode([Uint8ArrayType, UndefinedType]);
    12  
    13  export const PromiseType = factory.createIdentifier('Promise');
    14  export const ReadableType = factory.createIdentifier('Readable');
    15  export const BufferType = factory.createIdentifier('Buffer');
    16  export const Address = factory.createIdentifier('Address');
    17  export const Event = factory.createIdentifier('Event');
    18  export const ContractCodec = factory.createIdentifier('ContractCodec');
    19  export const Result = factory.createIdentifier('Result');
    20  export const CancelStreamSignal = factory.createIdentifier('CancelStreamSignal');
    21  export const ReturnType = factory.createIdentifier('ReturnType');
    22  export const listenerForName = factory.createIdentifier('listenerFor');
    23  export const linkerName = factory.createIdentifier('linker');
    24  export const keccakName = factory.createIdentifier('Keccak');
    25  
    26  export const TType = factory.createTypeReferenceNode('T');
    27  export const AddressType = factory.createTypeReferenceNode(Address);
    28  export const EventType = factory.createTypeReferenceNode(Event);
    29  export const ContractCodecType = factory.createTypeReferenceNode(ContractCodec);
    30  export const CancelStreamSignalType = factory.createTypeReferenceNode(CancelStreamSignal);
    31  
    32  export const PrivateToken = factory.createToken(ts.SyntaxKind.PrivateKeyword);
    33  export const PublicToken = factory.createToken(ts.SyntaxKind.PublicKeyword);
    34  export const ExportToken = factory.createToken(ts.SyntaxKind.ExportKeyword);
    35  export const EllipsisToken = factory.createToken(ts.SyntaxKind.DotDotDotToken);
    36  export const QuestionToken = factory.createToken(ts.SyntaxKind.QuestionToken);
    37  export const QuestionDotToken = factory.createToken(ts.SyntaxKind.QuestionDotToken);
    38  export const ColonToken = factory.createToken(ts.SyntaxKind.ColonToken);
    39  export const AsyncToken = factory.createToken(ts.SyntaxKind.AsyncKeyword);
    40  export const ReadonlyToken = factory.createToken(ts.SyntaxKind.ReadonlyKeyword);
    41  export const EqualsGreaterThanToken = factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken);
    42  export const Undefined = factory.createIdentifier('undefined');
    43  
    44  export function createCall(fn: ts.Expression | string, args?: ts.Expression[]): ts.CallExpression {
    45    return factory.createCallExpression(asExp(fn), undefined, args);
    46  }
    47  
    48  export function accessThis(name: ts.Identifier): ts.PropertyAccessExpression {
    49    return factory.createPropertyAccessExpression(factory.createThis(), name);
    50  }
    51  
    52  export function bufferFrom(...args: ts.Expression[]): ts.CallExpression {
    53    return createCall(factory.createPropertyAccessExpression(BufferType, factory.createIdentifier('from')), args);
    54  }
    55  
    56  export function asArray(type: ts.TypeNode): ts.ArrayTypeNode {
    57    return factory.createArrayTypeNode(type);
    58  }
    59  
    60  export function asTuple(type: ts.TypeNode, size: number): ts.TupleTypeNode {
    61    return factory.createTupleTypeNode(Array(size).fill(type));
    62  }
    63  
    64  export function asRefNode(id: ts.Identifier): ts.TypeReferenceNode {
    65    return factory.createTypeReferenceNode(id, undefined);
    66  }
    67  
    68  export function asConst(exp: ts.Expression): ts.AsExpression {
    69    return factory.createAsExpression(exp, factory.createTypeReferenceNode('const'));
    70  }
    71  
    72  export function constObject(elements: ts.ObjectLiteralElementLike[]): ts.AsExpression {
    73    return asConst(factory.createObjectLiteralExpression(elements));
    74  }
    75  
    76  export function arrowFunc(params: ts.ParameterDeclaration[], body: ConciseBody): ts.ArrowFunction {
    77    return factory.createArrowFunction(undefined, undefined, params, undefined, EqualsGreaterThanToken, body);
    78  }
    79  
    80  export function hexToBuffer(arg: ts.Expression): ts.CallExpression {
    81    return createCall(prop(BufferType, 'from'), [arg, factory.createStringLiteral('hex')]);
    82  }
    83  
    84  export function hexToKeccak256(str: ts.Expression): ts.CallExpression {
    85    // new Keccak(256).update(str).digest('binary');
    86    return createCall(
    87      prop(
    88        createCall(
    89          prop(factory.createNewExpression(keccakName, undefined, [factory.createNumericLiteral('256')]), 'update'),
    90          [str, factory.createStringLiteral('hex')],
    91        ),
    92        'digest',
    93      ),
    94      [factory.createStringLiteral('binary')],
    95    );
    96  }
    97  
    98  export function arrowFuncT(
    99    params: ts.ParameterDeclaration[],
   100    constraint: TypeNode | undefined,
   101    type: TypeNode | undefined,
   102    body: ConciseBody,
   103  ): ts.ArrowFunction {
   104    return factory.createArrowFunction(
   105      undefined,
   106      [factory.createTypeParameterDeclaration('T', constraint)],
   107      params,
   108      type,
   109      EqualsGreaterThanToken,
   110      body,
   111    );
   112  }
   113  
   114  export function prop(
   115    obj: ts.Expression | string,
   116    name: string | ts.Identifier,
   117    optionChain?: boolean,
   118  ): ts.PropertyAccessExpression {
   119    return factory.createPropertyAccessChain(asExp(obj), optionChain ? QuestionDotToken : undefined, name);
   120  }
   121  
   122  function asExp(exp: ts.Expression | string): ts.Expression {
   123    return typeof exp === 'string' ? factory.createIdentifier(exp) : exp;
   124  }
   125  
   126  export function createParameter(
   127    name: string | ts.BindingName,
   128    typeNode?: ts.TypeNode,
   129    initializer?: ts.Expression,
   130    isOptional?: boolean,
   131    isVariadic?: boolean,
   132  ): ts.ParameterDeclaration {
   133    return factory.createParameterDeclaration(
   134      undefined,
   135      undefined,
   136      isVariadic ? EllipsisToken : undefined,
   137      name,
   138      isOptional ? QuestionToken : undefined,
   139      typeNode,
   140      initializer,
   141    );
   142  }
   143  
   144  export function declareConstant(
   145    name: ts.Identifier | string,
   146    initializer?: ts.Expression,
   147    extern?: boolean,
   148  ): ts.VariableStatement {
   149    return factory.createVariableStatement(
   150      extern ? [ExportToken] : [],
   151      factory.createVariableDeclarationList(
   152        [factory.createVariableDeclaration(name, undefined, undefined, initializer)],
   153        ts.NodeFlags.Const,
   154      ),
   155    );
   156  }
   157  
   158  export function declareLet(name: ts.Identifier, initializer: ts.Expression, extern?: boolean): ts.VariableStatement {
   159    return factory.createVariableStatement(
   160      extern ? [ExportToken] : [],
   161      factory.createVariableDeclarationList(
   162        [factory.createVariableDeclaration(name, undefined, undefined, initializer)],
   163        ts.NodeFlags.Let,
   164      ),
   165    );
   166  }
   167  
   168  const resolveFn = factory.createIdentifier('resolve');
   169  const rejectFn = factory.createIdentifier('reject');
   170  
   171  export function createPromiseOf(...nodes: ts.TypeNode[]): ts.ExpressionWithTypeArguments {
   172    return factory.createExpressionWithTypeArguments(PromiseType, nodes);
   173  }
   174  
   175  export function createAssignmentStatement(left: ts.Expression, right: ts.Expression): ts.ExpressionStatement {
   176    return factory.createExpressionStatement(factory.createAssignment(left, right));
   177  }
   178  
   179  export function createPromiseBody(error: ts.Identifier, statements: ts.Expression[]): ts.ExpressionStatement {
   180    return factory.createExpressionStatement(
   181      factory.createConditionalExpression(
   182        error,
   183        QuestionToken,
   184        createCall(rejectFn, [error]),
   185        ColonToken,
   186        createCall(resolveFn, statements ? statements : undefined),
   187      ),
   188    );
   189  }
   190  
   191  export function rejectOrResolve(error: ts.Identifier, statements: ts.Statement[], success: ts.Expression[]) {
   192    return factory.createIfStatement(
   193      error,
   194      factory.createExpressionStatement(createCall(rejectFn, [error])),
   195      factory.createBlock([...statements, factory.createExpressionStatement(createCall(resolveFn, success))]),
   196    );
   197  }
   198  
   199  export function CreateNewPromise(
   200    body: ts.Statement[],
   201    returnType?: ts.TypeNode,
   202    multiLine?: boolean,
   203  ): ts.NewExpression {
   204    return factory.createNewExpression(PromiseType, undefined, [
   205      CreateCallbackDeclaration(resolveFn, rejectFn, body, returnType, multiLine || false),
   206    ]);
   207  }
   208  
   209  export function CreateCallbackDeclaration(
   210    first: ts.Identifier,
   211    second: ts.Identifier,
   212    body: ts.Statement[],
   213    returnType?: ts.TypeNode,
   214    multiLine?: boolean,
   215  ): ts.ArrowFunction {
   216    return factory.createArrowFunction(
   217      undefined,
   218      undefined,
   219      [createParameter(first, undefined), createParameter(second, undefined)],
   220      returnType,
   221      undefined,
   222      factory.createBlock(body, multiLine),
   223    );
   224  }
   225  
   226  export function createCallbackType(
   227    params: ts.ParameterDeclaration[],
   228    type: ts.TypeNode = VoidType,
   229  ): ts.FunctionTypeNode {
   230    return factory.createFunctionTypeNode(undefined, params, type);
   231  }
   232  
   233  function importFrom(pkg: string, ...things: ts.Identifier[]) {
   234    return factory.createImportDeclaration(
   235      undefined,
   236      undefined,
   237      factory.createImportClause(
   238        false,
   239        undefined,
   240        factory.createNamedImports(things.map((t) => factory.createImportSpecifier(undefined, t))),
   241      ),
   242      factory.createStringLiteral(pkg),
   243    );
   244  }
   245  
   246  export function importReadable(): ts.ImportDeclaration {
   247    return importFrom('stream', ReadableType);
   248  }
   249  
   250  export function importBurrow(burrowImportPath: string): ts.ImportDeclaration {
   251    return importFrom(
   252      burrowImportPath,
   253      Address,
   254      CancelStreamSignal,
   255      ContractCodec,
   256      Event,
   257      linkerName,
   258      listenerForName,
   259      Result,
   260      keccakName,
   261    );
   262  }
   263  
   264  export class Method {
   265    readonly id: ts.Identifier;
   266    type?: ts.TypeReferenceNode;
   267    params: ts.ParameterDeclaration[] = [];
   268    ret?: ts.TypeNode;
   269  
   270    constructor(name: string) {
   271      this.id = factory.createIdentifier(name);
   272    }
   273  
   274    parameter(name: string | ts.Identifier, type: ts.TypeNode, optional?: boolean, isVariadic?: boolean): Method {
   275      this.params.push(createParameter(name, type, undefined, optional, isVariadic));
   276      return this;
   277    }
   278  
   279    parameters(arg: ts.ParameterDeclaration | ts.ParameterDeclaration[]): Method {
   280      if (Array.isArray(arg)) {
   281        this.params.push(...arg);
   282      } else {
   283        this.params.push(arg);
   284      }
   285      return this;
   286    }
   287  
   288    returns(type: ts.TypeNode): Method {
   289      this.ret = type;
   290      return this;
   291    }
   292  
   293    signature(): ts.MethodSignature {
   294      return factory.createMethodSignature(undefined, this.id, undefined, undefined, this.params, this.ret);
   295    }
   296  
   297    declaration(statements: ts.Statement[], multiLine?: boolean): MethodDeclaration {
   298      return factory.createMethodDeclaration(
   299        undefined,
   300        undefined,
   301        undefined,
   302        this.id,
   303        undefined,
   304        undefined,
   305        this.params,
   306        this.ret,
   307        factory.createBlock(statements, multiLine),
   308      );
   309    }
   310  }