aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/ast
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/ast')
-rw-r--r--mesonbuild/ast/interpreter.py17
-rw-r--r--mesonbuild/ast/introspection.py10
2 files changed, 21 insertions, 6 deletions
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index ce4b93c..b2cd3f5 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -15,12 +15,14 @@
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool.
+from .visitor import AstVisitor
from .. import interpreterbase, mparser, mesonlib
from .. import environment
from ..interpreterbase import InvalidArguments, BreakRequest, ContinueRequest
import os, sys
+from typing import List
class DontCareObject(interpreterbase.InterpreterObject):
pass
@@ -44,10 +46,12 @@ ADD_SOURCE = 0
REMOVE_SOURCE = 1
class AstInterpreter(interpreterbase.InterpreterBase):
- def __init__(self, source_root, subdir):
+ def __init__(self, source_root: str, subdir: str, visitors: List[AstVisitor] = []):
super().__init__(source_root, subdir)
+ self.visitors = visitors
self.visited_subdirs = {}
self.assignments = {}
+ self.reverse_assignment = {}
self.funcs.update({'project': self.func_do_nothing,
'test': self.func_do_nothing,
'benchmark': self.func_do_nothing,
@@ -104,6 +108,11 @@ class AstInterpreter(interpreterbase.InterpreterBase):
def func_do_nothing(self, node, args, kwargs):
return True
+ def load_root_meson_file(self):
+ super().load_root_meson_file()
+ for i in self.visitors:
+ self.ast.accept(i)
+
def func_subdir(self, node, args, kwargs):
args = self.flatten_args(args)
if len(args) != 1 or not isinstance(args[0], str):
@@ -134,6 +143,8 @@ class AstInterpreter(interpreterbase.InterpreterBase):
raise me
self.subdir = subdir
+ for i in self.visitors:
+ codeblock.accept(i)
self.evaluate_codeblock(codeblock)
self.subdir = prev_subdir
@@ -148,6 +159,8 @@ class AstInterpreter(interpreterbase.InterpreterBase):
if node.var_name not in self.assignments:
self.assignments[node.var_name] = []
self.assignments[node.var_name] += [node.value] # Save a reference to the value node
+ if hasattr(node.value, 'ast_id'):
+ self.reverse_assignment[node.value.ast_id] = node
self.evaluate_statement(node.value) # Evaluate the value just in case
def evaluate_indexing(self, node):
@@ -185,6 +198,8 @@ class AstInterpreter(interpreterbase.InterpreterBase):
def assignment(self, node):
assert(isinstance(node, mparser.AssignmentNode))
self.assignments[node.var_name] = [node.value] # Save a reference to the value node
+ if hasattr(node.value, 'ast_id'):
+ self.reverse_assignment[node.value.ast_id] = node
self.evaluate_statement(node.value) # Evaluate the value just in case
def flatten_args(self, args, include_unknown_args: bool = False):
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index b6a523b..0917015 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -34,8 +34,8 @@ class IntrospectionHelper:
class IntrospectionInterpreter(AstInterpreter):
# Interpreter to detect the options without a build directory
# Most of the code is stolen from interperter.Interpreter
- def __init__(self, source_root, subdir, backend, cross_file=None, subproject='', subproject_dir='subprojects', env=None):
- super().__init__(source_root, subdir)
+ def __init__(self, source_root, subdir, backend, visitors=[], cross_file=None, subproject='', subproject_dir='subprojects', env=None):
+ super().__init__(source_root, subdir, visitors=visitors)
options = IntrospectionHelper(cross_file)
self.cross_file = cross_file
@@ -162,9 +162,9 @@ class IntrospectionInterpreter(AstInterpreter):
# Try to resolve the ID and append the node to the queue
id = curr.value
if id in self.assignments and self.assignments[id]:
- node = self.assignments[id][0]
- if isinstance(node, (mparser.ArrayNode, mparser.IdNode, mparser.FunctionNode)):
- srcqueue += [node]
+ tmp_node = self.assignments[id][0]
+ if isinstance(tmp_node, (mparser.ArrayNode, mparser.IdNode, mparser.FunctionNode)):
+ srcqueue += [tmp_node]
if arg_node is None:
continue
elemetary_nodes = list(filter(lambda x: isinstance(x, (str, mparser.StringNode)), arg_node.arguments))