// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package noder

import (
	"go/constant"

	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/syntax"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/compile/internal/types2"
)

// TODO(mdempsky): Skip blank declarations? Probably only safe
// for declarations without pragmas.

func (g *irgen) decls(res *ir.Nodes, decls []syntax.Decl) {
	for _, decl := range decls {
		switch decl := decl.(type) {
		case *syntax.ConstDecl:
			g.constDecl(res, decl)
		case *syntax.FuncDecl:
			g.funcDecl(res, decl)
		case *syntax.TypeDecl:
			if ir.CurFunc == nil {
				continue // already handled in irgen.generate
			}
			g.typeDecl(res, decl)
		case *syntax.VarDecl:
			g.varDecl(res, decl)
		default:
			g.unhandled("declaration", decl)
		}
	}
}

func (g *irgen) importDecl(p *noder, decl *syntax.ImportDecl) {
	g.pragmaFlags(decl.Pragma, 0)

	// Get the imported package's path, as resolved already by types2
	// and gcimporter. This is the same path as would be computed by
	// parseImportPath.
	switch pkgNameOf(g.info, decl).Imported().Path() {
	case "unsafe":
		p.importedUnsafe = true
	case "embed":
		p.importedEmbed = true
	}
}

// pkgNameOf returns the PkgName associated with the given ImportDecl.
func pkgNameOf(info *types2.Info, decl *syntax.ImportDecl) *types2.PkgName {
	if name := decl.LocalPkgName; name != nil {
		return info.Defs[name].(*types2.PkgName)
	}
	return info.Implicits[decl].(*types2.PkgName)
}

func (g *irgen) constDecl(out *ir.Nodes, decl *syntax.ConstDecl) {
	g.pragmaFlags(decl.Pragma, 0)

	for _, name := range decl.NameList {
		name, obj := g.def(name)

		// For untyped numeric constants, make sure the value
		// representation matches what the rest of the
		// compiler (really just iexport) expects.
		// TODO(mdempsky): Revisit after #43891 is resolved.
		val := obj.(*types2.Const).Val()
		switch name.Type() {
		case types.UntypedInt, types.UntypedRune:
			val = constant.ToInt(val)
		case types.UntypedFloat:
			val = constant.ToFloat(val)
		case types.UntypedComplex:
			val = constant.ToComplex(val)
		}
		name.SetVal(val)

		out.Append(ir.NewDecl(g.pos(decl), ir.ODCLCONST, name))
	}
}

