方法数量随机
属性数量随机
方法参数随机

效果:代码控制生成代码文件数量python 自动生成Object-c oc代码

python 自动生成Object-c oc代码

python 自动生成Object-c oc代码

python 自动生成Object-c oc代码
使用方法:python 代码名.py --oc_folder 制定你的工程目录

代码:

import os,sys
import random
import string
import re
import md5
import time
import json
import shutil
import hashlib 
import time
import argparse
#from Enum import enum

import sys 
reload(sys) 
sys.setdefaultencoding("utf-8")

script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
#垃圾代码临时存放目录
target_ios_folder = os.path.join(script_path, "./target_ios")
#备份目录
backup_ios_folder = os.path.join(script_path, "./backup_ios")

#忽略文件列表,不给这些文件添加垃圾函数
ignore_file_list = ["main.m", "GNative.mm", "MobClickCpp.mm"]
#忽略文件夹列表,不处理这些文件夹下的文件
ignore_folder_list = ["thirdparty","Support",".svn","paycenter","UMMobClick.framework","UMessage_Sdk_1.5.0a","TencentOpenApi_IOS_Bundle.bundle",
                        "TencentOpenAPI.framework","Bugly.framework","AlipaySDK.framework","AlipaySDK.bundle"]

ocModelClasses = ["UIImage","NSObject","NSString","NSMutableArray","NSMutableDictionary"]
ocControllerClasses = ["UIViewController","UINavigationController"]
ocViewClasses = ["UIImageView","UIView","UIButton","UILabel","UITableView", "UICollectionView", "UITextField"]
basidDataType = ["int","double", "float", "BOOL", "bool"]

exportFloder = "/Users/guoanguan/Desktop/laJiCode"

#class OCClassType(Enum):
#    oc_Model
#    oc_View
#    oc_Controller
#    oc_Other

#创建函数数量范围
create_func_min = 2
create_func_max = 10
            
#创建垃圾文件数量范围
create_file_min = 50
create_file_max = 100
            
#oc代码目录
ios_src_path = ""

#确保添加的函数不重名
funcname_set = set()

#单词列表,用以随机名称
with open(os.path.join(script_path, "./word_list.json"), "r") as fileObj:
    word_name_list = json.load(fileObj)

#获取一个随机名称
def getOneName():
    global word_name_list
    return random.choice(word_name_list)

#oc代码头文件函数声明
def getOCHeaderFuncText():
    funcName = getOneName()
    text = "\n- (void)%s" %(funcName)
    return text

def getMethodName():
    methodCanShuCount = random.randint(1,10)
    
    text = "\n- (void)"
    totleCount = methodCanShuCount
    while methodCanShuCount > 0:
        funcName = getOneName()
        argName = getOneName()#方法参数名
        classType = getOCClasses(random.randint(0, 20))#获取oc类类名
        if methodCanShuCount != totleCount:
            text = text + " "
        text = text + funcName + ":(" + classType + " *)" + argName
        methodCanShuCount = methodCanShuCount - 1

    text = text
    return text

def isObject(targetString):
    allClass = ocModelClasses + ocViewClasses + ocControllerClasses
    for ocC in allClass:
        if(targetString == ocC):
            return True

    for baseDataTypeStr in basidDataType:
        if(targetString == baseDataTypeStr):
            return False
    return False;
#oc代码函数实现模板
def getOCFuncText(header_text):
    arg1 = getOneName()
    text = [
        header_text + "\n",
        "{\n",
        "\tNSLog(@\"%s\");\n" %(arg1),
        "}\n"
    ]
    return "".join(text)

def getLJFOCFuncText(header_text):
    arg1 = getOneName()
    text = [
            header_text + "\n",
            "{\n"
    ]
    
    count = random.randint(0, 30)
    
    while count > -1:
        type = random.randint(0,5)
        allocText = getAlloc(type)
        text.append(allocText)
        count = count - 1;
    

    text.append("}\n");
    return "".join(text)


