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
5package 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//
19type SpotInfo uint32
20
21// SpotKind describes whether an identifier is declared (and what kind of
22// declaration) or used.
23type SpotKind uint32
24
25const (
26	PackageClause SpotKind = iota
27	ImportDecl
28	ConstDecl
29	TypeDecl
30	VarDecl
31	FuncDecl
32	MethodDecl
33	Use
34	nKinds
35)
36
37var (
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
52func (x SpotKind) Name() string { return name[x] }
53
54func 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.
63func 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
81func (x SpotInfo) Kind() SpotKind { return SpotKind(x >> 1 & 7) }
82func (x SpotInfo) Lori() int      { return int(x >> 4) }
83func (x SpotInfo) IsIndex() bool  { return x&1 != 0 }
84