Skip to content

Monaco editor fails to offer all valid completions for a string/enum property #86

@stanislawosinski

Description

@stanislawosinski

For a schema that uses oneOf to implement polymorphic types, Monaco sometimes fails to offer completions for all valid values of a string/enum property.

When I use the following JSON schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "component1.1": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.1"
          ]
        },
        "prop1.1": {
          "type": "integer"
        }
      },
      "required": [
        "type"
      ]
    },
    "component1.2": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.2"
          ]
        },
        "prop1.2": {
          "type": "integer"
        }
      },
      "required": [
        "type",
        "prop1.2"
      ]
    },
    "component1": {
      "oneOf": [
        {
          "$ref": "#/definitions/component1.1"
        },
        {
          "$ref": "#/definitions/component1.2"
        }
      ]
    }
  },
  "properties": {
    "component": {
      "$ref": "#/definitions/component1"
    }
  }
}

and when the contents of the editor is:

{
  "component": {
      "type": ""
  }
}

I'd expect Monaco to offer two auto-complete options for the type property: component1.1 and component1.2. However, for the above schema, only component1.1 is shown in the auto-complete box. (The full playground reproduction code is included at the bottom.)

Interestingly, when I edit the definition of component1.1 to make the prop1.1 property required, Monaco behaves correctly and offers both type values (Working definition 1 below). Also, when I make the prop1.2 property not required (Working definition 2 below), I'm also getting the correct behavior.

Is this inconsistency in auto-complete somehow justified?

Working definition 1
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "component1.1": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.1"
          ]
        },
        "prop1.1": {
          "type": "integer"
        }
      },
      "required": [
        "type", "prop1.1"
      ]
    },
    "component1.2": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.2"
          ]
        },
        "prop1.2": {
          "type": "integer"
        }
      },
      "required": [
        "type",
        "prop1.2"
      ]
    },
    "component1": {
      "oneOf": [
        {
          "$ref": "#/definitions/component1.1"
        },
        {
          "$ref": "#/definitions/component1.2"
        }
      ]
    }
  },
  "properties": {
    "component": {
      "$ref": "#/definitions/component1"
    }
  }
}
Working definition 2
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "component1.1": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.1"
          ]
        },
        "prop1.1": {
          "type": "integer"
        }
      },
      "required": [
        "type"
      ]
    },
    "component1.2": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.2"
          ]
        },
        "prop1.2": {
          "type": "integer"
        }
      },
      "required": [
        "type"
      ]
    },
    "component1": {
      "oneOf": [
        {
          "$ref": "#/definitions/component1.1"
        },
        {
          "$ref": "#/definitions/component1.2"
        }
      ]
    }
  },
  "properties": {
    "component": {
      "$ref": "#/definitions/component1"
    }
  }
}

monaco-editor version: 0.21.2
Browser: Chrome
OS: Windows 10
Playground code that reproduces the issue:

var jsonCode = `{
  "component": {
      "type": ""
  }
}`;
var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
var model = monaco.editor.createModel(jsonCode, "json", modelUri);

// configure the JSON language support with schemas and schema associations
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    schemas: [{
        uri: "http://myserver/foo-schema.json", // id of the first schema
        fileMatch: [modelUri.toString()], // associate with our model
        schema: {
            "$schema": "http://json-schema.org/draft-07/schema#",
            "type": "object",
            "definitions": {
                "component1.1": {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "enum": [
                                "component1.1"
                            ]
                        },
                        "prop1.1": {
                            "type": "integer"
                        }
                    },
                    "required": [
                        "type"
                    ]
                },
                "component1.2": {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "enum": [
                                "component1.2"
                            ]
                        },
                        "prop1.2": {
                            "type": "integer"
                        }
                    },
                    "required": [
                        "type",
                        "prop1.2"
                    ]
                },
                "component1": {
                    "oneOf": [
                        {
                            "$ref": "#/definitions/component1.1"
                        },
                        {
                            "$ref": "#/definitions/component1.2"
                        }
                    ]
                }
            },
            "properties": {
                "component": {
                    "$ref": "#/definitions/component1"
                }
            }
        }
    }]
});

monaco.editor.create(document.getElementById("container"), {
    model: model
});

Metadata

Metadata

Assignees

Labels

feature-requestRequest for new features or functionality

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions