mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile: refactor varEmbed logic
Simplify the code and make it easier to reuse with irgen. Change-Id: Id477c36e82c7598faa90025b1eed2606a3f82498 Reviewed-on: https://go-review.googlesource.com/c/go/+/282917 Trust: Matthew Dempsky <mdempsky@google.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
3e1a87ac2a
commit
9e746e4255
1 changed files with 24 additions and 51 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
package noder
|
package noder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/constant"
|
"go/constant"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
@ -556,19 +557,8 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
|
||||||
exprs := p.exprList(decl.Values)
|
exprs := p.exprList(decl.Values)
|
||||||
|
|
||||||
if pragma, ok := decl.Pragma.(*pragmas); ok {
|
if pragma, ok := decl.Pragma.(*pragmas); ok {
|
||||||
if len(pragma.Embeds) > 0 {
|
if err := varEmbed(p.makeXPos, names[0], decl, pragma); err != nil {
|
||||||
if !p.importedEmbed {
|
p.errorAt(decl.Pos(), "%s", err.Error())
|
||||||
// This check can't be done when building the list pragma.Embeds
|
|
||||||
// because that list is created before the noder starts walking over the file,
|
|
||||||
// so at that point it hasn't seen the imports.
|
|
||||||
// We're left to check now, just before applying the //go:embed lines.
|
|
||||||
for _, e := range pragma.Embeds {
|
|
||||||
p.errorAt(e.Pos, "//go:embed only allowed in Go files that import \"embed\"")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
exprs = varEmbed(p, names, typ, exprs, pragma.Embeds)
|
|
||||||
}
|
|
||||||
pragma.Embeds = nil
|
|
||||||
}
|
}
|
||||||
p.checkUnused(pragma)
|
p.checkUnused(pragma)
|
||||||
}
|
}
|
||||||
|
|
@ -2069,53 +2059,36 @@ func oldname(s *types.Sym) ir.Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds []pragmaEmbed) (newExprs []ir.Node) {
|
func varEmbed(makeXPos func(syntax.Pos) src.XPos, name *ir.Name, decl *syntax.VarDecl, pragma *pragmas) error {
|
||||||
haveEmbed := false
|
if pragma.Embeds == nil {
|
||||||
for _, decl := range p.file.DeclList {
|
return nil
|
||||||
imp, ok := decl.(*syntax.ImportDecl)
|
|
||||||
if !ok {
|
|
||||||
// imports always come first
|
|
||||||
break
|
|
||||||
}
|
|
||||||
path, _ := strconv.Unquote(imp.Path.Value)
|
|
||||||
if path == "embed" {
|
|
||||||
haveEmbed = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos := embeds[0].Pos
|
pragmaEmbeds := pragma.Embeds
|
||||||
if !haveEmbed {
|
pragma.Embeds = nil
|
||||||
p.errorAt(pos, "invalid go:embed: missing import \"embed\"")
|
|
||||||
return exprs
|
|
||||||
}
|
|
||||||
if base.Flag.Cfg.Embed.Patterns == nil {
|
if base.Flag.Cfg.Embed.Patterns == nil {
|
||||||
p.errorAt(pos, "invalid go:embed: build system did not supply embed configuration")
|
return errors.New("invalid go:embed: build system did not supply embed configuration")
|
||||||
return exprs
|
|
||||||
}
|
}
|
||||||
if len(names) > 1 {
|
if len(decl.NameList) > 1 {
|
||||||
p.errorAt(pos, "go:embed cannot apply to multiple vars")
|
return errors.New("go:embed cannot apply to multiple vars")
|
||||||
return exprs
|
|
||||||
}
|
}
|
||||||
if len(exprs) > 0 {
|
if decl.Values != nil {
|
||||||
p.errorAt(pos, "go:embed cannot apply to var with initializer")
|
return errors.New("go:embed cannot apply to var with initializer")
|
||||||
return exprs
|
|
||||||
}
|
}
|
||||||
if typ == nil {
|
if decl.Type == nil {
|
||||||
// Should not happen, since len(exprs) == 0 now.
|
// Should not happen, since Values == nil now.
|
||||||
p.errorAt(pos, "go:embed cannot apply to var without type")
|
return errors.New("go:embed cannot apply to var without type")
|
||||||
return exprs
|
|
||||||
}
|
}
|
||||||
if typecheck.DeclContext != ir.PEXTERN {
|
if typecheck.DeclContext != ir.PEXTERN {
|
||||||
p.errorAt(pos, "go:embed cannot apply to var inside func")
|
return errors.New("go:embed cannot apply to var inside func")
|
||||||
return exprs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v := names[0]
|
var embeds []ir.Embed
|
||||||
typecheck.Target.Embeds = append(typecheck.Target.Embeds, v)
|
for _, e := range pragmaEmbeds {
|
||||||
v.Embed = new([]ir.Embed)
|
embeds = append(embeds, ir.Embed{Pos: makeXPos(e.Pos), Patterns: e.Patterns})
|
||||||
for _, e := range embeds {
|
|
||||||
*v.Embed = append(*v.Embed, ir.Embed{Pos: p.makeXPos(e.Pos), Patterns: e.Patterns})
|
|
||||||
}
|
}
|
||||||
return exprs
|
typecheck.Target.Embeds = append(typecheck.Target.Embeds, name)
|
||||||
|
name.Embed = &embeds
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue