def evaluate(self, state, local_scope): """ Evaluate this statement. """ var = state.get_ref("variable").value for loop_var in var: # generate a subscope/namespace for each loop object_id = Scope.object_to_name(loop_var) namespace = Namespace(object_id, state.namespace) sub_scope = Scope.get_or_create_scope(state.graph, namespace.to_path()) # add the loop variable to the scope if not isinstance(loop_var, Variable): loop_var = Variable(loop_var) sub_scope.add_variable(self.loop_var, loop_var) # generate the import statement import_stmt = Import(self.module_name) import_stmt.namespace = namespace import_stmt.child_namespace = False child_state = DynamicState(state.compiler, namespace, import_stmt) child_state.add_to_graph(state.graph) state._child_statements[import_stmt] = child_state
def load(self): """ Compile the configuration model """ root_ns = Namespace("__root__") main_ns = Namespace("__config__") main_ns.parent = root_ns # add namespaces to the graph self.graph.add_namespace(root_ns) self._units.append(root_ns) self.graph.add_namespace(main_ns, root_ns) self._units.append(main_ns) self._add_other_ns(root_ns) # load main file cf_file = FileCompileUnit(self, self.__cf_file, main_ns) main_ns.unit = cf_file # load libraries for library in self.__lib_dirs: # TODO: take into account the precedence self.load_libdir(library, root_ns) self.__root_ns = root_ns return root_ns
def load_libdir(self, cf_dir, root_ns): """ Load all libraries located in a directory. @param cf_dir: The directory to get all files from @param root_ns: The root namespace to add the libraries too """ for cf_file in glob.glob(os.path.join(cf_dir, '*')): if os.path.isdir(cf_file) and self._is_cf_module(cf_file): name = os.path.basename(cf_file) namespace = Namespace(name) namespace.parent = root_ns self.graph.add_namespace(namespace, root_ns) self._units.append(namespace) self._load_dir(cf_file, namespace) # check for plugins plugin_path = os.path.join(cf_file, "plugins") if os.path.isdir(os.path.join(cf_file, "plugins")): self._load_plugins(plugin_path, namespace) # register the module self.loaded_modules[name] = cf_file
def _load_dir(self, cf_dir, namespace): """ Create a list of compile units for the given directory @param cf_dir: The directory to get all files from @param namespace: The namespace the files need to be added to """ for cf_file in glob.glob(os.path.join(cf_dir, "model", '*')): file_name = os.path.basename(cf_file) if os.path.isdir(cf_file) and self._is_cf_module(cf_file): # create a new namespace new_ns = Namespace(file_name) new_ns.parent = namespace self.graph.add_namespace(new_ns, namespace) self._units.append(new_ns) self._load_dir(cf_file, new_ns) elif file_name[-3:] == ".cf": if file_name == self.__init_cf: namespace.unit = FileCompileUnit(self, cf_file, namespace) else: new_ns = Namespace(file_name[:-3]) new_ns.parent = namespace self.graph.add_namespace(new_ns, namespace) self._units.append(new_ns) new_ns.unit = FileCompileUnit(self, cf_file, new_ns)
def _add_other_ns(self, root_ns): """ Add the namespace of builtin types and plugins. """ type_ns = Namespace("__types__") plugin_ns = Namespace("__plugins__") type_ns.parent = root_ns plugin_ns.parent = root_ns type_ns.unit = BuiltinCompileUnit(self, type_ns) plugin_ns.unit = PluginCompileUnit(self, plugin_ns) self.graph.add_namespace(type_ns, root_ns) self._units.append(type_ns) self.graph.add_namespace(plugin_ns, root_ns) self._units.append(plugin_ns)
def new_statements(self, state): """ Add any arguments that need to be validated to the graph """ attributes = set() # Set the value from the constructor object_ref = state.get_result_reference() for name, value in self.__attributes.items(): # set the attributes passed with the constructor stmt = SetAttribute(object_ref, name, value) self.copy_location(stmt) stmt.namespace = self.namespace state.add_statement(stmt) attributes.add(name) # Set values defined in default constructors type_class = state.get_type("classtype") if isinstance(type_class, Default): default = type_class type_class = type_class.get_entity() # set default values for attribute_name in type_class.get_all_attribute_names(): attribute = type_class.get_attribute(attribute_name) if attribute.name not in attributes: try: value = default.get_default(attribute.name) stmt = SetAttribute(object_ref, attribute.name, value) self.copy_location(stmt) stmt.namespace = self.namespace state.add_statement(stmt) attributes.add(attribute.name) except AttributeError: pass # Set default values if they have not been set yet for name, value in type_class.get_default_values().items(): if name not in attributes and value is not None: stmt = SetAttribute(object_ref, name, value) self.copy_location(stmt) stmt.namespace = self.namespace state.add_statement(stmt) # Make values of attributes available in subscopes by defining # variables with matching names in the subscope object_id = Scope.object_to_name(state) namespace = Namespace(object_id, state.namespace) scope = Scope.get_or_create_scope(state.graph, namespace.to_path()) added_variables = set() for attribute in type_class.get_all_attribute_names(): if attribute in added_variables: continue var = AttributeVariable.create(object_ref, attribute) self.copy_location(var) added_variables.add(attribute) scope.add_variable(attribute, var) # Set a attributes with low multiplicity == 0 -> set [] attribute_obj = type_class.get_attribute(attribute) if hasattr(attribute_obj, "low") and attribute_obj.low == 0: value = Variable(QList()) stmt = SetAttribute(object_ref, attribute_obj.name, value) self.copy_location(stmt) stmt.namespace = self.namespace state.add_statement(stmt) # set the self variable scope.add_variable("self", object_ref) # now check that all variables that have indexes on them, are already # defined and add the instance to the index for index in type_class._index_def: for attr in index: if attr not in attributes: raise Exception("%s is part of an index and should be set in the constructor." % attr)