代码行数统计

一、 代码统计

设计思想为各个类的方法名用正则表达式来匹配,每个放的行数使用栈来计算,类之间的引用关系使用图存储。通过判断是否存在环来判断是否有循环引用。使用Python实现。

1、类SourceCodeANA

方法:ListAllFile()

def ListAllFile():    #获取目录下所有的文件名及其路径
    path = os.getcwd()   #获取当前目录
    file_paths=[]
    new_path = os.path.join(path,'SLRtableProducer')
    listfile=os.listdir(new_path)  #列出目录下所有文件
    for files in listfile:
        file_paths.append(os.path.join(new_path,files))
    return listfile,file_paths      #返回所有文件名lisfile,返回所有文件的路径.

此方法的功能为遍历当前目录下多有的文件,返回其文件名和完整路径。

1.2 方法:GetName()

def GetName():   #生成类名字典
    listfile,file_paths = ListAllFile()
    i = 0
    class_dict={}
    for file_path in file_paths:
        dotposition=file_path.rfind('.')
        extention_name=file_path[dotposition+1:]  #获取扩展名
        class_name=file_path[file_path.rfind('/')+1:]  #类名,带.h
        if extention_name=='h':
            class_dict[class_name]=i
            newclass_dict[i]=class_name
            i=i+1
    return class_dict

此方法的功能为为每个类名生成键值对,已方便生成类引用图时表示的方便。返回类似这样的结果:{‘AnalysisTable.h’: 0, ‘global.h’: 1, ‘LexerSupport.h’: 2}

1.3 方法:CountLine(file_path)

def CountLine(file_path):  #计算方法行数,利用栈
s=Stack()
f=open(file_path,'r')
i=0
function_line=[]
for lines in f.readlines():
    if lines.find('{')!=-1:
        s.push(1)
        i=0
    if lines.find('}')!=-1:
        s.pop()
        if s.isEmpty()==True:
            function_line.append(i)
            i=0
    i=i+1
return function_line

此方法的作用统计每个方法的行数。每当遇到’{‘时就入栈,每当遇到’}’时就出栈,当栈为空是即为这个方法已经结束。每个从文件读入一行,每次读入累加器就会加1,以此来统计行数。

1.4 方法:ShowReference(file_paths,class_dict)

def ShowReference(file_paths,class_dict):  #生成类之间引用关系的图,用邻接矩阵存储
ReturnMat = numpy.zeros((21,21))
for file_path in file_paths:
    class_name=file_path[file_path.rfind('/')+1:]
    extention_name=file_path[file_path.rfind('.')+1:]  #获取扩展名
    if os.path.exists(file_path)==True and extention_name=='h':
        f=open(file_path,'r')
        content=f.read()
        result1=re.findall('#include "(.*)"',content)
        result2=re.findall('#include <(.*)>',content)
        result1.extend(result2)

        for result in result1:
            if class_dict.has_key(class_name)==True and class_dict.has_key(result)==True:
                ReturnMat[class_dict[class_name]][class_dict[result]]=1
return ReturnMat

此方法的作用为生成类之间引用关系的有向图,用邻接矩阵存储。

1.5 方法:dfs()

def dfs(i,m):
for j in range(20):
    if dataSet[i][j] == 1:

        if m!=i:
            print '----------------------------------------------------------'
        print newclass_dict[i],'->',newclass_dict[j]
        dataSet[i][j]=2
        m=j
        dfs(j,m)

这个方法是用来遍历类引用关系生成的邻接矩阵,采用了深度优先遍历,以此来得到类之间的引用关系。

1.6 方法:Main()

def Main():
listfile,file_paths=ListAllFile()
class_count=0      #类的个数
class_name=''      #类名
function_lines=0   #方法行数
reclass=[]         #类中所引用的类

for file_path in file_paths:  #遍历所有文件
    isCycle='否'      #是否存在循环引用
    reclass=[]       #引用类list
    dotposition=file_path.rfind('.')
    extention_name=file_path[dotposition+1:]  #获取扩展名
    if extention_name=='h':  #利用.h文件计算方法个数
        class_count=class_count+1  #类的个数
        class_name=file_path[file_path.rfind('/')+1:dotposition]  #类名,不带.h
        class_name_h=class_name+'.h'   #类名,带.h
        cppfile_path=file_path[:dotposition]+'.cpp'    #.cpp文件路径

        if os.path.exists(cppfile_path)==True:    #通过cpp计算方法行数
            function_lines=CountLine(cppfile_path)
        else:
            function_lines=0

        #打开.h文件,统计方法
        f=open(file_path,'r')
        content=f.read()
        reresult=re.findall('(\w*)\((.*?)\);| (\w*)\((.*?)\)\s*\{',content)
        function_count=len(reresult)
        for name in reresult:  #方法名加入list
            if name[0]!='':
                function_name.append(name[0])

        print '类名为:',class_name
        print '方法个数为:',function_count
        if function_count!=0 and function_lines!=0:
            print sorted(function_lines)
            print '最长的方法有:',sorted(function_lines)[0],'行'
            print '最短的方法有:',sorted(function_lines)[len(function_lines)-1],'行'
            print '引用的类有:',reclass
            print '是否存在循环引用:',isCycle
            print '------------------------------'
        else:
            print '------------------------------'

此函数为主函数,主要为获取各个函数名,以及输出最后的结果。

2、类Stack
class Stack:
def __init__(self,size = 16):
    self.stack = []
    self.size = size
    self.top = -1
def setSize(self, size):
    self.size = size
def isEmpty(self):
    if self.top == -1:
        return True
    else:
        return False
def isFull(self):
    if self.top +1 == self.size:
        return True
    else:
        return False
def top(self):
    if self.isEmpty():
        raise Exception("StackIsEmpty")
    else:
        return self.stack[self.top]
def push(self,obj):
    if self.isFull():
        raise Exception("StackOverFlow")
    else:
        self.stack.append(obj)
        self.top +=1
def pop(self):
    if self.isEmpty():
        raise Exception("StackIsEmpty")
    else:
        self.top -= 1
        return self.stack.pop()
def show(self):
    print(self.stack)

这个类实现了栈这种数据结构,用来统计代码行数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值