File size: 4,401 Bytes
10865e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
""" Management of documents for AXDebugging.
"""


import pythoncom
import win32api
from win32com.server.exception import Exception
from win32com.server.util import unwrap

from . import axdebug, codecontainer, contexts, gateways
from .util import RaiseNotImpl, _wrap, _wrap_remove, trace

# def trace(*args):
#       pass


def GetGoodFileName(fname):
    if fname[0] != "<":
        return win32api.GetFullPathName(fname)
    return fname


class DebugDocumentProvider(gateways.DebugDocumentProvider):
    def __init__(self, doc):
        self.doc = doc

    def GetName(self, dnt):
        return self.doc.GetName(dnt)

    def GetDocumentClassId(self):
        return self.doc.GetDocumentClassId()

    def GetDocument(self):
        return self.doc


class DebugDocumentText(
    gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument
):
    _com_interfaces_ = (
        gateways.DebugDocumentInfo._com_interfaces_
        + gateways.DebugDocumentText._com_interfaces_
        + gateways.DebugDocument._com_interfaces_
    )
    _public_methods_ = (
        gateways.DebugDocumentInfo._public_methods_
        + gateways.DebugDocumentText._public_methods_
        + gateways.DebugDocument._public_methods_
    )

    # A class which implements a DebugDocumentText, using the functionality
    # provided by a codeContainer
    def __init__(self, codeContainer):
        gateways.DebugDocumentText.__init__(self)
        gateways.DebugDocumentInfo.__init__(self)
        gateways.DebugDocument.__init__(self)
        self.codeContainer = codeContainer

    def _Close(self):
        self.docContexts = None
        #               self.codeContainer._Close()
        self.codeContainer = None

    # IDebugDocumentInfo
    def GetName(self, dnt):
        return self.codeContainer.GetName(dnt)

    def GetDocumentClassId(self):
        return "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"

    # IDebugDocument has no methods!
    #

    # IDebugDocumentText methods.
    # def GetDocumentAttributes
    def GetSize(self):
        #               trace("GetSize")
        return self.codeContainer.GetNumLines(), self.codeContainer.GetNumChars()

    def GetPositionOfLine(self, cLineNumber):
        return self.codeContainer.GetPositionOfLine(cLineNumber)

    def GetLineOfPosition(self, charPos):
        return self.codeContainer.GetLineOfPosition(charPos)

    def GetText(self, charPos, maxChars, wantAttr):
        # Get all the attributes, else the tokenizer will get upset.
        # XXX - not yet!
        #               trace("GetText", charPos, maxChars, wantAttr)
        cont = self.codeContainer
        attr = cont.GetSyntaxColorAttributes()
        return cont.GetText(), attr

    def GetPositionOfContext(self, context):
        trace("GetPositionOfContext", context)
        context = unwrap(context)
        return context.offset, context.length

    # Return a DebugDocumentContext.
    def GetContextOfPosition(self, charPos, maxChars):
        # Make one
        doc = _wrap(self, axdebug.IID_IDebugDocument)
        rc = self.codeContainer.GetCodeContextAtPosition(charPos)
        return rc.QueryInterface(axdebug.IID_IDebugDocumentContext)


class CodeContainerProvider:
    """An abstract Python class which provides code containers!

    Given a Python file name (as the debugger knows it by) this will
    return a CodeContainer interface suitable for use.

    This provides a simple base imlpementation that simply supports
    a dictionary of nodes and providers.
    """

    def __init__(self):
        self.ccsAndNodes = {}

    def AddCodeContainer(self, cc, node=None):
        fname = GetGoodFileName(cc.fileName)
        self.ccsAndNodes[fname] = cc, node

    def FromFileName(self, fname):
        cc, node = self.ccsAndNodes.get(GetGoodFileName(fname), (None, None))
        #               if cc is None:
        #                       print "FromFileName for %s returning None" % fname
        return cc

    def Close(self):
        for cc, node in self.ccsAndNodes.values():
            try:
                # Must close the node before closing the provider
                # as node may make calls on provider (eg Reset breakpoints etc)
                if node is not None:
                    node.Close()
                cc._Close()
            except pythoncom.com_error:
                pass
        self.ccsAndNodes = {}