diff --git a/misc/codegen/generators/rustgen.py b/misc/codegen/generators/rustgen.py index b47e5cc4bd9d..4dd6478df66b 100644 --- a/misc/codegen/generators/rustgen.py +++ b/misc/codegen/generators/rustgen.py @@ -101,12 +101,12 @@ def _get_class(self, name: str) -> rust.Class: ) def get_classes(self): - ret = {"": []} + ret = [] for k, cls in self._classmap.items(): if not cls.imported and not cls.synth: - ret.setdefault(cls.group, []).append(self._get_class(cls.name)) + ret.append(self._get_class(cls.name)) elif cls.imported: - ret[""].append(rust.Class(name=cls.name)) + ret.append(rust.Class(name=cls.name)) return ret @@ -114,25 +114,14 @@ def generate(opts, renderer): assert opts.rust_output processor = Processor(schemaloader.load_file(opts.schema)) out = opts.rust_output - groups = set() with renderer.manage(generated=out.rglob("*.rs"), stubs=(), registry=out / ".generated.list", force=opts.force) as renderer: - for group, classes in processor.get_classes().items(): - group = group or "top" - groups.add(group) - renderer.render( - rust.ClassList( - classes, - opts.schema, - ), - out / f"{group}.rs", - ) renderer.render( - rust.ModuleList( - groups, - opts.schema, + rust.ClassList( + classes=processor.get_classes(), + source=opts.schema, ), out / f"mod.rs", ) diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index 3b5f20cbbede..5c734279ac80 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -121,9 +121,14 @@ def _fill_hideable_information(classes: typing.Dict[str, schema.Class]): def _check_test_with(classes: typing.Dict[str, schema.Class]): + pragma = "qltest_test_with" for cls in classes.values(): - test_with = typing.cast(str, cls.pragmas.get("qltest_test_with")) - transitive_test_with = test_with and classes[test_with].pragmas.get("qltest_test_with") + if cls.name == cls.pragmas.get(pragma): + # this is already implicit + del cls.pragmas[pragma] + for cls in classes.values(): + test_with = typing.cast(str, cls.pragmas.get(pragma)) + transitive_test_with = test_with and classes[test_with].pragmas.get(pragma) if test_with and transitive_test_with: raise schema.Error(f"{cls.name} has test_with {test_with} which in turn " f"has test_with {transitive_test_with}, use that directly") diff --git a/rust/ast-generator/src/main.rs b/rust/ast-generator/src/main.rs index 3fe918a4c3eb..4b4c4decdccd 100644 --- a/rust/ast-generator/src/main.rs +++ b/rust/ast-generator/src/main.rs @@ -456,7 +456,7 @@ fn write_extractor(grammar: &AstSrc) -> std::io::Result { use super::base::Translator; use super::mappings::TextValue; -use crate::emit_detached; +use crate::{{emit_detached,emit_canonical_origin}}; use crate::generated; use crate::trap::{{Label, TrapId}}; use ra_ap_syntax::ast::{{ diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index cbc2dd7c6573..372ccc71a6a6 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1 @@ -mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs d09cf25daa06fc9bc802e438231e0f038443d2ede3972a0dd829f322b390c4e4 d09cf25daa06fc9bc802e438231e0f038443d2ede3972a0dd829f322b390c4e4 +mod.rs d053373b3e6ec84532b8e8db1358b6f641d023ebdb00341a5f71c7bfe7bfd94d d053373b3e6ec84532b8e8db1358b6f641d023ebdb00341a5f71c7bfe7bfd94d diff --git a/rust/extractor/src/generated/.gitattributes b/rust/extractor/src/generated/.gitattributes index 25bb20a99113..e8bb2bee7bc5 100644 --- a/rust/extractor/src/generated/.gitattributes +++ b/rust/extractor/src/generated/.gitattributes @@ -1,4 +1,3 @@ /.generated.list linguist-generated /.gitattributes linguist-generated /mod.rs linguist-generated -/top.rs linguist-generated diff --git a/rust/extractor/src/generated/mod.rs b/rust/extractor/src/generated/mod.rs index 0f95afeeff20..74d1b91f2d16 100644 --- a/rust/extractor/src/generated/mod.rs +++ b/rust/extractor/src/generated/mod.rs @@ -1,4 +1,11494 @@ // generated by codegen, do not edit -mod top; -pub use top::*; +#![cfg_attr(any(), rustfmt::skip)] + +use crate::trap; + +#[derive(Debug)] +pub struct File { + _unused: () +} + +impl trap::TrapClass for File { + fn class_name() -> &'static str { "File" } +} + +#[derive(Debug)] +pub struct Element { + _unused: () +} + +impl trap::TrapClass for Element { + fn class_name() -> &'static str { "Element" } +} + +#[derive(Debug)] +pub struct ExtractorStep { + pub id: trap::TrapId, + pub action: String, + pub file: trap::Label, + pub duration_ms: usize, +} + +impl trap::TrapEntry for ExtractorStep { + 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("extractor_steps", vec![id.into(), self.action.into(), self.file.into(), self.duration_ms.into()]); + } +} + +impl trap::TrapClass for ExtractorStep { + fn class_name() -> &'static str { "ExtractorStep" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ExtractorStep is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Locatable { + _unused: () +} + +impl trap::TrapClass for Locatable { + fn class_name() -> &'static str { "Locatable" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Locatable is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Unextracted { + _unused: () +} + +impl trap::TrapClass for Unextracted { + fn class_name() -> &'static str { "Unextracted" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Unextracted is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct AstNode { + _unused: () +} + +impl trap::TrapClass for AstNode { + fn class_name() -> &'static str { "AstNode" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme AstNode 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 AstNode is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Missing { + 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 { + fn class_name() -> &'static str { "Missing" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Missing 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 Missing is a subclass of Unextracted + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Unimplemented { + 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 { + fn class_name() -> &'static str { "Unimplemented" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Unimplemented 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 Unimplemented is a subclass of Unextracted + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +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 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 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 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 Abi is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Addressable { + _unused: () +} + +impl Addressable { + pub fn emit_canonical_path(id: trap::Label, value: trap::Label, out: &mut trap::Writer) { + out.add_tuple("addressable_canonical_paths", vec![id.into(), value.into()]); + } +} + +impl trap::TrapClass for Addressable { + fn class_name() -> &'static str { "Addressable" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Addressable 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 Addressable 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 Addressable is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct ArgList { + pub id: trap::TrapId, + pub args: Vec>, +} + +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 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 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 ArgList is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct AssocItem { + _unused: () +} + +impl trap::TrapClass for AssocItem { + fn class_name() -> &'static str { "AssocItem" } +} + +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 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 AssocItem is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[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 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 AssocItemList is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Attr { + pub id: trap::TrapId, + pub meta: Option>, +} + +impl trap::TrapEntry for Attr { + 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("attrs", vec![id.into()]); + if let Some(v) = self.meta { + out.add_tuple("attr_meta", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for Attr { + fn class_name() -> &'static str { "Attr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Attr 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 Attr 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 Attr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Callable { + _unused: () +} + +impl trap::TrapClass for Callable { + fn class_name() -> &'static str { "Callable" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme Callable 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 Callable 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 Callable is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct ClosureBinder { + pub id: trap::TrapId, + pub generic_param_list: Option>, +} + +impl trap::TrapEntry for ClosureBinder { + 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("closure_binders", vec![id.into()]); + if let Some(v) = self.generic_param_list { + out.add_tuple("closure_binder_generic_param_lists", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for ClosureBinder { + fn class_name() -> &'static str { "ClosureBinder" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ClosureBinder 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 ClosureBinder 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 ClosureBinder is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Expr { + _unused: () +} + +impl trap::TrapClass for Expr { + fn class_name() -> &'static str { "Expr" } +} + +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 + 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 + 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 + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct ExternItem { + _unused: () +} + +impl trap::TrapClass for ExternItem { + fn class_name() -> &'static str { "ExternItem" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ExternItem 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 ExternItem 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 ExternItem is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct ExternItemList { + pub id: trap::TrapId, + pub attrs: Vec>, + pub extern_items: Vec>, +} + +impl trap::TrapEntry for ExternItemList { + 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("extern_item_lists", vec![id.into()]); + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("extern_item_list_attrs", vec![id.into(), i.into(), v.into()]); + } + for (i, v) in self.extern_items.into_iter().enumerate() { + out.add_tuple("extern_item_list_extern_items", vec![id.into(), i.into(), v.into()]); + } + } +} + +impl trap::TrapClass for ExternItemList { + fn class_name() -> &'static str { "ExternItemList" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ExternItemList 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 ExternItemList 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 ExternItemList is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct FieldList { + _unused: () +} + +impl trap::TrapClass for FieldList { + fn class_name() -> &'static str { "FieldList" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme FieldList 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 FieldList 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 FieldList is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct FormatArgsArg { + pub id: trap::TrapId, + pub expr: Option>, + pub name: Option>, +} + +impl trap::TrapEntry for FormatArgsArg { + 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("format_args_args", vec![id.into()]); + if let Some(v) = self.expr { + out.add_tuple("format_args_arg_exprs", vec![id.into(), v.into()]); + } + if let Some(v) = self.name { + out.add_tuple("format_args_arg_names", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for FormatArgsArg { + fn class_name() -> &'static str { "FormatArgsArg" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme FormatArgsArg 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 FormatArgsArg 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 FormatArgsArg is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct GenericArg { + _unused: () +} + +impl trap::TrapClass for GenericArg { + fn class_name() -> &'static str { "GenericArg" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme GenericArg 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 GenericArg 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 GenericArg is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct GenericArgList { + pub id: trap::TrapId, + pub generic_args: Vec>, +} + +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()]); + for (i, v) in self.generic_args.into_iter().enumerate() { + out.add_tuple("generic_arg_list_generic_args", vec![id.into(), i.into(), v.into()]); + } + } +} + +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 GenericArgList 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 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 Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct GenericParam { + _unused: () +} + +impl trap::TrapClass for GenericParam { + fn class_name() -> &'static str { "GenericParam" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme GenericParam 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 GenericParam 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 GenericParam is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct GenericParamList { + pub id: trap::TrapId, + pub generic_params: Vec>, +} + +impl trap::TrapEntry for GenericParamList { + 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_param_lists", vec![id.into()]); + for (i, v) in self.generic_params.into_iter().enumerate() { + out.add_tuple("generic_param_list_generic_params", vec![id.into(), i.into(), v.into()]); + } + } +} + +impl trap::TrapClass for GenericParamList { + fn class_name() -> &'static str { "GenericParamList" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme GenericParamList 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 GenericParamList 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 GenericParamList is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct ItemList { + pub id: trap::TrapId, + pub attrs: Vec>, + pub items: Vec>, +} + +impl trap::TrapEntry for ItemList { + 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("item_lists", vec![id.into()]); + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("item_list_attrs", vec![id.into(), i.into(), v.into()]); + } + for (i, v) in self.items.into_iter().enumerate() { + out.add_tuple("item_list_items", vec![id.into(), i.into(), v.into()]); + } + } +} + +impl trap::TrapClass for ItemList { + fn class_name() -> &'static str { "ItemList" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ItemList 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 ItemList 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 ItemList is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +#[derive(Debug)] +pub struct Label { + pub id: trap::TrapId