X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/bcc25888b3299758ad36721530cca3b899b7166c..c043fa535514a76091be87a45ad472a505f9dd33:/lunaix-os/scripts/build-tools/lbuild/scope.py?ds=sidebyside diff --git a/lunaix-os/scripts/build-tools/lbuild/scope.py b/lunaix-os/scripts/build-tools/lbuild/scope.py new file mode 100644 index 0000000..149aa5a --- /dev/null +++ b/lunaix-os/scripts/build-tools/lbuild/scope.py @@ -0,0 +1,96 @@ +import inspect +from lib.utils import Schema +from .common import DirectoryTracker + +class ScopeProvider: + Enumerables = Schema(Schema.Union(list, tuple)) + Primitives = Schema(Schema.Union(str, int, bool)) + + def __init__(self, name): + super().__init__() + self.name = name + self.__accessors = {} + + def __add_accessor(self, accessor, type): + acc = accessor + if isinstance(accessor, str): + acc = type(accessor) + self.__accessors[acc.name] = acc + + def subscope(self, accessor): + self.__add_accessor(accessor, ScopeAccessor) + + def file_subscope(self, accessor): + self.__add_accessor(accessor, FileScopeAccessor) + + def accessors(self): + return self.__accessors.values() + + def reset(self): + for v in self.__accessors.values(): + v.reset() + + def context_name(self): + return f"__SC{self.name}" + + def __getitem__(self, name): + if name not in self.__accessors: + return None + return self.__accessors[name] + + def __setitem__(self, name, val): + pass + +class ScopeAccessor: + def __init__(self, name): + super().__init__() + self.name = name + self.__values = [] + self._active_context = None + + def values(self): + return self.__values + + def reset(self): + self.__values.clear() + + def add(self, x): + self.__load_build_context() + + if ScopeProvider.Enumerables == x: + for v in x: + self.add(v) + return + + if ScopeProvider.Primitives == x: + self.put_value(x) + return + + raise Exception(f"invalid value '{x}' of type ('{type(x).__name__}')") + + def put_value(self, x): + self.__values.append(x) + + def __load_build_context(self): + self._active_context = None + for f in inspect.stack(): + if "__LBUILD__" not in f.frame.f_globals: + continue + self._active_context = f.frame.f_globals + + if not self._active_context: + raise Exception( + f"unable to modify '{self.name}' outside build context)") + + def __iadd__(self, other): + self.add(other) + +class FileScopeAccessor(ScopeAccessor): + def __init__(self, name): + super().__init__(name) + + def put_value(self, x): + tracker = DirectoryTracker.get(self._active_context) + x = str(tracker.active_relative() / x) + return super().put_value(x) +