Extract a class definition node and its inheritance edges. Returns True if the child was handled (class with a name found).
(
self,
child,
source: bytes,
language: str,
file_path: str,
nodes: list[NodeInfo],
edges: list[EdgeInfo],
enclosing_class: Optional[str],
import_map: Optional[dict[str, str]],
defined_names: Optional[set[str]],
_depth: int,
)
| 4241 | )) |
| 4242 | |
| 4243 | def _extract_classes( |
| 4244 | self, |
| 4245 | child, |
| 4246 | source: bytes, |
| 4247 | language: str, |
| 4248 | file_path: str, |
| 4249 | nodes: list[NodeInfo], |
| 4250 | edges: list[EdgeInfo], |
| 4251 | enclosing_class: Optional[str], |
| 4252 | import_map: Optional[dict[str, str]], |
| 4253 | defined_names: Optional[set[str]], |
| 4254 | _depth: int, |
| 4255 | ) -> bool: |
| 4256 | """Extract a class definition node and its inheritance edges. |
| 4257 | |
| 4258 | Returns True if the child was handled (class with a name found). |
| 4259 | """ |
| 4260 | name = self._get_name(child, language, "class") |
| 4261 | if not name: |
| 4262 | return False |
| 4263 | |
| 4264 | # Swift: detect the actual type keyword (class/struct/enum/actor/extension) |
| 4265 | # and store it in extra["swift_kind"] for richer downstream analysis. |
| 4266 | # Tree-sitter maps struct/enum/actor/extension all to class_declaration; |
| 4267 | # protocol uses its own protocol_declaration node type. |
| 4268 | extra: dict = {} |
| 4269 | if language == "swift": |
| 4270 | if child.type == "class_declaration": |
| 4271 | _swift_keywords = {"class", "struct", "enum", "actor", "extension"} |
| 4272 | for kw_child in child.children: |
| 4273 | kw_text = kw_child.text.decode("utf-8", errors="replace") |
| 4274 | if kw_text in _swift_keywords: |
| 4275 | extra["swift_kind"] = kw_text |
| 4276 | break |
| 4277 | elif child.type == "protocol_declaration": |
| 4278 | extra["swift_kind"] = "protocol" |
| 4279 | |
| 4280 | # Java: detect Spring stereotype annotations and store as metadata |
| 4281 | class_annotations: list[str] = [] |
| 4282 | if language == "java": |
| 4283 | class_annotations = self._get_java_annotations(child) |
| 4284 | spring_stereotypes = [ |
| 4285 | a for a in class_annotations if a in _SPRING_STEREOTYPE_ANNOTATIONS |
| 4286 | ] |
| 4287 | if spring_stereotypes: |
| 4288 | extra["spring_stereotype"] = spring_stereotypes[0] |
| 4289 | if class_annotations: |
| 4290 | extra["spring_annotations"] = class_annotations |
| 4291 | temporal_roles = [ |
| 4292 | a for a in class_annotations if a in _TEMPORAL_INTERFACE_ANNOTATIONS |
| 4293 | ] |
| 4294 | if temporal_roles: |
| 4295 | is_wf = "WorkflowInterface" in temporal_roles |
| 4296 | role = "workflow_interface" if is_wf else "activity_interface" |
| 4297 | extra["temporal_role"] = role |
| 4298 | |
| 4299 | node = NodeInfo( |
| 4300 | kind="Class", |
no test coverage detected