oxidecomputer / oxidecomputer/typify

spuriously duplicated types may be generated

Open
#487 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
898
Forks
114
Avg merge
4h 18m
Merged PRs (30d)
14

Description

Consider this case (roughly) from the checked in github.json data:

    "issue_comment$deleted": {
      "$schema": "http://json-schema.org/draft-07/schema",
      "type": "object",
      "required": ["action", "issue", "comment", "repository", "sender"],
      "properties": {
        "action": { "type": "string", "enum": ["deleted"] },
        "issue": {
          "description": "The [issue](https://docs.github.com/en/rest/reference/issues) the comment belongs to.",
          "allOf": [
            { "$ref": "#/definitions/issue" },
            {
              "type": "object",
              "required": ["labels", "state", "locked", "assignee"],
              "properties": {
                "assignee": {
                  "oneOf": [
                    { "$ref": "#/definitions/user" },
                    { "type": "null" }
                  ]
                },
...

In particular note issue and it's assignee property. In #/definitions/issue (think of it as the base class), assignee is defined like this:

        "assignee": {
          "oneOf": [{ "$ref": "#/definitions/user" }, { "type": "null" }]
        },

So... the same. We would expect the merge logic to try to merge these two (identical) oneOfs and come up with that same, identical oneOf. That's sometimes not what happens, in particular if the #/definitions/user type is sufficiently complex. In that case we get a type generated named IssueCommentDeletedIssueAssignee that is identical to the User type.

Here is a schema that reproduces the issue:

{
  "definitions": {
    "issue": {
      "type": "object",
      "required": [
        "assignee"
      ],
      "properties": {
        "assignee": {
          "oneOf": [
            {
              "$ref": "#/definitions/user"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    },
    "issue_comment$deleted": {
      "type": "object",
      "required": [
        "issue"
      ],
      "properties": {
        "issue": {
          "allOf": [
            {
              "$ref": "#/definitions/issue"
            },
            {
              "type": "object",
              "required": [
                "assignee"
              ],
              "properties": {
                "assignee": {
                  "oneOf": [
                    {
                      "$ref": "#/definitions/user"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    },
    "user": {
      "$schema": "http://json-schema.org/draft-07/schema",
      "type": "object",
      "properties": {
        "email": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    }
  }
}

Note that if we made #/definitions/user/properties/email/type into a simple type (e.g. "string") rather than a type array, we get the expected result.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Use the minimal schema in the issue as the first reproduction, focusing on the allOf/oneOf merge involving issue.assignee and the complex user definition. Trace the merge logic and verify that identical schemas resolve to the existing User type rather than generating IssueCommentDeletedIssueAssignee; the reproduction should produce no duplicate type.

Written by the indexing model from the issue text.

Assessment

Tech stack
json, rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.