Beispiel #1
0
 def test_hashmap_builtin_pymethods(self):
     x = HashMap()
     x['a'] = 1
     x[(1, 2)] = 'xyz'
     self.assertEqual({tup for tup in x.items()}, {('a', 1), ((1, 2), 'xyz')})
     self.assertEqual(str(x), repr(x))
     self.assertEqual(type(str(x)), type(repr(x)))
Beispiel #2
0
class FunType(Type):
    """ generated source for class FunType """


    #@__init__.register(object, FunctionDef, Scope)
    def __init__(self, func=None, env=None):
        self.arrows = HashMap()
        self.cls = None
        self.defaultTypes = List()        
        
        self.selfType = None
        self.func = None
        from pysonarsq.java.Analyzer import Analyzer
        
        super(FunType, self).__init__()   
        self.env = None     
        if isinstance(func, FunctionDef):
            self.func = func
            self.env = env
        elif isinstance(func, Type):
            from_, to = func, env
            self.addMapping(from_, to)
            self.getTable().addSuper(Analyzer.self.builtins.BaseFunction.getTable())
            self.getTable().setPath(Analyzer.self.builtins.BaseFunction.getTable().getPath())            

    def addMapping(self, from_, to):
        if len(self.arrows) < 5:
            self.arrows[from_] = to
            oldArrows = self.arrows;
            self.arrows = self.compressArrows(self.arrows)
            if len(str(self)) > 900:
                self.arrows = oldArrows

    def getMapping(self, from_):
        return self.arrows.get(from_)

    def getReturnType(self):
        from pysonarsq.java.Analyzer import Analyzer
        
        if not _.isEmpty(self.arrows):
            #return self.arrows.values().iterator().next()
            return self.arrows.values()[0]
        else:
            return Analyzer.self.builtins.unknown

    def getFunc(self):
        return self.func

    def getEnv(self):
        return self.env

    def getCls(self):
        return self.cls

    def setCls(self, cls):
        self.cls = cls

    def getSelfType(self):
        return self.selfType

    def setSelfType(self, selfType):
        self.selfType = selfType

    def clearSelfType(self):
        self.selfType = None

    def getDefaultTypes(self):
        return self.defaultTypes

    def setDefaultTypes(self, defaultTypes):
        self.defaultTypes = defaultTypes

    def __eq__(self, other):
        if isinstance(other, (FunType, )):
            fo = other # cast in java code, should have been picked up by java2python
            return fo.getTable().getPath() == self.getTable().getPath() or self is other
        else:
            return False

    @classmethod
    def removeNoneReturn(cls, toType):
        from pysonarsq.java.Analyzer import Analyzer
        
        """ generated source for method removeNoneReturn """
        if toType.isUnionType():
            types.remove(Analyzer.self.builtins.Cont)
            return UnionType.newUnion(types)
        else:
            return toType

    def hashCode(self):
        return hash("FunType")

    def subsumed(self, type1, type2):
        return self.subsumedInner(type1, type2, TypeStack())

    def subsumedInner(self, type1, type2, typeStack):
        from pysonarsq.java.Analyzer import Analyzer
        
        if typeStack.contains(type1, type2):
            return True
        if type1.isUnknownType() or type1 == Analyzer.self.builtins.None_ or type1 == type2:
            return True
        if isinstance(type1, (TupleType, )) and isinstance(type2, (TupleType, )):
            elems1 = type1.getElementTypes();
            elems2 = type2.getElementTypes();            
            
            if len(elems1) == len(elems2):
                typeStack.push(type1, type2)
                for i in range(len(elems1)):
                    if not self.subsumedInner(elems1[i], elems2[i], self.typeStack):
                        self.typeStack.pop(type1, type2)
                        return False
            return True
        return False

    def compressArrows(self, arrows):
        ret = HashMap()
        for e1 in arrows.items():
            subsumed = False
            
            for e2 in arrows.items():
                if e1 != e2 and self.subsumed(e1[0], e2[0]):
                    subsumed = True
                    break
            if not subsumed:
                ret[e1[0]] = e1[1]
        return ret

    def printType(self, ctr):
        from pysonarsq.java.Analyzer import Analyzer
        
        if _.isEmpty(self.arrows):
            return "? -> ?"
            
        sb = []
        num = ctr.visit(self)
        if num is not None:
            sb.append("#")
            sb.append(num)
        else:
            newNum = ctr.push(self);
            
            i = 0;
            seen = set()
            for e in self.arrows.items():
                as_ = e[0].printType(ctr) + " -> " + e[1].printType(ctr);
                if not as_ in seen:
                    if i != 0:
                        if Analyzer.self.multilineFunType:
                            sb.append("\n| ")
                        else:
                            sb.append(" | ")
                    sb.append(as_)
                    seen.add(as_)
                i += 1
            if ctr.isUsed(self):
                sb.append("=#")
                sb.append(newNum)
                sb.append(": ")
            ctr.pop(self)
            
        return ''.join(map(str,sb))
