def run(self):
     status = 0
     classes_num = len(self._classes)
     for node in self._classes:
         print "Complete ",status,"/",classes_num," classes"
         # ProbUsed will be true, if this class will be detect as candidate for duck field
         #self._complete_signatures[node.get("id")]={'Attrs':Set([]),'Methods':Set([]),'ProbUsed' : False}
         for method in self.get_methods(node):
             if get_visibility(method)=='special':
                 ''' ignore __init__ etc.'''
                 continue
             if self._assign_method(node,method):
                 if self._methods.has_key(method):
                     self._methods[method].append((node.get("id"),node,method))
                 else:
                     self._methods[method]=[(node.get("id"),node,method)]
         status +=1
     methods_num = len(self._methods.keys())
     status = 0
     count = 0
     for method in self._methods.keys():
         print "Complete ",status,"/",methods_num," method names"
         if(len(self._methods[method])>1):
             print "Method ",method," implemented in classes(id): ",[t[0] for t in self._methods[method]]
             for t in self._methods[method]:
                 if self._classes_info.has_key(t[1]):
                     self._classes_info[t[1]].append(t[2])
                 else:
                     self._classes_info[t[1]]=[t[2]]
             count+=1
         status +=1
     for k in self._classes_info.keys():
         print len(self._classes_info[k])*1.0/len(self.get_methods(k))
     print count," method names of ",methods_num,"unique method names in project pretend to to be passed to common superclass"
def test_get_visibility(names, expected):
    for name in names:
        got = get_visibility(name)
        assert got == expected, "got %s instead of %s for value %s" % (
            got,
            expected,
            name,
        )
def test_get_visibility(names, expected):
    for name in names:
        got = get_visibility(name)
        assert got == expected, "got %s instead of %s for value %s" % (
            got,
            expected,
            name,
        )
 def test_protected(self):
     for name in [
             "_", "__", "___", "____", "_____", "___e__", "_nextsimple",
             "_filter_it_"
     ]:
         got = get_visibility(name)
         self.assertEqual(
             got, 'protected',
             'got %s instead of protected for value %s' % (got, name))
 def handle_assattr_self(self,node,ducks):
     if((node.expr.as_string()=="self") and (get_visibility(node.attrname)!= 'special')):
         if(not ducks.has_key(node.attrname)):
             self._ducks_count +=1
             self._assigned_ducks +=1
             ducks[node.attrname] = {'attrs':{},'methods':{},'type':[],'complex_type':None,'assigned':True} 
         else:
             if(not ducks[node.attrname]['assigned']):
                 ducks[node.attrname]['assigned'] = True
                 self._assigned_ducks+=1
         if(isinstance(node.parent, (Assign,AugAssign))):
             if(isinstance(node.parent.value, (Tuple,Dict,List))):
                 ducks[node.attrname]['complex_type'] = node.parent.value.__class__.__name__ 
 def handle_getattr_self(self,node,ducks):
     ''' Handle Getattr node during duck typing for "self"  names access 
         ducks - dictionary of processed ducks '''
     if((node.expr.as_string()=="self") and (get_visibility(node.attrname)!= 'special')):
         if isinstance(node.parent, For):
             if(not ducks.has_key(node.attrname)):
                 self._ducks_count +=1
                 ducks[node.attrname] = {'attrs':{},'methods':{},'type':[],'complex_type':'Unknown','assigned':False}
                 if isinstance(node.parent.target, AssName):
                     for body in node.parent.body:
                         self._check_cycle(body, node.parent.target.name, node.attrname, ducks)
         if isinstance(node.parent, Getattr):
             """ if additional info about attr's field may be obtained """
             if(not ducks.has_key(node.attrname)):
                 self._ducks_count += 1
                 ducks[node.attrname] = {'attrs':{}, 'methods':{}, 'type':[], 'complex_type':None, 'assigned':False}
             if isinstance(node.parent.parent, CallFunc):
                 """ we get info about attr's method """
                 self.add_duck_info(ducks[node.attrname],node.parent.attrname,'methods')
             else:
                 """ we get info about attr's attr """
                 self.add_duck_info(ducks[node.attrname],node.parent.attrname,'attrs')
         elif isinstance(node.parent, Subscript):
             """ attr of complex type (list, dict, tuple etc.) """
             if(not ducks.has_key(node.attrname)):
                 self._ducks_count +=1
                 ducks[node.attrname] = {'attrs':{},'methods':{},'type':[],'complex_type':'Unknown','assigned':False}
             else:
                 ducks[node.attrname]['complex_type'] = 'Unknown'
             if(isinstance(node.parent.parent,Getattr)):
                 """ get some info about element of complex type """
                 if(not ducks[node.attrname].has_key('element_signature')):
                     ducks[node.attrname]['element_signature']={'attrs':{},'methods':{}}
                 if isinstance(node.parent.parent.parent,CallFunc):
                     self.add_duck_info(ducks[node.attrname]['element_signature'],node.parent.parent.attrname,'methods')
                 else:
                     self.add_duck_info(ducks[node.attrname]['element_signature'],node.parent.parent.attrname,'attrs')
 def test_private(self):
     for name in ["__g_", "____dsf", "__23_9"]:
         got = get_visibility(name)
         self.assertEqual(got, 'private',
                          'got %s instead of private for value %s' % (got, name))
 def test_public(self):
     self.assertEqual(get_visibility('simple'), 'public')
 def test_private(self):
     for name in ["__g_", "____dsf", "__23_9"]:
         got = get_visibility(name)
         self.assertEqual(
             got, 'private',
             'got %s instead of private for value %s' % (got, name))
 def test_special(self):
     for name in ["__reduce_ex__", "__setattr__"]:
         self.assertEqual(get_visibility(name), 'special')
 def test_protected(self):
     for name in ["_","__", "___", "____", "_____", "___e__",
                  "_nextsimple", "_filter_it_"]:
         got = get_visibility(name)
         self.assertEqual(got, 'protected',
                          'got %s instead of protected for value %s' % (got, name))
 def test_public(self):
     self.assertEqual(get_visibility('simple'), 'public')
 def test_special(self):
     for name in ["__reduce_ex__",  "__setattr__"]:
         self.assertEqual(get_visibility(name), 'special')
