4
4
from compiler import ast
8
class ZopeInterfaceModule(model.Module):
10
super(ZopeInterfaceModule, self).setup()
11
self.implements_directly = [] # [name of interface]
14
def allImplementedInterfaces(self):
15
"""Return all the interfaces provided by this module
17
return list(self.implements_directly)
7
20
class ZopeInterfaceClass(model.Class):
9
22
isschemafield = False
45
58
r.append(sc.fullName())
48
class Attribute(model.Documentable):
50
css_class = "attribute"
51
document_in_parent_page = True
53
62
class ZopeInterfaceFunction(model.Function):
54
63
def docsources(self):
55
64
for source in super(ZopeInterfaceFunction, self).docsources():
57
if not isinstance(self.parent, model.Class):
66
if not isinstance(self.parent, (model.Class, model.Module)):
59
68
for interface in self.parent.allImplementedInterfaces:
60
69
io = self.system.objForFullName(interface)
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]
75
def addInterfaceInfoToModule(module, interfaceargs):
76
for arg in interfaceargs:
77
if not isinstance(arg, tuple):
78
fullName = module.expandName(ast_pp.pp(arg))
81
module.implements_directly.append(fullName)
82
obj = module.system.objForFullName(fullName)
84
if not obj.isinterface:
87
'probable interface %r not marked as such'%obj,
89
obj.isinterface = True
90
obj.kind = "Interface"
91
obj.implementedby_directly = []
92
obj.implementedby_directly.append(module.fullName())
66
94
def addInterfaceInfoToClass(cls, interfaceargs, implementsOnly):
67
95
cls.implementsOnly = 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))
74
103
cls.implements_directly.append(fullName)
75
104
obj = cls.system.objForFullName(fullName)
76
105
if obj is not None:
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)
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):
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':
126
n2fn = self.builder.current._name2fullname
127
n2fn['Interface'] = 'zope.interface.Interface'
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):
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
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)
160
182
def extractStringLiteral(node):
161
183
if isinstance(node, ast.Const) and isinstance(node.value, str):
202
224
if meth is not None:
227
def visitCallFunc_zope_interface_moduleProvides(self, funcName, node):
228
if not isinstance(self.builder.current, model.Module):
232
addInterfaceInfoToModule(self.builder.current, node.args)
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
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)
241
273
class ZopeInterfaceASTBuilder(astbuilder.ASTBuilder):
245
277
class ZopeInterfaceSystem(model.System):
278
Module = ZopeInterfaceModule
246
279
Class = ZopeInterfaceClass
247
280
Function = ZopeInterfaceFunction
248
281
defaultBuilder = ZopeInterfaceASTBuilder