def getAlloc(type):
    arg1 = getOneName()
    if(type == 1):
        return "\tUIImage *%s = [UIImage imageNamed:@\"%s\"];\n" %(arg1,arg1)
    if(type == 2):
        return "\tNSString *%s = [[NSString alloc ] initWithString:@\"%s\"];\n" %(arg1,arg1)

    if(type == 3):
        return "\tNSLog(@\"%s\");\n" %(arg1)

    if(type == 0):
        return "\tNSObject *%s = [[NSObject alloc] init];\n" %(arg1)

    if(type > 3):
        return "\tNSObject *%s = [[NSObject alloc] init];\n" %(arg1)




def getOCClasses(type):
    if type == 0:
        return "UIImage"
    if type == 1:
        return "NSObject"
    if type == 2:
        return "NSString"
    if type == 3:
        return "UIViewController"
    if type == 4:
        return "UIView"
    if type  == 5:
        return "UIButton"

    if type == 6:
        return "UILabel"
    return "NSString"

#oc代码以@end结尾,在其前面添加text
def appendTextToOCFile(file_path, text):
    with open(file_path, "r") as fileObj:
        old_text = fileObj.read()
        fileObj.close()
        end_mark_index = old_text.rfind("@end")
        if end_mark_index == -1:
            print "\t非法的结尾格式: " + file_path
            return
        new_text = old_text[:end_mark_index]
        new_text = new_text + text + "\n"
        new_text = new_text + old_text[end_mark_index:]

    with open(file_path, "w") as fileObj:
        fileObj.write(new_text)


def addProperty(file_path):
    #添加@property
    addProperty = random.randint(0,1)
    if addProperty == 1:
        addPropertyCount = random.randint(0,20)
        for i in range(0, addPropertyCount):
            propertyType = random.randint(0,1)
            strongOrWeak = "strong"
            xingHao = "*"
            className = "UIViewController"
            if propertyType == 1:#引用类型
                classType = random.randint(0,1)
                if classType == 1:#强引用
                    strongOrWeak = "strong"
                    className = getOneClassName()
                elif classType == 0:#弱引用
                    strongOrWeak = "weak"
                    className = getOneViewClassName()
            elif propertyType == 0:#值类型
                strongOrWeak = "readwrite"
                className = getBasicDataTypeName()
                xingHao = ""
            
            propertyName = getOneName()
            propertyText = "@property(nonatomic, %s)%s %s%s;\n" %(strongOrWeak, className, xingHao, propertyName)
            text.append(propertyText)

#处理单个OC文件,添加垃圾函数。确保其对应头文件存在于相同目录
def dealWithOCFile(filename, file_path):
    global target_ios_folder,create_func_min,create_func_max,funcname_set
    funcname_set.clear()
    end_index = file_path.rfind(".")
    pre_name = file_path[:end_index]
    header_path = pre_name + ".h"
    if not os.path.exists(header_path):
        print "\t相应头文件不存在:" + file_path
        return
    
    
    #添加@property
    addProperty = random.randint(0,1)
    if addProperty == 1:
        addPropertyCount = random.randint(0,20)
        for i in range(0, addPropertyCount):
            propertyType = random.randint(0,1)
            strongOrWeak = "strong"
            xingHao = "*"
            className = "UIViewController"
            if propertyType == 1:#引用类型
                classType = random.randint(0,1)
                if classType == 1:#强引用
                    strongOrWeak = "strong"
                    className = getOneClassName()
                elif classType == 0:#弱引用
                    strongOrWeak = "weak"
                    className = getOneViewClassName()
            elif propertyType == 0:#值类型
                strongOrWeak = "readwrite"
                className = getBasicDataTypeName()
                xingHao = ""
                
            propertyName = getOneName()
            propertyText = "@property(nonatomic, %s)%s %s%s;" %(strongOrWeak, className, xingHao, propertyName)
            
            propertyText = appendText_n(propertyText)
            #text.append(propertyText)
            appendTextToOCFile(header_path, propertyText)

    new_func_num = random.randint(create_func_min, create_func_max)
    print "\t给%s添加%d个方法" %(filename, new_func_num)
    for i in range(new_func_num):
        #header_text = getOCHeaderFuncText()
        header_text = getMethodName()
        # print "add %s to %s" %(header_text, header_path.replace(target_ios_folder, ""))
        appendTextToOCFile(header_path, header_text + ";\n")
        #funcText = getOCFuncText(header_text)
        funcText = getLJFOCFuncText(header_text)#给方法添加细节
        appendTextToOCFile(file_path, funcText)



