Esempio n. 1
0
func buildFunc(b *builder, f *pkgFunc) *tast.Func {
	b.scope.Push()
	defer scopePopAndCheck(b)

	t := f.sym.ObjType.(*types.Func)
	b.retNamed = f.f.NamedRet()
	b.retType = t.RetTypes

	ret := new(tast.Func)
	ret.Sym = f.sym

	if b.this != nil {
		if f.f.Recv != nil {
			if recvTok := f.f.Recv.Recv; recvTok != nil {
				recvSym := declareVar(b, recvTok, b.thisType, true)
				if recvSym == nil {
					return nil
				}
				ret.Receiver = recvSym
			}
		} else {
			// marking keyword <this> if it is an inlined method
			ret.This = b.thisType
		}
	}

	if b.this != nil {
		ret.Args = declareParas(b, f.f.Args, t.Args[1:])
	} else {
		ret.Args = declareParas(b, f.f.Args, t.Args)
	}

	if b.retNamed {
		ret.NamedRets = declareParas(b, f.f.Rets, t.Rets)
	}

	ret.Body = buildStmts(b, f.f.Body.Stmts)

	if len(b.retType) > 0 && !isBlockTerminal(f.f.Body) {
		b.Errorf(f.f.Body.Rbrace.Pos, "missing return at the end of function")
	}

	// clear for safety
	b.retType = nil
	b.retNamed = false

	return ret
}
Esempio n. 2
0
func buildFunc(b *builder, f *pkgFunc) *tast.Func {
	b.scope.Push()
	defer b.scope.Pop()

	t := f.sym.ObjType.(*types.Func)
	b.retNamed = f.f.NamedRet()
	b.retType = t.RetTypes

	ret := new(tast.Func)
	ret.Sym = f.sym

	if b.this != nil {
		if f.f.Recv != nil {
			if recvTok := f.f.Recv.Recv; recvTok != nil {
				recvSym := declareVar(b, recvTok, b.thisType)
				if recvSym == nil {
					return nil
				}
				ret.Receiver = recvSym
			}
		} else {
			// marking keyword <this> if it is an inlined method
			ret.This = b.thisType
		}
	}

	if b.this != nil {
		ret.Args = declareParas(b, f.f.Args, t.Args[1:])
	} else {
		ret.Args = declareParas(b, f.f.Args, t.Args)
	}

	if b.retNamed {
		ret.NamedRets = declareParas(b, f.f.Rets, t.Rets)
	}

	ret.Body = buildStmts(b, f.f.Body.Stmts)

	// clear for safety
	b.retType = nil
	b.retNamed = false

	return ret
}