super_class_linker.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. from compiler_exceptions import *
  2. from utils import Logger
  3. from visitor import Visitor
  4. class SuperClassLinker(Visitor):
  5. """ Computes the states that must be exited and entered for a specific transition if the system is to make
  6. that transition.
  7. """
  8. def visit_ClassDiagram(self, class_diagram):
  9. for c in class_diagram.classes :
  10. c.accept(self)
  11. def visit_Class(self, c):
  12. # replace super class names by super class objects
  13. for s in c.super_classes:
  14. super_class = None
  15. for clas in c.class_diagram.classes:
  16. if clas.name == s:
  17. super_class = clas
  18. if super_class == None:
  19. Logger.showWarning("Class <" + c.name + "> has undefined super class <" + s + ">.")
  20. else:
  21. c.super_class_objs[s] = super_class
  22. # calculate list of abstract methods
  23. c.abstract_method_names = getClassAbstractMethodNames(c)
  24. # check if <super> tags exist for all inherited classes
  25. for name,obj in c.super_class_objs.iteritems():
  26. if obj:
  27. if name not in c.constructors[0].super_class_parameters:
  28. num_params = len(obj.constructors[0].parameters)
  29. if num_params > 0:
  30. raise CompilerException("Class <" + c.name + "> inherits <" + name + "> and <" + name + ">'s constructor has " + str(num_params) + " parameter(s), but there's no <super> entry for that class in <" + c.name + ">'s constructor.")
  31. def getClassAbstractMethodNames(c):
  32. abstract_method_names = []
  33. non_abstract_method_names = []
  34. for m in c.methods:
  35. if m.isAbstract():
  36. abstract_method_names.append(m.name)
  37. else:
  38. non_abstract_method_names.append(m.name)
  39. for s in c.super_classes:
  40. if s in c.super_class_objs:
  41. super_abstract_method_names = getClassAbstractMethodNames(c.super_class_objs[s])
  42. for m_name in super_abstract_method_names:
  43. if m_name not in non_abstract_method_names:
  44. abstract_method_names.append(m_name)
  45. return abstract_method_names