--- /dev/null
+import ast
+
+from lib.utils import Schema, ConfigASTVisitor, SourceLogger
+from .common import NodeProperty
+
+class TreeSanitiser(ConfigASTVisitor):
+ DecoNative = Schema(ast.Name, id="native")
+ DecoName = Schema(ast.Name)
+ DecoNameE = Schema(ast.NamedExpr)
+ DecoCall = Schema(ast.Call)
+ DecoConst = Schema(ast.Constant)
+
+ def __init__(self):
+ super().__init__()
+ self.logger = SourceLogger(self)
+
+ # TODO
+ self.deco_rules = {}
+
+ def __sanitise_decorator(self, node: ast.FunctionDef):
+ deco_map = {}
+
+ for deco in node.decorator_list:
+ name = ""
+ if TreeSanitiser.DecoNative == deco:
+ setattr(node, "__builtin", True)
+ continue
+ elif TreeSanitiser.DecoCall == deco:
+ name = deco.func
+ elif TreeSanitiser.DecoConst == deco:
+ name = f"{deco.value}"
+ elif TreeSanitiser.DecoName == deco:
+ name = f"{deco.id}"
+ elif TreeSanitiser.DecoNameE == deco:
+ name = f"{ast.unparse(deco)}"
+ else:
+ self.logger.warn(deco, "invalid modifier type")
+ continue
+
+ deco_map[name] = deco
+
+ node.decorator_list = [x for x in deco_map.values()]
+
+ for desc, rule in self.deco_rules.items():
+ if rule(deco_map):
+ continue
+ self.logger.warn(node, desc)
+
+ def _visit_fndef(self, node):
+ self.__sanitise_decorator(node)
+ super()._visit_fndef(node)