Skip to content

Commit

Permalink
Merge branch 'main' into improvement-on-design-system
Browse files Browse the repository at this point in the history
  • Loading branch information
zsh77 committed May 10, 2024
2 parents 4917e23 + cc565e8 commit 6331bb5
Show file tree
Hide file tree
Showing 72 changed files with 5,795 additions and 4,762 deletions.
1,552 changes: 508 additions & 1,044 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/turbo-tasks-macros/Cargo.toml
Expand Up @@ -17,5 +17,6 @@ anyhow = { workspace = true }
proc-macro-error = "1.0.4"
proc-macro2 = { workspace = true }
quote = { workspace = true }
regex = { workspace = true }
syn = { workspace = true, features = ["full", "extra-traits", "visit-mut"] }
turbo-tasks-macros-shared = { workspace = true }
77 changes: 59 additions & 18 deletions crates/turbo-tasks-macros/src/value_macro.rs
@@ -1,9 +1,12 @@
use std::sync::OnceLock;

use proc_macro::TokenStream;
use proc_macro2::Ident;
use quote::quote;
use quote::{quote, ToTokens};
use regex::Regex;
use syn::{
parse::{Parse, ParseStream},
parse_macro_input,
parse_macro_input, parse_quote,
punctuated::Punctuated,
spanned::Spanned,
Error, Fields, FieldsUnnamed, Generics, Item, ItemEnum, ItemStruct, Lit, LitStr, Meta,
Expand Down Expand Up @@ -189,7 +192,7 @@ impl Parse for ValueArguments {
}

pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
let item = parse_macro_input!(input as Item);
let mut item = parse_macro_input!(input as Item);
let ValueArguments {
serialization_mode,
into_mode,
Expand All @@ -198,6 +201,58 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
transparent,
} = parse_macro_input!(args as ValueArguments);

let mut inner_type = None;
if transparent {
if let Item::Struct(ItemStruct {
attrs,
fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }),
..
}) = &mut item
{
if unnamed.len() == 1 {
let field = unnamed.iter().next().unwrap();
inner_type = Some(field.ty.clone());

// generate a type string to add to the docs
let inner_type_string = inner_type.to_token_stream().to_string();

// HACK: proc_macro2 inserts whitespace between every token. It's ugly, so
// remove it, assuming these whitespace aren't syntatically important. Using
// prettyplease (or similar) would be more correct, but slower and add another
// dependency.
static WHITESPACE_RE: OnceLock<Regex> = OnceLock::new();
// Remove whitespace, as long as there is a non-word character (e.g. `>` or `,`)
// on either side. Try not to remove whitespace between `dyn Trait`.
let whitespace_re = WHITESPACE_RE.get_or_init(|| {
Regex::new(r"\b \B|\B \b|\B \B").expect("WHITESPACE_RE is valid")
});
let inner_type_string = whitespace_re.replace_all(&inner_type_string, "");

// Add a couple blank lines in case there's already a doc comment we're
// effectively appending to. If there's not, rustdoc will strip
// the leading whitespace.
let doc_str = format!(
"\n\nThis is a [transparent value type][::turbo_tasks::value#transparent] \
wrapping [`{}`].",
inner_type_string,
);

attrs.push(parse_quote! {
#[doc = #doc_str]
});
}
}
if inner_type.is_none() {
item.span()
.unwrap()
.error(
"#[turbo_tasks::value(transparent)] is only valid with single-item unit \
structs",
)
.emit();
}
}

let ident = match &item {
Item::Enum(ItemEnum { ident, .. }) => ident,
Item::Struct(ItemStruct { ident, .. }) => ident,
Expand All @@ -211,20 +266,6 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
}
};

let mut inner_type = None;
if transparent {
if let Item::Struct(ItemStruct {
fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }),
..
}) = &item
{
if unnamed.len() == 1 {
let field = unnamed.iter().next().unwrap();
inner_type = Some(&field.ty);
}
}
}

