~ubuntu-branches/debian/sid/pydoctor/sid

« back to all changes in this revision

Viewing changes to pydoctor/zopeinterface.py

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2013-09-15 13:58:49 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20130915135849-g206zbvqwvz0ptdg
Tags: 0.5b1+bzr603-1
* New upstream snapshot.
* Switch from cdbs to dh.
* Bump standards version to 3.9.4 (no changes).
* Update Vcs header.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
from compiler import ast
5
5
import re
6
6
 
 
7
 
 
8
class ZopeInterfaceModule(model.Module):
 
9
    def setup(self):
 
10
        super(ZopeInterfaceModule, self).setup()
 
11
        self.implements_directly = [] # [name of interface]
 
12
 
 
13
    @property
 
14
    def allImplementedInterfaces(self):
 
15
        """Return all the interfaces provided by this module
 
16
        """
 
17
        return list(self.implements_directly)
 
18
 
 
19
 
7
20
class ZopeInterfaceClass(model.Class):
8
21
    isinterface = False
9
22
    isschemafield = False
45
58
                    r.append(sc.fullName())
46
59
        return r
47
60
 
48
 
class Attribute(model.Documentable):
49
 
    kind = "Attribute"
50
 
    css_class = "attribute"
51
 
    document_in_parent_page = True
52
61
 
53
62
class ZopeInterfaceFunction(model.Function):
54
63
    def docsources(self):
55
64
        for source in super(ZopeInterfaceFunction, self).docsources():
56
65
            yield source
57
 
        if not isinstance(self.parent, model.Class):
 
66
        if not isinstance(self.parent, (model.Class, model.Module)):
58
67
            return
59
68
        for interface in self.parent.allImplementedInterfaces:
60
69
            io = self.system.objForFullName(interface)
61
70
            if io is not None:
62
 
                if self.name in io.contents:
63
 
                    yield io.contents[self.name]
 
71
                for io2 in io.allbases(include_self=True):
 
72
                    if self.name in io2.contents:
 
73
                        yield io2.contents[self.name]
64
74
 
 
75
def addInterfaceInfoToModule(module, interfaceargs):
 
76
    for arg in interfaceargs:
 
77
        if not isinstance(arg, tuple):
 
78
            fullName = module.expandName(ast_pp.pp(arg))
 
79
        else:
 
80
            fullName = arg[1]
 
81
        module.implements_directly.append(fullName)
 
82
        obj = module.system.objForFullName(fullName)
 
83
        if obj is not None:
 
84
            if not obj.isinterface:
 
85
                obj.system.msg(
 
86
                    'zopeinterface',
 
87
                    'probable interface %r not marked as such'%obj,
 
88
                    thresh=1)
 
89
                obj.isinterface = True
 
90
                obj.kind = "Interface"
 
91
                obj.implementedby_directly = []
 
92
            obj.implementedby_directly.append(module.fullName())
65
93
 
66
94
def addInterfaceInfoToClass(cls, interfaceargs, implementsOnly):
67
95
    cls.implementsOnly = implementsOnly
68
96
    if implementsOnly:
69
97
        cls.implements_directly = []
70
98
    for arg in interfaceargs:
71
 
        fullName = cls.dottedNameToFullName(ast_pp.pp(arg))
72
 
        if fullName not in cls.system.allobjects:
73
 
            fullName = cls.system.resolveAlias(fullName)
 
99
        if not isinstance(arg, tuple):
 
100
            fullName = cls.expandName(ast_pp.pp(arg))
 
101
        else:
 
102
            fullName = arg[1]
74
103
        cls.implements_directly.append(fullName)
75
104
        obj = cls.system.objForFullName(fullName)
76
105
        if obj is not None:
112
141
 
113
142
    def funcNameFromCall(self, node):
114
143
        str_base = ast_pp.pp(node.node)
115
 
        return self.builder.current.dottedNameToFullName(str_base)
 
144
        return self.builder.current.expandName(str_base)
116
145
 
117
146
    def visitAssign(self, node):
118
147
        # i would like pattern matching in python please
119
148
        # if match(Assign([AssName(?name, _)], CallFunc(?funcName, [Const(?docstring)])), node):
120
149
        #     ...
121
150
        sup = lambda : super(ZopeInterfaceModuleVisitor, self).visitAssign(node)
122
 
        if isinstance(self.builder.current, model.Module) and \
123
 
               ast_pp.pp(node) == 'Interface = interface.Interface\n':
124
 
            # warner!!!
125
 
 
126
 
            n2fn = self.builder.current._name2fullname
127
 
            n2fn['Interface'] = 'zope.interface.Interface'
128
 
            return sup()
129
151
        if len(node.nodes) != 1 or \
130
152
               not isinstance(node.nodes[0], ast.AssName) or \
131
153
               not isinstance(node.expr, ast.CallFunc):
149
171
            return sup()
150
172
 
151
173
        def pushAttribute(docstring, kind):
152
 
            attr = self.builder._push(Attribute, node.nodes[0].name, docstring)
 
174
            attr = self.builder._push(model.Attribute, node.nodes[0].name, docstring)
153
175
            attr.linenumber = node.lineno
154
176
            attr.kind = kind
155
177
            if attr.parentMod.sourceHref:
156
178
                attr.sourceHref = attr.parentMod.sourceHref + '#L' + \
157
179
                                  str(attr.linenumber)
158
 
            self.builder._pop(Attribute)
 
180
            self.builder._pop(model.Attribute)
159
181
 
160
182
        def extractStringLiteral(node):
161
183
            if isinstance(node, ast.Const) and isinstance(node.value, str):
202
224
        if meth is not None:
203
225
            meth(base, node)
204
226
 
 
227
    def visitCallFunc_zope_interface_moduleProvides(self, funcName, node):
 
228
        if not isinstance(self.builder.current, model.Module):
 
229
            self.default(node)
 
230
            return
 
231
 
 
232
        addInterfaceInfoToModule(self.builder.current, node.args)
 
233
 
205
234
    def visitCallFunc_zope_interface_implements(self, funcName, node):
206
235
        if not isinstance(self.builder.current, model.Class):
207
236
            self.default(node)
211
240
    visitCallFunc_zope_interface_implementsOnly = visitCallFunc_zope_interface_implements
212
241
 
213
242
    def visitCallFunc_zope_interface_classImplements(self, funcName, node):
214
 
        clsname = self.builder.current.dottedNameToFullName(
 
243
        clsname = self.builder.current.expandName(
215
244
            ast_pp.pp(node.args[0]))
216
245
        if clsname not in self.system.allobjects:
217
246
            self.builder.system.msg(
236
265
        for n, o in zip(cls.bases, cls.baseobjects):
237
266
            if schema_prog.match(n) or (o and o.isschemafield):
238
267
                cls.isschemafield = True
 
268
        for ((dn, fn, o), args) in cls.decorators:
 
269
            if fn == 'zope.interface.implementer':
 
270
                addInterfaceInfoToClass(cls, args, False)
239
271
 
240
272
 
241
273
class ZopeInterfaceASTBuilder(astbuilder.ASTBuilder):
243
275
 
244
276
 
245
277
class ZopeInterfaceSystem(model.System):
 
278
    Module = ZopeInterfaceModule
246
279
    Class = ZopeInterfaceClass
247
280
    Function = ZopeInterfaceFunction
248
281
    defaultBuilder = ZopeInterfaceASTBuilder
249