Properly remember the location of builtin member function call

So we can report an error if they are called in a pure context
This commit is contained in:
Olivier Goffart 2022-12-14 19:46:00 +01:00 committed by Olivier Goffart
parent 9b2726f0eb
commit 8a09043e63
3 changed files with 21 additions and 21 deletions

View file

@ -8,7 +8,7 @@ use std::rc::Rc;
use itertools::Itertools;
use crate::expression_tree::{Expression, Unit};
use crate::expression_tree::{BuiltinFunction, Expression, Unit};
use crate::object_tree::{Component, PropertyVisibility};
use crate::parser::syntax_nodes;
use crate::typeregister::TypeRegister;
@ -512,17 +512,17 @@ impl ElementType {
})
}
pub fn lookup_member_function(&self, name: &str) -> Expression {
pub fn lookup_member_function(&self, name: &str) -> Option<BuiltinFunction> {
match self {
Self::Builtin(builtin) => builtin
.member_functions
.get(name)
.cloned()
.unwrap_or_else(|| crate::typeregister::reserved_member_function(name)),
.or_else(|| crate::typeregister::reserved_member_function(name)),
Self::Component(component) => {
component.root_element.borrow().base_type.lookup_member_function(name)
}
_ => Expression::Invalid,
_ => None,
}
}
@ -672,7 +672,7 @@ pub struct BuiltinElement {
/// Non-item type do not have reserved properties (x/width/rowspan/...) added to them (eg: PropertyAnimation)
pub is_non_item_type: bool,
pub accepts_focus: bool,
pub member_functions: HashMap<String, Expression>,
pub member_functions: HashMap<String, BuiltinFunction>,
pub is_global: bool,
pub default_size_binding: DefaultSizeBinding,
/// When true this is an internal type not shown in the auto-completion

View file

@ -1072,13 +1072,15 @@ fn continue_lookup_within_element(
} else if let Some(x) = it.next() {
ctx.diag.push_error("Cannot access fields of a function".into(), &x)
}
let member = elem.borrow().base_type.lookup_member_function(&lookup_result.resolved_name);
if !matches!(member, Expression::Invalid) {
if let Some(f) =
elem.borrow().base_type.lookup_member_function(&lookup_result.resolved_name)
{
// builtin member function
Expression::MemberFunction {
base: Box::new(Expression::ElementReference(Rc::downgrade(elem))),
base_node: Some(NodeOrToken::Node(node.into())),
member: Box::new(member),
member: Expression::BuiltinFunctionReference(f, Some(second.to_source_location()))
.into(),
}
} else {
Expression::FunctionReference(NamedReference::new(elem, &lookup_result.resolved_name))

View file

@ -7,7 +7,7 @@ use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
use crate::expression_tree::{BuiltinFunction, Expression};
use crate::expression_tree::BuiltinFunction;
use crate::langtype::{
BuiltinElement, BuiltinPropertyInfo, ElementType, Enumeration, PropertyLookupResult, Type,
};
@ -171,17 +171,15 @@ pub fn reserved_property(name: &str) -> PropertyLookupResult {
}
/// These member functions are injected in every time
pub fn reserved_member_function(name: &str) -> Expression {
pub fn reserved_member_function(name: &str) -> Option<BuiltinFunction> {
for (m, e) in [
("focus", Expression::BuiltinFunctionReference(BuiltinFunction::SetFocusItem, None)), // match for callable "focus" property
]
.iter()
{
if *m == name {
return e.clone();
("focus", BuiltinFunction::SetFocusItem), // match for callable "focus" property
] {
if m == name {
return Some(e);
}
}
Expression::Invalid
None
}
#[derive(Debug, Default)]
@ -254,10 +252,10 @@ impl TypeRegister {
"show".into(),
BuiltinPropertyInfo::new(BuiltinFunction::ShowPopupWindow.ty()),
);
Rc::get_mut(b).unwrap().member_functions.insert(
"show".into(),
Expression::BuiltinFunctionReference(BuiltinFunction::ShowPopupWindow, None),
);
Rc::get_mut(b)
.unwrap()
.member_functions
.insert("show".into(), BuiltinFunction::ShowPopupWindow);
}
_ => unreachable!(),
};