def appendText_n(text):
    k = random.randint(0,2)
    for i in range(0, k):
        text = text +"\n"

    return text


#扫描parent_folder,添加垃圾函数,处理了忽略列表,添加方法
def addOCFunctions(parent_folder):
    global ignore_file_list
    for parent, folders, files in os.walk(parent_folder):#遍历所有生成的.h .m 文件,为其生成方法内容
        need_ignore = None
        for ignore_folder in ignore_folder_list:
            if parent.find("/" + ignore_folder) != -1:#是x需要被忽略的文件夹
                need_ignore = ignore_folder
                break
        if need_ignore:
            print "\t忽略文件夹" + ignore_folder
            continue

        for file in files:
            if file.endswith(".m") or file.endswith(".mm"):
                if file in ignore_file_list:
                    continue
                dealWithOCFile(file, os.path.join(parent, file))

#新创建的垃圾文件header模板 添加头文件
def getOCHeaderFileText(class_name):
    global funcname_set
    new_func_name = getOneName()
    while new_func_name in funcname_set:
        new_func_name = getOneName()
    funcname_set.add(new_func_name)

    text = [
        "#import <Foundation/Foundation.h>\n\n",
        "@interface %s : NSObject {\n" %(class_name),
        "\tint %s;\n" %(new_func_name),
        "\tfloat %s;\n" %(getOneName()),
        "}\n\[email protected]"
    ]
    return string.join(text)

#新创建的垃圾文件mm模板
def getOCMMFileText(class_name):
    text = [
        '#import "%s.h"\n\n' %(class_name),
        "@implementation %s\n" %(class_name),
        "\n\[email protected]"
    ]
    return string.join(text)

#添加垃圾文件到parent_folder/trash/ 只有.h或者.m,无方法实现
def addOCFile(parent_folder):
    global create_file_min, create_file_max
    file_list = []
    target_folder = os.path.join(parent_folder, "trash")
    if os.path.exists(target_folder):
        shutil.rmtree(target_folder)
    os.mkdir(target_folder)
    file_num = random.randint(create_file_min, create_file_max)
    for i in range(file_num):
        file_name = getOneName()
        file_list.append("#import \"" + file_name + ".h\"")
        print "\t创建OC文件 trash/" + file_name
        #header_text = getOCHeaderFileText(file_name)
        header_text = create_ocHeader_h_Text(file_name);
        full_path = os.path.join(target_folder, file_name + ".h")
        with open(full_path, "w") as fileObj:
            fileObj.write(header_text)
            fileObj.close()

        mm_text = getOCMMFileText(file_name)
        full_path = os.path.join(target_folder, file_name + ".mm")
        with open(full_path, "w") as fileObj:
            fileObj.write(mm_text)
    all_header_text = "\n".join(file_list)

    with open(os.path.join(parent_folder, "Trash.h"), "w") as fileObj:
        fileObj.write(all_header_text)
        fileObj.close()

#解析参数       
def parse_args():#读取程序入口输入的参数
    parser = argparse.ArgumentParser(description='oc垃圾代码生成工具.')
    
    parser.add_argument('--oc_folder', dest='oc_folder', type=str, required=True, help='OC代码所在目录')
    
    parser.add_argument('--replace', dest='replace_ios', required=False, help='直接替换oc源代码', action="store_true")
    
    args = parser.parse_args()
    print "main"
    return args

