documents.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. """ Management of documents for AXDebugging.
  2. """
  3. import axdebug, gateways
  4. import pythoncom
  5. from .util import _wrap, _wrap_remove, RaiseNotImpl, trace
  6. from win32com.server.util import unwrap
  7. from . import codecontainer
  8. from . import contexts
  9. from win32com.server.exception import Exception
  10. import win32api, winerror, os, string, sys
  11. #def trace(*args):
  12. # pass
  13. def GetGoodFileName(fname):
  14. if fname[0] != "<":
  15. return win32api.GetFullPathName(fname)
  16. return fname
  17. class DebugDocumentProvider(gateways.DebugDocumentProvider):
  18. def __init__(self, doc):
  19. self.doc = doc
  20. def GetName(self, dnt):
  21. return self.doc.GetName(dnt)
  22. def GetDocumentClassId(self):
  23. return self.doc.GetDocumentClassId()
  24. def GetDocument(self):
  25. return self.doc
  26. class DebugDocumentText(gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument):
  27. _com_interfaces_ = gateways.DebugDocumentInfo._com_interfaces_ + \
  28. gateways.DebugDocumentText._com_interfaces_ + \
  29. gateways.DebugDocument._com_interfaces_
  30. _public_methods_ = gateways.DebugDocumentInfo._public_methods_ + \
  31. gateways.DebugDocumentText._public_methods_ + \
  32. gateways.DebugDocument._public_methods_
  33. # A class which implements a DebugDocumentText, using the functionality
  34. # provided by a codeContainer
  35. def __init__(self, codeContainer):
  36. gateways.DebugDocumentText.__init__(self)
  37. gateways.DebugDocumentInfo.__init__(self)
  38. gateways.DebugDocument.__init__(self)
  39. self.codeContainer = codeContainer
  40. def _Close(self):
  41. self.docContexts = None
  42. # self.codeContainer._Close()
  43. self.codeContainer = None
  44. # IDebugDocumentInfo
  45. def GetName(self, dnt):
  46. return self.codeContainer.GetName(dnt)
  47. def GetDocumentClassId(self):
  48. return "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
  49. # IDebugDocument has no methods!
  50. #
  51. # IDebugDocumentText methods.
  52. # def GetDocumentAttributes
  53. def GetSize(self):
  54. # trace("GetSize")
  55. return self.codeContainer.GetNumLines(), self.codeContainer.GetNumChars()
  56. def GetPositionOfLine(self, cLineNumber):
  57. return self.codeContainer.GetPositionOfLine(cLineNumber)
  58. def GetLineOfPosition(self, charPos):
  59. return self.codeContainer.GetLineOfPosition(charPos)
  60. def GetText(self, charPos, maxChars, wantAttr):
  61. # Get all the attributes, else the tokenizer will get upset.
  62. # XXX - not yet!
  63. # trace("GetText", charPos, maxChars, wantAttr)
  64. cont = self.codeContainer
  65. attr = cont.GetSyntaxColorAttributes()
  66. return cont.GetText(), attr
  67. def GetPositionOfContext(self, context):
  68. trace("GetPositionOfContext", context)
  69. context = unwrap(context)
  70. return context.offset, context.length
  71. # Return a DebugDocumentContext.
  72. def GetContextOfPosition(self, charPos, maxChars):
  73. # Make one
  74. doc = _wrap(self, axdebug.IID_IDebugDocument)
  75. rc = self.codeContainer.GetCodeContextAtPosition(charPos)
  76. return rc.QueryInterface(axdebug.IID_IDebugDocumentContext)
  77. class CodeContainerProvider:
  78. """An abstract Python class which provides code containers!
  79. Given a Python file name (as the debugger knows it by) this will
  80. return a CodeContainer interface suitable for use.
  81. This provides a simple base imlpementation that simply supports
  82. a dictionary of nodes and providers.
  83. """
  84. def __init__(self):
  85. self.ccsAndNodes = {}
  86. def AddCodeContainer(self, cc, node = None):
  87. fname = GetGoodFileName(cc.fileName)
  88. self.ccsAndNodes[fname] = cc, node
  89. def FromFileName(self, fname):
  90. cc, node = self.ccsAndNodes.get(GetGoodFileName(fname), (None, None))
  91. # if cc is None:
  92. # print "FromFileName for %s returning None" % fname
  93. return cc
  94. def Close(self):
  95. for cc, node in self.ccsAndNodes.values():
  96. try:
  97. # Must close the node before closing the provider
  98. # as node may make calls on provider (eg Reset breakpoints etc)
  99. if node is not None:
  100. node.Close()
  101. cc._Close()
  102. except pythoncom.com_error:
  103. pass
  104. self.ccsAndNodes = {}