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