Short-circuit full type (with lookupIndex) (#3804)
* Short-circuit full type (with lookupIndex) * Defaults for type expansion * Tuple with extra spaces removed * Fill in generated types * Adjust generation * Adjust tests * Adjust
This commit is contained in:
@@ -158,12 +158,12 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)",
|
||||
"type": "(AccountId,AccountId)",
|
||||
"name": "Occupied"
|
||||
}
|
||||
],
|
||||
"info": 3,
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId, AccountId)\"}}"
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId,AccountId)\"}}"
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
@@ -181,7 +181,7 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)"
|
||||
"type": "(AccountId,AccountId)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -198,4 +198,4 @@
|
||||
"info": 5,
|
||||
"type": "Option<AccountId>"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -206,12 +206,12 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)",
|
||||
"type": "(AccountId,AccountId)",
|
||||
"name": "Occupied"
|
||||
}
|
||||
],
|
||||
"info": 3,
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId, AccountId)\"}}"
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId,AccountId)\"}}"
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
@@ -229,7 +229,7 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)"
|
||||
"type": "(AccountId,AccountId)"
|
||||
},
|
||||
{
|
||||
"displayName": "ValueEntry",
|
||||
@@ -427,4 +427,4 @@
|
||||
],
|
||||
"type": "{\"_enum\":[\"NotOwner\",\"NotApproved\",\"TokenExists\",\"TokenNotFound\",\"CannotInsert\",\"CannotRemove\",\"CannotFetchValue\",\"NotAllowed\"]}"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -63,12 +63,12 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(u32, AccountId)",
|
||||
"type": "(u32,AccountId)",
|
||||
"name": "Occupied"
|
||||
}
|
||||
],
|
||||
"info": 3,
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(u32, AccountId)\"}}"
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(u32,AccountId)\"}}"
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
@@ -84,7 +84,7 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(u32, AccountId)"
|
||||
"type": "(u32,AccountId)"
|
||||
},
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
@@ -409,7 +409,7 @@
|
||||
"type": "{\"_enum\":{\"Confirmed\":\"()\",\"ConfirmationsNeeded\":\"u32\"}}"
|
||||
}
|
||||
],
|
||||
"type": "(u32, ConfirmationStatus)"
|
||||
"type": "(u32,ConfirmationStatus)"
|
||||
},
|
||||
{
|
||||
"displayName": "ConfirmationStatus",
|
||||
@@ -511,4 +511,4 @@
|
||||
"info": 5,
|
||||
"type": "Option<Vec<u8>>"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -158,12 +158,12 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)",
|
||||
"type": "(AccountId,AccountId)",
|
||||
"name": "Occupied"
|
||||
}
|
||||
],
|
||||
"info": 3,
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId, AccountId)\"}}"
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId,AccountId)\"}}"
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
@@ -181,7 +181,7 @@
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)"
|
||||
"type": "(AccountId,AccountId)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -202,4 +202,4 @@
|
||||
"info": 5,
|
||||
"type": "Option<AccountId>"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { encodeTypeDef } from './encodeTypes';
|
||||
import { TypeRegistry } from './registry';
|
||||
import { TypeDefInfo } from './types';
|
||||
|
||||
describe('encodeTypeDef', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('correctly encodes a complex struct', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef({
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
@@ -47,7 +50,7 @@ describe('encodeTypeDef', (): void => {
|
||||
|
||||
it('correctly encodes a complex struct (named)', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef({
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
@@ -88,7 +91,7 @@ describe('encodeTypeDef', (): void => {
|
||||
|
||||
it('correctly encodes a complex enum', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef({
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: [
|
||||
{
|
||||
@@ -148,7 +151,7 @@ describe('encodeTypeDef', (): void => {
|
||||
|
||||
it('correctly encodes a complex enum (named)', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef({
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: [
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ export function paramsNotation <T> (outer: string, inner?: T | T[], transform: (
|
||||
}`;
|
||||
}
|
||||
|
||||
function encodeWithParams (typeDef: TypeDef, outer: string): string {
|
||||
function encodeWithParams (registry: Registry, typeDef: TypeDef, lookupCounter: number, outer: string): string {
|
||||
const { info, sub } = typeDef;
|
||||
|
||||
switch (info) {
|
||||
@@ -32,24 +32,25 @@ function encodeWithParams (typeDef: TypeDef, outer: string): string {
|
||||
case TypeDefInfo.Option:
|
||||
case TypeDefInfo.Result:
|
||||
case TypeDefInfo.Vec:
|
||||
return paramsNotation(outer, sub, (param) => encodeTypeDef(param));
|
||||
return paramsNotation(outer, sub, (param) => encodeTypeDef(registry, param, lookupCounter));
|
||||
}
|
||||
|
||||
throw new Error(`Unable to encode ${stringify(typeDef)} with params`);
|
||||
}
|
||||
|
||||
function encodeDoNotConstruct ({ displayName }: TypeDef): string {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function encodeDoNotConstruct (registry: Registry, { displayName }: TypeDef, lookupCounter: number): string {
|
||||
return `DoNotConstruct<${displayName || 'Unknown'}>`;
|
||||
}
|
||||
|
||||
function encodeSubTypes (sub: TypeDef[], asEnum?: boolean): string {
|
||||
function encodeSubTypes (registry: Registry, sub: TypeDef[], lookupCounter: number, asEnum?: boolean): string {
|
||||
const names = sub.map(({ name }) => name);
|
||||
|
||||
assert(names.every((n) => !!n), () => `Subtypes does not have consistent names, ${names.join(', ')}`);
|
||||
|
||||
const inner = sub.reduce< Record<string, string>>((result, type) => ({
|
||||
...result,
|
||||
[type.name as string]: encodeTypeDef(type)
|
||||
[type.name as string]: encodeTypeDef(registry, type, lookupCounter)
|
||||
}), {});
|
||||
|
||||
return stringify(
|
||||
@@ -59,7 +60,7 @@ function encodeSubTypes (sub: TypeDef[], asEnum?: boolean): string {
|
||||
);
|
||||
}
|
||||
|
||||
function encodeEnum (typeDef: TypeDef): string {
|
||||
function encodeEnum (registry: Registry, typeDef: TypeDef, lookupCounter: number): string {
|
||||
assert(typeDef.sub && Array.isArray(typeDef.sub), 'Unable to encode Enum type');
|
||||
|
||||
const sub = typeDef.sub;
|
||||
@@ -68,28 +69,29 @@ function encodeEnum (typeDef: TypeDef): string {
|
||||
// TODO We need to take the disciminant into account and auto-add empty entries
|
||||
return sub.every(({ type }) => type === 'Null')
|
||||
? stringify({ _enum: sub.map(({ name }, index) => `${name || `Empty${index}`}`) })
|
||||
: encodeSubTypes(sub, true);
|
||||
: encodeSubTypes(registry, sub, lookupCounter, true);
|
||||
}
|
||||
|
||||
function encodeStruct (typeDef: TypeDef): string {
|
||||
function encodeStruct (registry: Registry, typeDef: TypeDef, lookupCounter: number): string {
|
||||
assert(typeDef.sub && Array.isArray(typeDef.sub), 'Unable to encode Struct type');
|
||||
|
||||
return encodeSubTypes(typeDef.sub);
|
||||
return encodeSubTypes(registry, typeDef.sub, lookupCounter);
|
||||
}
|
||||
|
||||
function encodeTuple (typeDef: TypeDef): string {
|
||||
function encodeTuple (registry: Registry, typeDef: TypeDef, lookupCounter: number): string {
|
||||
assert(typeDef.sub && Array.isArray(typeDef.sub), 'Unable to encode Tuple type');
|
||||
|
||||
return `(${typeDef.sub.map((type) => encodeTypeDef(type)).join(', ')})`;
|
||||
return `(${typeDef.sub.map((type) => encodeTypeDef(registry, type, lookupCounter)).join(',')})`;
|
||||
}
|
||||
|
||||
function encodeUInt ({ length }: TypeDef, type: 'Int' | 'UInt'): string {
|
||||
function encodeUInt (registry: Registry, { length }: TypeDef, lookupCounter: number, type: 'Int' | 'UInt'): string {
|
||||
assert(isNumber(length), 'Unable to encode VecFixed type');
|
||||
|
||||
return `${type}<${length}>`;
|
||||
}
|
||||
|
||||
function encodeVecFixed ({ length, sub }: TypeDef): string {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function encodeVecFixed (registry: Registry, { length, sub }: TypeDef, lookupCounter: number): string {
|
||||
assert(isNumber(length) && !isUndefined(sub) && !Array.isArray(sub), 'Unable to encode VecFixed type');
|
||||
|
||||
return `[${sub.type};${length}]`;
|
||||
@@ -97,38 +99,62 @@ function encodeVecFixed ({ length, sub }: TypeDef): string {
|
||||
|
||||
// We setup a record here to ensure we have comprehensive coverage (any item not covered will result
|
||||
// in a compile-time error with the missing index)
|
||||
const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
|
||||
[TypeDefInfo.BTreeMap]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeMap'),
|
||||
[TypeDefInfo.BTreeSet]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeSet'),
|
||||
[TypeDefInfo.Compact]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Compact'),
|
||||
[TypeDefInfo.DoNotConstruct]: (typeDef: TypeDef): string => encodeDoNotConstruct(typeDef),
|
||||
[TypeDefInfo.Enum]: (typeDef: TypeDef): string => encodeEnum(typeDef),
|
||||
[TypeDefInfo.HashMap]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'HashMap'),
|
||||
[TypeDefInfo.Int]: (typeDef: TypeDef): string => encodeUInt(typeDef, 'Int'),
|
||||
[TypeDefInfo.Linkage]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Linkage'),
|
||||
const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef, lookupCounter: number) => string> = {
|
||||
[TypeDefInfo.BTreeMap]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'BTreeMap'),
|
||||
[TypeDefInfo.BTreeSet]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'BTreeSet'),
|
||||
[TypeDefInfo.Compact]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'Compact'),
|
||||
[TypeDefInfo.DoNotConstruct]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeDoNotConstruct(registry, typeDef, lookupCounter),
|
||||
[TypeDefInfo.Enum]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeEnum(registry, typeDef, lookupCounter),
|
||||
[TypeDefInfo.HashMap]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'HashMap'),
|
||||
[TypeDefInfo.Int]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeUInt(registry, typeDef, lookupCounter, 'Int'),
|
||||
[TypeDefInfo.Linkage]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'Linkage'),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
[TypeDefInfo.Null]: (typeDef: TypeDef): string => 'Null',
|
||||
[TypeDefInfo.Option]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Option'),
|
||||
[TypeDefInfo.Plain]: (typeDef: TypeDef): string => typeDef.displayName || typeDef.type,
|
||||
[TypeDefInfo.Result]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Result'),
|
||||
[TypeDefInfo.Set]: (typeDef: TypeDef): string => typeDef.type,
|
||||
[TypeDefInfo.Si]: (typeDef: TypeDef): string => typeDef.type,
|
||||
[TypeDefInfo.Struct]: (typeDef: TypeDef): string => encodeStruct(typeDef),
|
||||
[TypeDefInfo.Tuple]: (typeDef: TypeDef): string => encodeTuple(typeDef),
|
||||
[TypeDefInfo.UInt]: (typeDef: TypeDef): string => encodeUInt(typeDef, 'UInt'),
|
||||
[TypeDefInfo.Vec]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Vec'),
|
||||
[TypeDefInfo.VecFixed]: (typeDef: TypeDef): string => encodeVecFixed(typeDef)
|
||||
[TypeDefInfo.Null]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
'Null',
|
||||
[TypeDefInfo.Option]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'Option'),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
[TypeDefInfo.Plain]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
typeDef.displayName || typeDef.type,
|
||||
[TypeDefInfo.Result]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'Result'),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
[TypeDefInfo.Set]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
typeDef.type,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
[TypeDefInfo.Si]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
typeDef.lookupName || typeDef.type,
|
||||
[TypeDefInfo.Struct]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeStruct(registry, typeDef, lookupCounter),
|
||||
[TypeDefInfo.Tuple]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeTuple(registry, typeDef, lookupCounter),
|
||||
[TypeDefInfo.UInt]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeUInt(registry, typeDef, lookupCounter, 'UInt'),
|
||||
[TypeDefInfo.Vec]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeWithParams(registry, typeDef, lookupCounter, 'Vec'),
|
||||
[TypeDefInfo.VecFixed]: (registry: Registry, typeDef: TypeDef, lookupCounter: number) =>
|
||||
encodeVecFixed(registry, typeDef, lookupCounter)
|
||||
};
|
||||
|
||||
function encodeType (typeDef: TypeDef): string {
|
||||
function encodeType (registry: Registry, typeDef: TypeDef, lookupCounter: number): string {
|
||||
const encoder = encoders[typeDef.info];
|
||||
|
||||
assert(encoder, () => `Cannot encode type: info=${typeDef.info}, typeDef=${stringify(typeDef)}`);
|
||||
assert(encoder, () => `Cannot encode type ${stringify(typeDef)}`);
|
||||
|
||||
return encoder(typeDef);
|
||||
return lookupCounter < 0 && isNumber(typeDef.lookupIndex)
|
||||
? typeDef.lookupName || registry.createLookupType(typeDef.lookupIndex)
|
||||
: encoder(registry, typeDef, lookupCounter--);
|
||||
}
|
||||
|
||||
export function encodeTypeDef (typeDef: TypeDef): string {
|
||||
export function encodeTypeDef (registry: Registry, typeDef: TypeDef, lookupCounter = 0): string {
|
||||
assert(!isUndefined(typeDef.info), () => `Invalid type definition with no instance info, typeDef=${stringify(typeDef)}`);
|
||||
|
||||
// In the case of contracts we do have the unfortunate situation where the displayName would
|
||||
@@ -138,12 +164,12 @@ export function encodeTypeDef (typeDef: TypeDef): string {
|
||||
return typeDef.displayName;
|
||||
}
|
||||
|
||||
return encodeType(typeDef);
|
||||
return encodeType(registry, typeDef, lookupCounter);
|
||||
}
|
||||
|
||||
export function withTypeString (_: Registry, typeDef: Omit<TypeDef, 'type'>): TypeDef {
|
||||
export function withTypeString (registry: Registry, typeDef: Omit<TypeDef, 'type'>, lookupCounter = 0): TypeDef {
|
||||
return {
|
||||
...typeDef,
|
||||
type: encodeType(typeDef as TypeDef)
|
||||
type: encodeType(registry, typeDef as TypeDef, lookupCounter)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,9 +36,11 @@ export interface TypeDef {
|
||||
displayName?: string;
|
||||
fallbackType?: string;
|
||||
info: TypeDefInfo;
|
||||
isFromSi?: boolean;
|
||||
index?: number;
|
||||
isFromSi?: boolean;
|
||||
length?: number;
|
||||
lookupIndex?: number;
|
||||
lookupName?: string;
|
||||
name?: string;
|
||||
namespace?: string;
|
||||
sub?: TypeDef | TypeDef[];
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { SiField, SiLookupTypeId, SiType, SiTypeDefArray, SiTypeDefCompact,
|
||||
import type { Type } from '../primitive/Type';
|
||||
import type { Registry, TypeDef } from '../types';
|
||||
|
||||
import { assert, isNumber, isString, stringCamelCase, stringify } from '@polkadot/util';
|
||||
import { assert, isNumber, isString, stringCamelCase, stringify, stringUpperFirst } from '@polkadot/util';
|
||||
|
||||
import { Struct } from '../codec/Struct';
|
||||
import { withTypeString } from '../create/encodeTypes';
|
||||
@@ -30,13 +30,52 @@ const PRIMITIVE_SP = [
|
||||
'pallet_identity::types::Data'
|
||||
];
|
||||
|
||||
function removeDuplicateNames (names: (string | null)[]): (string | null)[] {
|
||||
return names.map((name, index): string | null =>
|
||||
!name || names.some((o, i) => index !== i && name === o)
|
||||
? null
|
||||
: name
|
||||
);
|
||||
}
|
||||
|
||||
function extractNames (types: PortableType[]): Record<number, string> {
|
||||
return removeDuplicateNames(
|
||||
types.map(({ type: { path } }): string | null => {
|
||||
if (!path.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parts = path.map((p) => stringUpperFirst(stringCamelCase(p)));
|
||||
|
||||
if (parts.length >= 2 && parts[parts.length - 1] === parts[parts.length - 2]) {
|
||||
parts.pop();
|
||||
}
|
||||
|
||||
const typeName = parts.join('');
|
||||
|
||||
return ['BTreeMap', 'Cow', 'Result', 'Option'].includes(typeName) || ['frame_support'].includes(path[0].toString())
|
||||
? null
|
||||
: typeName;
|
||||
})
|
||||
).reduce<Record<number, string>>((all, name, index) => {
|
||||
if (name) {
|
||||
all[index] = name;
|
||||
}
|
||||
|
||||
return all;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export class GenericPortableRegistry extends Struct {
|
||||
#names: Record<number, string>;
|
||||
#typeDefs: Record<number, TypeDef> = {};
|
||||
|
||||
constructor (registry: Registry, value?: Uint8Array) {
|
||||
super(registry, {
|
||||
types: 'Vec<PortableType>'
|
||||
}, value);
|
||||
|
||||
this.#names = extractNames(this.types);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,34 +100,39 @@ export class GenericPortableRegistry extends Struct {
|
||||
* @description Lookup the type definition for the index
|
||||
*/
|
||||
public getTypeDef (lookupId: SiLookupTypeId | string | number): TypeDef {
|
||||
const index = this.#getLookupId(lookupId);
|
||||
const lookupIndex = this.#getLookupId(lookupId);
|
||||
|
||||
if (!this.#typeDefs[index]) {
|
||||
if (!this.#typeDefs[lookupIndex]) {
|
||||
// we set first since we will get into circular lookups along the way
|
||||
this.#typeDefs[index] = {
|
||||
this.#typeDefs[lookupIndex] = {
|
||||
info: TypeDefInfo.DoNotConstruct,
|
||||
type: this.registry.createLookupType(index)
|
||||
lookupIndex,
|
||||
lookupName: this.#names[lookupIndex],
|
||||
type: this.registry.createLookupType(lookupIndex)
|
||||
};
|
||||
|
||||
const typeDef = this.#extract(this.getSiType(lookupId), index);
|
||||
const extracted = this.#extract(this.getSiType(lookupId), lookupIndex);
|
||||
|
||||
Object.keys(typeDef).forEach((key): void => {
|
||||
Object.keys(extracted).forEach((key): void => {
|
||||
// these are safe since we are looking through the keys as set
|
||||
this.#typeDefs[index][key as 'info'] = typeDef[key as 'info'];
|
||||
this.#typeDefs[lookupIndex][key as 'info'] = extracted[key as 'info'];
|
||||
});
|
||||
}
|
||||
|
||||
return this.#typeDefs[index];
|
||||
return this.#typeDefs[lookupIndex];
|
||||
}
|
||||
|
||||
#createSiDef (lookupId: SiLookupTypeId): TypeDef {
|
||||
const typeDef = this.getTypeDef(lookupId);
|
||||
const lookupIndex = lookupId.toNumber();
|
||||
|
||||
// Flatten Plain types immediately, otherwise setup for a lookup
|
||||
return typeDef.info === TypeDefInfo.Plain
|
||||
? typeDef
|
||||
: {
|
||||
info: TypeDefInfo.Si,
|
||||
lookupIndex,
|
||||
lookupName: this.#names[lookupIndex],
|
||||
type: this.registry.createLookupType(lookupId)
|
||||
};
|
||||
}
|
||||
@@ -254,7 +298,12 @@ export class GenericPortableRegistry extends Struct {
|
||||
}
|
||||
|
||||
#extractTuple (_: number, ids: SiTypeDefTuple): TypeDef {
|
||||
if (ids.length === 1) {
|
||||
if (ids.length === 0) {
|
||||
return {
|
||||
info: TypeDefInfo.Null,
|
||||
type: 'Null'
|
||||
};
|
||||
} else if (ids.length === 1) {
|
||||
return this.getTypeDef(ids[0]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user