1# Copyright 2019 The Meson development team
2
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6
7#     http://www.apache.org/licenses/LICENSE-2.0
8
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# This class contains the basic functionality needed to run any interpreter
16# or an interpreter-based tool
17
18from . import AstVisitor
19from .. import mparser
20import typing as T
21
22class AstIndentationGenerator(AstVisitor):
23    def __init__(self):
24        self.level = 0
25
26    def visit_default_func(self, node: mparser.BaseNode) -> None:
27        # Store the current level in the node
28        node.level = self.level
29
30    def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
31        self.visit_default_func(node)
32        self.level += 1
33        node.args.accept(self)
34        self.level -= 1
35
36    def visit_DictNode(self, node: mparser.DictNode) -> None:
37        self.visit_default_func(node)
38        self.level += 1
39        node.args.accept(self)
40        self.level -= 1
41
42    def visit_MethodNode(self, node: mparser.MethodNode) -> None:
43        self.visit_default_func(node)
44        node.source_object.accept(self)
45        self.level += 1
46        node.args.accept(self)
47        self.level -= 1
48
49    def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
50        self.visit_default_func(node)
51        self.level += 1
52        node.args.accept(self)
53        self.level -= 1
54
55    def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
56        self.visit_default_func(node)
57        self.level += 1
58        node.items.accept(self)
59        node.block.accept(self)
60        self.level -= 1
61
62    def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
63        self.visit_default_func(node)
64        for i in node.ifs:
65            i.accept(self)
66        if node.elseblock:
67            self.level += 1
68            node.elseblock.accept(self)
69            self.level -= 1
70
71    def visit_IfNode(self, node: mparser.IfNode) -> None:
72        self.visit_default_func(node)
73        self.level += 1
74        node.condition.accept(self)
75        node.block.accept(self)
76        self.level -= 1
77
78class AstIDGenerator(AstVisitor):
79    def __init__(self):
80        self.counter = {}  # type: T.Dict[str, int]
81
82    def visit_default_func(self, node: mparser.BaseNode) -> None:
83        name = type(node).__name__
84        if name not in self.counter:
85            self.counter[name] = 0
86        node.ast_id = name + '#' + str(self.counter[name])
87        self.counter[name] += 1
88
89class AstConditionLevel(AstVisitor):
90    def __init__(self):
91        self.condition_level = 0
92
93    def visit_default_func(self, node: mparser.BaseNode) -> None:
94        node.condition_level = self.condition_level
95
96    def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
97        self.visit_default_func(node)
98        self.condition_level += 1
99        node.items.accept(self)
100        node.block.accept(self)
101        self.condition_level -= 1
102
103    def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
104        self.visit_default_func(node)
105        for i in node.ifs:
106            i.accept(self)
107        if node.elseblock:
108            self.condition_level += 1
109            node.elseblock.accept(self)
110            self.condition_level -= 1
111
112    def visit_IfNode(self, node: mparser.IfNode) -> None:
113        self.visit_default_func(node)
114        self.condition_level += 1
115        node.condition.accept(self)
116        node.block.accept(self)
117        self.condition_level -= 1
118