def create_ocHeader_h_Text(class_name):

    global funcname_set
    new_func_name = getOneName()
    while new_func_name in funcname_set:
        new_func_name = getOneName()
    funcname_set.add(new_func_name)

    ocCTypeEnumCount = 4#OCClassType.oc_Other - OCClassType.oc_Model + 1#emum个数
    ocCTypeEnumIndex = random.randint(0, ocCTypeEnumCount-1)#要添加的脚本的类型

    targetInheritClassesList =[]#可能会继承的类list
    if ocCTypeEnumIndex == 0:#ocCType.oc_Controller):
        targetInheritClassesList.append("UIViewController")
    if ocCTypeEnumIndex == 1:# ocCType.oc_View):
        targetInheritClassesList = ocViewClasses
    if ocCTypeEnumIndex == 2:# ocCType.oc_Model):
        targetInheritClassesList.append("NSObject")
    if ocCTypeEnumIndex == 3:# ocCType.oc_Other):
        targetInheritClassesList = ocViewClasses + ocModelClasses + ocControllerClasses

    inheritClassCount = len(targetInheritClassesList)#可能继承的类的数量
    targetInheritClassIndex = random.randint(0,inheritClassCount-1)
    text = [
            "#import <Foundation/Foundation.h>\n\n",
            "@interface %s : %s {\n" %(class_name, targetInheritClassesList[targetInheritClassIndex])
            ]

    addShuXing = random.randint(0,1)
    if addShuXing == 1:#头文件添加属性
        shuxingCount = random.randint(1,10)#要添加的属性数量
        for i in range(0,shuxingCount):
            #类名 变量名
            shuXingText = "\t%s %s;\n" %(basidDataType[random.randint(0,len(basidDataType) - 1)], getOneName())
            shuXingText = appendText_n(shuXingText)
            text.append(shuXingText)
            

    text.append("}\n\[email protected]")


                #print text
    return string.join(text)

def getOneViewClassName():
    k = random.randint(0, len(ocViewClasses) - 1)
    return ocViewClasses[k]

def getOneModelClassName():
    k = random.randint(0, len(ocModelClasses) - 1)
    return ocModelClasses[k]

def getOneClassName():
    k = random.randint(0,2)
    if k == 0:
        return getOneViewClassName()
    if k == 1:
        return getOneModelClassName()
    return "UIViewController"

def getBasicDataTypeName():
    k = random.randint(0, len(basidDataType) - 1)
    return basidDataType[k]

def main():
   
    app_args = parse_args()#读取程序入口输入的参数
    
    global ios_src_path, backup_ios_folder, target_ios_folder
    ios_src_path = app_args.oc_folder
    if not os.path.exists(ios_src_path):#如果不存在这个文件夹 终止程序
        print "oc_folder path not exist."
        exit(0)

    print "拷贝OC代码到target_ios"
    if os.path.exists(target_ios_folder):
        shutil.rmtree(target_ios_folder)
    shutil.copytree(ios_src_path, target_ios_folder)

    print "开始创建oc文件到trash目录"
    addOCFile(target_ios_folder)
    print "\n开始添加oc方法"
    addOCFunctions(target_ios_folder)

    if app_args.replace_ios:
        print "\n用target_ios替换原目录"
        print "\t备份OC代码到" + os.path.abspath(backup_ios_folder)
        if os.path.exists(backup_ios_folder):
            shutil.rmtree(backup_ios_folder)
        shutil.copytree(ios_src_path, backup_ios_folder)

        print "\t开始替换"
        trash_folder = os.path.join(ios_src_path, "trash")
        if os.path.exists(trash_folder):
            shutil.rmtree(trash_folder)
        os.mkdir(trash_folder)

        for parent, folders, files in os.walk(target_ios_folder):
            for file in files:
                if file.endswith(".h") or file.endswith(".m") or file.endswith(".mm"):
                    full_path = os.path.join(parent, file)
                    target_path = full_path.replace(target_ios_folder, ios_src_path)
                    shutil.copy(full_path, target_path)
        print "替换成功\n需要在Xcode上重新添加trash文件下的oc文件"
    else:
        print "垃圾代码生成完毕,垃圾代码目录:" + os.path.abspath(target_ios_folder)

    print "\nfinished"


if __name__ == "__main__":
    main()

相关文章: