Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions internal/compiler/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,17 +721,19 @@ impl ColorSpecific {
/// `["LayoutAlignment.center", "TextHorizontalAlignment.center"]`. This is the reverse of the
/// `ColorSpecific` / enum lookups above, used to build "did you mean" suggestions. The result is
/// sorted and deduplicated so it is deterministic.
pub fn enum_or_color_suggestions(type_register: &TypeRegister, name: &str) -> Vec<SmolStr> {
pub fn enum_or_color_suggestions(ctx: &LookupCtx, name: &str) -> Vec<SmolStr> {
let name = crate::parser::normalize_identifier(name);
let mut result = Vec::new();
if named_colors().contains_key(name.as_str()) {
if named_colors().contains_key(name.as_str())
&& BuiltinNamespaceLookup.lookup(ctx, &SmolStr::new_static("Colors")).is_some()
{
result.push(smol_str::format_smolstr!("{}.{name}", BuiltinNamespace::Colors));
}
for ty in type_register.all_types().values() {
if let Type::Enumeration(e) = ty {
if e.values.contains(&name) {
result.push(smol_str::format_smolstr!("{}.{name}", e.name));
}
for ty in ctx.type_register.all_types().values() {
if let Type::Enumeration(e) = ty
&& e.lookup(ctx, &name).is_some()
{
result.push(smol_str::format_smolstr!("{}.{name}", e.name));
}
}
result.sort();
Expand Down
9 changes: 4 additions & 5 deletions internal/compiler/passes/resolving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2380,11 +2380,10 @@ fn lookup_qualified_name_node(
if it.next().is_some() {
ctx.diag.push_error(format!("Cannot access id '{}'", first.text()), &node);
} else {
let mut parts =
crate::lookup::enum_or_color_suggestions(ctx.type_register, &first_str)
.iter()
.map(|s| format!("'{s}'"))
.collect::<Vec<_>>();
let mut parts = crate::lookup::enum_or_color_suggestions(ctx, &first_str)
.iter()
.map(|s| format!("'{s}'"))
.collect::<Vec<_>>();
let hint = match parts.pop() {
None => String::new(),
Some(last) if parts.is_empty() => format!(". Did you mean {last}?"),
Expand Down
3 changes: 3 additions & 0 deletions internal/compiler/tests/syntax/slint-sc/enums.slint
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ export component Test inherits Window {
in-out property <Direction> direction;
//#sls.enum.value
out property <Direction> fixed: Direction.down;

out property <int> bare: up;
// ><error{Unknown unqualified identifier 'up'. Did you mean 'Direction.up'?}
}
20 changes: 8 additions & 12 deletions tools/lsp/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1724,20 +1724,16 @@ fn get_code_actions(
// (`red` -> `Colors.red`). Like the import action above, re-derive the lookup error rather
// than reading diagnostics, so nothing is offered when the identifier does resolve.
use i_slint_compiler::lookup::LookupObject;
let is_lookup_error = util::with_lookup_ctx(document_cache, node.clone(), None, |ctx| {
let suggestions = util::with_lookup_ctx(document_cache, node.clone(), None, |ctx| {
let name = i_slint_compiler::parser::normalize_identifier(token.text());
i_slint_compiler::lookup::global_lookup().lookup(ctx, &name).is_none()
if i_slint_compiler::lookup::global_lookup().lookup(ctx, &name).is_none() {
i_slint_compiler::lookup::enum_or_color_suggestions(ctx, token.text())
} else {
Vec::new()
}
})
.unwrap_or(true);
if is_lookup_error {
let suggestions = {
let global_tr = document_cache.global_type_registry();
let tr = document_cache
.get_document_for_source_file(&token.source_file)
.map(|doc| &doc.local_registry)
.unwrap_or(&global_tr);
i_slint_compiler::lookup::enum_or_color_suggestions(tr, token.text())
};
.unwrap_or_default();
if !suggestions.is_empty() {
let range = util::text_range_to_lsp_range(
&token.source_file,
token.text_range(),
Expand Down
Loading