@@ -549,7 +549,7 @@ func (p *Package) extractEmbedLines(addError func(error)) {
549549 }
550550
551551 // Look for //go:embed comments.
552- var allPatterns []string
552+ var allPatterns []embedPattern
553553 for _ , comment := range doc .List {
554554 if comment .Text != "//go:embed" && ! strings .HasPrefix (comment .Text , "//go:embed " ) {
555555 continue
@@ -577,20 +577,20 @@ func (p *Package) extractEmbedLines(addError func(error)) {
577577 })
578578 continue
579579 }
580- for _ , pattern := range patterns {
580+ for _ , ep := range patterns {
581581 // Check that the pattern is well-formed.
582582 // It must be valid: the Go toolchain has already
583583 // checked for invalid patterns. But let's check
584584 // anyway to be sure.
585- if _ , err := path .Match (pattern , "" ); err != nil {
585+ if _ , err := path .Match (ep . pattern , "" ); err != nil {
586586 addError (types.Error {
587587 Fset : p .program .fset ,
588588 Pos : comment .Pos (),
589589 Msg : "invalid pattern syntax" ,
590590 })
591591 continue
592592 }
593- allPatterns = append (allPatterns , pattern )
593+ allPatterns = append (allPatterns , ep )
594594 }
595595 }
596596
@@ -624,16 +624,8 @@ func (p *Package) extractEmbedLines(addError func(error)) {
624624 // Match all //go:embed patterns against the embed files
625625 // provided by `go list`.
626626 for _ , name := range p .EmbedFiles {
627- for _ , pattern := range allPatterns {
628- // Check for "all:" prefix which includes hidden files.
629- // See: https://pkg.go.dev/embed#hdr-Directives
630- includeHidden := false
631- matchPat := pattern
632- if strings .HasPrefix (pattern , "all:" ) {
633- includeHidden = true
634- matchPat = pattern [4 :] // strip "all:" prefix
635- }
636- if matchPattern (matchPat , name , includeHidden ) {
627+ for _ , ep := range allPatterns {
628+ if matchPattern (ep .pattern , name , ep .includeHidden ) {
637629 p .EmbedGlobals [globalName ] = append (p .EmbedGlobals [globalName ], & EmbedFile {
638630 Name : name ,
639631 NeedsData : byteSlice ,
@@ -651,8 +643,7 @@ func (p *Package) extractEmbedLines(addError func(error)) {
651643
652644// matchPattern returns true if (and only if) the given pattern would match the
653645// filename. The pattern could also match a parent directory of name, in which
654- // case hidden files do not match (unless includeHidden is true, which happens
655- // when the pattern had an "all:" prefix).
646+ // case hidden files do not match (unless includeHidden is true).
656647func matchPattern (pattern , name string , includeHidden bool ) bool {
657648 // Match this file.
658649 matched , _ := path .Match (pattern , name )
@@ -690,13 +681,21 @@ func matchPattern(pattern, name string, includeHidden bool) bool {
690681 }
691682}
692683
684+ // embedPattern represents a parsed //go:embed pattern.
685+ // The "all:" prefix (if present) is stripped and reflected in includeHidden.
686+ type embedPattern struct {
687+ pattern string // the glob pattern (without "all:" prefix)
688+ includeHidden bool // true if "all:" prefix was present
689+ }
690+
693691// parseGoEmbed is like strings.Fields but for a //go:embed line. It parses
694692// regular fields and quoted fields (that may contain spaces).
695- func (p * Package ) parseGoEmbed (args string , pos token.Pos ) (patterns []string , err error ) {
693+ func (p * Package ) parseGoEmbed (args string , pos token.Pos ) (patterns []embedPattern , err error ) {
696694 args = strings .TrimSpace (args )
697695 initialLen := len (args )
698696 for args != "" {
699697 patternPos := pos + token .Pos (initialLen - len (args ))
698+ var pattern string
700699 switch args [0 ] {
701700 case '`' , '"' , '\\' :
702701 // Parse the next pattern using the Go scanner.
@@ -715,8 +714,7 @@ func (p *Package) parseGoEmbed(args string, pos token.Pos) (patterns []string, e
715714 Msg : "invalid quoted string in //go:embed" ,
716715 }
717716 }
718- pattern := constant .StringVal (constant .MakeFromLiteral (lit , tok , 0 ))
719- patterns = append (patterns , pattern )
717+ pattern = constant .StringVal (constant .MakeFromLiteral (lit , tok , 0 ))
720718 args = strings .TrimLeftFunc (args [len (lit ):], unicode .IsSpace )
721719 default :
722720 // The value is just a regular value.
@@ -725,23 +723,25 @@ func (p *Package) parseGoEmbed(args string, pos token.Pos) (patterns []string, e
725723 if index < 0 {
726724 index = len (args )
727725 }
728- pattern := args [:index ]
729- patterns = append (patterns , pattern )
726+ pattern = args [:index ]
730727 args = strings .TrimLeftFunc (args [len (pattern ):], unicode .IsSpace )
731728 }
732- // Validate the pattern syntax. Strip "all:" prefix before validation
733- // since it's a directive, not part of the glob pattern.
734- validatePattern := patterns [len (patterns )- 1 ]
735- if strings .HasPrefix (validatePattern , "all:" ) {
736- validatePattern = validatePattern [4 :]
729+ // Parse the "all:" prefix which includes hidden files.
730+ // See: https://pkg.go.dev/embed#hdr-Directives
731+ ep := embedPattern {pattern : pattern }
732+ if strings .HasPrefix (pattern , "all:" ) {
733+ ep .pattern = pattern [4 :]
734+ ep .includeHidden = true
737735 }
738- if _ , err := path .Match (validatePattern , "" ); err != nil {
736+ // Validate the pattern syntax.
737+ if _ , err := path .Match (ep .pattern , "" ); err != nil {
739738 return nil , types.Error {
740739 Fset : p .program .fset ,
741740 Pos : patternPos ,
742741 Msg : "invalid pattern syntax" ,
743742 }
744743 }
744+ patterns = append (patterns , ep )
745745 }
746746 return patterns , nil
747747}
0 commit comments