|
| 1 | +import { Materials } from "@ethdebug/materials"; |
| 2 | +import { Type, isType } from "@ethdebug/types"; |
| 3 | +import { Pointer, isPointer } from "@ethdebug/pointers"; |
| 4 | + |
| 5 | +export type Context = |
| 6 | + | Context.Code |
| 7 | + | Context.Variables |
| 8 | + | Context.Remark; |
| 9 | + |
| 10 | +export const isContext = (value: unknown): value is Context => [ |
| 11 | + Context.isCode, |
| 12 | + Context.isVariables, |
| 13 | + Context.isRemark, |
| 14 | +].some(guard => guard(value)); |
| 15 | + |
| 16 | +export namespace Context { |
| 17 | + export interface Code { |
| 18 | + code: Materials.SourceRange; |
| 19 | + } |
| 20 | + |
| 21 | + export const isCode = (value: unknown): value is Code => |
| 22 | + typeof value === "object" && !!value && |
| 23 | + "code" in value && Materials.isSourceRange(value.code); |
| 24 | + |
| 25 | + export interface Variables { |
| 26 | + variables: Variables.Variable[] |
| 27 | + } |
| 28 | + |
| 29 | + export const isVariables = (value: unknown): value is Variables => |
| 30 | + typeof value === "object" && !!value && |
| 31 | + "variables" in value && value.variables instanceof Array && |
| 32 | + value.variables.length > 0 && |
| 33 | + value.variables.every(Variables.isVariable); |
| 34 | + |
| 35 | + export namespace Variables { |
| 36 | + export interface Variable { |
| 37 | + identifier?: string; |
| 38 | + declaration?: Materials.SourceRange; |
| 39 | + type?: Type; |
| 40 | + pointer?: Pointer; |
| 41 | + } |
| 42 | + |
| 43 | + const allowedKeys = new Set([ |
| 44 | + "identifier", |
| 45 | + "declaration", |
| 46 | + "type", |
| 47 | + "pointer" |
| 48 | + ]); |
| 49 | + |
| 50 | + export const isVariable = (value: unknown): value is Variable => |
| 51 | + typeof value === "object" && !!value && |
| 52 | + Object.keys(value).length > 0 && |
| 53 | + Object.keys(value).every(key => allowedKeys.has(key)) && |
| 54 | + ( |
| 55 | + !("identifier" in value) || |
| 56 | + typeof value.identifier === "string" |
| 57 | + ) && |
| 58 | + ( |
| 59 | + !("declaration" in value) || |
| 60 | + Materials.isSourceRange(value.declaration) |
| 61 | + ) && |
| 62 | + ( |
| 63 | + !("type" in value) || |
| 64 | + isType(value.type) |
| 65 | + ) && |
| 66 | + ( |
| 67 | + !("pointer" in value) || |
| 68 | + isPointer(value.pointer) |
| 69 | + ); |
| 70 | + } |
| 71 | + |
| 72 | + export interface Remark { |
| 73 | + remark: string; |
| 74 | + } |
| 75 | + |
| 76 | + export const isRemark = (value: unknown): value is Remark => |
| 77 | + typeof value === "object" && !!value && |
| 78 | + "remark" in value && typeof value.remark === "string"; |
| 79 | +} |
0 commit comments