2 "Title": "Static analysis features of godoc"
6 span.err { 'font-size:120%; color:darkred; background-color: yellow; }
7 img.ss { margin-left: 1in; } /* screenshot */
8 img.dotted { border: thin dotted; }
11 <!-- Images were grabbed from Chrome/Linux at 150% zoom, and are
12 displayed at 66% of natural size. This allows users to zoom a
13 little before seeing pixels. -->
16 When invoked with the <code>-analysis</code> flag, godoc performs
17 static analysis on the Go packages it indexes and displays the
18 results in the source and package views. This document provides a
19 brief tour of these features.
22 <h2>Type analysis features</h2>
24 <code>godoc -analysis=type</code> performs static checking similar
25 to that done by a compiler: it detects ill-formed programs, resolves
26 each identifier to the entity it denotes, computes the type of each
27 expression and the method set of each type, and determines which
28 types are assignable to each interface type.
30 <b>Type analysis</b> is relatively quick, requiring about 10 seconds for
31 the >200 packages of the standard library, for example.
34 <h3>Compiler errors</h3>
36 If any source file contains a compilation error, the source view
37 will highlight the errant location in red. Hovering over it
38 displays the error message.
40 <img class="ss" width='811' src='error1.png'><br/>
42 <h3>Identifier resolution</h3>
44 In the source view, every referring identifier is annotated with
45 information about the language entity it refers to: a package,
46 constant, variable, type, function or statement label.
48 Hovering over the identifier reveals the entity's kind and type
49 (e.g. <code>var x int</code> or <code>func f
50 func(int) string</code>).
52 <img class="ss" width='652' src='ident-field.png'><br/>
54 <img class="ss" width='652' src='ident-func.png'>
56 Clicking the link takes you to the entity's definition.
58 <img class="ss" width='652' src='ident-def.png'><br/>
60 <h3>Type information: size/alignment, method set, interfaces</h3>
62 Clicking on the identifier that defines a named type causes a panel
63 to appear, displaying information about the named type, including
64 its size and alignment in bytes, its
65 <a href='http://golang.org/ref/spec#Method_sets'>method set</a>, and its
66 <i>implements</i> relation: the set of types T that are assignable to
67 or from this type U where at least one of T or U is an interface.
69 This example shows information about <code>net/rpc.methodType</code>.
71 <img class="ss" width='470' src='typeinfo-src.png'>
73 The method set includes not only the declared methods of the type,
74 but also any methods "promoted" from anonymous fields of structs,
75 such as <code>sync.Mutex</code> in this example.
77 In addition, the receiver type is displayed as <code>*T</code> or
78 <code>T</code> depending on whether it requires the address or just
79 a copy of the receiver value.
82 The method set and <i>implements</i> relation are also available
85 <img class="ss dotted" width='716' src='typeinfo-pkg.png'>
87 <h2>Pointer analysis features</h2>
89 <code>godoc -analysis=pointer</code> additionally performs a precise
90 whole-program <b>pointer analysis</b>. In other words, it
91 approximates the set of memory locations to which each
92 reference—not just vars of kind <code>*T</code>, but also
93 <code>[]T</code>, <code>func</code>, <code>map</code>,
94 <code>chan</code>, and <code>interface</code>—may refer. This
95 information reveals the possible destinations of each dynamic call
96 (via a <code>func</code> variable or interface method), and the
97 relationship between send and receive operations on the same
101 Compared to type analysis, pointer analysis requires more time and
102 memory, and is impractical for code bases exceeding a million lines.
105 <h3>Call graph navigation</h3>
107 When pointer analysis is complete, the source view annotates the
108 code with <b>callers</b> and <b>callees</b> information: callers
109 information is associated with the <code>func</code> keyword that
110 declares a function, and callees information is associated with the
111 open paren '<span style="color: dark-blue"><code>(</code></span>' of
115 In this example, hovering over the declaration of the
116 <code>rot13</code> function (defined in strings/strings_test.go)
117 reveals that it is called in exactly one place.
119 <img class="ss" width='612' src='callers1.png'>
121 Clicking the link navigates to the sole caller. (If there were
122 multiple callers, a list of choices would be displayed first.)
124 <img class="ss" width='680' src='callers2.png'>
126 Notice that hovering over this call reveals that there are 19
127 possible callees at this site, of which our <code>rot13</code>
128 function was just one: this is a dynamic call through a variable of
129 type <code>func(rune) rune</code>.
131 Clicking on the call brings up the list of all 19 potential callees,
132 shown truncated. Many of them are anonymous functions.
134 <img class="ss" width='564' src='call3.png'>
136 Pointer analysis gives a very precise approximation of the call
137 graph compared to type-based techniques.
139 As a case in point, the next example shows the dynamic call inside
140 the <code>testing</code> package responsible for calling all
141 user-defined functions named <code>Example<i>XYZ</i></code>.
143 <img class="ss" width='361' src='call-eg.png'>
145 Recall that all such functions have type <code>func()</code>,
146 i.e. no arguments and no results. A type-based approximation could
147 only conclude that this call might dispatch to any function matching
148 that type—and these are very numerous in most
149 programs—but pointer analysis can track the flow of specific
150 <code>func</code> values through the testing package.
152 As an indication of its precision, the result contains only
153 functions whose name starts with <code>Example</code>.
156 <h3>Intra-package call graph</h3>
158 The same call graph information is presented in a very different way
159 in the package view. For each package, an interactive tree view
160 allows exploration of the call graph as it relates to just that
161 package; all functions from other packages are elided.
163 The roots of the tree are the external entry points of the package:
164 not only its exported functions, but also any unexported or
165 anonymous functions that are called (dynamically) from outside the
169 This example shows the entry points of the
170 <code>path/filepath</code> package, with the call graph for
171 <code>Glob</code> expanded several levels
173 <img class="ss dotted" width='501' src='ipcg-pkg.png'>
175 Notice that the nodes for Glob and Join appear multiple times: the
176 tree is a partial unrolling of a cyclic graph; the full unrolling
177 is in general infinite.
180 For each function documented in the package view, another
181 interactive tree view allows exploration of the same graph starting
184 This is a portion of the internal graph of
185 <code>net/http.ListenAndServe</code>.
187 <img class="ss dotted" width='455' src='ipcg-func.png'>
189 <h3>Channel peers (send ↔ receive)</h3>
191 Because concurrent Go programs use channels to pass not just values
192 but also control between different goroutines, it is natural when
193 reading Go code to want to navigate from a channel send to the
194 corresponding receive so as to understand the sequence of events.
197 Godoc annotates every channel operation—make, send, range,
198 receive, close—with a link to a panel displaying information
199 about other operations that might alias the same channel.
202 This example, from the tests of <code>net/http</code>, shows a send
203 operation on a <code>chan bool</code>.
205 <img class="ss" width='811' src='chan1.png'>
207 Clicking on the <code><-</code> send operator reveals that this
208 channel is made at a unique location (line 332) and that there are
209 three receive operations that might read this value.
211 It hardly needs pointing out that some channel element types are
212 very widely used (e.g. struct{}, bool, int, interface{}) and that a
213 typical Go program might contain dozens of receive operations on a
214 value of type <code>chan bool</code>; yet the pointer analysis is
215 able to distinguish operations on channels at a much finer precision
216 than based on their type alone.
219 Notice also that the send occurs in a different (anonymous) function
220 from the outer one containing the <code>make</code> and the receive
224 Here's another example of send on a different <code>chan
225 bool</code>, also in package <code>net/http</code>:
227 <img class="ss" width='774' src='chan2a.png'>
229 The analysis finds just one receive operation that might receive
230 from this channel, in the test for this feature.
232 <img class="ss" width='737' src='chan2b.png'>
234 <h2>Known issues</h2>
236 All analysis results pertain to exactly
237 one configuration (e.g. amd64 linux). Files that are conditionally
238 compiled based on different platforms or build tags are not visible
242 Files that <code>import "C"</code> require
243 preprocessing by the cgo tool. The file offsets after preprocessing
244 do not align with the unpreprocessed file, so markup is misaligned.
247 Files are not periodically re-analyzed.
248 If the files change underneath the running server, the displayed
249 markup is misaligned.
252 Additional issues are listed at
253 <a href='https://go.googlesource.com/tools/+/master/godoc/analysis/README'>tools/godoc/analysis/README</a>.