Rust: fix generated hierarchy

This commit is contained in:
Paolo Tranquilli
2024-09-16 10:06:01 +02:00
parent 8f93f5e34b
commit f1233b14e8
7 changed files with 304 additions and 252 deletions

View File

@@ -80,7 +80,7 @@ class Processor:
if "rust_skip" not in p.pragmas and not p.synth
] if not cls.derived else [],
ancestors=sorted(set(a.name for a in _get_ancestors(cls, self._classmap))),
table_name=inflection.tableize(cls.name),
entry_table=inflection.tableize(cls.name) if not cls.derived else None,
)
def get_classes(self):

View File

@@ -110,13 +110,19 @@ class Field:
@dataclasses.dataclass
class Class:
name: str
table_name: str | None = None
entry_table: str | None = None
fields: list[Field] = dataclasses.field(default_factory=list)
ancestors: list[str] = dataclasses.field(default_factory=list)
@property
def single_field_entries(self):
ret = {self.table_name: []}
def is_entry(self) -> bool:
return bool(self.entry_table)
@property
def single_field_entries(self) -> dict[str, list[dict]]:
ret = {}
if self.is_entry:
ret[self.entry_table] = []
for f in self.fields:
if f.is_single:
ret.setdefault(f.table_name, []).append(f)

View File

