Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from __future__ import annotations
from typing import Callable
from types import MethodType
from functools import wraps
from .basic_nodes import SfgCallTreeNode
class VisitorDispatcher:
def __init__(self, wrapped_method):
self._dispatch_dict = {}
self._wrapped_method = wrapped_method
def case(self, node_type: type):
"""Decorator for visitor's methods"""
def decorate(handler: Callable):
if node_type in self._dispatch_dict:
raise ValueError(f"Duplicate visitor case {node_type}")
self._dispatch_dict[node_type] = handler
return handler
return decorate
def __call__(self, instance, node: SfgCallTreeNode, *args, **kwargs):
for cls in node.__class__.mro():
if cls in self._dispatch_dict:
return self._dispatch_dict[cls](instance, node, *args, **kwargs)
return self._wrapped_method(instance, node, *args, **kwargs)
def __get__(self, obj, objtype=None):
if obj is None:
return self
return MethodType(self, obj)
def visitor(method):
return wraps(method)(VisitorDispatcher(method))