aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/ast/interpreter.py
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2019-09-04 22:27:40 +0200
committerDylan Baker <dylan@pnwbakers.com>2019-09-04 15:05:41 -0700
commitbd37147b4b46081c58e0b15f6a0f0123099b27b1 (patch)
treec24d6a2ef591819f7e9c37e34a5329649381474b /mesonbuild/ast/interpreter.py
parent51a601c2ee9717381ef6574c9ca5ccfc583c930e (diff)
downloadmeson-bd37147b4b46081c58e0b15f6a0f0123099b27b1.zip
meson-bd37147b4b46081c58e0b15f6a0f0123099b27b1.tar.gz
meson-bd37147b4b46081c58e0b15f6a0f0123099b27b1.tar.bz2
mintro: Fix resolving nodes in kwargs (fixes #5884)
Diffstat (limited to 'mesonbuild/ast/interpreter.py')
-rw-r--r--mesonbuild/ast/interpreter.py108
1 files changed, 66 insertions, 42 deletions
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index 6684ca4..4d810fc 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -245,7 +245,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.reverse_assignment[node.value.ast_id] = node
self.assign_vals[node.var_name] = [self.evaluate_statement(node.value)] # Evaluate the value just in case
- def flatten_args(self, args: Any, include_unknown_args: bool = False, id_loop_detect: Optional[List[str]] = None) -> List[str]:
+ def resolve_node(self, node: BaseNode, include_unknown_args: bool = False, id_loop_detect: Optional[List[str]] = None) -> Optional[Any]:
def quick_resolve(n: BaseNode, loop_detect: Optional[List[str]] = None) -> Any:
if loop_detect is None:
loop_detect = []
@@ -260,74 +260,98 @@ class AstInterpreter(interpreterbase.InterpreterBase):
if id_loop_detect is None:
id_loop_detect = []
- flattend_args = []
+ result = None
+
+ if not isinstance(node, BaseNode):
+ return None
+
+ assert(hasattr(node, 'ast_id'))
+ if node.ast_id in id_loop_detect:
+ return None # Loop detected
+ id_loop_detect += [node.ast_id]
- if isinstance(args, BaseNode):
- assert(hasattr(args, 'ast_id'))
- if args.ast_id in id_loop_detect:
- return [] # Loop detected
- id_loop_detect += [args.ast_id]
+ # Try to evealuate the value of the node
+ if isinstance(node, IdNode):
+ result = quick_resolve(node)
- if isinstance(args, ArrayNode):
- args = [x for x in args.args.arguments]
+ elif isinstance(node, ElementaryNode):
+ result = node.value
- elif isinstance(args, ArgumentNode):
- args = [x for x in args.arguments]
+ elif isinstance(node, ArrayNode):
+ result = [x for x in node.args.arguments]
- elif isinstance(args, ArithmeticNode):
- if args.operation != 'add':
- return [] # Only handle string and array concats
- l = quick_resolve(args.left)
- r = quick_resolve(args.right)
+ elif isinstance(node, ArgumentNode):
+ result = [x for x in node.arguments]
+
+ elif isinstance(node, ArithmeticNode):
+ if node.operation != 'add':
+ return None # Only handle string and array concats
+ l = quick_resolve(node.left)
+ r = quick_resolve(node.right)
if isinstance(l, str) and isinstance(r, str):
- args = [l + r] # String concatination detected
+ result = l + r # String concatination detected
else:
- args = self.flatten_args(l, include_unknown_args, id_loop_detect) + self.flatten_args(r, include_unknown_args, id_loop_detect)
+ result = self.flatten_args(l, include_unknown_args, id_loop_detect) + self.flatten_args(r, include_unknown_args, id_loop_detect)
- elif isinstance(args, MethodNode):
- src = quick_resolve(args.source_object)
- margs = self.flatten_args(args.args, include_unknown_args, id_loop_detect)
+ elif isinstance(node, MethodNode):
+ src = quick_resolve(node.source_object)
+ margs = self.flatten_args(node.args, include_unknown_args, id_loop_detect)
try:
if isinstance(src, str):
- args = [self.string_method_call(src, args.name, margs)]
+ result = self.string_method_call(src, node.name, margs)
elif isinstance(src, bool):
- args = [self.bool_method_call(src, args.name, margs)]
+ result = self.bool_method_call(src, node.name, margs)
elif isinstance(src, int):
- args = [self.int_method_call(src, args.name, margs)]
+ result = self.int_method_call(src, node.name, margs)
elif isinstance(src, list):
- args = [self.array_method_call(src, args.name, margs)]
+ result = self.array_method_call(src, node.name, margs)
elif isinstance(src, dict):
- args = [self.dict_method_call(src, args.name, margs)]
- else:
- return []
+ result = self.dict_method_call(src, node.name, margs)
except mesonlib.MesonException:
- return []
+ return None
+
+ # Ensure that the result is fully resolved (no more nodes)
+ if isinstance(result, BaseNode):
+ result = self.resolve_node(result, include_unknown_args, id_loop_detect)
+ elif isinstance(result, list):
+ new_res = []
+ for i in result:
+ if isinstance(i, BaseNode):
+ resolved = self.resolve_node(i, include_unknown_args, id_loop_detect)
+ if resolved is not None:
+ new_res += self.flatten_args(resolved, include_unknown_args, id_loop_detect)
+ else:
+ new_res += [i]
+ result = new_res
+
+ return result
+ def flatten_args(self, args: Any, include_unknown_args: bool = False, id_loop_detect: Optional[List[str]] = None) -> List[Any]:
# Make sure we are always dealing with lists
if not isinstance(args, list):
args = [args]
+ flattend_args = []
+
# Resolve the contents of args
for i in args:
- if isinstance(i, IdNode):
- flattend_args += self.flatten_args(quick_resolve(i), include_unknown_args, id_loop_detect)
- elif isinstance(i, (ArrayNode, ArgumentNode, ArithmeticNode, MethodNode)):
- flattend_args += self.flatten_args(i, include_unknown_args, id_loop_detect)
- elif isinstance(i, mparser.ElementaryNode):
- flattend_args += [i.value]
- elif isinstance(i, (str, bool, int, float)):
- flattend_args += [i]
- elif include_unknown_args:
+ if isinstance(i, BaseNode):
+ resolved = self.resolve_node(i, include_unknown_args, id_loop_detect)
+ if resolved is not None:
+ if not isinstance(resolved, list):
+ resolved = [resolved]
+ flattend_args += resolved
+ elif isinstance(i, (str, bool, int, float)) or include_unknown_args:
flattend_args += [i]
return flattend_args
def flatten_kwargs(self, kwargs: object, include_unknown_args: bool = False):
flattend_kwargs = {}
for key, val in kwargs.items():
- if isinstance(val, ElementaryNode):
- flattend_kwargs[key] = val.value
- elif isinstance(val, (ArrayNode, ArgumentNode, ArithmeticNode, MethodNode)):
- flattend_kwargs[key] = self.flatten_args(val, include_unknown_args)
+ if isinstance(val, BaseNode):
+ resolved = self.resolve_node(val, include_unknown_args)
+ if resolved is not None:
+ flattend_kwargs[key] = resolved
elif isinstance(val, (str, bool, int, float)) or include_unknown_args:
flattend_kwargs[key] = val
return flattend_kwargs