一、 代码统计
设计思想为各个类的方法名用正则表达式来匹配,每个放的行数使用栈来计算,类之间的引用关系使用图存储。通过判断是否存在环来判断是否有循环引用。使用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)
这个类实现了栈这种数据结构,用来统计代码行数。