plcopen/plcopen.py
changeset 1281 47131e3388f4
parent 1276 29bfd39e8e7a
child 1283 f3cfe1ff917e
equal deleted inserted replaced
1279:0eb9f8af479f 1281:47131e3388f4
   500         self.CustomBlockTypes.append(block_infos)
   500         self.CustomBlockTypes.append(block_infos)
   501     setattr(cls, "AddCustomBlockType", AddCustomBlockType)
   501     setattr(cls, "AddCustomBlockType", AddCustomBlockType)
   502 
   502 
   503     def AddElementUsingTreeInstance(self, name, type_infos):
   503     def AddElementUsingTreeInstance(self, name, type_infos):
   504         typename = type_infos.getname()
   504         typename = type_infos.getname()
   505         if not self.ElementUsingTree.has_key(typename):
   505         elements = self.ElementUsingTree.setdefault(typename, set())
   506             self.ElementUsingTree[typename] = [name]
   506         elements.add(name)
   507         elif name not in self.ElementUsingTree[typename]:
       
   508             self.ElementUsingTree[typename].append(name)
       
   509     setattr(cls, "AddElementUsingTreeInstance", AddElementUsingTreeInstance)
   507     setattr(cls, "AddElementUsingTreeInstance", AddElementUsingTreeInstance)
   510     
   508     
   511     def RefreshElementUsingTree(self):
   509     def RefreshElementUsingTree(self):
   512         # Reset the tree of user-defined element cross-use
   510         # Reset the tree of user-defined element cross-use
   513         self.ElementUsingTree = {}
   511         self.ElementUsingTree = {}
   516         # Analyze each datatype
   514         # Analyze each datatype
   517         for datatype in datatypes:
   515         for datatype in datatypes:
   518             name = datatype.getname()
   516             name = datatype.getname()
   519             basetype_content = datatype.baseType.getcontent()
   517             basetype_content = datatype.baseType.getcontent()
   520             if basetype_content["name"] == "derived":
   518             if basetype_content["name"] == "derived":
   521                 typename = basetype_content["value"].getname()
   519                 self.AddElementUsingTreeInstance(name,
   522                 if name in self.ElementUsingTree[typename]:
   520                                                  basetype_content["value"])
   523                     self.ElementUsingTree[typename].append(name)
       
   524             elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]:
   521             elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]:
   525                 base_type = basetype_content["value"].baseType.getcontent()
   522                 base_type = basetype_content["value"].baseType.getcontent()
   526                 if base_type["name"] == "derived":
   523                 if base_type["name"] == "derived":
   527                     self.AddElementUsingTreeInstance(name, base_type["value"])
   524                     self.AddElementUsingTreeInstance(name, base_type["value"])
   528             elif basetype_content["name"] == "struct":
   525             elif basetype_content["name"] == "struct":
   538                 for type, varlist in pou.getvars():
   535                 for type, varlist in pou.getvars():
   539                     for var in varlist.getvariable():
   536                     for var in varlist.getvariable():
   540                         vartype_content = var.gettype().getcontent()
   537                         vartype_content = var.gettype().getcontent()
   541                         if vartype_content["name"] == "derived":
   538                         if vartype_content["name"] == "derived":
   542                             self.AddElementUsingTreeInstance(name, vartype_content["value"])
   539                             self.AddElementUsingTreeInstance(name, vartype_content["value"])
   543             for typename in self.ElementUsingTree.iterkeys():
       
   544                 if typename != name and pou.hasblock(block_type=typename) and name not in self.ElementUsingTree[typename]:
       
   545                     self.ElementUsingTree[typename].append(name)
       
   546         
   540         
   547     setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree)
   541     setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree)
   548 
   542 
   549     def GetParentType(self, type):
   543     def GetParentType(self, type):
   550         if self.CustomTypeHierarchy.has_key(type):
   544         if self.CustomTypeHierarchy.has_key(type):
   589         return False
   583         return False
   590     setattr(cls, "IsOfType", IsOfType)
   584     setattr(cls, "IsOfType", IsOfType)
   591 
   585 
   592     # Return if pou given by name is used by another pou
   586     # Return if pou given by name is used by another pou
   593     def ElementIsUsed(self, name):
   587     def ElementIsUsed(self, name):
   594         if self.ElementUsingTree.has_key(name):
   588         elements = self.ElementUsingTree.get(name, None)
   595             return len(self.ElementUsingTree[name]) > 0
   589         return elements is not None
   596         return False
       
   597     setattr(cls, "ElementIsUsed", ElementIsUsed)
   590     setattr(cls, "ElementIsUsed", ElementIsUsed)
   598 
   591 
   599     def DataTypeIsDerived(self, name):
   592     def DataTypeIsDerived(self, name):
   600         return name in self.CustomTypeHierarchy.values()
   593         return name in self.CustomTypeHierarchy.values()
   601     setattr(cls, "DataTypeIsDerived", DataTypeIsDerived)
   594     setattr(cls, "DataTypeIsDerived", DataTypeIsDerived)
   602 
   595 
   603     # Return if pou given by name is directly or undirectly used by the reference pou
   596     # Return if pou given by name is directly or undirectly used by the reference pou
   604     def ElementIsUsedBy(self, name, reference):
   597     def ElementIsUsedBy(self, name, reference):
   605         if self.ElementUsingTree.has_key(name):
   598         elements = self.ElementUsingTree.get(name, set())
   606             list = self.ElementUsingTree[name]
   599         # Test if pou is directly used by reference
   607             # Test if pou is directly used by reference
   600         if reference in elements:
   608             if reference in list:
   601             return True
   609                 return True
   602         else:
   610             else:
   603             # Test if pou is undirectly used by reference, by testing if pous
   611                 # Test if pou is undirectly used by reference, by testing if pous 
   604             # that directly use pou is directly or undirectly used by reference
   612                 # that directly use pou is directly or undirectly used by reference
   605             selffn = self.ElementIsUsedBy
   613                 used = False
   606             for element in elements:
   614                 for element in list:
   607                 if selffn(element, reference):
   615                     used |= self.ElementIsUsedBy(element, reference)
   608                     return True
   616                 return used
       
   617         return False
   609         return False
   618     setattr(cls, "ElementIsUsedBy", ElementIsUsedBy)
   610     setattr(cls, "ElementIsUsedBy", ElementIsUsedBy)
   619 
   611 
   620     def GetDataTypeRange(self, type):
   612     def GetDataTypeRange(self, type):
   621         if self.CustomDataTypeRange.has_key(type):
   613         if self.CustomDataTypeRange.has_key(type):
   652                 return customblocktype
   644                 return customblocktype
   653         return None
   645         return None
   654     setattr(cls, "GetCustomBlockType", GetCustomBlockType)
   646     setattr(cls, "GetCustomBlockType", GetCustomBlockType)
   655 
   647 
   656     # Return Block types checking for recursion
   648     # Return Block types checking for recursion
   657     def GetCustomBlockTypes(self, exclude = "", onlyfunctions = False):
   649     def GetCustomBlockTypes(self, exclude = None, onlyfunctions = False):
   658         type = None
   650         if exclude is not None:
   659         if exclude != "":
   651             return [customblocktype for customblocktype in self.CustomBlockTypes
   660             pou = self.getpou(exclude)
   652                 if (customblocktype["type"] != "program"
   661             if pou is not None:
   653                     and customblocktype["name"] != exclude
   662                 type = pou.getpouType()
   654                     and not self.ElementIsUsedBy(exclude, customblocktype["name"])
   663         customblocktypes = []
   655                     and not (onlyfunctions and customblocktype["type"] != "function"))]
   664         for customblocktype in self.CustomBlockTypes:
   656         return [customblocktype for customblocktype in self.CustomBlockTypes
   665             if customblocktype["type"] != "program" and customblocktype["name"] != exclude and not self.ElementIsUsedBy(exclude, customblocktype["name"]) and not (onlyfunctions and customblocktype["type"] != "function"):
   657             if (customblocktype["type"] != "program"
   666                 customblocktypes.append(customblocktype)
   658                 and not (onlyfunctions and customblocktype["type"] != "function"))]
   667         return customblocktypes
       
   668     setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes)
   659     setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes)
   669 
   660 
   670     # Return Function Block types checking for recursion
   661     # Return Function Block types checking for recursion
   671     def GetCustomFunctionBlockTypes(self, exclude = ""):
   662     def GetCustomFunctionBlockTypes(self, exclude = ""):
   672         customblocktypes = []
   663         customblocktypes = []