aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2019-12-03 23:34:47 -0500
committerXavier Claessens <xclaesse@gmail.com>2019-12-04 16:45:56 -0500
commit9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d (patch)
tree07868682f01264aad85710ee28fa19a9f711c37a /mesonbuild
parentb1c8f765fa6e2af0d185d2a20dc68c7567c916eb (diff)
downloadmeson-9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d.zip
meson-9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d.tar.gz
meson-9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d.tar.bz2
dict: Fully evaluate keys
The only restriction is keys must be string after evaluation. This fix various inconsistencies.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/interpreterbase.py25
-rw-r--r--mesonbuild/mparser.py14
2 files changed, 15 insertions, 24 deletions
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index 46f578e..2a976d3 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -496,7 +496,19 @@ class InterpreterBase:
def evaluate_dictstatement(self, cur):
(arguments, kwargs) = self.reduce_arguments(cur.args)
assert (not arguments)
- return kwargs
+ result = {}
+ self.argument_depth += 1
+ for key, value in kwargs.items():
+ if not isinstance(key, mparser.StringNode):
+ FeatureNew('Dictionary entry using non literal key', '0.53.0').use(self.subproject)
+ key = self.evaluate_statement(key)
+ if not isinstance(key, str):
+ raise InvalidArguments('Key must be a string')
+ if key in result:
+ raise InvalidArguments('Duplicate dictionary key: {}'.format(key))
+ result[key] = value
+ self.argument_depth -= 1
+ return result
def evaluate_notstatement(self, cur):
v = self.evaluate_statement(cur.value)
@@ -731,16 +743,7 @@ The result of this is undefined and will become a hard error in a future Meson r
elif isinstance(old_variable, dict):
if not isinstance(addition, dict):
raise InvalidArguments('The += operator requires a dict on the right hand side if the variable on the left is a dict')
- new_addition = {}
- for (key, value) in addition.items():
- if isinstance(key, str):
- new_addition[key] = value
- elif isinstance(key, mparser.IdNode) and isinstance(self.get_variable(key.value), str):
- FeatureNew('Adding dictionary entry using string variable as key', '0.53.0').use(self.subproject)
- new_addition[self.get_variable(key.value)] = value
- else:
- raise InvalidArguments('Dictionary key must be a string or string variable')
- new_value = {**old_variable, **new_addition}
+ new_value = {**old_variable, **addition}
# Add other data types here.
else:
raise InvalidArguments('The += operator currently only works with arrays, dicts, strings or ints ')
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index 80ffefd..76ad374 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -676,19 +676,7 @@ class Parser:
while not isinstance(s, EmptyNode):
potential = self.current
if self.accept('colon'):
- key_value = self.statement()
- if isinstance(s, StringNode):
- if s.value in a.kwargs:
- # + 1 to colno to point to the actual string, not the opening quote
- raise ParseException('Duplicate dictionary key: {}'.format(s.value), self.getline(), s.lineno, s.colno + 1)
- a.set_kwarg(s.value, key_value)
- elif isinstance(s, IdNode) and isinstance(s.value, str):
- for key in a.kwargs:
- if s.value == key.value:
- raise ParseException('Duplicate dictionary variable key: {}'.format(s.value), self.getline(), s.lineno, s.colno)
- a.set_kwarg(s, key_value)
- else:
- raise ParseException('Key must be a string or string variable', self.getline(), s.lineno, s.colno)
+ a.set_kwarg(s, self.statement())
potential = self.current
if not self.accept('comma'):
return a