Build completion item for class keywords (`self`, `static`, `parent`) in `new` expression contexts. When the cursor is inside a class and typing `new s`, these keywords should be offered alongside regular class names. If the current class has a constructor, the completion includes parameter snippets.
(
&self,
prefix: &str,
current_class: Option<&ClassInfo>,
)
| 1178 | /// should be offered alongside regular class names. If the current class |
| 1179 | /// has a constructor, the completion includes parameter snippets. |
| 1180 | fn build_class_keyword_completions( |
| 1181 | &self, |
| 1182 | prefix: &str, |
| 1183 | current_class: Option<&ClassInfo>, |
| 1184 | ) -> Vec<CompletionItem> { |
| 1185 | let mut items = Vec::new(); |
| 1186 | |
| 1187 | let Some(current_class) = current_class else { |
| 1188 | return items; |
| 1189 | }; |
| 1190 | |
| 1191 | let prefix_lower = prefix.to_lowercase(); |
| 1192 | |
| 1193 | for keyword in ["self", "static"] { |
| 1194 | if !keyword.starts_with(&prefix_lower) { |
| 1195 | continue; |
| 1196 | } |
| 1197 | |
| 1198 | let mut item = CompletionItem { |
| 1199 | label: keyword.to_string(), |
| 1200 | kind: Some(CompletionItemKind::KEYWORD), |
| 1201 | detail: Some("Instantiate current class".to_string()), |
| 1202 | filter_text: Some(keyword.to_string()), |
| 1203 | sort_text: Some(format!("0_{keyword}")), |
| 1204 | ..CompletionItem::default() |
| 1205 | }; |
| 1206 | |
| 1207 | // Add constructor snippet if available |
| 1208 | if let Some(ctor) = current_class.get_method("__construct") { |
| 1209 | let snippet = |
| 1210 | crate::completion::builder::build_callable_snippet(keyword, &ctor.parameters); |
| 1211 | item.insert_text = Some(snippet); |
| 1212 | item.insert_text_format = Some(InsertTextFormat::SNIPPET); |
| 1213 | } else { |
| 1214 | item.insert_text = Some(format!("{}()$0", keyword)); |
| 1215 | item.insert_text_format = Some(InsertTextFormat::SNIPPET); |
| 1216 | } |
| 1217 | |
| 1218 | items.push(item); |
| 1219 | } |
| 1220 | |
| 1221 | // `parent` - reference the parent class |
| 1222 | if "parent".starts_with(&prefix_lower) |
| 1223 | && let Some(parent_name) = ¤t_class.parent_class |
| 1224 | { |
| 1225 | let mut item = CompletionItem { |
| 1226 | label: "parent".to_string(), |
| 1227 | kind: Some(CompletionItemKind::KEYWORD), |
| 1228 | detail: Some(format!("Instantiate parent class ({})", parent_name)), |
| 1229 | filter_text: Some("parent".to_string()), |
| 1230 | sort_text: Some("0_parent".to_string()), |
| 1231 | ..CompletionItem::default() |
| 1232 | }; |
| 1233 | |
| 1234 | // Try to load parent class and get its constructor |
| 1235 | if let Some(parent_cls) = self.find_or_load_class(parent_name) { |
| 1236 | if let Some(ctor) = parent_cls.get_method("__construct") { |
| 1237 | let snippet = crate::completion::builder::build_callable_snippet( |
no test coverage detected