diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2020-08-14 17:41:18 -0400 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2020-09-02 12:55:31 -0400 |
commit | 9365486104dc66ee05d5bfaf97a0e83ce9d1289d (patch) | |
tree | 778b787e9973e3b0eab2bf80903a2e77aeca3634 /mesonbuild/interpreterbase.py | |
parent | bfb8d25deb794e9506775caa023bbf278dcf17e1 (diff) | |
download | meson-9365486104dc66ee05d5bfaf97a0e83ce9d1289d.zip meson-9365486104dc66ee05d5bfaf97a0e83ce9d1289d.tar.gz meson-9365486104dc66ee05d5bfaf97a0e83ce9d1289d.tar.bz2 |
Special case meson.version().version_compare() statement
when that statement gets evaluated, the interpreter remembers the
version target and if it was part of the evaluation of a `if` condition
then the target meson version is temporally overriden within that
if-block.
Fixes: #7590
Diffstat (limited to 'mesonbuild/interpreterbase.py')
-rw-r--r-- | mesonbuild/interpreterbase.py | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 6c4f273..e071243 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -54,6 +54,9 @@ TYPE_var = T.Union[TYPE_elementary, list, dict, InterpreterObject, ObjectHolder] TYPE_nvar = T.Union[TYPE_var, mparser.BaseNode] TYPE_nkwargs = T.Dict[T.Union[mparser.BaseNode, str], TYPE_nvar] +class MesonVersionString(str): + pass + # Decorators for method calls. def check_stringlist(a: T.Any, msg: str = 'Arguments must be strings.') -> None: @@ -451,6 +454,11 @@ class InterpreterBase: # Current node set during a function call. This can be used as location # when printing a warning message during a method call. self.current_node = None # type: mparser.BaseNode + # This is set to `version_string` when this statement is evaluated: + # meson.version().compare_version(version_string) + # If it was part of a if-clause, it is used to temporally override the + # current meson version target within that if-block. + self.tmp_meson_version = None # type: str def load_root_meson_file(self) -> None: mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) @@ -606,13 +614,22 @@ class InterpreterBase: def evaluate_if(self, node: mparser.IfClauseNode) -> T.Optional[Disabler]: assert(isinstance(node, mparser.IfClauseNode)) for i in node.ifs: + # Reset self.tmp_meson_version to know if it gets set during this + # statement evaluation. + self.tmp_meson_version = None result = self.evaluate_statement(i.condition) if isinstance(result, Disabler): return result if not(isinstance(result, bool)): raise InvalidCode('If clause {!r} does not evaluate to true or false.'.format(result)) if result: - self.evaluate_codeblock(i.block) + prev_meson_version = mesonlib.project_meson_versions[self.subproject] + if self.tmp_meson_version: + mesonlib.project_meson_versions[self.subproject] = self.tmp_meson_version + try: + self.evaluate_codeblock(i.block) + finally: + mesonlib.project_meson_versions[self.subproject] = prev_meson_version return None if not isinstance(node.elseblock, mparser.EmptyNode): self.evaluate_codeblock(node.elseblock) @@ -1023,6 +1040,8 @@ The result of this is undefined and will become a hard error in a future Meson r cmpr = posargs[0] if not isinstance(cmpr, str): raise InterpreterException('Version_compare() argument must be a string.') + if isinstance(obj, MesonVersionString): + self.tmp_meson_version = cmpr return mesonlib.version_compare(obj, cmpr) elif method_name == 'substring': if len(posargs) > 2: |