summaryrefslogtreecommitdiff
path: root/crates/typst-macros/src
diff options
context:
space:
mode:
authorMalo <57839069+MDLC01@users.noreply.github.com>2024-08-15 22:04:50 +0200
committerGitHub <noreply@github.com>2024-08-15 20:04:50 +0000
commitc43997de0a4fa958bc6bdfd5c29a47e1ba14800d (patch)
tree7798325886b6a03b79be85f29ee8339a9b4dea93 /crates/typst-macros/src
parent0edd8ec93d16a397e58cebaa215b6c14cd24de8f (diff)
Move `calc.nan` to `float.nan` and add `float.inf` (#4733)
Diffstat (limited to 'crates/typst-macros/src')
-rw-r--r--crates/typst-macros/src/scope.rs77
1 files changed, 48 insertions, 29 deletions
diff --git a/crates/typst-macros/src/scope.rs b/crates/typst-macros/src/scope.rs
index 07a0efe0..d86c6aea 100644
--- a/crates/typst-macros/src/scope.rs
+++ b/crates/typst-macros/src/scope.rs
@@ -13,11 +13,26 @@ pub fn scope(_: TokenStream, item: syn::Item) -> Result<TokenStream> {
let self_ty = &item.self_ty;
+ let mut primitive_ident_ext = None;
+ if let syn::Type::Path(syn::TypePath { path, .. }) = self_ty.as_ref() {
+ if let Some(ident) = path.get_ident() {
+ if is_primitive(ident) {
+ let ident_ext = quote::format_ident!("{ident}Ext");
+ primitive_ident_ext = Some(ident_ext);
+ }
+ }
+ }
+
+ let self_ty_expr = match &primitive_ident_ext {
+ None => quote! { #self_ty },
+ Some(ident_ext) => quote! { <#self_ty as #ident_ext> },
+ };
+
let mut definitions = vec![];
let mut constructor = quote! { None };
for child in &mut item.items {
let def = match child {
- syn::ImplItem::Const(item) => handle_const(self_ty, item)?,
+ syn::ImplItem::Const(item) => handle_const(&self_ty_expr, item)?,
syn::ImplItem::Fn(item) => match handle_fn(self_ty, item)? {
FnKind::Member(tokens) => tokens,
FnKind::Constructor(tokens) => {
@@ -33,14 +48,10 @@ pub fn scope(_: TokenStream, item: syn::Item) -> Result<TokenStream> {
item.items.retain(|item| !matches!(item, syn::ImplItem::Verbatim(_)));
- let mut base = quote! { #item };
- if let syn::Type::Path(syn::TypePath { path, .. }) = self_ty.as_ref() {
- if let Some(ident) = path.get_ident() {
- if is_primitive(ident) {
- base = rewrite_primitive_base(&item, ident);
- }
- }
- }
+ let base = match &primitive_ident_ext {
+ None => quote! { #item },
+ Some(ident_ext) => rewrite_primitive_base(&item, ident_ext),
+ };
Ok(quote! {
#base
@@ -60,7 +71,7 @@ pub fn scope(_: TokenStream, item: syn::Item) -> Result<TokenStream> {
}
/// Process a const item and returns its definition.
-fn handle_const(self_ty: &syn::Type, item: &syn::ImplItemConst) -> Result<TokenStream> {
+fn handle_const(self_ty: &TokenStream, item: &syn::ImplItemConst) -> Result<TokenStream> {
let ident = &item.ident;
let name = ident.to_string().to_kebab_case();
Ok(quote! { scope.define(#name, #self_ty::#ident) })
@@ -117,31 +128,39 @@ fn is_primitive(ident: &syn::Ident) -> bool {
}
/// Rewrite an impl block for a primitive into a trait + trait impl.
-fn rewrite_primitive_base(item: &syn::ItemImpl, ident: &syn::Ident) -> TokenStream {
+fn rewrite_primitive_base(item: &syn::ItemImpl, ident_ext: &syn::Ident) -> TokenStream {
let mut sigs = vec![];
let mut items = vec![];
for sub in &item.items {
- let syn::ImplItem::Fn(mut func) = sub.clone() else { continue };
- func.vis = syn::Visibility::Inherited;
- items.push(func.clone());
-
- let mut sig = func.sig;
- let inputs = sig.inputs.iter().cloned().map(|mut input| {
- if let syn::FnArg::Typed(typed) = &mut input {
- typed.attrs.clear();
+ match sub.clone() {
+ syn::ImplItem::Fn(mut func) => {
+ func.vis = syn::Visibility::Inherited;
+ items.push(func.clone());
+
+ let mut sig = func.sig;
+ let inputs = sig.inputs.iter().cloned().map(|mut input| {
+ if let syn::FnArg::Typed(typed) = &mut input {
+ typed.attrs.clear();
+ }
+ input
+ });
+ sig.inputs = parse_quote! { #(#inputs),* };
+
+ let ident_data = quote::format_ident!("{}_data", sig.ident);
+ sigs.push(quote! { #sig; });
+ sigs.push(quote! {
+ fn #ident_data() -> &'static #foundations::NativeFuncData;
+ });
+ }
+
+ syn::ImplItem::Const(cons) => {
+ sigs.push(quote! { #cons });
}
- input
- });
- sig.inputs = parse_quote! { #(#inputs),* };
-
- let ident_data = quote::format_ident!("{}_data", sig.ident);
- sigs.push(quote! { #sig; });
- sigs.push(quote! {
- fn #ident_data() -> &'static #foundations::NativeFuncData;
- });
+
+ _ => {}
+ }
}
- let ident_ext = quote::format_ident!("{ident}Ext");
let self_ty = &item.self_ty;
quote! {
trait #ident_ext {