Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property completions don't work when oneOf is nested #114

Open
charrondev opened this issue Nov 3, 2021 · 2 comments
Open

Property completions don't work when oneOf is nested #114

charrondev opened this issue Nov 3, 2021 · 2 comments

Comments

@charrondev
Copy link

charrondev commented Nov 3, 2021

Potentially related to #86

Use Case

I'm currently working with a schema that has a common definition "oneOf"ed with other properties all over the place. Unfortunately the property names never get autocompleted.

Example Schema

This is as minimal of an example schema I could come up with.

Here is a PR with a failing test case

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "type": "object",
    "properties": {
        "root": {
            "oneOf": [
                {
                    "type": "object",
                    "properties": {
                        "path1": {
                            "type": "string"
                        }
                    }
                },
                {
                    "$ref": "#/definitions/common"
                }
            ]
        }
    },
    "definitions": {
        "common": {
            "oneOf": [
                {
                    "type": "object",
                    "properties": {
                        "path2a": {
                            "type": "string"
                        },
                        "path2b": {
                            "type": "string"
                        }
                    }
                },
                {
                    "type": "object",
                    "properties": {
                        "path3a": {
                            "type": "string"
                        },
                        "path3b": {
                            "type": "string"
                        }
                    }
                }
            ]
        }
    }
}

The Problem

The relevant subschemas do match in JSONDocument.getMatchingSchemas, but they aren't on the requested nodes don't match here

Additionally though the second part of that failing test case indicates that even if they were applied, they might not be properly narrowed down by existing keys.

Moving towards a fix

I'm willing to make a PR for this (and have already gone through the code pretty well). I'm looking for some advice from the maintainers on how to best proceed here.

The best way I can see forward is to update getMatchingSchemas()

  • The s.node === node && !s.inverted should be taken into consideration when making the match. Currently every usage of getMatchingSchemas() performs this same check. getMatchingSchemas() could add some exceptions to this rule for oneOf.

I have a couple questions though:

Will the you guys accept an implementation that just fixes the oneOf behaviour and leaves the allOf/anyOf behaviours as is? I suspect they suffer from a similar issue but don't immediately need those for any workflows.

@aeschli
Copy link
Contributor

aeschli commented Nov 17, 2021

@charrondev I'm happy to take a PR!

@jeremyfiel
Copy link
Contributor

It's possible they are not populated because the schemas are unconstrained and would fail validation because the oneOf sub-schemas need to define additionalProperties: false.

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "type": "object",
    "properties": {
        "root": {
            "oneOf": [
                {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                        "path1": {
                            "type": "string"
                        }
                    }
                },
                {
                    "$ref": "#/definitions/common"
                }
            ]
        }
    },
    "definitions": {
        "common": {
            "oneOf": [
                {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                        "path2a": {
                            "type": "string"
                        },
                        "path2b": {
                            "type": "string"
                        }
                    }
                },
                {
                    "type": "object",
                   "additionalProperties": false,
                    "properties": {
                        "path3a": {
                            "type": "string"
                        },
                        "path3b": {
                            "type": "string"
                        }
                    }
                }
            ]
        }
    }
}

If you don't constrain an object schema in a oneOf, any property would be valid for each schema and a matching property from an alternate sub-schema could match both schemas, thus failing XOR conditional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants