diff --git a/internal/compiler/lookup.rs b/internal/compiler/lookup.rs index 67b709928e1..52dbaf2afd7 100644 --- a/internal/compiler/lookup.rs +++ b/internal/compiler/lookup.rs @@ -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 { +pub fn enum_or_color_suggestions(ctx: &LookupCtx, name: &str) -> Vec { 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(); diff --git a/internal/compiler/passes/resolving.rs b/internal/compiler/passes/resolving.rs index c724070c5cc..421b26464b2 100644 --- a/internal/compiler/passes/resolving.rs +++ b/internal/compiler/passes/resolving.rs @@ -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::>(); + let mut parts = crate::lookup::enum_or_color_suggestions(ctx, &first_str) + .iter() + .map(|s| format!("'{s}'")) + .collect::>(); let hint = match parts.pop() { None => String::new(), Some(last) if parts.is_empty() => format!(". Did you mean {last}?"), diff --git a/internal/compiler/tests/syntax/slint-sc/enums.slint b/internal/compiler/tests/syntax/slint-sc/enums.slint index 7b502d98b15..e72e5b464f5 100644 --- a/internal/compiler/tests/syntax/slint-sc/enums.slint +++ b/internal/compiler/tests/syntax/slint-sc/enums.slint @@ -32,4 +32,7 @@ export component Test inherits Window { in-out property direction; //#sls.enum.value out property fixed: Direction.down; + + out property bare: up; +// > `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(),