diff --git a/Cargo.lock b/Cargo.lock index 675a5200d2ba..a0d31f77ad8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,6 +382,7 @@ dependencies = [ "ra_ap_hir_def", "ra_ap_ide_db", "ra_ap_load-cargo", + "ra_ap_parser", "ra_ap_paths", "ra_ap_project_model", "ra_ap_syntax", @@ -680,6 +681,16 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" +[[package]] +name = "generate-schema" +version = "0.1.0" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote", + "ungrammar", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -849,6 +860,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -2335,6 +2355,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "ungrammar" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f" + [[package]] name = "unicode-ident" version = "1.0.13" diff --git a/Cargo.toml b/Cargo.toml index 4aacef79adc8..4b80e2ac9b77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "ruby/extractor", "rust/extractor", "rust/extractor/macros", + "rust/generate-schema", ] [patch.crates-io] diff --git a/MODULE.bazel b/MODULE.bazel index b539dee7874f..d1ff8b0b8d2a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -61,6 +61,7 @@ r.from_cargo( "//ruby/extractor:Cargo.toml", "//rust/extractor:Cargo.toml", "//rust/extractor/macros:Cargo.toml", + "//rust/generate-schema:Cargo.toml", "//shared/tree-sitter-extractor:Cargo.toml", ], ) diff --git a/rust/extractor/Cargo.toml b/rust/extractor/Cargo.toml index 550c3b514411..71ad6d8ac452 100644 --- a/rust/extractor/Cargo.toml +++ b/rust/extractor/Cargo.toml @@ -18,6 +18,7 @@ ra_ap_paths = "0.0.232" ra_ap_project_model = "0.0.232" ra_ap_syntax = "0.0.232" ra_ap_vfs = "0.0.232" +ra_ap_parser = "0.0.232" serde = "1.0.209" serde_with = "3.9.0" stderrlog = "0.6.0" diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 795e5d0a5506..c69acb7a2493 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs ec9ec5e218af9a6b449b40f716e00bbe23c2777941d105b9ed68071aa2468ca2 ec9ec5e218af9a6b449b40f716e00bbe23c2777941d105b9ed68071aa2468ca2 +top.rs 90a8dbfc1e4689d3310f40a3377ef0542f1886cd8c84782362d3047f0b27b3ff 90a8dbfc1e4689d3310f40a3377ef0542f1886cd8c84782362d3047f0b27b3ff diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 397120818723..353041d7fc43 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -78,7 +78,17 @@ impl From> for trap::Label { #[derive(Debug)] pub struct Missing { - _unused: () + pub id: trap::TrapId, +} + +impl trap::TrapEntry for Missing { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("missings", vec![id.into()]); + } } impl trap::TrapClass for Missing { @@ -105,7 +115,17 @@ impl From> for trap::Label { #[derive(Debug)] pub struct Unimplemented { - _unused: () + pub id: trap::TrapId, +} + +impl trap::TrapEntry for Unimplemented { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("unimplementeds", vec![id.into()]); + } } impl trap::TrapClass for Unimplemented { @@ -131,35 +151,49 @@ impl From> for trap::Label { } #[derive(Debug)] -pub struct Declaration { - _unused: () +pub struct Abi { + pub id: trap::TrapId, + pub abi_string: Option, +} + +impl trap::TrapEntry for Abi { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("abis", vec![id.into()]); + if let Some(v) = self.abi_string { + out.add_tuple("abi_abi_strings", vec![id.into(), v.into()]); + } + } } -impl trap::TrapClass for Declaration { - fn class_name() -> &'static str { "Declaration" } +impl trap::TrapClass for Abi { + fn class_name() -> &'static str { "Abi" } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Declaration is a subclass of AstNode +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Abi is a subclass of AstNode unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Declaration is a subclass of Element +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Abi is a subclass of Element unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Declaration is a subclass of Locatable +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Abi is a subclass of Locatable unsafe { Self::from_untyped(value.as_untyped()) } @@ -167,35 +201,49 @@ impl From> for trap::Label { } #[derive(Debug)] -pub struct Expr { - _unused: () +pub struct ArgList { + pub id: trap::TrapId, + pub args: Vec>, } -impl trap::TrapClass for Expr { - fn class_name() -> &'static str { "Expr" } +impl trap::TrapEntry for ArgList { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("arg_lists", vec![id.into()]); + for (i, v) in self.args.into_iter().enumerate() { + out.add_tuple("arg_list_args", vec![id.into(), i.into(), v.into()]); + } + } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Expr is a subclass of AstNode +impl trap::TrapClass for ArgList { + fn class_name() -> &'static str { "ArgList" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ArgList is a subclass of AstNode unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Expr is a subclass of Element +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ArgList is a subclass of Element unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme Expr is a subclass of Locatable +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ArgList is a subclass of Locatable unsafe { Self::from_untyped(value.as_untyped()) } @@ -203,63 +251,89 @@ impl From> for trap::Label { } #[derive(Debug)] -pub struct GenericArgList { - pub id: trap::TrapId, +pub struct AssocItem { + _unused: () } -impl trap::TrapEntry for GenericArgList { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("generic_arg_lists", vec![id.into()]); - } +impl trap::TrapClass for AssocItem { + fn class_name() -> &'static str { "AssocItem" } } -impl trap::TrapClass for GenericArgList { - fn class_name() -> &'static str { "GenericArgList" } +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AssocItem is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme GenericArgList is a subclass of AstNode +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AssocItem is a subclass of Element unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme GenericArgList is a subclass of Element +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AssocItem is a subclass of Locatable unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme GenericArgList is a subclass of Locatable +#[derive(Debug)] +pub struct AssocItemList { + pub id: trap::TrapId, + pub assoc_items: Vec>, + pub attrs: Vec>, +} + +impl trap::TrapEntry for AssocItemList { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("assoc_item_lists", vec![id.into()]); + for (i, v) in self.assoc_items.into_iter().enumerate() { + out.add_tuple("assoc_item_list_assoc_items", vec![id.into(), i.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("assoc_item_list_attrs", vec![id.into(), i.into(), v.into()]); + } + } +} + +impl trap::TrapClass for AssocItemList { + fn class_name() -> &'static str { "AssocItemList" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AssocItemList is a subclass of AstNode unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme GenericArgList is a subclass of Unextracted +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AssocItemList is a subclass of Element unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme GenericArgList is a subclass of Unimplemented +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AssocItemList is a subclass of Locatable unsafe { Self::from_untyped(value.as_untyped()) } @@ -267,46 +341,49 @@ impl From> for trap::Label { } #[derive(Debug)] -pub struct Label { - pub id: trap::TrapId