let cell_mode = match cell_mode {
CellMode::New => quote! {
turbo_tasks::VcCellNewMode<#ident>
Expand All @@ -234,7 +275,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {
},
};

let (cell_prefix, cell_access_content, read) = if let Some(inner_type) = inner_type {
let (cell_prefix, cell_access_content, read) = if let Some(inner_type) = &inner_type {
(
quote! { pub },
quote! {
Expand Down
5 changes: 4 additions & 1 deletion crates/turbo-tasks-memory/Cargo.toml
Expand Up @@ -17,6 +17,7 @@ anyhow = { workspace = true }
auto-hash-map = { workspace = true }
concurrent-queue = { workspace = true }
dashmap = { workspace = true }
indexmap = { workspace = true }
nohash-hasher = { workspace = true }
num_cpus = "1.13.1"
once_cell = { workspace = true }
Expand All @@ -33,8 +34,10 @@ turbo-tasks-malloc = { workspace = true, default-features = false }

[dev-dependencies]
criterion = { workspace = true, features = ["async_tokio"] }
indexmap = { workspace = true }
lazy_static = { workspace = true }
loom = "0.7.2"
rand = { workspace = true, features = ["small_rng"] }
rstest = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true, features = ["full"] }
turbo-tasks-testing = { workspace = true }
Expand Down
81 changes: 81 additions & 0 deletions crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs
@@ -0,0 +1,81 @@
use std::ops::{Deref, DerefMut};

use super::{
increase_aggregation_number_internal, AggregationContext, AggregationNode, AggregationNodeGuard,
};
use crate::aggregation::balance_queue::BalanceQueue;

/// Gives an reference to the aggregated data for a given item. This will
/// convert the item to a fully aggregated node.
pub fn aggregation_data<'l, C>(
ctx: &'l C,
node_id: &C::NodeRef,
) -> AggregationDataGuard<C::Guard<'l>>
where
C: AggregationContext + 'l,
{
let guard = ctx.node(node_id);
if guard.aggregation_number() == u32::MAX {
AggregationDataGuard { guard }
} else {
let mut balance_queue = BalanceQueue::new();
increase_aggregation_number_internal(
ctx,
&mut balance_queue,
guard,
node_id,
u32::MAX,
u32::MAX,
);
balance_queue.process(ctx);
let guard = ctx.node(node_id);
debug_assert!(guard.aggregation_number() == u32::MAX);
AggregationDataGuard { guard }
}
}

/// Converted the given node to a fully aggregated node. To make the next call
/// to `aggregation_data` instant.
pub fn prepare_aggregation_data<C: AggregationContext>(ctx: &C, node_id: &C::NodeRef) {
let mut balance_queue = BalanceQueue::new();
increase_aggregation_number_internal(
ctx,
&mut balance_queue,
ctx.node(node_id),
node_id,
u32::MAX,
u32::MAX,
);
balance_queue.process(ctx);
}

/// A reference to the aggregated data of a node. This holds a lock to the node.
pub struct AggregationDataGuard<G> {
guard: G,
}

impl<G> AggregationDataGuard<G> {
pub fn into_inner(self) -> G {
self.guard
}
}

impl<G: AggregationNodeGuard> Deref for AggregationDataGuard<G> {
type Target = G::Data;

fn deref(&self) -> &Self::Target {
match &*self.guard {
AggregationNode::Leaf { .. } => unreachable!(),
AggregationNode::Aggegating(aggregating) => &aggregating.data,
}
}
}

impl<G: AggregationNodeGuard> DerefMut for AggregationDataGuard<G> {
fn deref_mut(&mut self) -> &mut Self::Target {
match &mut *self.guard {
AggregationNode::Leaf { .. } => unreachable!(),
AggregationNode::Aggegating(aggregating) => &mut aggregating.data,
}
}
}

0 comments on commit 6331bb5

Please sign in to comment.