Example #14
0
def test_get_visibility(names, expected):
    for name in names:
        got = get_visibility(name)
        assert got == expected, f"got {got} instead of {expected} for value {name}"
 def test_public(self):
     self.assertEqual(get_visibility("simple"), "public")
    def run(self, args):
        """checking arguments and run project"""
        if not args:
            print self.help()
            return
        project = self.manager.project_from_files(args, astng_wrapper)
        self.project = project
        linker = ClassIRLinker(project)
        linker.visit(project)
        if self._criteria == 'capacity':
            found_ducks = {}
            bad_ducks = {}
            prob_used_classes = {}
            for t in numpy.arange(self._treshold,1,0.05):
                found_ducks[t] = 0
                bad_ducks[t] = 0
                prob_used_classes[t] = set([])
        else:
            prob_used_classes = set([])
            bad_ducks = 0
            found_ducks = 0
        ducks_num = len(list(linker.get_ducks()))
        count = 1
        dbg = set([])
        empty_ducks = 0
        """ Handle "duck" information and generate information about types """
        for current_class in linker.get_classes():
            for duck in current_class.cir_ducks.keys():
                print "Processing ", count, " duck of ",ducks_num
#                 print duck,current_class.cir_ducks[duck]
                count +=1
                duck_attrs, duck_methods = self.get_duck_signature(current_class.cir_ducks[duck])
                """ ignore empty ducks """
                if((not duck_attrs) and (not duck_methods)):
                    empty_ducks+=1
                    continue
                if not hasattr(current_class.cir_ducks[duck], 'complex_type'):
                    """ if duck is not detected  as complex type on previous stage (according to [],{} etc. usage)
                     we need to check its methods and fields """
                    complex_type = self._check_complex_type(duck_attrs, duck_methods)
                    if(complex_type):
                        current_class.cir_ducks[duck]['complex_type'] = complex_type
                        if self._criteria == 'capacity':
                            for t in found_ducks.keys():
                                found_ducks[t]+=1
                        else:
                            found_ducks+=1
                        continue
                if(self._criteria=='capacity'):
                    ''' Results of candidate class search will be saved for different thresholds '''
                    duck_found = {}
                    for t in numpy.arange(self._treshold,1,0.05):
                        duck_found[t] = False 
                else:
                    duck_found = False
                for field_candidate in linker.get_classes():
                    result = self.check_candidate(duck_attrs, duck_methods, field_candidate,self._criteria)
                    if self._criteria == 'capacity':
                        if(result>= self._treshold):
                            current_class.cir_ducks[duck]['type'].append(field_candidate)
                            if self._add_value:
                                ''' save value for candidate '''
                                if current_class.cir_ducks[duck].has_key('type_values'):
                                    current_class.cir_ducks[duck]['type_values'][field_candidate.cir_uid]=result
                                else:
                                    current_class.cir_ducks[duck]['type_values']={field_candidate.cir_uid:result}
                        for t in duck_found.keys():
                            ''' Save probably used classes for different thresholds '''
                            if(result>=t):
                                prob_used_classes[t] |= set([field_candidate.cir_uid])
                                duck_found[t] = True
                    else:
                        if(result):
                            current_class.cir_ducks[duck]['type'].append(field_candidate)
                            prob_used_classes |= set([field_candidate.cir_uid])
                      
                ''' check if duck not found at all '''
                if self._criteria =='capacity':
                    for t in duck_found.keys():
                        if(not duck_found[t]):
                            bad_ducks[t] += 1
                        else:
                            found_ducks[t]+=1 
                else:
                    if(not duck_found):
                        bad_ducks += 1
                    else:
                        found_ducks+=1 
