luaur_analysis/functions/
autocomplete_autocomplete.rs1use crate::enums::solver_mode::SolverMode;
6use crate::functions::autocomplete_autocomplete_core::autocomplete_;
7use crate::functions::find_ancestry_at_position_for_autocomplete_ast_query::find_ancestry_at_position_for_autocomplete_source_module_position;
8use crate::functions::find_scope_at_position::find_scope_at_position;
9use crate::functions::is_within_comment_module_alt_b::is_within_comment_source_module_position;
10use crate::functions::is_within_hot_comment_module_alt_b::is_within_hot_comment_source_module_position;
11use crate::records::autocomplete_result::AutocompleteResult;
12use crate::records::frontend::Frontend;
13use crate::records::type_arena::TypeArena;
14use crate::type_aliases::module_name_file_resolver::ModuleName;
15use crate::type_aliases::string_completion_callback::StringCompletionCallback;
16use luaur_ast::records::position::Position;
17use luaur_common::macros::luau_assert::LUAU_ASSERT;
18use luaur_common::macros::luau_timetrace_argument::LUAU_TIMETRACE_ARGUMENT;
19use luaur_common::macros::luau_timetrace_scope::LUAU_TIMETRACE_SCOPE;
20
21pub fn autocomplete(
22 frontend: &mut Frontend,
23 module_name: &ModuleName,
24 position: Position,
25 callback: StringCompletionCallback,
26) -> AutocompleteResult {
27 LUAU_TIMETRACE_SCOPE!("Luau::autocomplete", "Autocomplete");
28 LUAU_TIMETRACE_ARGUMENT!("name", module_name.as_str());
29
30 let source_module = frontend.get_source_module(module_name);
31 if source_module.is_null() {
32 return AutocompleteResult::autocomplete_result();
33 }
34
35 let module = if frontend.get_luau_solver_mode() == SolverMode::New {
38 frontend.module_resolver.get_module(module_name)
39 } else {
40 frontend
41 .module_resolver_for_autocomplete
42 .get_module(module_name)
43 };
44
45 let builtin_types = unsafe { &*frontend.builtin_types };
46
47 let global_scope = if frontend.get_luau_solver_mode() == SolverMode::New {
48 alloc::sync::Arc::as_ptr(&frontend.globals.global_scope)
49 as *mut crate::records::scope::Scope
50 } else {
51 alloc::sync::Arc::as_ptr(&frontend.globals_for_autocomplete.global_scope)
52 as *mut crate::records::scope::Scope
53 };
54
55 let mut type_arena = TypeArena::default();
56 let is_in_hot_comment =
57 is_within_hot_comment_source_module_position(unsafe { &*source_module }, position);
58 if is_within_comment_source_module_position(unsafe { &*source_module }, position)
59 && !is_in_hot_comment
60 {
61 return AutocompleteResult::autocomplete_result();
62 }
63
64 let mut ancestry = find_ancestry_at_position_for_autocomplete_source_module_position(
65 unsafe { &*source_module },
66 position,
67 );
68 LUAU_ASSERT!(!ancestry.is_empty());
69 let start_scope = find_scope_at_position(&module, position).unwrap();
73
74 autocomplete_(
75 &module,
76 builtin_types,
77 &mut type_arena,
78 &mut ancestry,
79 global_scope,
80 &start_scope,
81 position,
82 frontend.file_resolver,
83 callback,
84 is_in_hot_comment,
85 )
86}