UNPKG

@cosmology/ast

Version:
634 lines (581 loc) 20.2 kB
import * as t from '@babel/types'; import { FromPartialMethod } from './index'; import { identifier, callExpression, TypeLong } from '../../../utils'; import { getFieldsTypeName } from '..'; import { getDefaultTSTypeFromProtoType } from '../../types'; // message.sender = expr const setField = (prop: string, expr: t.Expression): t.Statement => { return t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( t.identifier('message'), t.identifier(prop) ), expr ) ); }; // message.sender = object.sender ?? value; const setNullishCoalescing = (prop: string, value: t.Expression): t.Statement => { return setField(prop, t.logicalExpression( '??', t.memberExpression( t.identifier('object'), t.identifier(prop) ), value )); }; const setNotUndefinedAndNotNull = ( prop: string, value: t.Expression, defaultValue: t.Expression, args: FromPartialMethod ): t.Statement => { const strictNullCheckForPrototypeMethods = args.context.pluginValue('prototypes.strictNullCheckForPrototypeMethods'); if(strictNullCheckForPrototypeMethods){ return t.ifStatement( t.logicalExpression( '&&', t.binaryExpression( '!==', t.memberExpression( t.identifier('object'), t.identifier(prop) ), t.identifier('undefined') ), t.binaryExpression( '!==', t.memberExpression( t.identifier('object'), t.identifier(prop) ), t.nullLiteral() ) ), t.blockStatement([ t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( t.identifier('message'), t.identifier(prop) ), value )) ]) ) } else{ return t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( t.identifier('message'), t.identifier(prop) ), t.conditionalExpression( t.logicalExpression( '&&', t.binaryExpression( '!==', t.memberExpression( t.identifier('object'), t.identifier(prop) ), t.identifier('undefined') ), t.binaryExpression( '!==', t.memberExpression( t.identifier('object'), t.identifier(prop) ), t.nullLiteral() ) ), value, defaultValue ) ) ); } }; export const fromPartial = { // message.sender = object.sender ?? ""; string(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, getDefaultTSTypeFromProtoType(args.context, args.field, args.isOneOf) ); }, // message.disableMacros = object.disableMacros ?? false; bool(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, getDefaultTSTypeFromProtoType(args.context, args.field, args.isOneOf) ); }, // message.doubleValue = object.doubleValue ?? 0; number(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, getDefaultTSTypeFromProtoType(args.context, args.field, args.isOneOf) ); }, int32(args: FromPartialMethod) { return fromPartial.number(args); }, uint32(args: FromPartialMethod) { return fromPartial.number(args); }, sint32(args: FromPartialMethod) { return fromPartial.number(args); }, fixed32(args: FromPartialMethod) { return fromPartial.number(args); }, sfixed32(args: FromPartialMethod) { return fromPartial.number(args); }, double(args: FromPartialMethod) { return fromPartial.number(args); }, float(args: FromPartialMethod) { return fromPartial.number(args); }, // OLD: message.myInt64Value = object.myInt64Value !== undefined && object.myInt64Value !== null ? Long.fromValue(object.myInt64Value) : Long.ZERO; // NEW: if( object.myInt64Value !== undefined && object.myInt64Value !== null ) { message.myInt64Value = Long.fromValue(object.myInt64Value) } long(args: FromPartialMethod) { const prop = args.field.name; TypeLong.addUtil(args.context); return setNotUndefinedAndNotNull( prop, TypeLong.getFromValueWithArgs(args.context, t.memberExpression( t.identifier('object'), t.identifier(prop) ) ), getDefaultTSTypeFromProtoType(args.context, args.field, args.isOneOf), args ); }, int64(args: FromPartialMethod) { return fromPartial.long(args); }, uint64(args: FromPartialMethod) { return fromPartial.long(args); }, sint64(args: FromPartialMethod) { return fromPartial.long(args); }, fixed64(args: FromPartialMethod) { return fromPartial.long(args); }, sfixed64(args: FromPartialMethod) { return fromPartial.long(args); }, // message.signDoc = object.signDoc !== undefined && object.signDoc !== null ? SignDocDirectAux.fromPartial(object.signDoc) : SignDocDirectAux.fromPartial({}); type(args: FromPartialMethod) { const prop = args.field.name; let name = args.context.getTypeName(args.field); if ( !args.context.options.aminoEncoding.useLegacyInlineEncoding && args.context.options.interfaces.enabled && args.context.options.interfaces?.useGlobalDecoderRegistry && args.field.type === 'google.protobuf.Any' && args.field.options['(cosmos_proto.accepts_interface)'] ) { name = 'GlobalDecoderRegistry'; } return setNotUndefinedAndNotNull( prop, t.callExpression( t.memberExpression( t.identifier(name), t.identifier('fromPartial') ), [ t.memberExpression( t.identifier('object'), t.identifier(prop) ) ] ), t.identifier('undefined'), args ); }, // message.mode = object.mode ?? 0; enum(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, getDefaultTSTypeFromProtoType(args.context, args.field, args.isOneOf) ); }, // message.queryData = object.queryData ?? new Uint8Array() bytes(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, getDefaultTSTypeFromProtoType(args.context, args.field, args.isOneOf) ); }, // message.period = object.period ?? undefined; duration(args: FromPartialMethod) { const durationFormat = args.context.pluginValue('prototypes.typingsFormat.duration'); switch (durationFormat) { case 'string': return fromPartial.durationString(args); case 'duration': default: return fromPartial.type(args); } }, durationString(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, t.identifier('undefined') ); }, timestamp(args: FromPartialMethod) { const timestampFormat = args.context.pluginValue('prototypes.typingsFormat.timestamp') switch (timestampFormat) { case 'timestamp': return fromPartial.type(args); case 'date': default: return fromPartial.timestampDate(args); } }, // message.periodReset = object.periodReset ?? undefined; timestampDate(args: FromPartialMethod) { const prop = args.field.name; return setNullishCoalescing( prop, t.identifier('undefined') ); }, // message.referenceMap = Object.entries(object.referenceMap ?? {}).reduce<{ // [key: Long]: Reference; // }>((acc, [key, value]) => { // if (value !== undefined) { // acc[Number(key)] = Reference.fromPartial(value); // } // return acc; // }, {}); // message.labels = Object.entries(object.typeMap ?? {}).reduce<{ // [key: string]: string; // }>((acc, [key, value]) => { // if (value !== undefined) { // acc[key] = String(value); // } // return acc; // }, {}); keyHash(args: FromPartialMethod) { const prop = args.field.name; const keyType = args.field.keyType; const valueType = args.field.parsedType.name let fromPartialWithArgs = null; // valueTypeType: string for identifier let valueTypeType = valueType; switch (valueType) { case 'string': fromPartialWithArgs = t.callExpression( t.identifier('String'), [ t.identifier('value') ] ); break; case 'int32': case 'uint32': valueTypeType = 'number'; fromPartialWithArgs = t.callExpression( t.identifier('Number'), [ t.identifier('value') ] ); break; case 'int64': case 'uint64': case 'sint64': case 'fixed64': case 'sfixed64': TypeLong.addUtil(args.context); valueTypeType = TypeLong.getPropType(args.context); fromPartialWithArgs = TypeLong.getFromValueWithArgs(args.context, t.identifier('value')); break; default: fromPartialWithArgs = t.callExpression( t.memberExpression( t.identifier(valueType), t.identifier('fromPartial') ), [ t.identifier('value') ] ); } let wrapKey = null; let keyTypeType = null; switch (keyType) { case 'string': wrapKey = (a) => a; keyTypeType = t.tsStringKeyword(); break; case 'int64': case 'uint64': case 'sint64': case 'fixed64': case 'sfixed64': wrapKey = (a) => t.callExpression( t.identifier('Number'), [ a ] ); TypeLong.addUtil(args.context); keyTypeType = t.tsTypeReference(TypeLong.getPropIdentifier(args.context)); break; case 'int32': case 'uint32': wrapKey = (a) => t.callExpression( t.identifier('Number'), [ a ] ); keyTypeType = t.tsNumberKeyword() break; default: throw new Error('keyHash requires new type. Ask maintainers.'); } return t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( t.identifier('message'), t.identifier(prop) ), callExpression( t.memberExpression( t.callExpression( t.memberExpression( t.identifier('Object'), t.identifier('entries') ), [ t.logicalExpression( '??', t.memberExpression( t.identifier('object'), t.identifier(prop) ), t.objectExpression([]) ) ] ), t.identifier('reduce') ), [ t.arrowFunctionExpression( [ t.identifier('acc'), t.arrayPattern([ t.identifier('key'), t.identifier('value') ]) ], t.blockStatement([ t.ifStatement( t.binaryExpression( '!==', t.identifier('value'), t.identifier('undefined') ), t.blockStatement([ t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( t.identifier('acc'), wrapKey(t.identifier('key')), true ), fromPartialWithArgs ) ) ]) ), t.returnStatement( t.identifier('acc') ) ]) ), t.objectExpression([]), ], t.tsTypeParameterInstantiation( [ t.tsTypeLiteral( [ t.tsIndexSignature( [ identifier('key', t.tsTypeAnnotation( keyTypeType )) ], t.tsTypeAnnotation( t.tsTypeReference( t.identifier(valueTypeType) ) ) ) ] ) ] ) ) ) ) }, // message.codeIds = object.codeIds?.map(e => Long.fromValue(e)) || []; array(args: FromPartialMethod, expr: t.Expression) { const prop = args.field.name; return t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( t.identifier('message'), t.identifier(prop) ), t.logicalExpression( '||', t.optionalCallExpression( t.optionalMemberExpression( t.memberExpression( t.identifier('object'), t.identifier(prop) ), t.identifier('map'), false, true ), [ t.arrowFunctionExpression( [ t.identifier('e') ], expr ) ], false ), t.arrayExpression([]) ) ) ); } }; export const arrayTypes = { // message.overloadId = object.overloadId?.map(e => e) || []; identity() { return t.identifier('e'); }, string() { return arrayTypes.identity(); }, bool() { return arrayTypes.identity(); }, bytes() { return arrayTypes.identity(); }, double() { return arrayTypes.identity(); }, float() { return arrayTypes.identity(); }, int32() { return arrayTypes.identity(); }, uint32() { return arrayTypes.identity(); }, sint32() { return arrayTypes.identity(); }, fixed32() { return arrayTypes.identity(); }, sfixed32() { return arrayTypes.identity(); }, enum() { return arrayTypes.identity(); }, // message.codeIds = object.codeIds?.map(e => Long.fromValue(e)) || []; long(args: FromPartialMethod) { TypeLong.addUtil(args.context); return TypeLong.getFromValueWithArgs(args.context, t.identifier('e') ); }, int64(args: FromPartialMethod) { return arrayTypes.long(args); }, uint64(args: FromPartialMethod) { return arrayTypes.long(args); }, sint64(args: FromPartialMethod) { return arrayTypes.long(args); }, fixed64(args: FromPartialMethod) { return arrayTypes.long(args); }, sfixed64(args: FromPartialMethod) { return arrayTypes.long(args); }, // message.tokenInMaxs = object.tokenInMaxs?.map(e => Coin.fromPartial(e)) || []; type(args: FromPartialMethod) { let name = args.context.getTypeName(args.field); let callee = t.memberExpression( t.identifier(name), t.identifier('fromPartial') ) if ( !args.context.options.aminoEncoding.useLegacyInlineEncoding && args.context.options.interfaces.enabled && args.context.options.interfaces?.useGlobalDecoderRegistry && args.field.type === 'google.protobuf.Any' && args.field.options['(cosmos_proto.accepts_interface)'] ) { name = 'GlobalDecoderRegistry'; callee = t.memberExpression( t.identifier(name), t.identifier('fromPartial') ) return t.tsAsExpression(t.callExpression( callee, [ t.identifier('e') ] ), t.tsAnyKeyword()) } return t.callExpression( callee, [ t.identifier('e') ] ); } }