| 260 | |
| 261 | |
| 262 | class Node(): |
| 263 | def __init__(self, token, calls, variables, parent, import_tokens=None, |
| 264 | line_number=None, is_constructor=False): |
| 265 | self.token = token |
| 266 | self.line_number = line_number |
| 267 | self.calls = calls |
| 268 | self.variables = variables |
| 269 | self.import_tokens = import_tokens or [] |
| 270 | self.parent = parent |
| 271 | self.is_constructor = is_constructor |
| 272 | |
| 273 | self.uid = "node_" + os.urandom(4).hex() |
| 274 | |
| 275 | # Assume it is a leaf and a trunk. These are modified later |
| 276 | self.is_leaf = True # it calls nothing else |
| 277 | self.is_trunk = True # nothing calls it |
| 278 | |
| 279 | def __repr__(self): |
| 280 | return f"<Node token={self.token} parent={self.parent}>" |
| 281 | |
| 282 | def __lt__(self, other): |
| 283 | return self.name() < other.name() |
| 284 | |
| 285 | def name(self): |
| 286 | """ |
| 287 | Names exist largely for unit tests and deterministic node sorting |
| 288 | :rtype: str |
| 289 | """ |
| 290 | return f"{self.first_group().filename()}::{self.token_with_ownership()}" |
| 291 | |
| 292 | def first_group(self): |
| 293 | """ |
| 294 | The first group that contains this node. |
| 295 | :rtype: Group |
| 296 | """ |
| 297 | parent = self.parent |
| 298 | while not isinstance(parent, Group): |
| 299 | parent = parent.parent |
| 300 | return parent |
| 301 | |
| 302 | def file_group(self): |
| 303 | """ |
| 304 | Get the file group that this node is in. |
| 305 | :rtype: Group |
| 306 | """ |
| 307 | parent = self.parent |
| 308 | while parent.parent: |
| 309 | parent = parent.parent |
| 310 | return parent |
| 311 | |
| 312 | def is_attr(self): |
| 313 | """ |
| 314 | Whether this node is attached to something besides the file |
| 315 | :rtype: bool |
| 316 | """ |
| 317 | return (self.parent |
| 318 | and isinstance(self.parent, Group) |
| 319 | and self.parent.group_type in (GROUP_TYPE.CLASS, GROUP_TYPE.NAMESPACE)) |
no outgoing calls
no test coverage detected