Beispiel #1
0
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)
		}
	}
}
Beispiel #2
0
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}
}
Beispiel #3
0
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}
}