golang.org/x/tools/gopls@v0.15.3/internal/cache/constraints.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package cache
     6  
     7  import (
     8  	"go/ast"
     9  	"go/build/constraint"
    10  	"go/parser"
    11  	"go/token"
    12  )
    13  
    14  // isStandaloneFile reports whether a file with the given contents should be
    15  // considered a 'standalone main file', meaning a package that consists of only
    16  // a single file.
    17  func isStandaloneFile(src []byte, standaloneTags []string) bool {
    18  	f, err := parser.ParseFile(token.NewFileSet(), "", src, parser.PackageClauseOnly|parser.ParseComments)
    19  	if err != nil {
    20  		return false
    21  	}
    22  
    23  	if f.Name == nil || f.Name.Name != "main" {
    24  		return false
    25  	}
    26  
    27  	found := false
    28  	walkConstraints(f, func(c constraint.Expr) bool {
    29  		if tag, ok := c.(*constraint.TagExpr); ok {
    30  			for _, t := range standaloneTags {
    31  				if t == tag.Tag {
    32  					found = true
    33  					return false
    34  				}
    35  			}
    36  		}
    37  		return true
    38  	})
    39  
    40  	return found
    41  }
    42  
    43  // walkConstraints calls f for each constraint expression in the file, until
    44  // all constraints are exhausted or f returns false.
    45  func walkConstraints(file *ast.File, f func(constraint.Expr) bool) {
    46  	for _, cg := range file.Comments {
    47  		// Even with PackageClauseOnly the parser consumes the semicolon following
    48  		// the package clause, so we must guard against comments that come after
    49  		// the package name.
    50  		if cg.Pos() > file.Name.Pos() {
    51  			continue
    52  		}
    53  		for _, comment := range cg.List {
    54  			if c, err := constraint.Parse(comment.Text); err == nil {
    55  				if !f(c) {
    56  					return
    57  				}
    58  			}
    59  		}
    60  	}
    61  }