aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2019-04-20 23:02:03 +0200
committerDaniel Mensinger <daniel@mensinger-ka.de>2019-04-23 09:10:47 +0200
commit75b7a856cd7a5fc8af697584aec453c82c7c923d (patch)
tree7d1563770c95e6dc75fb21f4715053a26d98c067
parentfeff2630ae151f4a89f12f5b19babce605e64d58 (diff)
downloadmeson-75b7a856cd7a5fc8af697584aec453c82c7c923d.zip
meson-75b7a856cd7a5fc8af697584aec453c82c7c923d.tar.gz
meson-75b7a856cd7a5fc8af697584aec453c82c7c923d.tar.bz2
ast: support elementary object methods
-rw-r--r--mesonbuild/ast/interpreter.py46
-rw-r--r--mesonbuild/interpreter.py18
-rw-r--r--mesonbuild/interpreterbase.py18
-rw-r--r--test cases/unit/55 introspection/meson.build5
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)