X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Ihm%2FI_MACRO_ETAPE.py;h=c79ae36b93ff930f36b3d4cca0275d979db41b64;hb=36ca867c4099d6a804374b8f6a2b897d9ea69a09;hp=06f71488ec22181bd27b5c6e1d46fa2924eaf262;hpb=d5b080aa968b4d52a638010251b70f043f81748c;p=tools%2Feficas.git diff --git a/Ihm/I_MACRO_ETAPE.py b/Ihm/I_MACRO_ETAPE.py index 06f71488..c79ae36b 100644 --- a/Ihm/I_MACRO_ETAPE.py +++ b/Ihm/I_MACRO_ETAPE.py @@ -32,6 +32,7 @@ from Noyau.N_ASSD import ASSD import Noyau, Validation.V_MACRO_ETAPE from Noyau import N_Exception from Noyau.N_Exception import AsException +import Accas # attention aux imports circulaires # fin import à résorber class MACRO_ETAPE(I_ETAPE.ETAPE): @@ -63,9 +64,13 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): ou leve une exception --> utilisée par ops.POURSUITE et INCLUDE """ + #print "get_contexte_jdc" try: # on essaie de créer un objet JDC auxiliaire avec un contexte initial - context_ini = self.parent.get_contexte_avant(self) + # Attention get_contexte_avant retourne un dictionnaire qui contient + # le contexte courant. Ce dictionnaire est reactualise regulierement. + # Si on veut garder l'etat du contexte fige, il faut en faire une copie. + context_ini = self.parent.get_contexte_avant(self).copy() # Indispensable avant de creer un nouveau JDC CONTEXT.unset_current_step() @@ -80,12 +85,14 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): # En principe si la memorisation est faite au bon moment il n'est pas necessaire # de prendre cette precaution mais ce n'est pas vrai partout. old_recorded_units=self.recorded_units.copy() - self.recorded_units.clear() + #print "get_contexte_jdc",id(self.recorded_units) + #self.recorded_units.clear() - j=self.JdC_aux( procedure=text,cata=self.jdc.cata, - nom=fichier, - context_ini = context_ini, + j=self.JdC_aux( procedure=text, nom=fichier, appli=self.jdc.appli, + cata=self.jdc.cata, + cata_ord_dico=self.jdc.cata_ordonne_dico, + context_ini = context_ini, jdc_pere=self.jdc,etape_include=self, prefix_include=prefix_include, recorded_units=self.recorded_units, @@ -94,6 +101,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): j.analyse() # On récupère les étapes internes (pour validation) self.etapes=j.etapes + self.jdc_aux=j + #print "get_contexte_jdc",id(self.etapes) except: traceback.print_exc() # On force le contexte (etape courante) à self @@ -109,15 +118,19 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): CONTEXT.set_current_step(self) raise Exception("Impossible de relire le fichier\n"+str(j.cr)) - cr=j.report() - if not cr.estvide(): + if not j.isvalid(): # L'INCLUDE n'est pas valide. + # on produit un rapport d'erreurs # On force le contexte (etape courante) à self + cr=j.report() CONTEXT.unset_current_step() CONTEXT.set_current_step(self) - raise Exception("Le fichier include contient des erreurs\n"+str(j.cr)) + raise Exception("Le fichier include contient des erreurs\n"+str(cr)) + # Si aucune erreur rencontrée # On recupere le contexte de l'include verifie + #print "context_ini",j.context_ini + #print "g_context",j.g_context try: j_context=j.get_verif_contexte() except: @@ -125,6 +138,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): CONTEXT.set_current_step(self) raise + #print "context_ini",j.context_ini + # On remplit le dictionnaire des concepts produits inclus # en retirant les concepts présents dans le contexte initial # On ajoute egalement le concept produit dans le sds_dict du parent @@ -140,11 +155,13 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): # On recupere le contexte courant self.current_context=j.current_context self.index_etape_courante=j.index_etape_courante + self.jdc_aux=j # XXX j.supprime() ??? # On rétablit le contexte (etape courante) à self CONTEXT.unset_current_step() CONTEXT.set_current_step(self) + #print "context_ini",self.jdc_aux.context_ini return j_context @@ -153,6 +170,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): Avec la liste des SD qui ont été supprimées, propage la disparition de ces SD dans toutes les étapes et descendants """ + #print "reevalue_sd_jdc" l_sd_supp,l_sd_repl = self.diff_contextes() for sd in l_sd_supp: self.parent.delete_concept_after_etape(self,sd) @@ -222,12 +240,12 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): def supprime_sdprods(self): """ - Fonction: - Lors d'une destruction d'etape, detruit tous les concepts produits + Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits Un opérateur n a qu un concept produit Une procedure n'en a aucun Une macro en a en général plus d'un """ + #print "supprime_sdprods" if not self.is_reentrant() : # l'étape n'est pas réentrante # le concept retourné par l'étape est à supprimer car il était @@ -246,12 +264,118 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.parent.delete_concept(co) # On met g_context à blanc self.g_context={} + + def delete_concept(self,sd): + """ + Fonction : Mettre a jour les mots cles de l etape et eventuellement + le concept produit si reuse suite à la disparition du concept sd + Seuls les mots cles simples MCSIMP font un traitement autre + que de transmettre aux fils + """ + #print "delete_concept",sd + I_ETAPE.ETAPE.delete_concept(self,sd) + for etape in self.etapes: + etape.delete_concept(sd) + + def replace_concept(self,old_sd,sd): + """ + Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse + suite au remplacement du concept old_sd par sd + """ + #print "replace_concept",old_sd,sd + I_ETAPE.ETAPE.replace_concept(self,old_sd,sd) + for etape in self.etapes: + etape.replace_concept(sd) + def change_fichier_init(self,new_fic,text): + """ + Tente de changer le fichier include. Le precedent include est conservé + dans old_xxx + """ + if not hasattr(self,'fichier_ini'): + self.fichier_ini=None + self.fichier_text=None + self.fichier_err="Le fichier n'est pas defini" + self.contexte_fichier_init={} + self.recorded_units={} + self.jdc_aux=None + self.fichier_unite="PasDefini" + import Extensions.jdc_include + self.JdC_aux=Extensions.jdc_include.JdC_include + + self.old_fic = self.fichier_ini + self.old_text = self.fichier_text + self.old_err = self.fichier_err + self.old_context=self.contexte_fichier_init + self.old_units=self.recorded_units + self.old_etapes=self.etapes + self.old_jdc_aux=self.jdc_aux + + self.fichier_ini = new_fic + self.fichier_text=text + + try: + self.make_contexte_include(new_fic,text) + except: + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + self.fichier_err=string.join(l) + raise + + # L'evaluation de text dans un JDC auxiliaire s'est bien passé + # on peut poursuivre le traitement + self.init_modif() + self.state="undetermined" + self.fichier_err=None + # On enregistre la modification de fichier + self.record_unite() + # Le contexte du parent doit etre reinitialise car les concepts produits ont changé + self.parent.reset_context() + + # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression + self.old_contexte_fichier_init=self.old_context + self.reevalue_sd_jdc() + + self.fin_modif() + + def restore_fichier_init(self): + """ + Restaure le fichier init enregistre dans old_xxx + """ + self.fichier_ini=self.old_fic + self.fichier_text=self.old_text + self.fichier_err=self.old_err + self.contexte_fichier_init=self.old_context + self.recorded_units=self.old_units + self.etapes=self.old_etapes + self.jdc_aux=self.old_jdc_aux + + def force_fichier_init(self): + """ + Force le fichier init en erreur + """ + # On conserve la memoire du nouveau fichier + # mais on n'utilise pas les concepts crees par ce fichier + # on met l'etape en erreur : fichier_err=string.join(l) + self.init_modif() + # On enregistre la modification de fichier + self.record_unite() + #self.etapes=[] + self.g_context={} + # Le contexte du parent doit etre reinitialise car les concepts produits ont changé + self.parent.reset_context() + + self.old_contexte_fichier_init=self.old_context + self.contexte_fichier_init={} + self.reevalue_sd_jdc() + + self.fin_modif() + def make_contexte_include(self,fichier,text): """ Cette méthode sert à créer un contexte en interprétant un texte source Python """ + #print "make_contexte_include" # on récupère le contexte d'un nouveau jdc dans lequel on interprete text contexte = self.get_contexte_jdc(fichier,text) if contexte == None : @@ -266,8 +390,9 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro self.contexte_fichier_init = contexte - def reevalue_fichier_init(self): + def reevalue_fichier_init_OBSOLETE(self): """Recalcule les concepts produits par le fichier enregistre""" + #print "reevalue_fichier_init" old_context=self.contexte_fichier_init try: self.make_contexte_include(self.fichier_ini ,self.fichier_text) @@ -286,18 +411,23 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.fichier_err = None self.old_contexte_fichier_init=old_context self.reevalue_sd_jdc() + #print "reevalue_fichier_init",self.jdc_aux.context_ini def update_fichier_init(self,unite): """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur les noms des fichiers Ceci suppose que les relations entre unites et noms ont été memorisees préalablement """ - + #print "update_fichier_init",unite self.fichier_err=None self.old_contexte_fichier_init=self.contexte_fichier_init + old_fichier_ini=self.fichier_ini + + #print "update_fichier_init",self,self.parent,self.parent.recorded_units - if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite): - # Changement d'unite ou Nouvelle unite + #if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite): + if not self.parent.recorded_units.has_key(unite): + # Nouvelle unite f,text=self.get_file(unite=unite,fic_origine=self.parent.nom) units={} if f is not None: @@ -308,7 +438,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus", message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini") else: - # Meme unite existante + # Unite existante f,text,units=self.parent.recorded_units[unite] self.fichier_ini = f self.fichier_text=text @@ -324,6 +454,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.reevalue_sd_jdc() return + if old_fichier_ini == self.fichier_ini: + # Le fichier inclus n'a pas changé. On ne recrée pas le contexte + #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini + return + try: self.make_contexte_include(self.fichier_ini,self.fichier_text) # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects @@ -346,6 +481,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): # Si des concepts ont disparu lors du changement de fichier, on # demande leur suppression self.reevalue_sd_jdc() + #print "update_fichier_init",self.jdc_aux.context_ini def record_unite(self): if self.nom == "POURSUITE": @@ -358,10 +494,18 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): """Retourne le nom du fichier et le source correspondant a l'unite unite Initialise en plus recorded_units """ - units={} + #print "get_file_memo",unite,fic_origine,self,self.parent + #print self.parent.old_recorded_units + #print self.parent.recorded_units + if unite is None: + units={} + else: + units=self.parent.recorded_units if self.parent.old_recorded_units.has_key(unite): f,text,units=self.parent.old_recorded_units[unite] + #print id(self.recorded_units) self.recorded_units=units + #print id(self.recorded_units) return f,text elif self.jdc : f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine) @@ -378,6 +522,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): """Retourne le nom du fichier et le source correspondant a l'unite unite Initialise en plus recorded_units """ + #print "get_file",unite units={} if self.jdc : f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine) @@ -395,7 +540,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): Sinon on retourne None. Les concepts produits par l'INCLUDE sont pris en compte par le JDC parent lors du calcul du contexte (appel de ???) """ - + #print "make_include",unite # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini del self.unite @@ -411,7 +556,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.contexte_fichier_init={} self.fichier_unite=unite self.fichier_err=None - import Extensions.jdc_include + try: + import Extensions.jdc_include + except: + traceback.print_exc() + raise self.JdC_aux=Extensions.jdc_include.JdC_include if f is None: @@ -422,6 +571,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): try: self.make_contexte_include(self.fichier_ini ,self.fichier_text) self.parent.record_unit(unite,self) + #print "make_include.context_ini",self.jdc_aux.context_ini except: l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) if self.jdc.appli: @@ -458,7 +608,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.fichier_err=None self.contexte_fichier_init={} # On specifie la classe a utiliser pour le JDC auxiliaire - import Extensions.jdc_include + try: + import Extensions.jdc_include + except: + traceback.print_exc() + raise self.JdC_aux=Extensions.jdc_include.JdC_include try: self.make_contexte_include(self.fichier_ini ,self.fichier_text) @@ -491,7 +645,6 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): """ try: sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom) - self.state="modified" except AsException,e: # Une erreur s'est produite lors de la construction du concept # Comme on est dans EFICAS, on essaie de poursuivre quand meme @@ -511,6 +664,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): def make_poursuite(self): """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE """ + #print "make_poursuite" if not hasattr(self,'fichier_ini') : # Si le fichier n'est pas defini on le demande f,text=self.get_file_memo(fic_origine=self.parent.nom) @@ -519,7 +673,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.fichier_unite = None self.fichier_text = text self.fichier_err=None - import Extensions.jdc_include + try: + import Extensions.jdc_include + except: + traceback.print_exc() + raise self.JdC_aux=Extensions.jdc_include.JdC_poursuite self.contexte_fichier_init={} @@ -549,3 +707,103 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): self.update_fichier_init(None) if self.fichier_err is not None: raise Exception(self.fichier_err) +#ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro + def type_sdprod(self,co,t): + """ + Cette methode a pour fonction de typer le concept co avec le type t + dans les conditions suivantes + 1- co est un concept produit de self + 2- co est un concept libre : on le type et on l attribue à self + Elle enregistre egalement les concepts produits (on fait l hypothese + que la liste sdprods a été correctement initialisee, vide probablement) + """ + #print "type_sdprod",co,t + if not hasattr(co,'etape'): + # Le concept vaut None probablement. On ignore l'appel + return + # + # On cherche a discriminer les differents cas de typage d'un concept + # produit par une macro qui est specifie dans un mot cle simple. + # On peut passer plusieurs fois par type_sdprod ce qui explique + # le nombre important de cas. + # + # Cas 1 : Le concept est libre. Il vient d'etre cree par CO(nom) + # Cas 2 : Le concept est produit par la macro. On est deja passe par type_sdprod. + # Cas semblable a Cas 1. + # Cas 3 : Le concept est produit par la macro englobante (parent). On transfere + # la propriete du concept de la macro parent a la macro courante (self) + # en verifiant que le type est valide + # Cas 4 : La concept est la propriete d'une etape fille. Ceci veut dire qu'on est + # deja passe par type_sdprod et que la propriete a ete transfere a une + # etape fille. Cas semblable a Cas 3. + # Cas 5 : Le concept est produit par une etape externe a la macro. + # + if co.etape == None: + # Cas 1 : le concept est libre + # On l'attache a la macro et on change son type dans le type demande + # Recherche du mot cle simple associe au concept + mcs=self.get_mcs_with_co(co) + if len(mcs) != 1: + raise AsException("""Erreur interne. +Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co) + mcs=mcs[0] + # + # Attention : la seule modif est ici : Accas.CO au lieu de CO + # + if not Accas.CO in mcs.definition.type: + raise AsException("""Erreur interne. +Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type)) + co.etape=self + co.__class__ = t + self.sdprods.append(co) + + elif co.etape== self: + # Cas 2 : le concept est produit par la macro (self) + # On est deja passe par type_sdprod (Cas 1 ou 3). + # Il suffit de le mettre dans la liste des concepts produits (self.sdprods) + # Le type du concept doit etre coherent avec le type demande (seulement derive) + if not isinstance(co,t): + raise AsException("""Erreur interne. +Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__)) + self.sdprods.append(co) + + elif co.etape== self.parent: + # Cas 3 : le concept est produit par la macro parente (self.parent) + # on transfere la propriete du concept a la macro fille + # et on change le type du concept comme demande + # Au prealable, on verifie que le concept existant (co) est une instance + # possible du type demande (t) + # Cette règle est normalement cohérente avec les règles de vérification des mots-clés + if not isinstance(co,t): + raise AsException(""" +Impossible de changer le type du concept produit (%s) en (%s). +Le type actuel (%s) devrait etre une classe derivee du nouveau type (%s)""" % (co,t,co.__class__,t)) + mcs=self.get_mcs_with_co(co) + if len(mcs) != 1: + raise AsException("""Erreur interne. +Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co) + mcs=mcs[0] + if not Accas.CO in mcs.definition.type: + raise AsException("""Erreur interne. +Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type)) + co.etape=self + # On ne change pas le type car il respecte la condition isinstance(co,t) + #co.__class__ = t + self.sdprods.append(co) + + elif self.issubstep(co.etape): + # Cas 4 : Le concept est propriété d'une sous etape de la macro (self). + # On est deja passe par type_sdprod (Cas 3 ou 1). + # Il suffit de le mettre dans la liste des concepts produits (self.sdprods) + # Le type du concept et t doivent etre derives. + # Il n'y a aucune raison pour que la condition ne soit pas verifiee. + if not isinstance(co,t): + raise AsException("""Erreur interne. +Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__)) + self.sdprods.append(co) + + else: + # Cas 5 : le concept est produit par une autre étape + # On ne fait rien + return +