def mekeMathState(meth): vars = [] cats = [] if (meth.variables is not None): for v in meth.variables: t = meth.variables[v][0] if (JOcHelper.isNumber(t)): vars.append(v) cats.append(t) if (meth.argNames is not None): for i in range(len(meth.argNames)): t = meth.argTypes[i] if (JOcHelper.isNumber(t)): vars.append(meth.argNames[i]) cats.append(t) if (len(vars) == 1): v = vars[0] r = random.random() if (r < 0.2): return v + random.choice(('++', '--')) + ';' elif (r < 0.5): return random.choice(('++', '--')) + v + ';' elif (r < 0.8): return v + ' ' + random.choice(('+', '-', '*')) + '= ' + v + ';' else: return v + ' = ' + v + random.choice(OC_MATH) + str(random.randint(2, 10)) + ';' elif (len(vars) > 1): i = int(random.random() * len(vars)) v = vars[i] s = v + ' = (' + cats[i] + ') (' for i in range(len(vars)): v = vars[i] s += v if (i == 0) else (random.choice(OC_MATH) + v) s += ');' return s
def __init__(self, className, baseClass=None, protocol=None): JOcClass.__init__(self, className, baseClass, protocol) self.imports = [] self.variables = {} self._include_classes = None # 引用的类数组 JOcHelper.randVars(self.variables, 0.85, JRand.rand_nearest(8)) # 初始化私有类变量
def addVarialbe(self, type=None): var_list = [] var_list.extend(self.variables.keys()) if (self.argNames is not None): var_list.extend(self.argNames) v = JOcHelper.var(var_list) if (type is None): type = random.choice(OC_BASE) d = JOcHelper.randValue(type) self.variables[v] = [type, d] return v
def __make__while(self, useClasses): c1 = JOcHelper.getMethodCondition(self.mMethod) c2 = JOcHelper.getMethodCondition(self.mMethod, True) s1 = JOcMixBlock(self.mMethod) s2 = JOcMixBlock(self.mMethod) s1.__push__if(c2, s2) s2.__make__statement(useClasses) if (random.random() < 0.3): s2.makeReturn() else: s2.__push__statement('break;') self.__push__while(c1, s1)
def _prepare(self): JFileUtils.rmdir(self._source_dir) mix_dirs = [] for i in range(random.randint(1, 21)): d = os.path.join(self._source_dir, JOcHelper.var(self._mix_dirs)) JFileUtils.mkdir(d) mix_dirs.append(d) self._mix_dirs = mix_dirs refs_dir = os.path.join(self._source_dir, JOcHelper.var()) JFileUtils.mkdir(refs_dir) self._refs_dir = refs_dir
def __make__if(self, useClasses): c1 = JOcHelper.getMethodCondition(self.mMethod) s1 = JOcMixBlock(self.mMethod) s1.__make__statement(useClasses) if (random.random() < 0.3): s1.makeReturn() self.__push__if(c1, s1)
def makeAssignState(meth): r = random.random() * 10 if (r < 2): # 参数赋值 if (meth.argNames is not None): i = int(random.random() * len(meth.argNames)) v = meth.argNames[i] d = JOcHelper.randValue(meth.argTypes[i]) return v + ' = ' + d + ';' elif (r < 4): # 局部变量赋值 var_map = meth.variables if (var_map is not None) and (len(var_map) > 0): v = random.choice(list(var_map.keys())) d = JOcHelper.randValue(var_map[v][0]) # meth.variables[v][1] = d return v + ' = ' + d + ';' elif (r < 6): # 类变量赋值 var_map = meth.mClass.variables if (var_map is not None) and (len(var_map) > 0) and (not JOcMixHelper.isClassMethod(meth.scope)): v = random.choice(list(var_map.keys())) d = JOcHelper.randValue(var_map[v][0]) # meth.mClass.variables[v][1] = d return v + ' = ' + d + ';' elif (r < 9): # 变量互相赋值 tdict = JOcMixHelper.getVisibleVars(meth) # for t in tdict: # if (t.startswith('const')): # tdict[t] = [] # 去除常量,因为常量不能赋值。 vls = list(tdict.values()) for i in range(len(vls)-1, -1, -1): if (vls[i] is None) or (len(vls[i]) < 2): del vls[i] if (len(vls) > 0): vls = vls[int(random.random() * len(vls))] i = int(random.random() * len(vls)) v1 = vls[i] del vls[i] i = int(random.random() * len(vls)) v2 = vls[i] return v1 + ' = ' + v2 + ';'
def setIncludes(self, classes): self._include_classes = classes # 添加引用类的导入 for cls in classes: self.imports.append(cls.className + '.h') # 添加私有变量 if (random.random() < 0.3): for cls in classes: n = JOcHelper.var(self.variables.keys()) self.variables[n] = (cls.className + '*', None)
def makeRet(meth): vars = [] r = meth.ret if (meth.variables is not None): for v in meth.variables: t = meth.variables[v][0] if (t == r): vars.append(v) elif (JOcHelper.isNumber(r) and JOcHelper.isNumber(t)): vars.append('(' + r + ')' + v) if (meth.argNames is not None): for i in range(len(meth.argNames)): t = meth.argTypes[i] if (t == r): vars.append(meth.argNames[i]) elif (JOcHelper.isNumber(r) and JOcHelper.isNumber(t)): vars.append('(' + r + ')' + meth.argNames[i]) if len(vars) > 0: return random.choice(vars) else: return JOcHelper.randValue(r)
def makeBody(self, refClasses=None): # 初始化局部变量 if (self.argNames is None): JOcHelper.randVars(self.variables, 0.00, random.randint(0, 5)) else: JOcHelper.randVars(self.variables, 0.85, JRand.rand_nearest(5)) # 生成逻辑 tree = JOcMixBlock(self) self.lineTree = tree if (refClasses is not None): others = refClasses[:] n = JRand.rand_int(1, len(refClasses)) for i in range(n): cls = JRand.rand_lave_list(others, n, i, 1) tree.randStatement(cls) else: n = random.randint(1, 3) for i in range(n): tree.randStatement() if (self.ret != 'void'): tree.makeReturn()
def _gen_line(self, method, statement): line = JOcLineTree(method) temp = [statement + ';'] for i in range(random.randint(1, 5)): temp.append(JOcHelper.getOCSingleton() + ';') stats = [] while len(temp) > 0: i = int(random.random() * len(temp)) stats.append(temp[i]) del temp[i] for ste in stats: line.statements.append(ste) return line
def _map_method(self, name, statement, argTypes=None, argNames=None): notice = JOcHelper.var(self._api_map.values()) self._api_map[name] = notice method = JOcMethod(self) method.scope = '+' method.ret = 'void' method.messages.append(notice) if argTypes is not None: method.argTypes = [argTypes] if argNames is not None: method.argNames = [argNames] if statement is not None: method.lineTree = self._gen_line(method, statement) self.methods.append(method)
def __make__declare(self): var_list = self.variables.keys() # 生成指令表 msgNums = 1 + JRand.rand_nearest(4) # [1, 5] for i in range(msgNums): while (True): n = JOcHelper.var(self.messages) if (n not in var_list): self.messages.append(n) break # 生成参数表 argNums = msgNums if (msgNums != 1) else (0 if ( random.random() < 0.5) else 1) if (argNums > 0): self.argTypes = [] self.argNames = [] for i in range(argNums): self.argTypes.append(JRand.chose_nearest(OC_BASE)) while (True): n = JOcHelper.var(self.argNames) if (n not in var_list): self.argNames.append(n) break
def makeStatement(meth): # 赋值语句 s = JOcMixHelper.makeAssignState(meth) if (s is not None): return s # 数学运算 s = JOcMixHelper.mekeMathState(meth) if (s is not None): return s # 调用引用的类 s = meth.mClass.useOtherClass(meth) if (s is not None): return s # 永远不报错 return JOcHelper.getOCSingleton() + ';'
def callMethod(meth, cl = None, fromMeth = None): s = ('[' + cl.className) if (cl is not None) else '' vard = None if (fromMeth is None) else JOcMixHelper.getVisibleVars(fromMeth) msgs = meth.messages args = meth.argTypes for i in range(len(msgs)): s += ' ' + msgs[i] if (args is not None): t = args[i] if (vard is not None): vars = vard.get(t) if (vars is not None): s += ':' + vars[int(random.random() * len(vars))] continue s += ':' + JOcHelper.randValue(t) s += '];' return s
def _rand_cls_name(self): p = random.choice(self._prifixs) s = random.choice(self._subfixs) n = JOcHelper.cla(self._class_names, p, s) self._class_names.append(n) return n