diff --git a/data/syntax-highlighting/vim/syntax/meson.vim b/data/syntax-highlighting/vim/syntax/meson.vim index 215a3b77f..15f523258 100644 --- a/data/syntax-highlighting/vim/syntax/meson.vim +++ b/data/syntax-highlighting/vim/syntax/meson.vim @@ -3,7 +3,7 @@ " License: VIM License " Maintainer: Nirbheek Chauhan " Liam Beguin -" Last Change: 2016 Dec 7 +" Last Change: 2021 Aug 16 " Credits: Zvezdan Petkovic " Neil Schemenauer " Dmitry Vasiliev @@ -118,6 +118,7 @@ syn keyword mesonBuiltin \ summary \ target_machine \ test + \ unset_variable \ vcs_tag \ warning \ range diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 81a6daf74..6454830ca 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -1852,6 +1852,17 @@ Defined tests can be run in a backend-agnostic way by calling `meson test` inside the build dir, or by using backend-specific commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`. +### unset_variable() + +*(since 0.60.0)* + +```meson + void unset_variable(varname) +``` + +Unsets a variable. Referencing a variable which has been unset is an error until +it has been set again. + ### vcs_tag() ``` meson diff --git a/docs/markdown/snippets/unset_variable.md b/docs/markdown/snippets/unset_variable.md new file mode 100644 index 000000000..7b2bcdbbe --- /dev/null +++ b/docs/markdown/snippets/unset_variable.md @@ -0,0 +1,16 @@ +## `unset_variable()` + +`unset_variable()` can be used to unset a variable. Reading a variable after +calling `unset_variable()` will raise an exception unless the variable is set +again. + +```meson +# tests/meson.build +tests = ['test1', 'test2'] + +# ... + +unset_variable('tests') + +# tests is no longer usable until it is set again +``` diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py index 19b3a1d21..029901419 100644 --- a/mesonbuild/ast/interpreter.py +++ b/mesonbuild/ast/interpreter.py @@ -127,6 +127,7 @@ class AstInterpreter(InterpreterBase): 'subdir': self.func_subdir, 'set_variable': self.func_do_nothing, 'get_variable': self.func_do_nothing, + 'unset_variable': self.func_do_nothing, 'is_disabler': self.func_do_nothing, 'is_variable': self.func_do_nothing, 'disabler': self.func_do_nothing, diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index b527115cc..ab7efa0cd 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -360,6 +360,7 @@ class Interpreter(InterpreterBase, HoldableObject): 'static_library': self.func_static_lib, 'both_libraries': self.func_both_lib, 'test': self.func_test, + 'unset_variable': self.func_unset_variable, 'vcs_tag': self.func_vcs_tag, 'range': self.func_range, }) @@ -2638,6 +2639,16 @@ This will become a hard error in the future.''', location=self.current_node) def func_is_variable(self, node: mparser.BaseNode, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> bool: return args[0] in self.variables + @FeatureNew('unset_variable', '0.60.0') + @typed_pos_args('unset_variable', str) + @noKwargs + def func_unset_variable(self, node: mparser.BaseNode, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> None: + varname = args[0] + try: + del self.variables[varname] + except KeyError: + raise InterpreterException(f'Tried to unset unknown variable "{varname}".') + @staticmethod def machine_from_native_kwarg(kwargs: T.Dict[str, T.Any]) -> MachineChoice: native = kwargs.get('native', False) diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py index 115e24be0..f0668e417 100644 --- a/mesonbuild/interpreterbase/interpreterbase.py +++ b/mesonbuild/interpreterbase/interpreterbase.py @@ -542,7 +542,7 @@ The result of this is undefined and will become a hard error in a future Meson r func_name = node.func_name (h_posargs, h_kwargs) = self.reduce_arguments(node.args) (posargs, kwargs) = self._unholder_args(h_posargs, h_kwargs) - if is_disabled(posargs, kwargs) and func_name not in {'get_variable', 'set_variable', 'is_disabler'}: + if is_disabled(posargs, kwargs) and func_name not in {'get_variable', 'set_variable', 'unset_variable', 'is_disabler'}: return Disabler() if func_name in self.funcs: func = self.funcs[func_name] diff --git a/test cases/common/244 variable scope/meson.build b/test cases/common/244 variable scope/meson.build new file mode 100644 index 000000000..e5e797387 --- /dev/null +++ b/test cases/common/244 variable scope/meson.build @@ -0,0 +1,15 @@ +project('variable scope') + +x = 1 + +assert(is_variable('x')) + +assert(get_variable('x') == 1) + +set_variable('x', 10) + +assert(get_variable('x') == 10) + +unset_variable('x') + +assert(not is_variable('x'))