def generateSimpleFieldCall(self, cls, basecls, basefunc, field, invokeFuncName): callinfo = ast.Call( ast.AttrRef(ast.Identifier(field.name), invokeFuncName), [ast.Identifier(param.name) for param in basefunc.spec.params]) # teststmts = [ast.CallStatement(ast.Call(ast.Identifier('println'), [ast.makeLiteral('GenerateTreeFunc check ' + basefunc.name + ' ' + field.name), # ast.Identifier(field.name), # ast.Call(ast.Identifier('toString'), [])]))] teststmts = [] isStatement = basefunc.spec.returnType is None or ( isinstance(basefunc.spec.returnType, ast.UserType) and basefunc.spec.returnType.fullpath == 'void') if isStatement: body = ast.StatementBody([ # ast.Call(ast.Identifier('println'), [ast.makeLiteral('GenerateTreeFunc ' + basefunc.name + ' ' + field.name), # ast.Call(ast.AttrRef(ast.Identifier(field.name), 'toString'), []), # ast.Call(ast.Identifier('toString'), [])]), callinfo ]) branch = ast.IfBranch( ast.BinaryOp('!=', ast.Identifier(field.name), ast.Nil()), body) return ast.StatementBody(teststmts + [ast.IfStatement([branch], None)]) return ast.IfElseExpr( ast.BinaryOp('!=', ast.Identifier(field.name), ast.Nil()), callinfo, ast.Nil())
def cacheName_ClassDef(self, cls): # self.logger.debug('cacheName_ClassDef', cls, cls.owner, cls.instantiator, cls.instantiation) owner = cls.owner assert not owner.hasSymbol(cls.name) assert not isinstance(owner, ast.StatementBlock) if cls.isProtoType(): owner.addSymbol(cls) for p in cls.genericParams[:]: p.visit(self) return if cls.isSimpleClass(): owner.addSymbol(cls) cls.destructor = None for d in cls.definitions: # self.logger.debug('cacheName_ClassDef def', cls.name, d, cls) assert not cls.isProtoType() or cls.isInstantiation(), (cls.name, cls, d) d.visit(self) for script in cls.scripts: script.visit(self) if len(cls.constructors) == 0: cons = ast.FuncDef([], cls.name, ast.FuncSpec([], None), ast.StatementBody([])) # self.logger.debug('cacheName_ClassDef add constructor', cls.name, cons, cls) cons.info.type = ast.FuncType.constructor cls.constructors.append(cons) cls.definitions.append(cons) self.setupNewItem(cons, cls, True)
def insertToString(self, cls, basecls, visitor): # visitor.logger.debug('insertToString', cls, basecls) name = 'toString' if name not in cls.symbols: # visitor.logger.debug('insertToString do', cls, basecls) clsname = ast.Call(ast.Identifier('getClassName'), []) thisptr = ast.Call(ast.Identifier('formatId'), []) expr = None if 'name' in cls.symbols: # visitor.logger.debug('insertToString with name', cls, basecls, clsname, thisptr) expr = ast.BinaryOp( '%', ast.makeLiteral('%s(name=%s,id=%s)'), ast.TupleLiteral( [clsname, ast.Identifier('name'), thisptr])) else: # visitor.logger.debug('insertToString without name', cls, basecls, clsname, thisptr) expr = ast.BinaryOp('%', ast.makeLiteral('%s(id=%s)'), ast.TupleLiteral([clsname, thisptr])) func = ast.FuncDef([], name, ast.FuncSpec([], ast.makePrimitiveType('string')), ast.StatementBody([ast.Return(expr)])) # visitor.logger.debug('insertFunc ok', name, cls, basecls, cls.primaryVars, func) cls.definitions.append(func) func.setOwner(cls) visitor.visitNewItem(func)
def addMixinFunc(self, visitor, script, f, owner, mixincls): # visitor.logger.debug('addMixinFunc', f.name, owner, f, mixincls) if not owner.hasSymbol(f.name): callinfo = ast.Call(ast.AttrRef(script.args[1].clone(), f.name), [ast.Identifier(param.name) for param in f.spec.params]) # visitor.logger.debug('addMixinFunc callinfo', f.name, owner, f, mixincls, callinfo, callinfo.caller) newfunc = ast.FuncDef([], f.name, f.spec.clone(), ast.StatementBody([ast.Return(callinfo)])) owner.definitions.append(newfunc) newfunc.setOwner(owner) visitor.visitNewItem(newfunc)
def processScript(self, visitor, script): owner = script.owner assert isinstance(owner, ast.ClassDef) cls = owner cls.singleton = True if not cls.hasSymbol('instance'): proto = parseFuncProto('instance() => %s' % owner.name) func = ast.FuncDef([], proto.name, proto.spec, ast.StatementBody([])) func.spec.static = True cls.definitions.append(func) func.setOwner(cls) visitor.visitNewItem(func) visitor.logger.debug('SingletonScript.processScript func', cls.name, func.name, cls, func)
def processScript(self, visitor, script): owner = script.owner assert isinstance(owner, ast.ClassDef), (script, script.owner) # visitor.logger.debug('NameScript.processScript', self, script, owner) cls = owner if not cls.hasSymbol('getClassName'): # visitor.logger.debug('NameScript.processScript add getClassName', self, script, owner) proto = parseFuncProto('getClassName() => string') stmts = [ast.Return(ast.makeLiteral(cls.name))] func = ast.FuncDef([], proto.name, proto.spec, ast.StatementBody(stmts)) cls.definitions.append(func) func.setOwner(cls) visitor.visitNewItem(func)
def insertFunc(self, cls, basecls, visitor, name, fieldExprGen, stmtsGen): basefunc = basecls.symbols[name] if name not in cls.symbols: # visitor.logger.debug('insertFunc', name, cls, basecls, cls.primaryVars) stmts = [ self.generateFieldExpr(cls, basecls, basefunc, fieldExprGen, visitor, field) for field in cls.primaryVars ] stmts = [stmt for stmt in stmts if stmt is not None] stmts = stmtsGen(cls, basecls, visitor, stmts) func = ast.FuncDef([], name, basefunc.spec.clone(), ast.StatementBody(stmts)) # visitor.logger.debug('insertFunc ok', name, cls, basecls, cls.primaryVars, func, stmts) cls.definitions.append(func) func.setOwner(cls) visitor.visitNewItem(func)
def generateInitializeOwnerCall(self, cls, basecls, basefunc, field): # print('generateInitializeOwnerCall', basefunc.name, cls, field, basefunc) # msgstmt = ast.Call(ast.Identifier('println'), [ast.makeLiteral('generate initializeOwner start ' + field.name), # ast.Identifier(field.name), # ast.Call(ast.Identifier('toString'), [])]) body = ast.StatementBody([ # ast.Call(ast.Identifier('println'), [ast.makeLiteral('generate initializeOwner ' + field.name), # ast.Identifier(field.name), # ast.Call(ast.Identifier('toString'), [])]), ast.Call(ast.AttrRef(ast.Identifier(field.name), 'setOwner'), [ast.This()]), self.generateSimpleFieldCall(cls, basecls, basefunc, field, 'initializeOwner') ]) branch = ast.IfBranch( ast.BinaryOp('!=', ast.Identifier(field.name), ast.Nil()), body) # return ast.StatementBody([msgstmt, ast.IfStatement([branch], None)]) return ast.IfStatement([branch], None)
def processScript(self, visitor, script): owner = script.owner # visitor.logger.debug('MixinScript.processScript', script, owner.bases, script.args) assert isinstance(owner, ast.ClassDef) script.mixin_var_type = ast.UserType(getScriptQuialifiedName(script.args[0])) script.mixin_var = ast.SingleVarDef(script.mixin_var_name, script.mixin_var_type, ast.Call(script.args[0].clone(), script.args[3:], script.namedArgs)) proto = parseFuncProto('%s() => %s' % (script.mixin_propget_name, script.mixin_var_type.fullpath)) script.mixin_propget = ast.FuncDef([], script.mixin_propget_name, proto.spec, ast.StatementBody([ast.Return(ast.Identifier(script.mixin_var_name))])) script.mixin_class = owner.resolveSymbol(script.mixin_var_type.path) # visitor.logger.debug('MixinScript.processScript add var', owner, script.owner, script, owner.bases, script.args, script.mixin_var) owner.definitions.append(script.mixin_var) script.mixin_var.setOwner(script.owner) owner.definitions.append(script.mixin_propget) script.mixin_propget.setOwner(script.owner) # visitor.logger.debug('MixinScript.processScript add var', owner, script.owner, script, owner.bases, script.args, script.mixin_var, script.mixin_var.owner) visitor.visitNewItem(script.mixin_var) visitor.visitNewItem(script.mixin_propget) self.addMixinFuncs(visitor, script, script.mixin_class, owner)
def generateFieldExpr(self, cls, basecls, basefunc, fieldExprGen, visitor, field): # visitor.logger.debug('generateFieldExpr', basefunc.name, cls, basecls, visitor, field, field.getType(), fieldExprGen) isStatement = basefunc.spec.returnType is None or ( isinstance(basefunc.spec.returnType, ast.UserType) and basefunc.spec.returnType.fullpath == 'void') vartype = field.getType() assert isinstance(vartype, ast.Type), (field, field.name, vartype) assert vartype, (visitor, field) if isinstance(vartype, ast.UserType) and vartype.fullpath == 'List': fvar = None collcopy = ast.Slicing(ast.Identifier(field.name), None, None, None) # visitor.logger.debug('generateFieldExpr ListType', basefunc.name, cls, field) if isinstance( vartype.genericArgs[0].type, ast.UserType ) and vartype.genericArgs[0].type.fullpath == 'Tuple': varnames = [ field.name + '_item' + str(i) for i in range( len(vartype.genericArgs[0].type.elementTypes)) ] fvar = ast.createTupleVarDef( varnames, vartype.genericArgs[0].type.clone(), None) fvar.type.setTarget(vartype.genericArgs[0].type.getTarget()) else: fvar = ast.SingleVarDef(field.name + '_item', vartype.genericArgs[0].type.clone(), None) fvar.type.setTarget(vartype.genericArgs[0].type.getTarget()) if isStatement: stmts = self.generateFieldExpr(cls, basecls, basefunc, fieldExprGen, visitor, fvar) if stmts is None: # assert basefunc.name != 'visitChildren', (cls, basecls, basefunc, field, isStatement, field.getType()) return None if not isinstance(stmts, list): stmts = [stmts] else: stmts = [stmt for stmt in stmts if stmt is not None] return ast.ForEachStatement( fvar, collcopy, ast.StatementBody(stmts)) if stmts else None else: listfor = ast.ListComprehensionFor(fvar, collcopy, None) # visitor.logger.debug('generateFieldExpr add ListComprehension', basefunc, cls, field) assert basefunc.name not in [ 'visitChildren', 'dump', 'dumpCode' ], basefunc stmt = ast.ListComprehension( self.generateFieldExpr(cls, basecls, basefunc, fieldExprGen, visitor, fvar), [listfor]) # visitor.logger.debug('generateFieldExpr ListComprehension', basefunc.name, stmt, cls, basecls, basefunc, field, listfor) return stmt if isinstance(vartype, ast.UserType) and vartype.fullpath == 'Tuple': assert isinstance(field, ast.TupleVarDef), (basecls, visitor, field) exprs = [ self.generateFieldExpr(cls, basecls, basefunc, fieldExprGen, visitor, itemvar) for itemvar in field.vars ] return exprs if isStatement else ast.TupleLiteral(exprs) varcls = vartype.getTypeClass() if ast.isSubClass(varcls, basecls): callinfo = fieldExprGen(cls, basecls, basefunc, field) if isStatement: stmts = [ ast.CallStatement(c) if isinstance(c, ast.Call) else c for c in callinfo ] if isinstance(callinfo, list) else ast.CallStatement( callinfo) if isinstance(callinfo, ast.Call) else callinfo # visitor.logger.debug('generateFieldExpr ok', basefunc.name, cls, basecls, visitor, field, stmts) return stmts return callinfo # visitor.logger.debug('generateFieldExpr none', basefunc.name, isStatement, vartype, cls, basecls, visitor, field, varcls, ast.isSubClass(varcls, basecls)) return None if isStatement else ast.Identifier(field.name)