func (g *irgen) funcDecl(out *ir.Nodes, decl *syntax.FuncDecl) {
	assert(g.curDecl == "")
	// Set g.curDecl to the function name, as context for the type params declared
	// during types2-to-types1 translation if this is a generic function.
	g.curDecl = decl.Name.Value
	obj2 := g.info.Defs[decl.Name]
	recv := types2.AsSignature(obj2.Type()).Recv()
	if recv != nil {
		t2 := deref2(recv.Type())
		// This is a method, so set g.curDecl to recvTypeName.methName instead.
		g.curDecl = t2.(*types2.Named).Obj().Name() + "." + g.curDecl
	}

	fn := ir.NewFunc(g.pos(decl))
	fn.Nname, _ = g.def(decl.Name)
	fn.Nname.Func = fn
	fn.Nname.Defn = fn

	fn.Pragma = g.pragmaFlags(decl.Pragma, funcPragmas)
	if fn.Pragma&ir.Systemstack != 0 && fn.Pragma&ir.Nosplit != 0 {
		base.ErrorfAt(fn.Pos(), "go:nosplit and go:systemstack cannot be combined")
	}
	if fn.Pragma&ir.Nointerface != 0 {
		// Propagate //go:nointerface from Func.Pragma to Field.Nointerface.
		// This is a bit roundabout, but this is the earliest point where we've
		// processed the function's pragma flags, and we've also already created
		// the Fields to represent the receiver's method set.
		if recv := fn.Type().Recv(); recv != nil {
			typ := types.ReceiverBaseType(recv.Type)
			if orig := typ.OrigType(); orig != nil {
				// For a generic method, we mark the methods on the
				// base generic type, since those are the methods
				// that will be stenciled.
				typ = orig
			}
			meth := typecheck.Lookdot1(fn, typecheck.Lookup(decl.Name.Value), typ, typ.Methods(), 0)
			meth.SetNointerface(true)
		}
	}

	if decl.Body != nil {
		if fn.Pragma&ir.Noescape != 0 {
			base.ErrorfAt(fn.Pos(), "can only use //go:noescape with external func implementations")
		}
		if (fn.Pragma&ir.UintptrKeepAlive != 0 && fn.Pragma&ir.UintptrEscapes == 0) && fn.Pragma&ir.Nosplit == 0 {
			// Stack growth can't handle uintptr arguments that may
			// be pointers (as we don't know which are pointers
			// when creating the stack map). Thus uintptrkeepalive
			// functions (and all transitive callees) must be
			// nosplit.
			//
			// N.B. uintptrescapes implies uintptrkeepalive but it
			// is OK since the arguments must escape to the heap.
			//
			// TODO(prattmic): Add recursive nosplit check of callees.
			// TODO(prattmic): Functions with no body (i.e.,
			// assembly) must also be nosplit, but we can't check
			// that here.
			base.ErrorfAt(fn.Pos(), "go:uintptrkeepalive requires go:nosplit")
		}
	}

	if decl.Name.Value == "init" && decl.Recv == nil {
		g.target.Inits = append(g.target.Inits, fn)
	}

	saveHaveEmbed := g.haveEmbed
	saveCurDecl := g.curDecl
	g.curDecl = ""
	g.later(func() {
		defer func(b bool, s string) {
			// Revert haveEmbed and curDecl back to what they were before
			// the "later" function.
			g.haveEmbed = b
			g.curDecl = s
		}(g.haveEmbed, g.curDecl)

		// Set haveEmbed and curDecl to what they were for this funcDecl.
		g.haveEmbed = saveHaveEmbed
		g.curDecl = saveCurDecl
		if fn.Type().HasTParam() {
			g.topFuncIsGeneric = true
		}
		g.funcBody(fn, decl.Recv, decl.Type, decl.Body)
		g.topFuncIsGeneric = false
		if fn.Type().HasTParam() && fn.Body != nil {
			// Set pointers to the dcls/body of a generic function/method in
			// the Inl struct, so it is marked for export, is available for
			// stenciling, and works with Inline_Flood().
			fn.Inl = &ir.Inline{
				Cost: 1,
				Dcl:  fn.Dcl,
				Body: fn.Body,
			}
		}

		out.Append(fn)
	})
}

func (g *irgen) typeDecl(out *ir.Nodes, decl *syntax.TypeDecl) {
	// Set the position for any error messages we might print (e.g. too large types).
	base.Pos = g.pos(decl)
	assert(ir.CurFunc != nil || g.curDecl == "")
	// Set g.curDecl to the type name, as context for the type params declared
	// during types2-to-types1 translation if this is a generic type.
	saveCurDecl := g.curDecl
	g.curDecl = decl.Name.Value
	if decl.Alias {
		name, _ := g.def(decl.Name)
		g.pragmaFlags(decl.Pragma, 0)
		assert(name.Alias()) // should be set by irgen.obj

		out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
		g.curDecl = ""
		return
	}

	// Prevent size calculations until we set the underlying type.
	types.DeferCheckSize()

	name, obj := g.def(decl.Name)
	ntyp, otyp := name.Type(), obj.Type()
	if ir.CurFunc != nil {
		ntyp.SetVargen()
	}

	pragmas := g.pragmaFlags(decl.Pragma, 0)
	name.SetPragma(pragmas) // TODO(mdempsky): Is this still needed?

	ntyp.SetUnderlying(g.typeExpr(decl.Type))

	tparams := otyp.(*types2.Named).TypeParams()
	if n := tparams.Len(); n > 0 {
		rparams := make([]*types.Type, n)
		for i := range rparams {
			rparams[i] = g.typ(tparams.At(i))
		}
		// This will set hasTParam flag if any rparams are not concrete types.
		ntyp.SetRParams(rparams)
	}
	types.ResumeCheckSize()

	g.curDecl = saveCurDecl
	if otyp, ok := otyp.(*types2.Named); ok && otyp.NumMethods() != 0 {
		methods := make([]*types.Field, otyp.NumMethods())
		for i := range methods {
			m := otyp.Method(i)
			// Set g.curDecl to recvTypeName.methName, as context for the
			// method-specific type params in the receiver.
			g.curDecl = decl.Name.Value + "." + m.Name()
			meth := g.obj(m)
			methods[i] = types.NewField(meth.Pos(), g.selector(m), meth.Type())
			methods[i].Nname = meth
			g.curDecl = ""
		}
		ntyp.Methods().Set(methods)
	}

	out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
}

