Visit every cursor in the translation unit. ``mujoco_include`` is the include root; we only capture decls whose file lives under it (so libc / Windows SDK / TinyXML noise is filtered out).
(tu, mujoco_include: str, snapshot: IntrospectSnapshot)
| 80 | |
| 81 | |
| 82 | def _walk(tu, mujoco_include: str, snapshot: IntrospectSnapshot) -> None: |
| 83 | """Visit every cursor in the translation unit. ``mujoco_include`` is |
| 84 | the include root; we only capture decls whose file lives under it |
| 85 | (so libc / Windows SDK / TinyXML noise is filtered out).""" |
| 86 | import clang.cindex as cx # noqa: E402, local-only |
| 87 | |
| 88 | plugin_root_norm = os.path.normcase(os.path.abspath(_PLUGIN_ROOT)) |
| 89 | |
| 90 | def _normalised_path(loc) -> str: |
| 91 | """Return the location's file as a forward-slash path relative to |
| 92 | the plugin root, so the snapshot is byte-identical across |
| 93 | developers (no absolute ``c:\\users\\...`` strings).""" |
| 94 | if not loc or not loc.file: |
| 95 | return "" |
| 96 | abs_path = os.path.normcase(os.path.abspath(loc.file.name)) |
| 97 | if abs_path.startswith(plugin_root_norm): |
| 98 | rel = os.path.relpath(abs_path, plugin_root_norm) |
| 99 | return rel.replace("\\", "/") |
| 100 | return abs_path.replace("\\", "/") |
| 101 | |
| 102 | # Filter root mirrors _normalised_path: relative-to-plugin-root with |
| 103 | # forward slashes. |
| 104 | mujoco_abs = os.path.normcase(os.path.abspath(mujoco_include)) |
| 105 | if mujoco_abs.startswith(plugin_root_norm): |
| 106 | norm_root = os.path.relpath(mujoco_abs, plugin_root_norm).replace("\\", "/") |
| 107 | else: |
| 108 | norm_root = mujoco_abs.replace("\\", "/") |
| 109 | |
| 110 | for cursor in tu.cursor.get_children(): |
| 111 | fp = _normalised_path(cursor.location) |
| 112 | if not fp.startswith(norm_root): |
| 113 | continue |
| 114 | |
| 115 | kind = cursor.kind |
| 116 | |
| 117 | if kind == cx.CursorKind.FUNCTION_DECL: |
| 118 | params: List[CFunctionParam] = [] |
| 119 | for arg in cursor.get_arguments(): |
| 120 | t = arg.type.spelling |
| 121 | dim = None |
| 122 | if "[" in t and "]" in t: |
| 123 | # e.g. "double [4]" -> dim=4 |
| 124 | try: |
| 125 | dim_str = t[t.index("[") + 1:t.index("]")] |
| 126 | if dim_str.strip().isdigit(): |
| 127 | dim = int(dim_str) |
| 128 | except ValueError: |
| 129 | pass |
| 130 | params.append(CFunctionParam( |
| 131 | name=arg.spelling, c_type=t, array_dim=dim, |
| 132 | )) |
| 133 | fn = CFunction( |
| 134 | name=cursor.spelling, |
| 135 | return_type=cursor.result_type.spelling, |
| 136 | params=params, |
| 137 | doc=_strip_doc(cursor.raw_comment or ""), |
| 138 | file=fp, |
| 139 | line=cursor.location.line if cursor.location else 0, |
no test coverage detected