Logo Search packages:      
Sourcecode: eclipse-pydev version File versions  Download package


import StringIO
import traceback
from java.lang import StringBuffer
from java.lang import String
import java.lang
import sys

from org.python.core import PyReflectedFunction

from org.python import core

#completion types.


def _imp(name):
        return __import__(name)
        if '.' in name:
            sub = name[0:name.rfind('.')]
            return _imp(sub)
            s = 'Unable to import module: %s - sys.path: %s' % (str(name), sys.path)
            raise RuntimeError(s)

def Find( name ):
    f = None
    if name.startswith('__builtin__'):
        if name == '__builtin__.str':
            name = 'org.python.core.PyString'
        elif name == '__builtin__.dict':
            name = 'org.python.core.PyDictionary'
    mod = _imp(name)
    if hasattr(mod, '__file__'):
        f = mod.__file__

    components = name.split('.')

    for comp in components[1:]:
        mod = getattr(mod, comp)
        if hasattr(mod, '__file__'):
            f = mod.__file__
    return f, mod

def formatParamClassName(paramClassName):
    if paramClassName.startswith('['):
        if paramClassName == '[C':
            paramClassName = 'char[]'
        elif paramClassName == '[B':
            paramClassName = 'byte[]'
        elif paramClassName == '[I':
            paramClassName = 'int[]'
        elif paramClassName.startswith('[L') and paramClassName.endswith(';'):
            paramClassName = paramClassName[2:-1]
            paramClassName += '[]'
    return paramClassName

def GenerateTip( data ):
    data = data.replace( '\n', '' )
    if data.endswith( '.' ):
        data = data.rstrip( '.' )
    f, mod = Find( data )
    tips = GenerateImportsTipForModule( mod )
    return f, tips

class Info:
    def __init__(self, name, **kwargs):
        self.name = name
        self.doc = kwargs.get('doc', None)
        self.args = kwargs.get('args', ()) #tuple of strings
        self.varargs = kwargs.get('varargs', None) #string
        self.kwargs = kwargs.get('kwargs', None) #string
        self.ret = kwargs.get('ret', None) #string
    def basicAsStr(self):
        '''@returns this class information as a string (just basic format)
        s = 'function:%s args=%s, varargs=%s, kwargs=%s, docs:%s' % \
            (str(self.name), str( self.args), str( self.varargs), str( self.kwargs), str( self.doc))
        return s

    def getAsDoc(self):
        s = str(self.name)
        if self.doc:
            s+='\n@doc %s\n' % str(self.doc)
        if self.args:
            s+='\n@params '
            for arg in self.args:
                s+='  '
        if self.varargs:
            s+='\n@varargs '
        if self.kwargs:
            s+='\n@kwargs '
        if self.ret:
            s+='\n@return '
        return str(s)
def isclass(cls):
    return isinstance(cls, core.PyClass)

def ismethod(func):
    '''this function should return the information gathered on a function
    @param func: this is the function we want to get info on
    @return a tuple where:
        0 = indicates whether the parameter passed is a method or not
        1 = a list of classes 'Info', with the info gathered from the function
            this is a list because when we have methods from java with the same name and different signatures,
            we actually have many methods, each with its own set of arguments
        if isinstance(func, core.PyFunction):
            #ok, this is from python, created by jython
            #print '    PyFunction'
            def getargs(func_code):
                """Get information about the arguments accepted by a code object.
                Three things are returned: (args, varargs, varkw), where 'args' is
                a list of argument names (possibly containing nested lists), and
                'varargs' and 'varkw' are the names of the * and ** arguments or None."""
                nargs = func_code.co_argcount
                names = func_code.co_varnames
                args = list(names[:nargs])
                step = 0
                varargs = None
                if func_code.co_flags & func_code.CO_VARARGS:
                    varargs = func_code.co_varnames[nargs]
                    nargs = nargs + 1
                varkw = None
                if func_code.co_flags & func_code.CO_VARKEYWORDS:
                    varkw = func_code.co_varnames[nargs]
                return args, varargs, varkw
            args = getargs(func.func_code)
            return 1, [Info(func.func_name, args = args[0], varargs = args[1],  kwargs = args[2], doc = func.func_doc)]
        if isinstance(func, core.PyMethod):
            #this is something from java itself, and jython just wrapped it...
            #things to play in func:
            #['__call__', '__class__', '__cmp__', '__delattr__', '__dir__', '__doc__', '__findattr__', '__name__', '_doget', 'im_class',
            #'im_func', 'im_self', 'toString']
            #print '    PyMethod'
            #that's the PyReflectedFunction... keep going to get it
            func = func.im_func
        if isinstance(func, PyReflectedFunction):
            #this is something from java itself, and jython just wrapped it...
            #print '    PyReflectedFunction'
            infos = []
            for i in range(len(func.argslist)):
                #things to play in func.argslist[i]:
                #'PyArgsCall', 'PyArgsKeywordsCall', 'REPLACE', 'StandardCall', 'args', 'compare', 'compareTo', 'data', 'declaringClass'
                #'flags', 'isStatic', 'matches', 'precedence']
                #print '        ', func.argslist[i].data.__class__
                #func.argslist[i].data.__class__ == java.lang.reflect.Method
                if func.argslist[i]:
                    met = func.argslist[i].data
                    name = met.getName()
                        ret = met.getReturnType()
                    except AttributeError:
                        ret = ''
                    parameterTypes = met.getParameterTypes()
                    args = []
                    for j in range(len(parameterTypes)):
                        paramTypesClass = parameterTypes[j]
                                paramClassName = paramTypesClass.getName()
                                paramClassName = paramTypesClass.getName(paramTypesClass)
                        except AttributeError:
                                paramClassName = repr(paramTypesClass) #should be something like <type 'object'>
                                paramClassName = paramClassName.split('\'')[1]
                                paramClassName = repr(paramTypesClass) #just in case something else happens... it will at least be visible
                        #if the parameter equals [C, it means it it a char array, so, let's change it
                        a = formatParamClassName(paramClassName)
                        #a = a.replace('[]','Array')
                        #a = a.replace('Object', 'obj')
                        #a = a.replace('String', 's')
                        #a = a.replace('Integer', 'i')
                        #a = a.replace('Char', 'c')
                        #a = a.replace('Double', 'd')
                        args.append(a) #so we don't leave invalid code
                    info = Info(name, args = args, ret = ret)
                    #print info.basicAsStr()
            return 1, infos
    except Exception, e:
        s = StringIO.StringIO()
        return 1, [Info(str('ERROR'),  doc = s.getvalue())]
    return 0, None

