OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // The doc package extracts source code documentation from a Go AST. | 5 // The doc package extracts source code documentation from a Go AST. |
6 package doc | 6 package doc |
7 | 7 |
8 import ( | 8 import ( |
9 "container/vector" | 9 "container/vector" |
10 "go/ast" | 10 "go/ast" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 typ := doc.lookupTypeDoc(domName) | 140 typ := doc.lookupTypeDoc(domName) |
141 if typ != nil { | 141 if typ != nil { |
142 values = typ.values // associate with that type | 142 values = typ.values // associate with that type |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 values.Push(decl) | 146 values.Push(decl) |
147 } | 147 } |
148 | 148 |
149 | 149 |
| 150 // Helper function to set the table entry for function f. Makes sure that |
| 151 // at least one f with associated documentation is stored in table, if there |
| 152 // are multiple f's with the same name. |
| 153 func setFunc(table map[string]*ast.FuncDecl, f *ast.FuncDecl) { |
| 154 name := f.Name.Name() |
| 155 if g, exists := table[name]; exists && g.Doc != nil { |
| 156 // a function with the same name has already been registered; |
| 157 // since it has documentation, assume f is simply another |
| 158 // implementation and ignore it |
| 159 // TODO(gri) consider collecting all functions, or at least |
| 160 // all comments |
| 161 return |
| 162 } |
| 163 // function doesn't exist or has no documentation; use f |
| 164 table[name] = f |
| 165 } |
| 166 |
| 167 |
150 func (doc *docReader) addFunc(fun *ast.FuncDecl) { | 168 func (doc *docReader) addFunc(fun *ast.FuncDecl) { |
151 name := fun.Name.Name() | 169 name := fun.Name.Name() |
152 | 170 |
153 // determine if it should be associated with a type | 171 // determine if it should be associated with a type |
154 if fun.Recv != nil { | 172 if fun.Recv != nil { |
155 // method | 173 // method |
156 typ := doc.lookupTypeDoc(baseTypeName(fun.Recv.List[0].Type)) | 174 typ := doc.lookupTypeDoc(baseTypeName(fun.Recv.List[0].Type)) |
157 if typ != nil { | 175 if typ != nil { |
158 // exported receiver type | 176 // exported receiver type |
159 » » » typ.methods[name] = fun | 177 » » » setFunc(typ.methods, fun) |
160 } | 178 } |
161 // otherwise don't show the method | 179 // otherwise don't show the method |
162 // TODO(gri): There may be exported methods of non-exported type
s | 180 // TODO(gri): There may be exported methods of non-exported type
s |
163 // that can be called because of exported values (consts, vars,
or | 181 // that can be called because of exported values (consts, vars,
or |
164 // function results) of that type. Could determine if that is th
e | 182 // function results) of that type. Could determine if that is th
e |
165 // case and then show those methods in an appropriate section. | 183 // case and then show those methods in an appropriate section. |
166 return | 184 return |
167 } | 185 } |
168 | 186 |
169 // perhaps a factory function | 187 // perhaps a factory function |
(...skipping 10 matching lines...) Expand all Loading... |
180 // named and exported result type | 198 // named and exported result type |
181 | 199 |
182 // Work-around for failure of heuristic: In pack
age os | 200 // Work-around for failure of heuristic: In pack
age os |
183 // too many functions are considered factory fun
ctions | 201 // too many functions are considered factory fun
ctions |
184 // for the Error type. Eliminate manually for no
w as | 202 // for the Error type. Eliminate manually for no
w as |
185 // this appears to be the only important case in
the | 203 // this appears to be the only important case in
the |
186 // current library where the heuristic fails. | 204 // current library where the heuristic fails. |
187 if doc.pkgName == "os" && tname == "Error" && | 205 if doc.pkgName == "os" && tname == "Error" && |
188 name != "NewError" && name != "NewSyscal
lError" { | 206 name != "NewError" && name != "NewSyscal
lError" { |
189 // not a factory function for os.Error | 207 // not a factory function for os.Error |
190 » » » » » doc.funcs[name] = fun // treat as ordina
ry function | 208 » » » » » setFunc(doc.funcs, fun) // treat as ordi
nary function |
191 return | 209 return |
192 } | 210 } |
193 | 211 |
194 » » » » typ.factories[name] = fun | 212 » » » » setFunc(typ.factories, fun) |
195 return | 213 return |
196 } | 214 } |
197 } | 215 } |
198 } | 216 } |
199 | 217 |
200 // ordinary function | 218 // ordinary function |
201 » doc.funcs[name] = fun | 219 » setFunc(doc.funcs, fun) |
202 } | 220 } |
203 | 221 |
204 | 222 |
205 func (doc *docReader) addDecl(decl ast.Decl) { | 223 func (doc *docReader) addDecl(decl ast.Decl) { |
206 switch d := decl.(type) { | 224 switch d := decl.(type) { |
207 case *ast.GenDecl: | 225 case *ast.GenDecl: |
208 if len(d.Specs) > 0 { | 226 if len(d.Specs) > 0 { |
209 switch d.Tok { | 227 switch d.Tok { |
210 case token.CONST, token.VAR: | 228 case token.CONST, token.VAR: |
211 // constants and variables are always handled as
a group | 229 // constants and variables are always handled as
a group |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 // TODO: Recognize "Type.Method" as a name. | 663 // TODO: Recognize "Type.Method" as a name. |
646 // TODO(r): maybe precompile the regexps. | 664 // TODO(r): maybe precompile the regexps. |
647 // | 665 // |
648 func (p *PackageDoc) Filter(names []string) { | 666 func (p *PackageDoc) Filter(names []string) { |
649 p.Consts = filterValueDocs(p.Consts, names) | 667 p.Consts = filterValueDocs(p.Consts, names) |
650 p.Vars = filterValueDocs(p.Vars, names) | 668 p.Vars = filterValueDocs(p.Vars, names) |
651 p.Types = filterTypeDocs(p.Types, names) | 669 p.Types = filterTypeDocs(p.Types, names) |
652 p.Funcs = filterFuncDocs(p.Funcs, names) | 670 p.Funcs = filterFuncDocs(p.Funcs, names) |
653 p.Doc = "" // don't show top-level package doc | 671 p.Doc = "" // don't show top-level package doc |
654 } | 672 } |
OLD | NEW |