#        empty_ducks = len(list(linker.get_empty_ducks()))  
#         print len(dbg)
#         print dbg
        print "Project - ",self._project        
        print "Duck typing criteria - ",self._criteria            
        print "Numbers of classes: ",len(list(linker.get_classes()))
        print "Numbers of ducks(non-empty): ", linker.get_ducks_count()-empty_ducks
        print "Numbers of ducks with complex type: ", len(list(linker.get_complex_ducks()))
        if self._criteria == 'capacity':
            if(linker.get_ducks_count()!=empty_ducks):
                b = found_ducks.keys()
                for t in sorted(found_ducks.keys()):
                    print t,"found ducks: ",found_ducks[t], " percentage from non-empty ducks: ",round(100*float(found_ducks[t])/(linker.get_ducks_count()-empty_ducks),1), " %"
            if(linker.get_attrs_count()!=0):
                for t in sorted(found_ducks.keys()):
                    print t,"Numbers of all attributes in project: ", linker.get_attrs_count(), " percentage of found attrs: ",round(100*float(found_ducks[t])/linker.get_attrs_count(),1), " %"
            if(len(list(linker.get_classes()))!=0):
                for t in sorted(found_ducks.keys()):
                    print t,"Probably used (as field) classes: ",len(prob_used_classes[t])," percentage: ",round(100*float(len(prob_used_classes[t]))/len(list(linker.get_classes())),1), " %"
        else:  
            if(linker.get_ducks_count()!=empty_ducks):
                print "Found ducks: ",found_ducks, " percentage from non-empty ducks: ",round(100*float(found_ducks)/(linker.get_ducks_count()-empty_ducks),1), " %"
            if(linker.get_attrs_count()!=0):
                print "Numbers of all attributes in project: ", linker.get_attrs_count(), " percentage of found attrs: ",round(100*float(found_ducks)/linker.get_attrs_count(),1), " %"
            if(len(list(linker.get_classes()))!=0):
                print "Probably used (as field) classes: ",len(prob_used_classes)," percentage: ",round(100*float(len(prob_used_classes))/len(list(linker.get_classes())),1), " %"
        
        # result XML generation
        mapper = {}
        root = etree.Element("Classes")
        for obj in linker.get_classes():
            self._all_classes +=1
            node = etree.Element("Class",name=obj.name,fromlineno=str(obj.fromlineno),col_offset=str(obj.col_offset),id=str(obj.cir_uid),label=obj.root().name)
            mapper[obj] = node
            root.append(node)
            for attrname in obj.ucr_attrs:
                attr_node = etree.Element('Attr',name=attrname)
                mod_node = etree.Element('Modifier',name=get_visibility(attrname))
                attr_node.append(mod_node)
                node.append(attr_node)
                if(attrname in obj.cir_ducks):
                    if obj.cir_ducks[attrname]['complex_type']:
                        for prob_type in obj.cir_ducks[attrname]['type']:
                            attr_node.append(etree.Element('AggregatedType',name=str(obj.cir_ducks[attrname]['complex_type']),element_type=prob_type.name,element_id=str(prob_type.cir_uid)))
                    else:
                        for prob_type in obj.cir_ducks[attrname]['type']:
                            if(obj.cir_ducks[attrname].has_key('type_values')):
                                common_type_node = etree.Element('CommonType',
                                                                 name=prob_type.name,
                                                                 id=str(prob_type.cir_uid),
                                                                 type_value=str(obj.cir_ducks[attrname]['type_values'][prob_type.cir_uid]))
                            else:
                                common_type_node = etree.Element('CommonType',
                                                                 name=prob_type.name,
                                                                 id=str(prob_type.cir_uid))
                            attr_node.append(common_type_node)    
            for meth in linker.get_methods(obj):
                meth_node = etree.Element('Method',name=meth.name)
                meth_node.set("fromlineno",str(meth.fromlineno))
                meth_node.set("col_offset",str(meth.col_offset))
                mod_node = etree.Element('Modifier',name=get_visibility(meth.name))
                meth_node.append(mod_node)
                """ This is needed for some native libs(pyx) """
                if(meth.args.args == None):
                    continue
                for arg in meth.args.args:
                    # ignore self arg
                    if not arg.name == 'self':
                        meth_node.append(etree.Element('Arg',name=arg.name))
                node.append(meth_node)
        for rel in linker.get_inheritances():
            mapper[rel[0]].append(etree.Element('Parent',name=rel[1].name,id=str(rel[1].cir_uid)))
        print "Writing ", self._out_file
        f = open(self._out_file,'w')
        f.write(etree.tostring(root, pretty_print=True, encoding='utf-8', xml_declaration=True))
        f.close()
 def handle_attrs(self,node,class_node):
     if class_node is None:
         return
     if isinstance(node, (AssAttr,Getattr)):
         if((node.expr.as_string()=="self") and (get_visibility(node.attrname)!= 'special')):
             class_node.ucr_attrs.add(node.attrname)
 def visit_class(self,node):
     self._classes.append(node)
     node.ucr_attrs = set([item[0] for item in node.items() if (isinstance(item[1], AssName) and (get_visibility(item[0])!= 'special'))])
     node.ucr_complete_attrs = node.ucr_attrs.copy()