【iOS】Object-C 检测属性修饰符是否使用正确

通过以下脚本,可以部分检测出代码中的属性修饰符是否使用正确,目前的检测只加了5道,可继续扩展。

# -*- coding:utf-8 -*-
#!/usr/bin/env python
# @auther hehaichi

## 本脚本用于检测属性的修饰符是否正确
##useage:
## python3 modifier_check.py -d 【你需要检查的根目录】
## version : 0.0.1

import os
import sys
from datetime import date,datetime
import shutil
import getopt
import re

dir = "/Users/hehaichi/Documents/imgotv_iphone/MGTV-iPhone"


opts,args = getopt.getopt(sys.argv[1:],'-d:',['demo='])
for opt_name,opt_value in opts:
    if opt_name in ('-d','--dir'):
        dir = opt_value
        
total_files = []
for root, dirs, files in os.walk(dir):
    # 遍历文件
    for f in files:
        if f.endswith(".m") or f.endswith(".h"):
            total_files.append(os.path.join(root, f))

assign = "float,int,double,int,NSInteger,NSUIngeger,CGFloat,CGSize,CGPoint,CGRect,BOOL,long,long long,uint,UIEdgeInsets,unsigned"
copy = "NSString,NSDictionary,NSArray,NSURL,NSSet,NSURLRequest,Block"

def redPrint(txt):
    print('\033[0;31m%s\033[0m'%txt)

def greenPrint(txt):
    print('\033[0;32m%s\033[0m'%txt)
    
## 检查带*号的指针变量是否使用了assign
def check1(name,type,modifier):
    if "*" in name and "assign" in modifier:
        return False
    return True
## 检查block是否使用过assign
def check2(name,type,modifier):
    if type == "Block" and "assign" in modifier:
        return False
    return True
## 检查代理是否使用过assign或strong或copy
def check3(name,type,modifier):
    if type.startswith("id<") and ("assign" in modifier):
        return False
    return True
### 检查是否用了retain
def check4(name,type,modifier):
    if "retain" in modifier:
        return False
    return True

## 检查可变数组可变字符串等是否正确使用了修饰符
def check5(name,type,modifier):
    if (type.startswith("NSMutable") or type.startswith("LHSafeMutable")) and ("copy" in modifier or "assign" in modifier):
        return False
    return True

### 校验集
checkArray = [check1,check2,check3,check4,check5]
   
errArr = []
def checkFile(f):
#    print("\n正在检测:%s\n"%f)
    with open(f,"r") as file:
        try:
            content = file.read()
        except:
            return
        ## @property (strong, nonatomic) DownloadingCoverView *waveView;
        res1 = re.findall("@property\s*\((.*?)\)\s*(\w+)\s*(\*?\s*\w+)\s*;",content) ## 属性
        ## @property (weak, nonatomic) id  delegate; 【type valname】
        res2 = re.findall("@property\s*\((.*?)\)\s*(\w+\s*<\s*\w+\s*>)\s*(\*?\s*\w+)\s*;",content)##
        ## @property (nonatomic, copy) id (^onMiniAppShow)(id appInfo);
        res3 = re.findall("@property\s*\((.*?)\)\s*\w+\s*\(\^(\w+)\)\s*\(\w+\s+\w+\)\s*;",content) ## block
        
        arr = []
        
        
        for item in res1:
            modifiers = list(map(lambda x: x.strip(), item[0].split(",")))
            a = (modifiers,item[1],item[2],f)
            arr.append(a)
        
        for item in res2:
            modifiers = list(map(lambda x: x.strip(), item[0].split(",")))
            a = (modifiers,item[1],item[2],f)
            arr.append(a)
            
        for item in res3:
            modifiers = list(map(lambda x: x.strip(), item[0].split(",")))
            a = (modifiers,"Block",item[1],f)
            arr.append(a)
        
        for item in arr:
            name = item[2]
            type = item[1]
            modifier = item[0]
            isOK = True
            for check in checkArray:
                if not check(name,type,modifier):
                    isOK = False
                    break
            if isOK:
#                greenPrint("变量名:%s\t类型:%s\t修饰符:%s"%(name,type,modifier))
                pass
            else:
#                redPrint("变量名:%s\t类型:%s\t修饰符:%s"%(name,type,modifier))
                errArr.append(item)
    
for f in total_files:
    checkFile(f)

print("\n\n====================================以下为错误项统计====================================\n\n")
for item in errArr:
    f = item[3]
    name = item[2]
    type = item[1]
    modifier = item[0]
    redPrint("%s\n变量名:%s\t类型:%s\t修饰符:%s\n"%(f,name,type,modifier))
 

你可能感兴趣的:(【iOS】Object-C 检测属性修饰符是否使用正确)