github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/godoc/spot.go (about)

     1  // Copyright 2013 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 godoc
     6  
     7  // ----------------------------------------------------------------------------
     8  // SpotInfo
     9  
    10  // A SpotInfo value describes a particular identifier spot in a given file;
    11  // It encodes three values: the SpotKind (declaration or use), a line or
    12  // snippet index "lori", and whether it's a line or index.
    13  //
    14  // The following encoding is used:
    15  //
    16  //   bits    32   4    1       0
    17  //   value    [lori|kind|isIndex]
    18  //
    19  type SpotInfo uint32
    20  
    21  // SpotKind describes whether an identifier is declared (and what kind of
    22  // declaration) or used.
    23  type SpotKind uint32
    24  
    25  const (
    26  	PackageClause SpotKind = iota
    27  	ImportDecl
    28  	ConstDecl
    29  	TypeDecl
    30  	VarDecl
    31  	FuncDecl
    32  	MethodDecl
    33  	Use
    34  	nKinds
    35  )
    36  
    37  var (
    38  	// These must match the SpotKind values above.
    39  	name = []string{
    40  		"Packages",
    41  		"Imports",
    42  		"Constants",
    43  		"Types",
    44  		"Variables",
    45  		"Functions",
    46  		"Methods",
    47  		"Uses",
    48  		"Unknown",
    49  	}
    50  )
    51  
    52  func (x SpotKind) Name() string { return name[x] }
    53  
    54  func init() {
    55  	// sanity check: if nKinds is too large, the SpotInfo
    56  	// accessor functions may need to be updated
    57  	if nKinds > 8 {
    58  		panic("internal error: nKinds > 8")
    59  	}
    60  }
    61  
    62  // makeSpotInfo makes a SpotInfo.
    63  func makeSpotInfo(kind SpotKind, lori int, isIndex bool) SpotInfo {
    64  	// encode lori: bits [4..32)
    65  	x := SpotInfo(lori) << 4
    66  	if int(x>>4) != lori {
    67  		// lori value doesn't fit - since snippet indices are
    68  		// most certainly always smaller then 1<<28, this can
    69  		// only happen for line numbers; give it no line number (= 0)
    70  		x = 0
    71  	}
    72  	// encode kind: bits [1..4)
    73  	x |= SpotInfo(kind) << 1
    74  	// encode isIndex: bit 0
    75  	if isIndex {
    76  		x |= 1
    77  	}
    78  	return x
    79  }
    80  
    81  func (x SpotInfo) Kind() SpotKind { return SpotKind(x >> 1 & 7) }
    82  func (x SpotInfo) Lori() int      { return int(x >> 4) }
    83  func (x SpotInfo) IsIndex() bool  { return x&1 != 0 }