func (g *irgen) varDecl(out *ir.Nodes, decl *syntax.VarDecl) {
	pos := g.pos(decl)
	// Set the position for any error messages we might print (e.g. too large types).
	base.Pos = pos
	names := make([]*ir.Name, len(decl.NameList))
	for i, name := range decl.NameList {
		names[i], _ = g.def(name)
	}

	if decl.Pragma != nil {
		pragma := decl.Pragma.(*pragmas)
		varEmbed(g.makeXPos, names[0], decl, pragma, g.haveEmbed)
		g.reportUnused(pragma)
	}

	haveEmbed := g.haveEmbed
	do := func() {
		defer func(b bool) { g.haveEmbed = b }(g.haveEmbed)

		g.haveEmbed = haveEmbed
		values := g.exprList(decl.Values)

		var as2 *ir.AssignListStmt
		if len(values) != 0 && len(names) != len(values) {
			as2 = ir.NewAssignListStmt(pos, ir.OAS2, make([]ir.Node, len(names)), values)
		}

		for i, name := range names {
			if ir.CurFunc != nil {
				out.Append(ir.NewDecl(pos, ir.ODCL, name))
			}
			if as2 != nil {
				as2.Lhs[i] = name
				name.Defn = as2
			} else {
				as := ir.NewAssignStmt(pos, name, nil)
				if len(values) != 0 {
					as.Y = values[i]
					name.Defn = as
				} else if ir.CurFunc == nil {
					name.Defn = as
				}
				if !g.delayTransform() {
					lhs := []ir.Node{as.X}
					rhs := []ir.Node{}
					if as.Y != nil {
						rhs = []ir.Node{as.Y}
					}
					transformAssign(as, lhs, rhs)
					as.X = lhs[0]
					if as.Y != nil {
						as.Y = rhs[0]
					}
				}
				as.SetTypecheck(1)
				out.Append(as)
			}
		}
		if as2 != nil {
			if !g.delayTransform() {
				transformAssign(as2, as2.Lhs, as2.Rhs)
			}
			as2.SetTypecheck(1)
			out.Append(as2)
		}
	}

	// If we're within a function, we need to process the assignment
	// part of the variable declaration right away. Otherwise, we leave
	// it to be handled after all top-level declarations are processed.
	if ir.CurFunc != nil {
		do()
	} else {
		g.later(do)
	}
}

// pragmaFlags returns any specified pragma flags included in allowed,
// and reports errors about any other, unexpected pragmas.
func (g *irgen) pragmaFlags(pragma syntax.Pragma, allowed ir.PragmaFlag) ir.PragmaFlag {
	if pragma == nil {
		return 0
	}
	p := pragma.(*pragmas)
	present := p.Flag & allowed
	p.Flag &^= allowed
	g.reportUnused(p)
	return present
}

// reportUnused reports errors about any unused pragmas.
func (g *irgen) reportUnused(pragma *pragmas) {
	for _, pos := range pragma.Pos {
		if pos.Flag&pragma.Flag != 0 {
			base.ErrorfAt(g.makeXPos(pos.Pos), "misplaced compiler directive")
		}
	}
	if len(pragma.Embeds) > 0 {
		for _, e := range pragma.Embeds {
			base.ErrorfAt(g.makeXPos(e.Pos), "misplaced go:embed directive")
		}
	}
}
