diff --git a/interpreter.py b/interpreter.py index 2893b8d95..2d8980438 100644 --- a/interpreter.py +++ b/interpreter.py @@ -738,9 +738,10 @@ class Interpreter(): try: self.evaluate_statement(cur) except Exception as e: - e.lineno = cur.lineno - e.colno = cur.colno - e.file = os.path.join(self.subdir, 'meson.build') + if not(hasattr(e, 'lineno')): + e.lineno = cur.lineno + e.colno = cur.colno + e.file = os.path.join(self.subdir, 'meson.build') raise e i += 1 # In THE FUTURE jump over blocks and stuff. @@ -1438,11 +1439,34 @@ class Interpreter(): obj = obj.get_value() if isinstance(obj, str): return self.string_method_call(obj, method_name, args) + if isinstance(obj, list): + return self.array_method_call(obj, method_name, self.reduce_arguments(args)[0]) if not isinstance(obj, InterpreterObject): raise InvalidArguments('Variable "%s" is not callable.' % object_name) (args, kwargs) = self.reduce_arguments(args) return obj.method_call(method_name, args, kwargs) + def array_method_call(self, obj, method_name, args): + if method_name == 'contains': + return self.check_contains(obj, args) + raise InterpreterException('Arrays do not have a method called "%s".' % method_name) + + def check_contains(self, obj, args): + if len(args) != 1: + raise InterpreterException('Contains method takes exactly one argument.') + item = args[0] + for element in obj: + if isinstance(element, list): + found = self.check_contains(element, args) + if found: + return True + try: + if element == item: + return True + except Exception: + pass + return False + def evaluate_if(self, node): assert(isinstance(node, mparser.IfClauseNode)) for i in node.ifs: diff --git a/test cases/common/63 array methods/meson.build b/test cases/common/63 array methods/meson.build new file mode 100644 index 000000000..cdda41dbf --- /dev/null +++ b/test cases/common/63 array methods/meson.build @@ -0,0 +1,46 @@ +project('array methods', 'c') + +empty = [] +one = ['abc'] +two = ['def', 'ghi'] +combined = [empty, one, two] + +if empty.contains('abc') + error('Empty is not empty.') +endif + +if one.contains('a') + error('One claims to contain a') +endif + +if not one.contains('abc') + error('One claims to not contain abc.') +endif + +if one.contains('abcd') + error('One claims to contain abcd.') +endif + +if two.contains('abc') + error('Two claims to contain abc.') +endif + +if not two.contains('def') + error('Two claims not to contain def.') +endif + +if not two.contains('ghi') + error('Two claims not to contain ghi.') +endif + +if two.contains('defg') + error('Two claims to contain defg.') +endif + +if not combined.contains('abc') + error('Combined claims not to contain abc.') +endif + +if not combined.contains('ghi') + error('Combined claims not to contain ghi.') +endif