Beispiel #3
0
class FunType(Type):
    """ generated source for class FunType """

    #@__init__.register(object, FunctionDef, Scope)
    def __init__(self, func=None, env=None):
        self.arrows = HashMap()
        self.cls = None
        self.defaultTypes = List()

        self.selfType = None
        self.func = None
        from pysonarsq.java.Analyzer import Analyzer

        super(FunType, self).__init__()
        self.env = None
        if isinstance(func, FunctionDef):
            self.func = func
            self.env = env
        elif isinstance(func, Type):
            from_, to = func, env
            self.addMapping(from_, to)
            self.getTable().addSuper(
                Analyzer.self.builtins.BaseFunction.getTable())
            self.getTable().setPath(
                Analyzer.self.builtins.BaseFunction.getTable().getPath())

    def addMapping(self, from_, to):
        if len(self.arrows) < 5:
            self.arrows[from_] = to
            oldArrows = self.arrows
            self.arrows = self.compressArrows(self.arrows)
            if len(str(self)) > 900:
                self.arrows = oldArrows

    def getMapping(self, from_):
        return self.arrows.get(from_)

    def getReturnType(self):
        from pysonarsq.java.Analyzer import Analyzer

        if not _.isEmpty(self.arrows):
            #return self.arrows.values().iterator().next()
            return self.arrows.values()[0]
        else:
            return Analyzer.self.builtins.unknown

    def getFunc(self):
        return self.func

    def getEnv(self):
        return self.env

    def getCls(self):
        return self.cls

    def setCls(self, cls):
        self.cls = cls

    def getSelfType(self):
        return self.selfType

    def setSelfType(self, selfType):
        self.selfType = selfType

    def clearSelfType(self):
        self.selfType = None

    def getDefaultTypes(self):
        return self.defaultTypes

    def setDefaultTypes(self, defaultTypes):
        self.defaultTypes = defaultTypes

    def __eq__(self, other):
        if isinstance(other, (FunType, )):
            fo = other  # cast in java code, should have been picked up by java2python
            return fo.getTable().getPath() == self.getTable().getPath(
            ) or self is other
        else:
            return False

    @classmethod
    def removeNoneReturn(cls, toType):
        from pysonarsq.java.Analyzer import Analyzer
        """ generated source for method removeNoneReturn """
        if toType.isUnionType():
            types.remove(Analyzer.self.builtins.Cont)
            return UnionType.newUnion(types)
        else:
            return toType

    def hashCode(self):
        return hash("FunType")

    def subsumed(self, type1, type2):
        return self.subsumedInner(type1, type2, TypeStack())

    def subsumedInner(self, type1, type2, typeStack):
        from pysonarsq.java.Analyzer import Analyzer

        if typeStack.contains(type1, type2):
            return True
        if type1.isUnknownType(
        ) or type1 == Analyzer.self.builtins.None_ or type1 == type2:
            return True
        if isinstance(type1,
                      (TupleType, )) and isinstance(type2, (TupleType, )):
            elems1 = type1.getElementTypes()
            elems2 = type2.getElementTypes()

            if len(elems1) == len(elems2):
                typeStack.push(type1, type2)
                for i in range(len(elems1)):
                    if not self.subsumedInner(elems1[i], elems2[i],
                                              self.typeStack):
                        self.typeStack.pop(type1, type2)
                        return False
            return True
        return False

    def compressArrows(self, arrows):
        ret = HashMap()
        for e1 in arrows.items():
            subsumed = False

            for e2 in arrows.items():
                if e1 != e2 and self.subsumed(e1[0], e2[0]):
                    subsumed = True
                    break
            if not subsumed:
                ret[e1[0]] = e1[1]
        return ret

    def printType(self, ctr):
        from pysonarsq.java.Analyzer import Analyzer

        if _.isEmpty(self.arrows):
            return "? -> ?"

        sb = []
        num = ctr.visit(self)
        if num is not None:
            sb.append("#")
            sb.append(num)
        else:
            newNum = ctr.push(self)

            i = 0
            seen = set()
            for e in self.arrows.items():
                as_ = e[0].printType(ctr) + " -> " + e[1].printType(ctr)
                if not as_ in seen:
                    if i != 0:
                        if Analyzer.self.multilineFunType:
                            sb.append("\n| ")
                        else:
                            sb.append(" | ")
                    sb.append(as_)
                    seen.add(as_)
                i += 1
            if ctr.isUsed(self):
                sb.append("=#")
                sb.append(newNum)
                sb.append(": ")
            ctr.pop(self)

        return ''.join(map(str, sb))