@@ -5,7 +5,7 @@
use crate::trap;
{{#classes}}
{{#table_name}}
{{#is_entry}}
#[derive(Debug)]
pub struct {{name}} {
pub id: trap::TrapId<{{name}}>,
@@ -15,15 +15,13 @@ pub struct {{name}} {
}
impl trap::TrapEntry for {{name}} {
fn class_name() -> &'static str { "{{name}}" }
fn extract_id(&mut self) -> trap::TrapId<Self> {
std::mem::replace(&mut self.id, trap::TrapId::Star)
}
fn emit(self, id: trap::Label<Self>, out: &mut trap::Writer) {
{{#single_field_entries}}
out.add_tuple("{{table_name}}", vec![id.into(){{#fields}}, self.{{field_name}}.into(){{/fields}}]);
out.add_tuple("{{entry_table}}", vec![id.into(){{#fields}}, self.{{field_name}}.into(){{/fields}}]);
{{/single_field_entries}}
{{#fields}}
{{#is_predicate}}
@@ -53,13 +51,18 @@ impl trap::TrapEntry for {{name}} {
{{/fields}}
}
}
{{/table_name}}
{{^table_name}}
{{/is_entry}}
{{^is_entry}}
{{! virtual class, make it unbuildable }}
#[derive(Debug)]
pub struct {{name}} {
unused: ()
_unused: ()
}
{{/is_entry}}
impl trap::TrapClass for {{name}} {
fn class_name() -> &'static str { "{{name}}" }
}
{{/table_name}}
{{#ancestors}}
impl From<trap::Label<{{name}}>> for trap::Label<{{.}}> {

View File

@@ -1,2 +1,2 @@
mod.rs 7cdfedcd68cf8e41134daf810c1af78624082b0c3e8be6570339b1a69a5d457e 7cdfedcd68cf8e41134daf810c1af78624082b0c3e8be6570339b1a69a5d457e
top.rs 775cb04552f9242ff999b279a375f7a446124f4ef28668e42496751bf69e7dd3 775cb04552f9242ff999b279a375f7a446124f4ef28668e42496751bf69e7dd3
top.rs 834f3eff470c256398cf3c8e876ee0d9d466c5f4f01e97588a1a1f5422b8ad0a 834f3eff470c256398cf3c8e876ee0d9d466c5f4f01e97588a1a1f5422b8ad0a

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
use crate::archive::Archiver;
use crate::trap::{AsTrapKeyPart, Label, TrapEntry, TrapFile, TrapId};
use crate::trap::{AsTrapKeyPart, Label, TrapClass, TrapFile, TrapId};
use crate::{generated, trap_key};
use codeql_extractor::trap;
use ra_ap_hir::db::{DefDatabase, InternDatabase};
@@ -71,7 +71,7 @@ impl CrateTranslator<'_> {
})
}
fn emit_location_for_ast_ptr<E: TrapEntry, T: AstNode>(
fn emit_location_for_ast_ptr<E: TrapClass, T: AstNode>(
&mut self,
label: Label<E>,
source: ra_ap_hir::InFile<ra_ap_syntax::AstPtr<T>>,
@@ -132,7 +132,7 @@ impl CrateTranslator<'_> {
}
}
fn emit_location_for_label<E: TrapEntry>(
fn emit_location_for_label<E: TrapClass>(
&mut self,
label: Label<E>,
label_id: ra_ap_hir_def::hir::LabelId,
@@ -144,7 +144,7 @@ impl CrateTranslator<'_> {
self.emit_location_for_ast_ptr(label, source)
}
}
fn emit_location<E: TrapEntry, T: HasSource>(&mut self, label: Label<E>, entity: T)
fn emit_location<E: TrapClass, T: HasSource>(&mut self, label: Label<E>, entity: T)
where
T::Ast: AstNode,
{
@@ -157,7 +157,7 @@ impl CrateTranslator<'_> {
self.emit_location_for_textrange(label, data, range);
});
}
fn emit_location_for_textrange<E: TrapEntry>(
fn emit_location_for_textrange<E: TrapClass>(
&mut self,
label: Label<E>,
data: FileData,

View File

@@ -35,6 +35,15 @@ impl AsTrapKeyPart for &str {
}
}
pub trait TrapClass {
fn class_name() -> &'static str;
}
pub trait TrapEntry: Debug + Sized + TrapClass {
fn extract_id(&mut self) -> TrapId<Self>;
fn emit(self, id: Label<Self>, out: &mut Writer);
}
#[derive(Debug, Clone)]
pub enum TrapId<T: TrapEntry> {
Star,
@@ -72,7 +81,7 @@ macro_rules! trap_key {
}
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct Label<T: TrapEntry> {
pub struct Label<T: TrapClass> {
untyped: UntypedLabel,
phantom: PhantomData<T>, // otherwise Rust wants `T` to be used
}
@@ -80,15 +89,15 @@ pub struct Label<T: TrapEntry> {
// not deriving `Clone` and `Copy` because they require `T: Clone` and `T: Copy` respectively,
// even if `T` is not actually part of the fields.
// see https://github.com/rust-lang/rust/issues/108894
impl<T: TrapEntry> Clone for Label<T> {
impl<T: TrapClass> Clone for Label<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T: TrapEntry> Copy for Label<T> {}
impl<T: TrapClass> Copy for Label<T> {}
impl<T: TrapEntry> Label<T> {
impl<T: TrapClass> Label<T> {
pub fn as_untyped(&self) -> UntypedLabel {
self.untyped
}
@@ -103,24 +112,18 @@ impl<T: TrapEntry> Label<T> {
}
}
impl<T: TrapEntry> AsTrapKeyPart for Label<T> {
impl<T: TrapClass> AsTrapKeyPart for Label<T> {
fn as_key_part(&self) -> String {
self.as_untyped().as_key_part()
}
}
impl<T: TrapEntry> From<Label<T>> for trap::Arg {
impl<T: TrapClass> From<Label<T>> for trap::Arg {
fn from(value: Label<T>) -> Self {
trap::Arg::Label(value.as_untyped())
}
}
pub trait TrapEntry: std::fmt::Debug + Sized {
fn class_name() -> &'static str;
fn extract_id(&mut self) -> TrapId<Self>;
fn emit(self, id: Label<Self>, out: &mut Writer);
}
pub struct TrapFile {
path: PathBuf,
writer: Writer,
@@ -128,10 +131,10 @@ pub struct TrapFile {
}
impl TrapFile {
pub fn emit_location<T: TrapEntry>(
pub fn emit_location<E: TrapClass>(
&mut self,
file_label: UntypedLabel,
entity_label: Label<T>,
entity_label: Label<E>,
start: LineCol,
end: LineCol,
) {