func analyzeClassBody(gs *GoState, cls *GoClassDefinition, body *grammar.JClassBody) { for _, bobj := range body.List { switch b := bobj.(type) { case *grammar.JClassDecl: gs.addClassDecl(cls, b) case *grammar.JEnumDecl: gs.Program().addEnum(b) case *grammar.JInterfaceDecl: log.Printf("//ERR// Ignoring class body %T\n", b) /* idecl := analyzeInterfaceDeclaration(gs, b) if idecl != nil { decls = append(decls, idecl) } */ case *grammar.JMethodDecl: cls.AddNewMethod(gs, b) case *grammar.JUnimplemented: log.Printf("//ERR// Ignoring unimplemented body %s\n", b.TypeStr) case *grammar.JVariableDecl: govar := gs.addVariableDecl(b, true) if b.Init == nil { cls.addVar(&GoVarInit{govar: govar}) } else { cls.addVar(analyzeVariableInit(gs, cls, b.Init, govar)) } default: grammar.ReportCastError("Body.ClassDecl", bobj) } } }
func analyzeAllocationExpr(gs *GoState, owner GoMethodOwner, alloc *grammar.JClassAllocationExpr) *GoClassAlloc { if alloc.Name.IsPrimitive() { panic(fmt.Sprintf("Class allocation should not use primitive \"%s\"", alloc.Name.String())) } var type_args []*TypeData if alloc.TypeArgs != nil && len(alloc.TypeArgs) > 0 { type_args = make([]*TypeData, len(alloc.TypeArgs)) for i, arg := range alloc.TypeArgs { if arg.Ts_type != grammar.TS_NONE { log.Printf("//ERR// Ignoring allexpr ts#%d type %v\n", i, arg.Ts_type) } if arg.TypeSpec == nil { type_args[i] = genericObject } else { type_args[i] = gs.Program().createTypeData(arg.TypeSpec.Name, arg.TypeSpec.TypeArgs, 0) } } } var args []GoExpr if alloc.Arglist != nil && len(alloc.Arglist) > 0 { args = make([]GoExpr, len(alloc.Arglist)) for i, arg := range alloc.Arglist { args[i] = analyzeExpr(gs, owner, arg) } } alloc_name := alloc.Name.String() var cref GoClass var body []GoStatement for _, b := range alloc.Body { switch j := b.(type) { case *grammar.JClassBody: gs2 := NewGoState(gs) c2 := NewGoClassDefinition(gs.Program(), owner, alloc_name) analyzeClassBody(gs2, c2, j) var anon_name string for i := 0; ; i++ { anon_name = fmt.Sprintf("Anonymous_%s_%d", alloc_name, i) if gs.findClass(owner, anon_name) == nil { break } } c2.name = anon_name gs.addClass(c2) cref = c2 case *grammar.JBlock: stmt := analyzeBlock(gs, owner, j) if stmt != nil { body = append(body, stmt) } case *grammar.JEmpty: // do nothing default: grammar.ReportCastError("JClassAllocationExpr.body", b) } } if cref == nil { cref = gs.findClass(owner, alloc_name) if cref == nil { cref = &GoClassReference{name: alloc_name, parent: owner} gs.addClass(cref) } } if type_args != nil && len(type_args) > 0 { if gs.Program().verbose { log.Printf("//ERR// Not handling %v type_args\n", alloc_name) } else { log.Printf("//ERR// Not handling clsalloc type_args\n") } type_args = nil } if body != nil && len(body) > 0 { if gs.Program().verbose { log.Printf( "//ERR// Ignoring %v class alloc body (%d stmts)\n", cref.Name(), len(body)) } else { log.Printf("//ERR// Not handling clsalloc body\n") } } arglist := &GoMethodArguments{args} mthd := findMethod(owner, cref, "New"+cref.Name(), arglist, gs.Program().verbose) return &GoClassAlloc{class: cref, method: mthd, type_args: type_args, args: args, body: body} }
func analyzeBlock(gs *GoState, owner GoMethodOwner, blk *grammar.JBlock) *GoBlock { stmts := make([]GoStatement, 0) gs2 := NewGoState(gs) for _, bobj := range blk.List { switch b := bobj.(type) { case *grammar.JBlock: blk := analyzeBlock(gs2, owner, b) if blk != nil { stmts = append(stmts, blk) } case *grammar.JClassDecl: gs2.addClassDecl(owner, b) case *grammar.JEnumDecl: gs2.Program().addEnum(b) case *grammar.JEmpty: continue case *grammar.JForColon: stmt := analyzeForColon(gs2, owner, b) if stmt != nil { stmts = append(stmts, stmt) } case *grammar.JForExpr: stmt := analyzeForExpr(gs2, owner, b) if stmt != nil { stmts = append(stmts, stmt) } case *grammar.JForVar: stmt := analyzeForVar(gs2, owner, b) if stmt != nil { stmts = append(stmts, stmt) } case *grammar.JIfElseStmt: stmt := analyzeIfElseStmt(gs2, owner, b) if stmt != nil { stmts = append(stmts, stmt) } case *grammar.JJumpToLabel: if b != nil { stmts = append(stmts, NewGoJumpToLabel(b.Label, b.IsContinue)) } case *grammar.JLabeledStatement: stmt := analyzeLabelledStmt(gs2, owner, b) if stmt != nil { stmts = append(stmts, stmt) } case *grammar.JLocalVariableDecl: lvlist := analyzeLocalVariableDeclaration(gs2, owner, b) if lvlist != nil && len(lvlist) > 0 { stmts = append(stmts, lvlist...) } case *grammar.JMethodDecl: if cls, ok := owner.(*GoClassDefinition); ok { cls.AddNewMethod(gs2, b) } else { log.Printf("//ERR// Cannot add new method to %T\n", owner) } case *grammar.JSimpleStatement: ss := analyzeSimpleStatement(gs2, owner, b) if ss != nil { stmts = append(stmts, ss) } case *grammar.JSynchronized: ss := analyzeSynchronized(gs2, owner, b) if ss != nil { stmts = append(stmts, ss) } case *grammar.JSwitch: swtch := analyzeSwitch(gs2, owner, b) if swtch != nil { stmts = append(stmts, swtch) } case *grammar.JTry: try := analyzeTry(gs2, owner, b) if try != nil { stmts = append(stmts, try) } case *grammar.JUnimplemented: log.Printf("//ERR// Ignoring unimplemented block %s\n", b.TypeStr) case *grammar.JWhile: while := analyzeWhile(gs2, owner, b) if while != nil { stmts = append(stmts, while) } case nil: log.Printf("//ERR// Ignoring nil block entry\n") default: grammar.ReportCastError("Block", bobj) } } return &GoBlock{stmts: stmts} }