Beispiel #4
0
class Scope(object):

    #@overloaded
    def __init__(self, parent=None, type_=None):
        #  stays null for most scopes (mem opt)
        #  all are non-null except global table
        #  link to the closest non-class scope, for lifting functions out
            # ....          
        
        if not hasattr(self, 'scopeType'):
            self.scopeType = None
        
        self.supers = List()
        self.globalNames = Set()
        self.type_ = None
        self.path = ""        
        self.parent = parent
        self.setScopeType(type_)
        self.forwarding = None
        self.table = Map()
    
        if isinstance(parent, Scope) and type_ is None:
            s = parent # case of creating a new scope from an existing one
            if s.table is not None:
                self.table = HashMap()
                self.table.update(s.table)
                self.parent = s.parent
                self.setScopeType(s.scopeType)
                self.forwarding = s.forwarding
                self.supers = s.supers
                self.globalNames = s.globalNames
            self.type_ = s.type_
            self.path = s.path        
        elif parent is not None:
            self.parent = parent
            self.setScopeType(type_)
            if type_ == self.ScopeType.CLASS:
                self.forwarding = (None if parent is None else parent.getForwarding())
            else:
                self.forwarding = self
                
    #  erase and overwrite this to s's contents
    def overwrite(self, s):
        self.table = s.table
        self.parent = s.parent
        self.setScopeType(s.scopeType)
        self.forwarding = s.forwarding
        self.supers = s.supers
        self.globalNames = s.globalNames
        self.type_ = s.type_
        self.path = s.path
        
    def copy(self):
        return Scope(self)

    #@overloaded
    def _merge(self, other):
        for e1 in self.getInternalTable().items():
            b1 = e1[1]
            b2 = other.getInternalTable().get(e1[0])
            #  both branch have the same name, need merge
            if b2 is not None and b1 != b2:
                b1 += b2
                
        for e2 in other.getInternalTable().items():
            
            b1 = self.getInternalTable().get(e2[0]);
            b2 = e2[1]
            #  both branch have the same name, need merge
            if b1 is None and b1 != b2:
                self.update(e2[0], b2)
                
        return self

    @classmethod
    def merge(cls, scope1, scope2=None):
        if scope2 is not None:
            return scope1._merge(scope2)
        else:
            ret = scope1.copy()
            ret.merge(scope2)
            return ret

    def setParent(self, parent):
        if parent is not None:
            self.parent = parent

    def getParent(self):
        return self.parent

    def getForwarding(self):
        if self.forwarding is not None:
            return self.forwarding
        else:
            return self

    def addSuper(self, sup):
        if self.supers is None:
            self.supers = ArrayList()
        self.supers.append(sup)

    def setScopeType(self, type_):
        if type_ is not None:
            self.scopeType = type_

    def getScopeType(self):
        return self.scopeType

    def addGlobalName(self, name):
        if self.globalNames is None:
            self.globalNames = HashSet()
        self.globalNames.add(name)

    def isGlobalName(self, name):
        if self.globalNames is not None:
            return name in self.globalNames
        elif self.parent is not None:
            return self.parent.isGlobalName(name)
        else:
            return False

    def remove(self, _id):
        if self.table is not None:
            if _id in self.table: del self.table[_id]

    #  create new binding and insert
    def insert(self, id, node, type_, kind):
        b = Binding(id, node, type_, kind)
        if type_.isModuleType():
            b.setQname(type_.asModuleType().getQname())
        else:
            b.setQname(self.extendPath(id))
        self.update(id, b)

    #  directly insert a given binding
    #@overloaded
    def update(self, id, bs):
        if hasattr(bs, '__len__'):
            self.getInternalTable()[id] = bs
        else:
            bs = [bs]
            self.getInternalTable()[id] = bs
            
        return bs

    def setPath(self, path):
        self.path = path

    def getPath(self):
        return self.path

    def getType(self):
        return self.type_

    def setType(self, type_):
        self.type_ = type_

    # 
    #      * Look up a name in the current symbol table only. Don't recurse on the
    #      * parent table.
    #      
    def lookupLocal(self, name):
        if self.table is None:
            return None
        else:
            return self.table.get(name)

    # 
    #      * Look up a name (String) in the current symbol table.  If not found,
    #      * recurse on the parent table.
    #      
    def lookup(self, name):
        b = self.getModuleBindingIfGlobal(name)
        if b is not None:
            return b
        else:
            ent = self.lookupLocal(name)
            if ent is not None:
                return ent
            elif self.getParent() is not None:
                return self.getParent().lookup(name)
            else:
                return None

    # 
    #      * Look up a name in the module if it is declared as global, otherwise look
    #      * it up locally.
    #      
    def lookupScope(self, name):
        b = self.getModuleBindingIfGlobal(name)
        if b is not None:
            return b
        else:
            return self.lookupLocal(name)

    # 
    #      * Look up an attribute in the type hierarchy.  Don't look at parent link,
    #      * because the enclosing scope may not be a super class. The search is
    #      * "depth first, left to right" as in Python's (old) multiple inheritance
    #      * rule. The new MRO can be implemented, but will probably not introduce
    #      * much difference.
    #      
    looked = HashSet()

    #  circularity prevention
    def lookupAttr(self, attr):
        if self in self.looked:
            return None
        else:
            b = self.lookupLocal(attr);
            if b is not None:
                return b
            else:
                if self.supers is not None and len(self.supers):
                    self.looked.add(self)
                    for p in self.supers:
                        b = p.lookupAttr(attr)
                        if b is not None:
                            self.looked.remove(self)
                            return b
                    self.looked.remove(self)
                    return None
                else:
                    return None

    # 
    #      * Look for a binding named {@code name} and if found, return its type.
    #      
    def lookupType(self, name):
        bs = self.lookup(name)
        if bs is None:
            return None
        else:
            return self.makeUnion(bs)

    # 
    #      * Look for a attribute named {@code attr} and if found, return its type.
    #      
    def lookupAttrType(self, attr):
        bs = self.lookupAttr(attr)
        if bs is None:
            return None
        else:
            return self.makeUnion(bs)

    @classmethod
    def makeUnion(cls, bs):
        from pysonarsq.java.Analyzer import Analyzer

        t = Analyzer.self.builtins.unknown
        for b in bs:
            t = UnionType.union(t, b.getType())
            
        return t

    # 
    #      * Find a symbol table of a certain type in the enclosing scopes.
    #      
    def getSymtabOfType(self, type_):
        if self.scopeType == type_:
            return self
        elif self.parent is None:
            return None
        else:
            return self.parent.getSymtabOfType(type_)

    # 
    #      * Returns the global scope (i.e. the module scope for the current module).
    #      
    def getGlobalTable(self):
        result = self.getSymtabOfType(self.ScopeType.MODULE)
        if result is not None:
            return result
        else:
            _.die("Couldn't find global table. Shouldn't happen")
            return self

    # 
    #      * If {@code name} is declared as a global, return the module binding.
    #      
    def getModuleBindingIfGlobal(self, name):
        if self.isGlobalName(name):
            module_ = self.getGlobalTable();
            if module_ != self:
                return module_.lookupLocal(name)
        return None

    def putAll(self, other):
        self.getInternalTable().update(other.getInternalTable())

    def keySet(self):
        if self.table is not None:
            return self.table.items()
        else:
            return set()

    def values(self):
        if self.table is not None:
            ret = list()
            for bs in self.table.values():
                ret += bs
            return ret
        return Collections.emptySet()

    def entrySet(self):
        if self.table is not None:
            return self.table.items()
        return set()

    def isEmpty(self):
        return self.table is None or self.table.isEmpty()

    def extendPath(self, name):
        name = _.moduleName(name)
        if self.path == "":
            return name
        return self.path + "." + name

    def getInternalTable(self):
        if self.table is None:
            self.table = HashMap()
        return self.table

    def __str__(self):
        return "<Scope:" + str(self.getScopeType()) + ":" + str("{}" if self.table is None else self.table.items()) + ">"
