| 320 | |
| 321 | @dataclass |
| 322 | class Constant(ASTNode): |
| 323 | value: NodeType |
| 324 | |
| 325 | def _visit_node(self, context: Context): |
| 326 | context.visit_child( |
| 327 | node = self.value, |
| 328 | replace = partial(self.__replace_value, visitor=context.visitor) |
| 329 | ) |
| 330 | |
| 331 | def __replace_value(self, value, visitor): |
| 332 | self.value = value |
| 333 | visitor.modified = True |
| 334 | |
| 335 | def __post_init__(self): |
| 336 | super().__post_init__() |
| 337 | self._taint_class = Taints.SAFE |
| 338 | |
| 339 | def __str__(self): |
| 340 | if type(self.value) in (str, String, bool, Dictionary, dict): |
| 341 | return str(self.value) |
| 342 | elif self.value == ...: |
| 343 | return "..." |
| 344 | else: |
| 345 | raise ValueError(f"Incompatible value type: {repr(type(self.value))}") |
| 346 | |
| 347 | def __int__(self): |
| 348 | if type(self.value) in (int, Number): |
| 349 | return int(self.value) |
| 350 | else: |
| 351 | raise ValueError(f"Incompatible value type: {repr(type(self.value))}") |
| 352 | |
| 353 | def match(self, other, ctx) -> bool: |
| 354 | if type(other) != Constant: |
| 355 | return False |
| 356 | if other.value != self.value: |
| 357 | return False |
| 358 | return True |
| 359 | |
| 360 | |
| 361 | @dataclass |