Source file src/cmd/vendor/golang.org/x/tools/internal/packagepath/packagepath.go

     1  // Copyright 2025 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 packagepath provides metadata operations on package path
     6  // strings.
     7  package packagepath
     8  
     9  // (This package should not depend on go/ast.)
    10  import "strings"
    11  
    12  // CanImport reports whether one package is allowed to import another.
    13  //
    14  // TODO(adonovan): allow customization of the accessibility relation
    15  // (e.g. for Bazel).
    16  func CanImport(from, to string) bool {
    17  	// TODO(adonovan): better segment hygiene.
    18  	if to == "internal" || strings.HasPrefix(to, "internal/") {
    19  		// Special case: only std packages may import internal/...
    20  		// We can't reliably know whether we're in std, so we
    21  		// use a heuristic on the first segment.
    22  		first, _, _ := strings.Cut(from, "/")
    23  		if strings.Contains(first, ".") {
    24  			return false // example.com/foo ∉ std
    25  		}
    26  		if first == "testdata" {
    27  			return false // testdata/foo ∉ std
    28  		}
    29  	}
    30  	if strings.HasSuffix(to, "/internal") {
    31  		return strings.HasPrefix(from, to[:len(to)-len("/internal")])
    32  	}
    33  	if i := strings.LastIndex(to, "/internal/"); i >= 0 {
    34  		return strings.HasPrefix(from, to[:i])
    35  	}
    36  	return true
    37  }
    38  
    39  // IsStdPackage reports whether the specified package path belongs to a
    40  // package in the standard library (including internal dependencies).
    41  func IsStdPackage(path string) bool {
    42  	// A standard package has no dot in its first segment.
    43  	// (It may yet have a dot, e.g. "vendor/golang.org/x/foo".)
    44  	slash := strings.IndexByte(path, '/')
    45  	if slash < 0 {
    46  		slash = len(path)
    47  	}
    48  	return !strings.Contains(path[:slash], ".") && path != "testdata"
    49  }
    50  

View as plain text