mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 23:38:06 +08:00
Fix regression breaking Into/Convert node type coercion (#3681)
This commit is contained in:
@@ -794,7 +794,14 @@ impl TypingContext {
|
||||
.into_iter()
|
||||
.chain(&inputs)
|
||||
.enumerate()
|
||||
.filter_map(|(i, t)| if i == 0 { None } else { Some(format!("• Input {}: {t}", i + convert_node_index_offset)) })
|
||||
.filter_map(|(i, t)| {
|
||||
if i == 0 {
|
||||
None
|
||||
} else {
|
||||
let number = i + convert_node_index_offset;
|
||||
Some(format!("• Input {number}: {t}"))
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
Err(vec![GraphError::new(node, GraphErrorType::InvalidImplementations { inputs, error_inputs })])
|
||||
@@ -821,13 +828,13 @@ impl TypingContext {
|
||||
return Ok(node_io.clone());
|
||||
}
|
||||
}
|
||||
let inputs = [call_argument].into_iter().chain(&inputs).map(|t| t.to_string()).collect::<Vec<_>>().join(", ");
|
||||
let inputs = [call_argument].into_iter().chain(&inputs).map(ToString::to_string).collect::<Vec<_>>().join(", ");
|
||||
let valid = valid_output_types.into_iter().cloned().collect();
|
||||
Err(vec![GraphError::new(node, GraphErrorType::MultipleImplementations { inputs, valid })])
|
||||
}
|
||||
|
||||
_ => {
|
||||
let inputs = [call_argument].into_iter().chain(&inputs).map(|t| t.to_string()).collect::<Vec<_>>().join(", ");
|
||||
let inputs = [call_argument].into_iter().chain(&inputs).map(ToString::to_string).collect::<Vec<_>>().join(", ");
|
||||
let valid = valid_output_types.into_iter().cloned().collect();
|
||||
Err(vec![GraphError::new(node, GraphErrorType::MultipleImplementations { inputs, valid })])
|
||||
}
|
||||
@@ -871,9 +878,7 @@ fn check_generic(types: &NodeIOTypes, input: &Type, parameters: &[Type], generic
|
||||
/// Returns a list of all generic types used in the node
|
||||
fn replace_generics(types: &mut NodeIOTypes, lookup: &HashMap<String, Type>) {
|
||||
let replace = |ty: &Type| {
|
||||
let Type::Generic(ident) = ty else {
|
||||
return None;
|
||||
};
|
||||
let Type::Generic(ident) = ty else { return None };
|
||||
lookup.get(ident.as_ref()).cloned()
|
||||
};
|
||||
types.call_argument.replace_nested(replace);
|
||||
|
||||
@@ -118,11 +118,10 @@ impl NodeIOTypes {
|
||||
|
||||
impl std::fmt::Debug for NodeIOTypes {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!(
|
||||
"node({}) → {}",
|
||||
[&self.call_argument].into_iter().chain(&self.inputs).map(|input| input.to_string()).collect::<Vec<_>>().join(", "),
|
||||
self.return_value
|
||||
))
|
||||
let inputs = self.inputs.iter().map(ToString::to_string).collect::<Vec<_>>().join(", ");
|
||||
let return_value = &self.return_value;
|
||||
let call_argument = &self.call_argument;
|
||||
f.write_fmt(format_args!("({inputs}) → {return_value} called with {call_argument}"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +201,7 @@ impl std::hash::Hash for TypeDescriptor {
|
||||
|
||||
impl std::fmt::Display for TypeDescriptor {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let text = make_type_user_readable(&format_type(&self.name));
|
||||
let text = make_type_user_readable(&simplify_identifier_name(&self.name));
|
||||
write!(f, "{text}")
|
||||
}
|
||||
}
|
||||
@@ -337,15 +336,17 @@ impl Type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_cow_string(&self) -> Cow<'static, str> {
|
||||
pub fn identifier_name(&self) -> String {
|
||||
match self {
|
||||
Type::Generic(name) => name.clone(),
|
||||
_ => Cow::Owned(self.to_string()),
|
||||
Type::Generic(name) => name.to_string(),
|
||||
Type::Concrete(ty) => simplify_identifier_name(&ty.name),
|
||||
Type::Fn(call_arg, return_value) => format!("{} called with {}", return_value.identifier_name(), call_arg.identifier_name()),
|
||||
Type::Future(ty) => ty.identifier_name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_type(ty: &str) -> String {
|
||||
pub fn simplify_identifier_name(ty: &str) -> String {
|
||||
ty.split('<')
|
||||
.map(|path| path.split(',').map(|path| path.split("::").last().unwrap_or(path)).collect::<Vec<_>>().join(","))
|
||||
.collect::<Vec<_>>()
|
||||
@@ -361,42 +362,26 @@ pub fn make_type_user_readable(ty: &str) -> String {
|
||||
|
||||
impl std::fmt::Debug for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let text = match self {
|
||||
Self::Generic(name) => name.to_string(),
|
||||
#[cfg(feature = "type_id_logging")]
|
||||
Self::Concrete(ty) => format!("Concrete<{}, {:?}>", ty.name, ty.id),
|
||||
#[cfg(not(feature = "type_id_logging"))]
|
||||
Self::Concrete(ty) => format_type(&ty.name),
|
||||
Self::Fn(call_arg, return_value) => format!("{return_value:?} called with {call_arg:?}"),
|
||||
Self::Future(ty) => format!("{ty:?}"),
|
||||
};
|
||||
let text = make_type_user_readable(&text);
|
||||
write!(f, "{text}")
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
// Display
|
||||
impl std::fmt::Display for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self == &concrete!(glam::DVec2) {
|
||||
return write!(f, "vec2");
|
||||
}
|
||||
if self == &concrete!(glam::DAffine2) {
|
||||
return write!(f, "transform");
|
||||
}
|
||||
if self == &concrete!(Footprint) {
|
||||
return write!(f, "footprint");
|
||||
}
|
||||
if self == &concrete!(&str) || self == &concrete!(String) {
|
||||
return write!(f, "string");
|
||||
}
|
||||
use glam::*;
|
||||
|
||||
let text = match self {
|
||||
Type::Generic(name) => name.to_string(),
|
||||
Type::Concrete(ty) => format_type(&ty.name),
|
||||
Type::Fn(call_arg, return_value) => format!("{return_value} called with {call_arg}"),
|
||||
Type::Future(ty) => ty.to_string(),
|
||||
};
|
||||
let text = make_type_user_readable(&text);
|
||||
write!(f, "{text}")
|
||||
match self {
|
||||
Type::Generic(name) => write!(f, "{}", make_type_user_readable(name)),
|
||||
Type::Concrete(ty) => match () {
|
||||
() if self == &concrete!(DVec2) || self == &concrete!(Vec2) || self == &concrete!(IVec2) || self == &concrete!(UVec2) => write!(f, "Vec2"),
|
||||
() if self == &concrete!(glam::DAffine2) => write!(f, "Transform"),
|
||||
() if self == &concrete!(Footprint) => write!(f, "Footprint"),
|
||||
() if self == &concrete!(&str) || self == &concrete!(String) => write!(f, "String"),
|
||||
_ => write!(f, "{}", make_type_user_readable(&simplify_identifier_name(&ty.name))),
|
||||
},
|
||||
Type::Fn(call_arg, return_value) => write!(f, "{return_value} called with {call_arg}"),
|
||||
Type::Future(ty) => write!(f, "{ty}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ pub fn generate_node_substitutions() -> HashMap<ProtoNodeIdentifier, DocumentNod
|
||||
let id = id.clone();
|
||||
|
||||
let NodeMetadata { fields, .. } = metadata;
|
||||
let Some(implementations) = &node_registry.get(&id) else { continue };
|
||||
let Some(implementations) = node_registry.get(&id) else { continue };
|
||||
let valid_call_args: HashSet<_> = implementations.iter().map(|(_, node_io)| node_io.call_argument.clone()).collect();
|
||||
let first_node_io = implementations.first().map(|(_, node_io)| node_io).unwrap_or(const { &NodeIOTypes::empty() });
|
||||
let mut node_io_types = vec![HashSet::new(); fields.len()];
|
||||
@@ -69,8 +69,8 @@ pub fn generate_node_substitutions() -> HashMap<ProtoNodeIdentifier, DocumentNod
|
||||
let input_ty = input.nested_type();
|
||||
let mut inputs = vec![NodeInput::import(input.clone(), i)];
|
||||
|
||||
let into_node_identifier = ProtoNodeIdentifier::with_owned_string(format!("graphene_core::ops::IntoNode<{}>", input_ty.clone()));
|
||||
let convert_node_identifier = ProtoNodeIdentifier::with_owned_string(format!("graphene_core::ops::ConvertNode<{}>", input_ty.clone()));
|
||||
let into_node_identifier = ProtoNodeIdentifier::with_owned_string(format!("graphene_core::ops::IntoNode<{}>", input_ty.identifier_name()));
|
||||
let convert_node_identifier = ProtoNodeIdentifier::with_owned_string(format!("graphene_core::ops::ConvertNode<{}>", input_ty.identifier_name()));
|
||||
|
||||
let proto_node = if into_node_registry.keys().any(|ident: &ProtoNodeIdentifier| ident.as_str() == into_node_identifier.as_str()) {
|
||||
generated_nodes += 1;
|
||||
|
||||
Reference in New Issue
Block a user