ast: support elementary object methods

pull/5292/head
Daniel Mensinger 6 years ago
parent feff2630ae
commit 75b7a856cd
No known key found for this signature in database
GPG Key ID: 54DD94C131E277D4
  1. 46
      mesonbuild/ast/interpreter.py
  2. 18
      mesonbuild/interpreter.py
  3. 18
      mesonbuild/interpreterbase.py
  4. 5
      test cases/unit/55 introspection/meson.build

@ -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]

@ -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):

@ -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)

@ -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)

Loading…
Cancel
Save