Beispiel #5
0
class Scope(object):

    #@overloaded
    def __init__(self, parent=None, type_=None):
        #  stays null for most scopes (mem opt)
        #  all are non-null except global table
        #  link to the closest non-class scope, for lifting functions out
        # ....

        if not hasattr(self, 'scopeType'):
            self.scopeType = None

        self.supers = List()
        self.globalNames = Set()
        self.type_ = None
        self.path = ""
        self.parent = parent
        self.setScopeType(type_)
        self.forwarding = None
        self.table = Map()

        if isinstance(parent, Scope) and type_ is None:
            s = parent  # case of creating a new scope from an existing one
            if s.table is not None:
                self.table = HashMap()
                self.table.update(s.table)
                self.parent = s.parent
                self.setScopeType(s.scopeType)
                self.forwarding = s.forwarding
                self.supers = s.supers
                self.globalNames = s.globalNames
            self.type_ = s.type_
            self.path = s.path
        elif parent is not None:
            self.parent = parent
            self.setScopeType(type_)
            if type_ == self.ScopeType.CLASS:
                self.forwarding = (None if parent is None else
                                   parent.getForwarding())
            else:
                self.forwarding = self

    #  erase and overwrite this to s's contents
    def overwrite(self, s):
        self.table = s.table
        self.parent = s.parent
        self.setScopeType(s.scopeType)
        self.forwarding = s.forwarding
        self.supers = s.supers
        self.globalNames = s.globalNames
        self.type_ = s.type_
        self.path = s.path

    def copy(self):
        return Scope(self)

    #@overloaded
    def _merge(self, other):
        for e1 in self.getInternalTable().items():
            b1 = e1[1]
            b2 = other.getInternalTable().get(e1[0])
            #  both branch have the same name, need merge
            if b2 is not None and b1 != b2:
                b1 += b2

        for e2 in other.getInternalTable().items():

            b1 = self.getInternalTable().get(e2[0])
            b2 = e2[1]
            #  both branch have the same name, need merge
            if b1 is None and b1 != b2:
                self.update(e2[0], b2)

        return self

    @classmethod
    def merge(cls, scope1, scope2=None):
        if scope2 is not None:
            return scope1._merge(scope2)
        else:
            ret = scope1.copy()
            ret.merge(scope2)
            return ret

    def setParent(self, parent):
        if parent is not None:
            self.parent = parent

    def getParent(self):
        return self.parent

    def getForwarding(self):
        if self.forwarding is not None:
            return self.forwarding
        else:
            return self

    def addSuper(self, sup):
        if self.supers is None:
            self.supers = ArrayList()
        self.supers.append(sup)

    def setScopeType(self, type_):
        if type_ is not None:
            self.scopeType = type_

    def getScopeType(self):
        return self.scopeType

    def addGlobalName(self, name):
        if self.globalNames is None:
            self.globalNames = HashSet()
        self.globalNames.add(name)

    def isGlobalName(self, name):
        if self.globalNames is not None:
            return name in self.globalNames
        elif self.parent is not None:
            return self.parent.isGlobalName(name)
        else:
            return False

    def remove(self, _id):
        if self.table is not None:
            if _id in self.table: del self.table[_id]

    #  create new binding and insert
    def insert(self, id, node, type_, kind):
        b = Binding(id, node, type_, kind)
        if type_.isModuleType():
            b.setQname(type_.asModuleType().getQname())
        else:
            b.setQname(self.extendPath(id))
        self.update(id, b)

    #  directly insert a given binding
    #@overloaded
    def update(self, id, bs):
        if hasattr(bs, '__len__'):
            self.getInternalTable()[id] = bs
        else:
            bs = [bs]
            self.getInternalTable()[id] = bs

        return bs

    def setPath(self, path):
        self.path = path

    def getPath(self):
        return self.path

    def getType(self):
        return self.type_

    def setType(self, type_):
        self.type_ = type_

    #
    #      * Look up a name in the current symbol table only. Don't recurse on the
    #      * parent table.
    #
    def lookupLocal(self, name):
        if self.table is None:
            return None
        else:
            return self.table.get(name)

    #
    #      * Look up a name (String) in the current symbol table.  If not found,
    #      * recurse on the parent table.
    #
    def lookup(self, name):
        b = self.getModuleBindingIfGlobal(name)
        if b is not None:
            return b
        else:
            ent = self.lookupLocal(name)
            if ent is not None:
                return ent
            elif self.getParent() is not None:
                return self.getParent().lookup(name)
            else:
                return None

    #
    #      * Look up a name in the module if it is declared as global, otherwise look
    #      * it up locally.
    #
    def lookupScope(self, name):
        b = self.getModuleBindingIfGlobal(name)
        if b is not None:
            return b
        else:
            return self.lookupLocal(name)

    #
    #      * Look up an attribute in the type hierarchy.  Don't look at parent link,
    #      * because the enclosing scope may not be a super class. The search is
    #      * "depth first, left to right" as in Python's (old) multiple inheritance
    #      * rule. The new MRO can be implemented, but will probably not introduce
    #      * much difference.
    #
    looked = HashSet()

    #  circularity prevention
    def lookupAttr(self, attr):
        if self in self.looked:
            return None
        else:
            b = self.lookupLocal(attr)
            if b is not None:
                return b
            else:
                if self.supers is not None and len(self.supers):
                    self.looked.add(self)
                    for p in self.supers:
                        b = p.lookupAttr(attr)
                        if b is not None:
                            self.looked.remove(self)
                            return b
                    self.looked.remove(self)
                    return None
                else:
                    return None

    #
    #      * Look for a binding named {@code name} and if found, return its type.
    #
    def lookupType(self, name):
        bs = self.lookup(name)
        if bs is None:
            return None
        else:
            return self.makeUnion(bs)

    #
    #      * Look for a attribute named {@code attr} and if found, return its type.
    #
    def lookupAttrType(self, attr):
        bs = self.lookupAttr(attr)
        if bs is None:
            return None
        else:
            return self.makeUnion(bs)

    @classmethod
    def makeUnion(cls, bs):
        from pysonarsq.java.Analyzer import Analyzer

        t = Analyzer.self.builtins.unknown
        for b in bs:
            t = UnionType.union(t, b.getType())

        return t

    #
    #      * Find a symbol table of a certain type in the enclosing scopes.
    #
    def getSymtabOfType(self, type_):
        if self.scopeType == type_:
            return self
        elif self.parent is None:
            return None
        else:
            return self.parent.getSymtabOfType(type_)

    #
    #      * Returns the global scope (i.e. the module scope for the current module).
    #
    def getGlobalTable(self):
        result = self.getSymtabOfType(self.ScopeType.MODULE)
        if result is not None:
            return result
        else:
            _.die("Couldn't find global table. Shouldn't happen")
            return self

    #
    #      * If {@code name} is declared as a global, return the module binding.
    #
    def getModuleBindingIfGlobal(self, name):
        if self.isGlobalName(name):
            module_ = self.getGlobalTable()
            if module_ != self:
                return module_.lookupLocal(name)
        return None

    def putAll(self, other):
        self.getInternalTable().update(other.getInternalTable())

    def keySet(self):
        if self.table is not None:
            return self.table.items()
        else:
            return set()

    def values(self):
        if self.table is not None:
            ret = list()
            for bs in self.table.values():
                ret += bs
            return ret
        return Collections.emptySet()

    def entrySet(self):
        if self.table is not None:
            return self.table.items()
        return set()

    def isEmpty(self):
        return self.table is None or self.table.isEmpty()

    def extendPath(self, name):
        name = _.moduleName(name)
        if self.path == "":
            return name
        return self.path + "." + name

    def getInternalTable(self):
        if self.table is None:
            self.table = HashMap()
        return self.table

    def __str__(self):
        return "<Scope:" + str(self.getScopeType()) + ":" + str(
            "{}" if self.table is None else self.table.items()) + ">"