Unify the warning system (#2649)

* unify the warning system

* fix VirtualDom::new warning with a component

* move warnings to dioxuslabs

* also allow writes in the component body when converting from T -> ReadOnlySignal<T>

* fix clippy from merge conflict

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2024-07-24 15:50:36 -07:00
1 parent f8cb07e673
commit a6c025c8ef
10 files changed
+132 -63

No files matched your search

+27 -25
View File
@@ -117,34 +117,36 @@ where
P::builder()
}
/// A warning that will trigger if a component is called as a function
#[warnings::warning]
pub(crate) fn component_called_as_function<C: ComponentFunction<P, M>, P, M>(_: C) {
// We trim WithOwner from the end of the type name for component with a builder that include a special owner which may not match the function name directly
let mut type_name = std::any::type_name::<C>();
if let Some((_, after_colons)) = type_name.rsplit_once("::") {
type_name = after_colons;
}
let component_name = Runtime::with(|rt| {
current_scope_id()
.ok()
.and_then(|id| rt.get_state(id).map(|scope| scope.name))
})
.ok()
.flatten();
// If we are in a component, and the type name is the same as the active component name, then we can just return
if component_name == Some(type_name) {
return;
}
// Otherwise the component was called like a function, so we should log an error
tracing::error!("It looks like you called the component {type_name} like a function instead of a component. Components should be called with braces like `{type_name} {{ prop: value }}` instead of as a function");
}
/// Make sure that this component is currently running as a component, not a function call
#[doc(hidden)]
#[allow(unused)]
#[allow(clippy::no_effect)]
pub fn verify_component_called_as_component<C: ComponentFunction<P, M>, P, M>(component: C) {
#[cfg(debug_assertions)]
{
// We trim WithOwner from the end of the type name for component with a builder that include a special owner which may not match the function name directly
let mut type_name = std::any::type_name::<C>();
if let Some((_, after_colons)) = type_name.rsplit_once("::") {
type_name = after_colons;
}
let component_name = Runtime::with(|rt| {
current_scope_id()
.ok()
.and_then(|id| rt.get_state(id))
.map(|scope| scope.name)
})
.ok()
.flatten();
// If we are in a component, and the type name is the same as the active component name, then we can just return
if component_name == Some(type_name) {
return;
}
// Otherwise the component was called like a function, so we should log an error
tracing::error!("It looks like you called the component {type_name} like a function instead of a component. Components should be called with braces like `{type_name} {{ prop: value }}` instead of as a function");
}
component_called_as_function(component);
}
/// Any component that implements the `ComponentFn` trait can be used as a component.
+10 -3
View File
@@ -254,8 +254,15 @@ impl VirtualDom {
/// ```
///
/// Note: the VirtualDom is not progressed, you must either "run_with_deadline" or use "rebuild" to progress it.
pub fn new<F: Fn() -> Element + Clone + 'static>(app: F) -> Self {
Self::new_with_props(app, ())
pub fn new(app: fn() -> Element) -> Self {
Self::new_with_props(
move || {
use warnings::Warning;
// The root props don't come from a vcomponent so we need to manually rerun them sometimes
crate::properties::component_called_as_function::allow(app)
},
(),
)
}
/// Create a new VirtualDom with the given properties for the root component.
@@ -313,7 +320,7 @@ impl VirtualDom {
}
/// Create a new virtualdom and build it immediately
pub fn prebuilt<F: Fn() -> Element + Clone + 'static>(app: F) -> Self {
pub fn prebuilt(app: fn() -> Element) -> Self {
let mut dom = Self::new(app);
dom.rebuild_in_place();
dom