From 75b7a856cd7a5fc8af697584aec453c82c7c923d Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 20 Apr 2019 23:02:03 +0200 Subject: ast: support elementary object methods --- mesonbuild/ast/interpreter.py | 46 ++++++++++++++++++++++++---- mesonbuild/interpreter.py | 18 ----------- mesonbuild/interpreterbase.py | 18 +++++++++++ test cases/unit/55 introspection/meson.build | 5 ++- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py index 6db9d41..bef1296 100644 --- a/mesonbuild/ast/interpreter.py +++ b/mesonbuild/ast/interpreter.py @@ -20,7 +20,20 @@ from .. import interpreterbase, mparser, mesonlib from .. import environment from ..interpreterbase import InvalidArguments, BreakRequest, ContinueRequest -from ..mparser import BaseNode, ElementaryNode, IdNode, ArgumentNode, ArrayNode, ArithmeticNode, AssignmentNode, PlusAssignmentNode, TernaryNode, EmptyNode +from ..mparser import ( + ArgumentNode, + ArithmeticNode, + ArrayNode, + AssignmentNode, + BaseNode, + ElementaryNode, + EmptyNode, + IdNode, + MethodNode, + PlusAssignmentNode, + TernaryNode, + StringNode, +) import os, sys from typing import List, Any, Optional @@ -185,10 +198,12 @@ class AstInterpreter(interpreterbase.InterpreterBase): pass def reduce_arguments(self, args): - assert(isinstance(args, ArgumentNode)) - if args.incorrect_order(): - raise InvalidArguments('All keyword arguments must be after positional arguments.') - return args.arguments, args.kwargs + if isinstance(args, ArgumentNode): + if args.incorrect_order(): + raise InvalidArguments('All keyword arguments must be after positional arguments.') + return self.flatten_args(args.arguments), args.kwargs + else: + return self.flatten_args(args), {} def evaluate_comparison(self, node): self.evaluate_statement(node.left) @@ -258,6 +273,25 @@ class AstInterpreter(interpreterbase.InterpreterBase): else: args = self.flatten_args(l) + self.flatten_args(r) + elif isinstance(args, MethodNode): + src = quick_resolve(args.source_object) + margs = self.flatten_args(args.args) + try: + if isinstance(src, str): + args = [self.string_method_call(src, args.name, margs)] + elif isinstance(src, bool): + args = [self.bool_method_call(src, args.name, margs)] + elif isinstance(src, int): + args = [self.int_method_call(src, args.name, margs)] + elif isinstance(src, list): + args = [self.array_method_call(src, args.name, margs)] + elif isinstance(src, dict): + args = [self.dict_method_call(src, args.name, margs)] + else: + return [] + except Exception: + return [] + # Make sure we are always dealing with lists if not isinstance(args, list): args = [args] @@ -266,7 +300,7 @@ class AstInterpreter(interpreterbase.InterpreterBase): for i in args: if isinstance(i, IdNode): flattend_args += self.flatten_args(quick_resolve(i), include_unknown_args) - elif isinstance(i, (ArrayNode, ArgumentNode, ArithmeticNode)): + elif isinstance(i, (ArrayNode, ArgumentNode, ArithmeticNode, MethodNode)): flattend_args += self.flatten_args(i, include_unknown_args) elif isinstance(i, mparser.ElementaryNode): flattend_args += [i.value] diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index b107a25..8ca7758 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -4076,24 +4076,6 @@ This will become a hard error in the future.''', location=self.current_node) if not os.path.isfile(fname): raise InterpreterException('Tried to add non-existing source file %s.' % s) - def format_string(self, templ, args): - if isinstance(args, mparser.ArgumentNode): - args = args.arguments - arg_strings = [] - for arg in args: - arg = self.evaluate_statement(arg) - if isinstance(arg, bool): # Python boolean is upper case. - arg = str(arg).lower() - arg_strings.append(str(arg)) - - def arg_replace(match): - idx = int(match.group(1)) - if idx >= len(arg_strings): - raise InterpreterException('Format placeholder @{}@ out of range.'.format(idx)) - return arg_strings[idx] - - return re.sub(r'@(\d+)@', arg_replace, templ) - # Only permit object extraction from the same subproject def validate_extraction(self, buildtarget): if not self.subdir.startswith(self.subproject_dir): diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 650d1e0..c148cbd 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -920,6 +920,24 @@ The result of this is undefined and will become a hard error in a future Meson r return mesonlib.version_compare(obj, cmpr) raise InterpreterException('Unknown method "%s" for a string.' % method_name) + def format_string(self, templ, args): + if isinstance(args, mparser.ArgumentNode): + args = args.arguments + arg_strings = [] + for arg in args: + arg = self.evaluate_statement(arg) + if isinstance(arg, bool): # Python boolean is upper case. + arg = str(arg).lower() + arg_strings.append(str(arg)) + + def arg_replace(match): + idx = int(match.group(1)) + if idx >= len(arg_strings): + raise InterpreterException('Format placeholder @{}@ out of range.'.format(idx)) + return arg_strings[idx] + + return re.sub(r'@(\d+)@', arg_replace, templ) + def unknown_function_called(self, func_name): raise InvalidCode('Unknown function "%s".' % func_name) diff --git a/test cases/unit/55 introspection/meson.build b/test cases/unit/55 introspection/meson.build index 5dd1b33..7ee11a8 100644 --- a/test cases/unit/55 introspection/meson.build +++ b/test cases/unit/55 introspection/meson.build @@ -21,12 +21,11 @@ subdir('sharedlib') subdir('staticlib') var1 = '1' -var2 = '2' +var2 = 2.to_string() var3 = 'test3' t1 = executable('test' + var1, ['t1.cpp'], link_with: [sharedlib], install: true, build_by_default: get_option('test_opt2')) -#t2 = executable('test@0@'.format('' + '@0@'.format(var2)), 't2.cpp', link_with: [staticlib]) -t2 = executable('test2', 't2.cpp', link_with: [staticlib]) +t2 = executable('test@0@'.format('@0@'.format(var2)), 't2.cpp', link_with: [staticlib]) t3 = executable(var3, 't3.cpp', link_with: [sharedlib, staticlib], dependencies: [dep1]) test('test case 1', t1) -- cgit v1.1