extractProperty (1986) — property_declaration only (dispatch-gated to class-like scopes). Accessor bodies and `=>` value clauses are never walked; type refs DO come from the `type` field.
(&mut self, node: Node<'t>)
| 740 | /// class-like scopes). Accessor bodies and `=>` value clauses are never |
| 741 | /// walked; type refs DO come from the `type` field. |
| 742 | fn extract_property(&mut self, node: Node<'t>) { |
| 743 | let docstring = preceding_docstring(node, self.src); |
| 744 | let visibility = Some(self.visibility_of(node)); |
| 745 | let is_static = Some(self.is_static(node)); // ?? false — always concrete |
| 746 | |
| 747 | let name_node = node |
| 748 | .child_by_field_name("name") |
| 749 | .or_else(|| node.child_by_field_name("property")) |
| 750 | .or_else(|| { |
| 751 | (0..node.named_child_count()) |
| 752 | .filter_map(|i| node.named_child(i)) |
| 753 | .find(|c| c.kind() == "identifier") |
| 754 | }); |
| 755 | let Some(name_node) = name_node else { return }; |
| 756 | let name = self.text(name_node).to_string(); |
| 757 | if name.is_empty() { |
| 758 | return; |
| 759 | } |
| 760 | |
| 761 | // Generic scan (isTsJsField=false): FIRST namedChild that isn't a |
| 762 | // modifier/name/accessor/initializer. A BARE-identifier declared type |
| 763 | // (`public Widget Parent {get;}`) is excluded by the `identifier` |
| 764 | // filter → the signature loses its type (QUIRK, preserve); the type |
| 765 | // ref below still fires via the `type` FIELD. |
| 766 | let type_node = (0..node.named_child_count()) |
| 767 | .filter_map(|i| node.named_child(i)) |
| 768 | .find(|c| { |
| 769 | !matches!( |
| 770 | c.kind(), |
| 771 | "modifier" | "modifiers" | "identifier" | "accessor_list" | "accessors" |
| 772 | | "equals_value_clause" |
| 773 | ) |
| 774 | }); |
| 775 | let type_text = type_node.map(|t| { |
| 776 | let raw = self.text(t); |
| 777 | // TS `.replace(/^:\s*/, '')` — inert for C# type text; mirrored. |
| 778 | match raw.strip_prefix(':') { |
| 779 | Some(rest) => rest.trim_start_matches(is_js_space).to_string(), |
| 780 | None => raw.to_string(), |
| 781 | } |
| 782 | }); |
| 783 | let signature = match &type_text { |
| 784 | Some(t) => format!("{t} {name}"), |
| 785 | None => name.clone(), |
| 786 | }; |
| 787 | |
| 788 | let row = self.create_node( |
| 789 | "property", |
| 790 | &name, |
| 791 | node, |
| 792 | Extra { docstring, signature: Some(signature), visibility, is_static, ..Extra::default() }, |
| 793 | ); |
| 794 | if let Some(row) = row { |
| 795 | // decorators: none for C#; then the csharp type-ref path. |
| 796 | self.extract_csharp_type_refs(node, row); |
| 797 | } |
| 798 | } |
| 799 |
no test coverage detected