Skip to content

Commit

Permalink
Define function types
Browse files Browse the repository at this point in the history
- Use `contains` object mapping style for `parameters` types and
  `returns` types. Force `parameters` to be a type wrapper around a
  tuple type (and allow `returns` to be a tuple type)

- Define one-of required fields `internal: true` xor `external: true`.

- Override external types `contains` field to also allow a `contract`
  field (for the contract in which an external function type is defined)
  • Loading branch information
gnidan committed Jan 7, 2024
1 parent be0bee0 commit eda1bee
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 3 deletions.
9 changes: 8 additions & 1 deletion schemas/type/complex.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -61,4 +68,4 @@ $defs:
- array
- mapping
- struct

- function
164 changes: 164 additions & 0 deletions schemas/type/complex/function.schema.yaml
Original file line number Diff line number Diff line change
@@ -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"
4 changes: 4 additions & 0 deletions tests/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
];
Expand Down Expand Up @@ -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();
Expand Down
20 changes: 20 additions & 0 deletions web/spec/type/complex/function.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
sidebar_position: 6
description: Function types schema
---

import SchemaViewer from "@site/src/components/SchemaViewer";

# `function`

<SchemaViewer
schema={{ id: "schema:ethdebug/format/type/complex/function" }}
/>


## Parameters schema

<SchemaViewer
schema={{ id: "schema:ethdebug/format/type/complex/function" }}
pointer="#/$defs/Parameters"
/>
11 changes: 9 additions & 2 deletions web/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -44,6 +45,7 @@ export const schemaYamls = [
typeComplexMappingSchemaYaml,
typeComplexStructSchemaYaml,
typeComplexTupleSchemaYaml,
typeComplexFunctionSchemaYaml,
typeComplexSchemaYaml,
typeSchemaYaml,
].map(schema => ({
Expand Down Expand Up @@ -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"
},



Expand Down

0 comments on commit eda1bee

Please sign in to comment.