diff --git a/schemas/type/complex.schema.yaml b/schemas/type/complex.schema.yaml index 1d0ad57b..d6194b0e 100644 --- a/schemas/type/complex.schema.yaml +++ b/schemas/type/complex.schema.yaml @@ -48,6 +48,13 @@ allOf: then: $ref: "schema:ethdebug/format/type/complex/struct" + - if: + properties: + kind: + const: function + then: + $ref: "schema:ethdebug/format/type/complex/function" + $defs: Kind: title: Known complex kind @@ -61,4 +68,4 @@ $defs: - array - mapping - struct - + - function diff --git a/schemas/type/complex/function.schema.yaml b/schemas/type/complex/function.schema.yaml new file mode 100644 index 00000000..21b8992e --- /dev/null +++ b/schemas/type/complex/function.schema.yaml @@ -0,0 +1,164 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/type/complex/function" + +title: ethdebug/format/type/complex/function +description: | + Schema for representing a function type. + + Type representations must indicate whether they represent a function that is + called internally (within the semantics of the language) or a function that + is called externally (via EVM contract call semantics and the Solidity ABI). + Internal function types require the `"internal": true` field; external + function types require `"external": true`. + + Note that external function types may include a representation of the + contract type that defines or provides this function as an external + interface. + +type: object +properties: + class: + type: string + const: complex + kind: + type: string + const: function + contains: + type: object + title: Parameter and return types + description: | + Types this function type composes. Function types inherently compose + two groupings of types (an ordered list of parameter types and typically + either a return value or return parameters). Function types' `contains` + field is organized as a mapping of `parameters` types (a type wrapper for + a tuple type) and an optional `returns` type (either a generic type + wrapper or a type wrapper for a tuple type). + + This definition applies for both cases (internal and external function + types). Each of those specific types may expand this `contains` field + schema with other semantic details (such as an external function type + indicating the contract type from which it is exposed). + properties: + parameters: + $ref: "#/$defs/Parameters" + returns: + type: object + title: Return type (or tuple of types) + description: | + To accommodate languages differing in whether functions return single + values or lists of values, this field may be either a generic type + wrapper or explicitly defined as a type wrapper around a tuple type. + + Debuggers that implement this schema **should** be aware that + languages whose functions return sole values might return tuple + types. Resolving this ambiguity remains outside the scope of the + schema (but compilers **must** be consistent when representing + function types in this schema). + anyOf: + - $ref: "schema:ethdebug/format/type/wrapper" + - $ref: "#/$defs/Parameters" + required: + - parameters + definition: + $ref: "schema:ethdebug/format/type/definition" + +oneOf: + - type: object + title: External function type + properties: + internal: + const: false + external: + const: true + contains: + type: object + title: Additional contents + properties: + contract: + type: object + title: Contract type providing external function + description: + A wrapper around the contract type that composes this external + function type. + allOf: + - $ref: "schema:ethdebug/format/type/wrapper" + - type: object + title: Contract type wrapper + properties: + type: + $ref: "schema:ethdebug/format/type/elementary/contract" + required: + - external + + - type: object + title: Internal function type + properties: + internal: + const: true + external: + const: false + required: + - internal + +examples: + - kind: function + internal: true + definition: + name: increment + contains: + parameters: + type: + kind: tuple + contains: + - name: value + type: + kind: uint + bits: 256 + returns: + type: + kind: uint + bits: 256 + - kind: function + external: true + definition: + name: withdraw + contains: + contract: + type: + kind: contract + payable: true + interface: true + definition: + name: Bank + parameters: + type: + kind: tuple + contains: + - name: beneficiary + type: + kind: address + payable: true + - name: amount + type: + kind: ufixed + bits: 128 + places: 18 + returns: + type: + kind: tuple + contains: [] + +$defs: + Parameters: + type: object + title: Parameters + description: + A type wrapper around a tuple of types. This schema uses a tuple type to + represent an ordered list of types. + allOf: + - $ref: "schema:ethdebug/format/type/wrapper" + - title: Tuple type wrapper + type: object + properties: + type: + $ref: "schema:ethdebug/format/type/complex/tuple" diff --git a/tests/src/schemas.ts b/tests/src/schemas.ts index 33935a8c..980ebf8e 100644 --- a/tests/src/schemas.ts +++ b/tests/src/schemas.ts @@ -32,6 +32,7 @@ const readSchemas = (): { "type/complex/array.schema.yaml", "type/complex/mapping.schema.yaml", "type/complex/struct.schema.yaml", + "type/complex/function.schema.yaml", "type/complex.schema.yaml", "type.schema.yaml", ]; @@ -132,6 +133,9 @@ export const schemaExtensions: { "schema:ethdebug/format/type/complex/struct": { extends: new Set(["schema:ethdebug/format/type/complex"]) }, + "schema:ethdebug/format/type/complex/function": { + extends: new Set(["schema:ethdebug/format/type/complex"]) + }, } const schemas = readSchemas(); diff --git a/web/spec/type/complex/function.mdx b/web/spec/type/complex/function.mdx new file mode 100644 index 00000000..366cbe5d --- /dev/null +++ b/web/spec/type/complex/function.mdx @@ -0,0 +1,20 @@ +--- +sidebar_position: 6 +description: Function types schema +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# `function` + + + + +## Parameters schema + + diff --git a/web/src/schemas.ts b/web/src/schemas.ts index 777dc778..aae72ef6 100644 --- a/web/src/schemas.ts +++ b/web/src/schemas.ts @@ -20,6 +20,7 @@ import typeComplexArraySchemaYaml from "../../schemas/type/complex/array.schema. import typeComplexMappingSchemaYaml from "../../schemas/type/complex/mapping.schema.yaml"; import typeComplexStructSchemaYaml from "../../schemas/type/complex/struct.schema.yaml"; import typeComplexTupleSchemaYaml from "../../schemas/type/complex/tuple.schema.yaml"; +import typeComplexFunctionSchemaYaml from "../../schemas/type/complex/function.schema.yaml"; import typeComplexSchemaYaml from "../../schemas/type/complex.schema.yaml"; import typeSchemaYaml from "../../schemas/type.schema.yaml"; @@ -44,6 +45,7 @@ export const schemaYamls = [ typeComplexMappingSchemaYaml, typeComplexStructSchemaYaml, typeComplexTupleSchemaYaml, + typeComplexFunctionSchemaYaml, typeComplexSchemaYaml, typeSchemaYaml, ].map(schema => ({ @@ -100,14 +102,19 @@ export const schemaIndex: SchemaIndex = { ), ...( [ - "alias", "tuple", "array", "mapping", "struct" + "alias", "tuple", "array", "mapping", "struct", "function" ].map(kind => ({ [`schema:ethdebug/format/type/complex/${kind}`]: { href: `/spec/type/complex/${kind}` } })) .reduce((a, b) => ({ ...a, ...b }), {}) - ) + ), + + "schema:ethdebug/format/type/complex/function#/$defs/Parameters": { + title: "Parameters schema", + href: "/spec/type/complex/function#parameters-schema" + },