1#     Copyright 2021, Kay Hayen, mailto:kay.hayen@gmail.com
2#
3#     Part of "Nuitka", an optimizing Python compiler that is compatible and
4#     integrates with CPython, but also works on its own.
5#
6#     Licensed under the Apache License, Version 2.0 (the "License");
7#     you may not use this file except in compliance with the License.
8#     You may obtain a copy of the License at
9#
10#        http://www.apache.org/licenses/LICENSE-2.0
11#
12#     Unless required by applicable law or agreed to in writing, software
13#     distributed under the License is distributed on an "AS IS" BASIS,
14#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15#     See the License for the specific language governing permissions and
16#     limitations under the License.
17#
18""" Tags and set of it.
19
20Used by optimization to keep track of the current state of optimization, these
21tags trigger the execution of optimization steps, which in turn may emit these
22tags to execute other steps.
23
24"""
25
26
27allowed_tags = (
28    # New code means new statements.
29    # Could be a new module, or an inlined exec statement.
30    "new_code",
31    # Added new import.
32    "new_import",
33    # New statements added, removed.
34    "new_statements",
35    # New expression added.
36    "new_expression",
37    # Loop analysis is incomplete, or only just now completed.
38    "loop_analysis",
39    # TODO: A bit unclear what this it, potentially a changed variable.
40    "var_usage",
41    # Detected module variable to be read only.
42    "read_only_mvar",
43    # New built-in reference detected.
44    "new_builtin_ref",
45    # New built-in call detected.
46    "new_builtin",
47    # New raise statement detected.
48    "new_raise",
49    # New constant introduced.
50    "new_constant",
51)
52
53
54class TagSet(set):
55    def onSignal(self, signal):
56        if type(signal) is str:
57            signal = signal.split()
58
59        for tag in signal:
60            self.add(tag)
61
62    def check(self, tags):
63        for tag in tags.split():
64            assert tag in allowed_tags, tag
65
66            if tag in self:
67                return True
68        return False
69
70    def add(self, tag):
71        assert tag in allowed_tags, tag
72
73        set.add(self, tag)
74