gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / console / jintrospect.py @ 462
History | View | Annotate | Download (5.1 KB)
1 |
"""Extend introspect.py for Java based Jython classes."""
|
---|---|
2 |
|
3 |
from introspect import * |
4 |
import string |
5 |
|
6 |
__author__ = "Don Coleman <dcoleman@chariotsolutions.com>"
|
7 |
__cvsid__ = "$Id: jintrospect.py 5782 2006-06-12 07:56:49Z jmvivo $"
|
8 |
|
9 |
def getAutoCompleteList(command='', locals=None, includeMagic=1, |
10 |
includeSingle=1, includeDouble=1): |
11 |
"""Return list of auto-completion options for command.
|
12 |
|
13 |
The list of options will be based on the locals namespace."""
|
14 |
attributes = [] |
15 |
# Get the proper chunk of code from the command.
|
16 |
root = getRoot(command, terminator='.')
|
17 |
try:
|
18 |
if locals is not None: |
19 |
object = eval(root, locals) |
20 |
else:
|
21 |
object = eval(root)
|
22 |
except:
|
23 |
return attributes
|
24 |
|
25 |
if ispython(object): |
26 |
# use existing code
|
27 |
attributes = getAttributeNames(object, includeMagic, includeSingle, includeDouble)
|
28 |
else:
|
29 |
methods = methodsOf(object.__class__)
|
30 |
attributes = [eachMethod.__name__ for eachMethod in methods] |
31 |
|
32 |
return attributes
|
33 |
|
34 |
def methodsOf(clazz): |
35 |
"""return a list of all the methods in a class"""
|
36 |
classMembers = vars(clazz).values()
|
37 |
methods = [eachMember for eachMember in classMembers if callable(eachMember)] |
38 |
for eachBase in clazz.__bases__: |
39 |
methods.extend(methodsOf(eachBase)) |
40 |
return methods
|
41 |
|
42 |
def getCallTipJava(command='', locals=None): |
43 |
"""For a command, return a tuple of object name, argspec, tip text.
|
44 |
|
45 |
The call tip information will be based on the locals namespace."""
|
46 |
|
47 |
calltip = ('', '', '') # object name, argspec, tip text. |
48 |
|
49 |
# Get the proper chunk of code from the command.
|
50 |
root = getRoot(command, terminator='(')
|
51 |
|
52 |
try:
|
53 |
if locals is not None: |
54 |
object = eval(root, locals) |
55 |
else:
|
56 |
object = eval(root)
|
57 |
except:
|
58 |
return calltip
|
59 |
|
60 |
if ispython(object): |
61 |
# Patrick's code handles python code
|
62 |
# TODO fix in future because getCallTip runs eval() again
|
63 |
return getCallTip(command, locals) |
64 |
|
65 |
name = ''
|
66 |
try:
|
67 |
name = object.__name__
|
68 |
except AttributeError: |
69 |
pass
|
70 |
|
71 |
tipList = [] |
72 |
argspec = '' # not using argspec for Java |
73 |
|
74 |
if inspect.isbuiltin(object): |
75 |
# inspect.isbuiltin() fails for Jython
|
76 |
# Can we get the argspec for Jython builtins? We can't in Python.
|
77 |
pass
|
78 |
elif inspect.isclass(object): |
79 |
# get the constructor(s)
|
80 |
# TODO consider getting modifiers since jython can access private methods
|
81 |
constructors = object.getConstructors()
|
82 |
for constructor in constructors: |
83 |
paramList = [] |
84 |
paramTypes = constructor.getParameterTypes() |
85 |
# paramTypes is an array of classes, we need Strings
|
86 |
# TODO consider list comprehension
|
87 |
for param in paramTypes: |
88 |
# TODO translate [B to byte[], [C to char[] etc
|
89 |
paramList.append(param.__name__) |
90 |
paramString = string.join(paramList,', ')
|
91 |
tip = "%s(%s)" % (constructor.name, paramString)
|
92 |
tipList.append(tip) |
93 |
|
94 |
elif inspect.ismethod(object): |
95 |
method = object
|
96 |
object = method.im_class |
97 |
|
98 |
# java allows overloading so we may have more than one method
|
99 |
methodArray = object.getMethods()
|
100 |
|
101 |
for eachMethod in methodArray: |
102 |
if eachMethod.name == method.__name__:
|
103 |
paramList = [] |
104 |
for eachParam in eachMethod.parameterTypes: |
105 |
paramList.append(eachParam.__name__) |
106 |
|
107 |
paramString = string.join(paramList,', ')
|
108 |
|
109 |
# create a python style string a la PyCrust
|
110 |
# we're showing the parameter type rather than the parameter name, since that's all I can get
|
111 |
# we need to show multiple methods for overloading
|
112 |
# TODO improve message format
|
113 |
# do we want to show the method visibility
|
114 |
# how about exceptions?
|
115 |
# note: name, return type and exceptions same for EVERY overload method
|
116 |
|
117 |
tip = "%s(%s) -> %s" % (eachMethod.name, paramString, eachMethod.returnType)
|
118 |
tipList.append(tip) |
119 |
|
120 |
# else:
|
121 |
# print "Not a java class :("
|
122 |
|
123 |
calltip = (name, argspec, string.join(tipList,"\n"))
|
124 |
return calltip
|
125 |
|
126 |
def ispython(object): |
127 |
"""
|
128 |
Figure out if this is Python code or Java Code
|
129 |
|
130 |
"""
|
131 |
pyclass = 0
|
132 |
pycode = 0
|
133 |
pyinstance = 0
|
134 |
|
135 |
if inspect.isclass(object): |
136 |
try:
|
137 |
object.__doc__
|
138 |
pyclass = 1
|
139 |
except AttributeError: |
140 |
pyclass = 0
|
141 |
|
142 |
elif inspect.ismethod(object): |
143 |
try:
|
144 |
object.__dict__
|
145 |
pycode = 1
|
146 |
except AttributeError: |
147 |
pycode = 0
|
148 |
else: # I guess an instance of an object falls here |
149 |
try:
|
150 |
object.__dict__
|
151 |
pyinstance = 1
|
152 |
except AttributeError: |
153 |
pyinstance = 0
|
154 |
|
155 |
# print "object", object, "pyclass", pyclass, "pycode", pycode, "returning", pyclass | pycode
|
156 |
|
157 |
return pyclass | pycode | pyinstance
|
158 |
|