diff options
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 23 | ||||
-rw-r--r-- | mesonbuild/interpreterbase/interpreterbase.py | 13 | ||||
-rw-r--r-- | test cases/failing/130 invalid ast/meson.build | 3 | ||||
-rw-r--r-- | test cases/failing/130 invalid ast/test.json | 9 |
4 files changed, 41 insertions, 7 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 9e20446..c6602a5 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -525,6 +525,24 @@ class Interpreter(InterpreterBase, HoldableObject): else: raise InterpreterException(f'Module returned a value of unknown type {v!r}.') + def handle_meson_version(self, pv: str, location: mparser.BaseNode) -> None: + if not mesonlib.version_compare(coredata.version, pv): + raise InterpreterException.from_node(f'Meson version is {coredata.version} but project requires {pv}', node=location) + + def handle_meson_version_from_ast(self) -> None: + if not self.ast.lines: + return + project = self.ast.lines[0] + # first line is always project() + if not isinstance(project, mparser.FunctionNode): + return + for kw, val in project.args.kwargs.items(): + assert isinstance(kw, mparser.IdNode), 'for mypy' + if kw.value == 'meson_version': + # mypy does not understand "and isinstance" + if isinstance(val, mparser.StringNode): + self.handle_meson_version(val.value, val) + def get_build_def_files(self) -> mesonlib.OrderedSet[str]: return self.build_def_files @@ -1151,10 +1169,7 @@ class Interpreter(InterpreterBase, HoldableObject): # This needs to be evaluated as early as possible, as meson uses this # for things like deprecation testing. if kwargs['meson_version']: - cv = coredata.version - pv = kwargs['meson_version'] - if not mesonlib.version_compare(cv, pv): - raise InterpreterException(f'Meson version is {cv} but project requires {pv}') + self.handle_meson_version(kwargs['meson_version'], node) mesonlib.project_meson_versions[self.subproject] = kwargs['meson_version'] if os.path.exists(self.option_file): diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py index c8ef303..666045f 100644 --- a/mesonbuild/interpreterbase/interpreterbase.py +++ b/mesonbuild/interpreterbase/interpreterbase.py @@ -16,8 +16,7 @@ # or an interpreter-based tool. from __future__ import annotations -from .. import mparser, mesonlib -from .. import environment +from .. import environment, mparser, mesonlib from .baseobjects import ( InterpreterObject, @@ -103,6 +102,10 @@ class InterpreterBase: # current meson version target within that if-block. self.tmp_meson_version = None # type: T.Optional[str] + def handle_meson_version_from_ast(self, strict: bool = True) -> None: + # do nothing in an AST interpreter + return + def load_root_meson_file(self) -> None: mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) if not os.path.isfile(mesonfile): @@ -114,8 +117,12 @@ class InterpreterBase: assert isinstance(code, str) try: self.ast = mparser.Parser(code, mesonfile).parse() - except mesonlib.MesonException as me: + except mparser.ParseException as me: me.file = mesonfile + # try to detect parser errors from new syntax added by future + # meson versions, and just tell the user to update meson + self.ast = me.ast + self.handle_meson_version_from_ast() raise me def parse_project(self) -> None: diff --git a/test cases/failing/130 invalid ast/meson.build b/test cases/failing/130 invalid ast/meson.build new file mode 100644 index 0000000..06011c2 --- /dev/null +++ b/test cases/failing/130 invalid ast/meson.build @@ -0,0 +1,3 @@ +project('invalid ast crash', meson_version: '0.1.0') + += >%@ diff --git a/test cases/failing/130 invalid ast/test.json b/test cases/failing/130 invalid ast/test.json new file mode 100644 index 0000000..025d50c --- /dev/null +++ b/test cases/failing/130 invalid ast/test.json @@ -0,0 +1,9 @@ +{ + "stdout": [ + { + "match": "re", + "line": "test cases/failing/130 invalid ast/meson.build:1:44: ERROR: Meson version is [0-9.]+ but project requires 0.1.0" + } + ] +} + |