aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter/interpreter.py23
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py13
-rw-r--r--test cases/failing/130 invalid ast/meson.build3
-rw-r--r--test cases/failing/130 invalid ast/test.json9
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"
+ }
+ ]
+}
+