def ismodule(mod):
    #java modules... do we have other way to know that?
    if not hasattr(mod, 'getClass') and not hasattr(mod, '__class__') \
       and hasattr(mod, '__name__'):
           return 1
    return isinstance(mod, core.PyModule)

def dirObj(obj):
    ret = []
    found = java.util.HashMap()
    original = obj
    if hasattr(obj, '__class__') and obj.__class__ ==  java.lang.Class:

        #get info about superclasses
        classes = []
        c = obj.getSuperclass()
        while c != None:
            c = c.getSuperclass()
        #get info about interfaces
        interfs = []
        for obj in classes:
        #now is the time when we actually get info on the declared methods and fields
        for obj in classes:
            declaredMethods = obj.getDeclaredMethods()
            declaredFields = obj.getDeclaredFields()
            for i in range(len(declaredMethods)):
                name = declaredMethods[i].getName()
                found.put(name, 1)
            for i in range(len(declaredFields)):
                name = declaredFields[i].getName()
                found.put(name, 1)

    #this simple dir does not always get all the info, that's why we have the part before
    #(e.g.: if we do a dir on String, some methods that are from other interfaces such as 
    #charAt don't appear)
    d = dir(original)
    for name in d:
        if found.get(name) is not 1:
    return ret

def formatArg(arg):
    '''formats an argument to be shown
    s = str( arg )
    dot = s.rfind('.')
    if dot >= 0:
        s = s[dot+1:]
    s = s.replace(';','')
    s = s.replace('[]','Array')
    if len(s) > 0:
        c = s[0].lower()
        s =  c + s[1:]

    return s
def GenerateImportsTipForModule( mod ):
    @param mod: the module from where we should get the completions
    ret = []
    dirComps = dirObj( mod )
    dontGetDocsOn = (float, int, str, tuple, list, type)
    for d in dirComps:

        args = ''
        doc = ''
        retType = TYPE_BUILTIN

            obj = getattr(mod, d)
        except AttributeError:
            #jython has a bug in its custom classloader that prevents some things from working correctly, so, let's see if
            #we can fix that... (maybe fixing it in jython itself would be a better idea, as this is clearly a bug)
            #for that we need a custom classloader... we have references from it in the below places:
            #note: this only happens when we add things to the sys.path at runtime, if they are added to the classpath
            #before the run, everything goes fine.
            #The code below ilustrates what I mean... 
            #import sys
            #sys.path.insert(1, r"C:\bin\eclipse310\plugins\org.junit_3.8.1\junit.jar" )
            #import junit.framework
            #print dir(junit.framework) #shows the TestCase class here
            #import junit.framework.TestCase 
            #raises the error:
            #Traceback (innermost last):
            #  File "<console>", line 1, in ?
            #ImportError: No module named TestCase
            #whereas if we had added the jar to the classpath before, everything would be fine by now...

            ret.append(   (d, '', '', str(retType))   )
            #that's ok, private things cannot be gotten...

            isMet = ismethod(obj)
            if isMet[0]:
                info = isMet[1][0]
                    args, vargs, kwargs = info.args, info.varargs, info.kwargs
                    doc = info.getAsDoc()
                    r = ''
                    for a in ( args ):
                        if len( r ) > 0:
                            r += ', '
                        r += formatArg(a)
                    args = '(%s)' % (r)
                except TypeError:
                    print traceback.print_exc()
                    args = '()'
                retType = TYPE_FUNCTION
            elif isclass(obj):
                retType = TYPE_CLASS
            elif ismodule(obj):
                retType = TYPE_IMPORT
        #add token and doc to return - assure only strings.
        ret.append(   (d, doc, args, str(retType))   )
    return ret

if __name__ == "__main__":
    import sys
    print Find('junit.framework.TestCase')

Generated by  Doxygen 1.6.0   Back to index