-
Notifications
You must be signed in to change notification settings - Fork 1.1k
ctest: Add type alias extraction logic #4477
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use std::{env, error::Error, path::Path, process::Command}; | ||
|
||
/// Use cargo expand to expand all macros and pretty print the crate | ||
/// into a single file. | ||
pub fn expand(crate_path: &Path) -> Result<String, Box<dyn Error>> { | ||
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); | ||
|
||
let output = Command::new(cargo) | ||
.arg("expand") | ||
.current_dir(crate_path) | ||
.output()?; | ||
|
||
let expanded = std::str::from_utf8(&output.stdout)?.to_string(); | ||
|
||
Ok(expanded) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use proc_macro2::TokenStream; | ||
use syn::Ident; | ||
|
||
#[derive(Debug)] | ||
pub struct Constant { | ||
public: bool, | ||
ident: Ident, | ||
ty: TokenStream, | ||
value: TokenStream, | ||
} | ||
|
||
impl Constant { | ||
pub fn new(public: bool, ident: Ident, ty: TokenStream, value: TokenStream) -> Self { | ||
Self { | ||
public, | ||
ident, | ||
ty, | ||
value, | ||
} | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Ident { | ||
&self.ident | ||
} | ||
|
||
pub fn ty(&self) -> &TokenStream { | ||
&self.ty | ||
} | ||
|
||
pub fn value(&self) -> &TokenStream { | ||
&self.value | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use proc_macro2::TokenStream; | ||
use syn::Ident; | ||
|
||
#[derive(Debug)] | ||
pub struct Field { | ||
public: bool, | ||
ident: Option<Ident>, | ||
ty: TokenStream, | ||
} | ||
|
||
impl Field { | ||
pub fn new(public: bool, ident: Option<Ident>, ty: TokenStream) -> Self { | ||
Self { public, ident, ty } | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Option<Ident> { | ||
&self.ident | ||
} | ||
|
||
pub fn ty(&self) -> &TokenStream { | ||
&self.ty | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use proc_macro2::TokenStream; | ||
use syn::Ident; | ||
|
||
use crate::ir::Parameter; | ||
|
||
#[derive(Debug)] | ||
pub struct Function { | ||
public: bool, | ||
ident: Ident, | ||
parameters: Vec<Parameter>, | ||
return_value: TokenStream, | ||
} | ||
|
||
impl Function { | ||
pub fn new( | ||
public: bool, | ||
ident: Ident, | ||
parameters: Vec<Parameter>, | ||
return_value: TokenStream, | ||
) -> Self { | ||
Self { | ||
public, | ||
ident, | ||
parameters, | ||
return_value, | ||
} | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Ident { | ||
&self.ident | ||
} | ||
|
||
pub fn parameters(&self) -> &Vec<Parameter> { | ||
&self.parameters | ||
} | ||
|
||
pub fn return_value(&self) -> &TokenStream { | ||
&self.return_value | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a nit, this is more of an |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
mod constant; | ||
mod field; | ||
mod function; | ||
mod parameter; | ||
mod static_variable; | ||
mod structure; | ||
mod type_alias; | ||
mod union; | ||
|
||
pub use constant::Constant; | ||
pub use field::Field; | ||
pub use function::Function; | ||
pub use parameter::Parameter; | ||
pub use static_variable::Static; | ||
pub use structure::Struct; | ||
pub use type_alias::TypeAlias; | ||
pub use union::Union; | ||
Comment on lines
+10
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you keep these names consistent with I actually prefer the names you have now, but consistency with the ecosystem is useful. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use proc_macro2::TokenStream; | ||
|
||
#[derive(Debug)] | ||
pub struct Parameter { | ||
pattern: TokenStream, | ||
ty: TokenStream, | ||
} | ||
|
||
impl Parameter { | ||
pub fn new(pattern: TokenStream, ty: TokenStream) -> Self { | ||
Self { pattern, ty } | ||
} | ||
|
||
pub fn pattern(&self) -> &TokenStream { | ||
&self.pattern | ||
} | ||
|
||
pub fn ty(&self) -> &TokenStream { | ||
&self.ty | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use proc_macro2::TokenStream; | ||
use syn::Ident; | ||
|
||
#[derive(Debug)] | ||
pub struct Static { | ||
public: bool, | ||
ident: Ident, | ||
ty: TokenStream, | ||
// We do not care about the value as we only parse foreign statics. | ||
} | ||
|
||
impl Static { | ||
pub fn new(public: bool, ident: Ident, ty: TokenStream) -> Self { | ||
Self { public, ident, ty } | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Ident { | ||
&self.ident | ||
} | ||
|
||
pub fn ty(&self) -> &TokenStream { | ||
&self.ty | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use syn::Ident; | ||
|
||
use crate::ir::Field; | ||
|
||
#[derive(Debug)] | ||
pub struct Struct { | ||
public: bool, | ||
ident: Ident, | ||
fields: Vec<Field>, | ||
} | ||
|
||
impl Struct { | ||
pub fn new(public: bool, ident: Ident, fields: Vec<Field>) -> Self { | ||
Self { | ||
public, | ||
ident, | ||
fields, | ||
} | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Ident { | ||
&self.ident | ||
} | ||
|
||
pub fn fields(&self) -> &Vec<Field> { | ||
&self.fields | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use proc_macro2::TokenStream; | ||
use syn::Ident; | ||
|
||
#[derive(Debug)] | ||
pub struct TypeAlias { | ||
public: bool, | ||
ident: Ident, | ||
ty: TokenStream, | ||
} | ||
|
||
impl TypeAlias { | ||
pub fn new(public: bool, ident: Ident, ty: TokenStream) -> Self { | ||
Self { public, ident, ty } | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Ident { | ||
&self.ident | ||
} | ||
|
||
pub fn ty(&self) -> &TokenStream { | ||
&self.ty | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use syn::Ident; | ||
|
||
use crate::ir::Field; | ||
|
||
#[derive(Debug)] | ||
pub struct Union { | ||
public: bool, | ||
ident: Ident, | ||
fields: Vec<Field>, | ||
} | ||
|
||
impl Union { | ||
pub fn new(public: bool, ident: Ident, fields: Vec<Field>) -> Self { | ||
Self { | ||
public, | ||
ident, | ||
fields, | ||
} | ||
} | ||
|
||
pub fn public(&self) -> bool { | ||
self.public | ||
} | ||
|
||
pub fn ident(&self) -> &Ident { | ||
&self.ident | ||
} | ||
|
||
pub fn fields(&self) -> &Vec<Field> { | ||
&self.fields | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,10 @@ | ||
pub fn add(left: usize, right: usize) -> usize { | ||
left + right | ||
} | ||
#![allow(dead_code)] | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will need to be removed before merge. Add |
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
mod cargo_expand; | ||
mod ir; | ||
mod skip; | ||
mod symbol_table; | ||
mod translation; | ||
|
||
#[test] | ||
fn it_works() { | ||
let result = add(2, 2); | ||
assert_eq!(result, 4); | ||
} | ||
} | ||
// TODO: Implement proper error types instead of Box<dyn Error>. | ||
// TODO: Add documentation. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use crate::ir::{Constant, Field, Function, Static, Struct, TypeAlias, Union}; | ||
|
||
/// A boxed predicate function wrapper for filtering items of type `T`. | ||
pub struct Predicate<T>(Box<dyn Fn(T) -> bool>); | ||
|
||
impl<T> Predicate<T> { | ||
pub fn new<F>(f: F) -> Self | ||
where | ||
F: Fn(T) -> bool + 'static, | ||
{ | ||
Self(Box::new(f)) | ||
} | ||
|
||
pub fn test(&self, value: T) -> bool { | ||
(self.0)(value) | ||
} | ||
} | ||
|
||
impl<T, F> From<F> for Predicate<T> | ||
where | ||
F: Fn(T) -> bool + 'static, | ||
{ | ||
fn from(f: F) -> Self { | ||
Predicate(Box::new(f)) | ||
} | ||
} | ||
|
||
/// Specifies a filter condition for skipping specific kinds of items. | ||
/// | ||
/// To be used as `SkipItem::Struct((|s: Struct| !s.public()).into())` | ||
pub enum SkipItem { | ||
Constant(Predicate<Constant>), | ||
Function(Predicate<Function>), | ||
Static(Predicate<Static>), | ||
TypeAlias(Predicate<TypeAlias>), | ||
Struct(Predicate<Struct>), | ||
Field(Predicate<Field>), | ||
Union(Predicate<Union>), | ||
} | ||
Comment on lines
+31
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this should be reversed; in AST add a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For our public API, we probably don't want to expose
syn
/pm2
types to give us more flexibility in the future. So for now you can change any-> TokenStream
methods topub(crate)
and mark them#[expect(unused)]
if needed. and thenident
should return aString
. Or also save anident_string
field so we can return an&str
.(applies to all the types in
ir
)