interpreter: add a special class to track the lifecycle of get_option() strings

pull/10652/head
Eli Schwartz 2 years ago
parent d395b1a768
commit e19e9ce6f1
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 6
      mesonbuild/interpreter/interpreter.py
  2. 3
      mesonbuild/interpreter/primitives/__init__.py
  3. 27
      mesonbuild/interpreter/primitives/string.py

@ -445,6 +445,7 @@ class Interpreter(InterpreterBase, HoldableObject):
str: P_OBJ.StringHolder,
P_OBJ.MesonVersionString: P_OBJ.MesonVersionStringHolder,
P_OBJ.DependencyVariableString: P_OBJ.DependencyVariableStringHolder,
P_OBJ.OptionString: P_OBJ.OptionStringHolder,
# Meson types
mesonlib.File: OBJ.FileHolder,
@ -1094,6 +1095,8 @@ class Interpreter(InterpreterBase, HoldableObject):
opt.name = optname
return opt
elif isinstance(opt, coredata.UserOption):
if isinstance(opt.value, str):
return P_OBJ.OptionString(opt.value, f'{{{optname}}}')
return opt.value
return opt
@ -2845,6 +2848,9 @@ class Interpreter(InterpreterBase, HoldableObject):
ret = os.path.join(*parts).replace('\\', '/')
if isinstance(parts[0], P_OBJ.DependencyVariableString) and '..' not in other:
return P_OBJ.DependencyVariableString(ret)
elif isinstance(parts[0], P_OBJ.OptionString):
name = os.path.join(parts[0].optname, other)
return P_OBJ.OptionString(ret, name)
else:
return ret

@ -22,5 +22,6 @@ from .range import RangeHolder
from .string import (
StringHolder,
MesonVersionString, MesonVersionStringHolder,
DependencyVariableString, DependencyVariableStringHolder
DependencyVariableString, DependencyVariableStringHolder,
OptionString, OptionStringHolder,
)

@ -157,10 +157,14 @@ class StringHolder(ObjectHolder[str]):
def version_compare_method(self, args: T.Tuple[str], kwargs: TYPE_kwargs) -> bool:
return version_compare(self.held_object, args[0])
@staticmethod
def _op_div(this: str, other: str) -> str:
return os.path.join(this, other).replace('\\', '/')
@FeatureNew('/ with string arguments', '0.49.0')
@typed_operator(MesonOperator.DIV, str)
def op_div(self, other: str) -> str:
return os.path.join(self.held_object, other).replace('\\', '/')
return self._op_div(self.held_object, other)
@typed_operator(MesonOperator.INDEX, int)
def op_index(self, other: int) -> str:
@ -194,3 +198,24 @@ class DependencyVariableStringHolder(StringHolder):
if '..' in other:
return ret
return DependencyVariableString(ret)
class OptionString(str):
optname: str
def __new__(cls, value: str, name: str) -> 'OptionString':
obj = str.__new__(cls, value)
obj.optname = name
return obj
def __getnewargs__(self) -> T.Tuple[str, str]: # type: ignore # because the entire point of this is to diverge
return (str(self), self.optname)
class OptionStringHolder(StringHolder):
held_object: OptionString
def op_div(self, other: str) -> T.Union[str, OptionString]:
ret = super().op_div(other)
name = self._op_div(self.held_object.optname, other)
return OptionString(ret, name)

Loading…
Cancel
Save