(&mut self, node: Node<'t>)
| 255 | // --- extractProperty (#808 property-classified class fields) --------------------- |
| 256 | |
| 257 | pub(super) fn extract_property(&mut self, node: Node<'t>) -> Option<(u32, String)> { |
| 258 | let docstring = crate::docstring::preceding_docstring(node, self.src); |
| 259 | let visibility = self.visibility_of(node); |
| 260 | let is_static = Some(self.is_static(node).unwrap_or(false)); // `?? false` — always present |
| 261 | |
| 262 | let name_node = node |
| 263 | .child_by_field_name("name") |
| 264 | .or_else(|| node.child_by_field_name("property")) |
| 265 | .or_else(|| { |
| 266 | (0..node.named_child_count()) |
| 267 | .filter_map(|i| node.named_child(i)) |
| 268 | .find(|c| c.kind() == "identifier") |
| 269 | })?; |
| 270 | let name = self.text(name_node).to_string(); |
| 271 | |
| 272 | // TS/JS field definitions carry an explicit `type` field; the generic |
| 273 | // scan is for other languages (#808). |
| 274 | let type_text = node.child_by_field_name("type").map(|t| { |
| 275 | let raw = self.text(t); |
| 276 | raw.strip_prefix(':').unwrap_or(raw).trim_start().to_string() |
| 277 | }); |
| 278 | let signature = match &type_text { |
| 279 | Some(t) => format!("{t} {name}"), |
| 280 | None => name.clone(), |
| 281 | }; |
| 282 | |
| 283 | let row = self.create_node( |
| 284 | "property", |
| 285 | &name, |
| 286 | node, |
| 287 | Extra { docstring, signature: Some(signature), visibility, is_static, ..Extra::default() }, |
| 288 | )?; |
| 289 | self.extract_decorators_for(node, row); |
| 290 | self.extract_type_annotations(node, row); |
| 291 | Some((row, name)) |
| 292 | } |
| 293 | |
| 294 | // --- extractVariable (TS/JS branch) ------------------------------------------------ |
| 295 |
no test coverage detected