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

Investigate: Use expectorate and schemafy to autogenerate code #154

Open
kjeremy opened this issue Apr 5, 2020 · 3 comments
Open

Investigate: Use expectorate and schemafy to autogenerate code #154

kjeremy opened this issue Apr 5, 2020 · 3 comments

Comments

@kjeremy
Copy link
Contributor

kjeremy commented Apr 5, 2020

https://github.com/deathbeds/expectorate can give us a JSON schema of the LSP. See if we can use that in combination with @Marwes schemafy crate to autogenerate the LSP types.

@lnicola
Copy link
Contributor

lnicola commented Apr 8, 2022

There's now actually an official machine-readable description available:

There is also a first version of a meta model for LSP together with the corresponding schema as a JSON schema or as TypeScript type definitions. The meta model contains the following information: specified requests and notifications together with their parameter types, return types, partial return types, and registration options. It also contains all defined structures and enums.

@Marwes
Copy link
Member

Marwes commented Apr 8, 2022

metaModel.json unfortunately seems to be a custom format, only the schema for that json file exists as a json schema. So https://github.com/Marwes/schemafy couldn't be used to generate the types (only the types describing the custom format).

Meta model

``` #[doc = " Represents an `and`type (e.g. TextDocumentParams & WorkDoneProgressParams`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct AndType { pub items: Vec, pub kind: String, } #[doc = " Represents an array type (e.g. `TextDocument[]`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct ArrayType { pub element: Type, pub kind: String, } #[doc = " Represents a base type like `string` or `DocumentUri`."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct BaseType { pub kind: String, pub name: BaseTypes, } #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub enum BaseTypes { Uri, DocumentUri, #[serde(rename = "integer")] Integer, #[serde(rename = "uinteger")] Uinteger, #[serde(rename = "decimal")] Decimal, RegExp, #[serde(rename = "string")] String, #[serde(rename = "boolean")] Boolean, #[serde(rename = "null")] Null, } #[doc = " Represents a boolean literal type (e.g. `kind: true`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct BooleanLiteralType { pub kind: String, pub value: bool, } #[doc = " Defines an enumeration."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Enumeration { #[doc = " An optional documentation."] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " The name of the enumeration."] pub name: String, #[doc = " Whether this is a proposed enumeration. If omitted, the enumeration is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Since when (release number) this enumeration is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, #[doc = " The type of the elements."] #[serde(rename = "type")] pub type_: EnumerationType, #[doc = " The enum values."] pub values: Vec, } #[doc = " Defines an enumeration entry."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct EnumerationEntry { #[doc = " An optional documentation."] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " The name of the enum item."] pub name: String, #[doc = " Whether this is a proposed enumeration entry. If omitted, the enumeration entry is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Since when (release number) this enumeration entry is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, #[doc = " The value."] pub value: serde_json::Value, } #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct EnumerationType { pub kind: String, pub name: String, } #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct IntegerLiteralType { #[doc = " Represents an integer literal type (e.g. `kind: 1`)."] pub kind: String, pub value: f64, } #[doc = " Represents a type that can be used as a key in a map type. If a reference type is used then the "] #[doc = " type must either resolve to a `string` or `integer` type. (e.g. `type "] #[doc = " ChangeAnnotationIdentifier === string`)."] pub type MapKeyType = serde_json::Value; #[doc = " Represents a JSON object map (e.g. `interface Map { [key: K] => "] #[doc = " V; }`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct MapType { pub key: MapKeyType, pub kind: String, pub value: Type, } #[doc = " The actual meta model."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct MetaModel { #[doc = " The enumerations."] pub enumerations: Vec, #[doc = " The notifications."] pub notifications: Vec, #[doc = " The requests."] pub requests: Vec, #[doc = " The structures."] pub structures: Vec, #[doc = " The type aliases."] #[serde(rename = "typeAliases")] pub type_aliases: Vec, } #[doc = " Represents a LSP notification"] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Notification { #[doc = " An optional documentation;"] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " The request's method name."] pub method: String, #[doc = " The parameter type(s) if any."] #[serde(default)] #[serde(with = "::schemafy_core::one_or_many")] pub params: Vec, #[doc = " Whether this is a proposed notification. If omitted the notification is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Optional registration options if the notification supports dynamic registration."] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "registrationOptions")] pub registration_options: Option, #[doc = " Since when (release number) this notification is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, } #[doc = " Represents an `or` type (e.g. `Location | LocationLink`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct OrType { pub items: Vec, pub kind: String, } #[doc = " Represents an object property."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Property { #[doc = " An optional documentation."] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " The property name;"] pub name: String, #[doc = " Whether the property is optional. If omitted, the property is mandatory."] #[serde(skip_serializing_if = "Option::is_none")] pub optional: Option, #[doc = " Whether this is a proposed property. If omitted, the structure is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Since when (release number) this property is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, #[doc = " The type of the property"] #[serde(rename = "type")] pub type_: Type, } #[doc = " Represents a reference to another type (e.g. `TextDocument`). This is either a `Structure`, a "] #[doc = " `Enumeration` or a `TypeAlias` in the same meta model."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct ReferenceType { pub kind: String, pub name: String, } #[doc = " Represents a LSP request"] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Request { #[doc = " An optional documentation;"] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " An optional error data type."] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "errorData")] pub error_data: Option, #[doc = " The request's method name."] pub method: String, #[doc = " The parameter type(s) if any."] #[serde(default)] #[serde(with = "::schemafy_core::one_or_many")] pub params: Vec, #[doc = " Optional partial result type if the request supports partial result reporting."] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "partialResult")] pub partial_result: Option, #[doc = " Whether this is a proposed feature. If omitted the feature is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Optional registration options if the request supports dynamic registration."] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "registrationOptions")] pub registration_options: Option, #[doc = " The result type."] pub result: Type, #[doc = " Since when (release number) this request is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, } #[doc = " Represents a string literal type (e.g. `kind: 'rename'`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct StringLiteralType { pub kind: String, pub value: String, } #[doc = " Defines the structure of an object literal."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct Structure { #[doc = " An optional documentation;"] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " Structures extended from. This structures form a polymorphic type hierarchy."] #[serde(skip_serializing_if = "Option::is_none")] pub extends: Option>, #[doc = " Structures to mix in. The properties of these structures are `copied` into this structure. "] #[doc = " Mixins don't form a polymorphic type hierarchy in LSP."] #[serde(skip_serializing_if = "Option::is_none")] pub mixins: Option>, #[doc = " The name of the structure."] pub name: String, #[doc = " The properties."] pub properties: Vec, #[doc = " Whether this is a proposed structure. If omitted, the structure is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Since when (release number) this structure is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, } #[doc = " Defines a unnamed structure of an object literal."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct StructureLiteral { #[doc = " An optional documentation."] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " The properties."] pub properties: Vec, #[doc = " Whether this is a proposed structure. If omitted, the structure is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Since when (release number) this structure is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, } #[doc = " Represents a literal structure (e.g. `property: { start: uinteger; end: uinteger; }`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct StructureLiteralType { pub kind: String, pub value: StructureLiteral, } #[doc = " Represents a `tuple` type (e.g. `[integer, integer]`)."] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct TupleType { pub items: Vec, pub kind: String, } pub type Type = serde_json::Value; #[doc = " Defines a type alias. (e.g. `type Definition = Location | LocationLink`)"] #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct TypeAlias { #[doc = " An optional documentation."] #[serde(skip_serializing_if = "Option::is_none")] pub documentation: Option, #[doc = " The name of the type alias."] pub name: String, #[doc = " Whether this is a proposed type alias. If omitted, the type alias is final."] #[serde(skip_serializing_if = "Option::is_none")] pub proposed: Option, #[doc = " Since when (release number) this structure is available. Is undefined if not known."] #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, #[doc = " The aliased type."] #[serde(rename = "type")] pub type_: Type, } #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub enum TypeKind { #[serde(rename = "base")] Base, #[serde(rename = "reference")] Reference, #[serde(rename = "array")] Array, #[serde(rename = "map")] Map, #[serde(rename = "and")] And, #[serde(rename = "or")] Or, #[serde(rename = "tuple")] Tuple, #[serde(rename = "literal")] Literal, #[serde(rename = "stringLiteral")] StringLiteral, #[serde(rename = "integerLiteral")] IntegerLiteral, #[serde(rename = "booleanLiteral")] BooleanLiteral, } pub type Schema = serde_json::Value; ```

@lnicola
Copy link
Contributor

lnicola commented Apr 8, 2022

Yes, but that's to be expected. Maybe I should have filed a new issue instead.

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