github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/cmd/tast-lint/internal/check/inter_file_refs.go (about)

     1  // Copyright 2018 The ChromiumOS Authors
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package check
     6  
     7  import (
     8  	"fmt"
     9  	"go/ast"
    10  	"go/token"
    11  	"path/filepath"
    12  )
    13  
    14  // InterFileRefs checks that entry files do not have inter-file references.
    15  // f should be one obtained from cachedParser; that is, its references within
    16  // the package should have been resolved, but imports should not have been
    17  // resolved.
    18  func InterFileRefs(fs *token.FileSet, f *ast.File) []*Issue {
    19  	const docURL = "https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/writing_tests.md#scoping-and-shared-code"
    20  
    21  	filename := fs.Position(f.Package).Filename
    22  	if !isEntryFile(filename) {
    23  		return nil
    24  	}
    25  
    26  	var issues []*Issue
    27  	v := funcVisitor(func(node ast.Node) {
    28  		// Look into resolved references only. Since we do not resolve imports,
    29  		// all resolved references are declared in the same package.
    30  		id, ok := node.(*ast.Ident)
    31  		if !ok || id == nil || id.Obj == nil || id.Obj.Decl == nil {
    32  			return
    33  		}
    34  
    35  		decl := id.Obj.Decl.(ast.Node)
    36  		declFn := fs.Position(decl.Pos()).Filename
    37  		if declFn != filename {
    38  			issues = append(issues, &Issue{
    39  				Pos:  fs.Position(node.Pos()),
    40  				Msg:  fmt.Sprintf("Tast forbids inter-file references in entry files; move %s %s in %s to a shared package", id.Obj.Kind, id.Name, filepath.Base(declFn)),
    41  				Link: docURL,
    42  			})
    43  		}
    44  	})
    45  	ast.Walk(v, f)
    46  
    47  	return issues
    48  }