1
2
3
4
5
6
7
8
9
10 package godoc
11
12 import (
13 "bytes"
14 "fmt"
15 "go/ast"
16 "go/token"
17 )
18
19 type Snippet struct {
20 Line int
21 Text string
22 }
23
24 func (p *Presentation) newSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
25
26 var buf1 bytes.Buffer
27 p.writeNode(&buf1, nil, fset, decl)
28
29 var buf2 bytes.Buffer
30 buf2.WriteString("<pre>")
31 FormatText(&buf2, buf1.Bytes(), -1, true, id.Name, nil)
32 buf2.WriteString("</pre>")
33 return &Snippet{fset.Position(id.Pos()).Line, buf2.String()}
34 }
35
36 func findSpec(list []ast.Spec, id *ast.Ident) ast.Spec {
37 for _, spec := range list {
38 switch s := spec.(type) {
39 case *ast.ImportSpec:
40 if s.Name == id {
41 return s
42 }
43 case *ast.ValueSpec:
44 for _, n := range s.Names {
45 if n == id {
46 return s
47 }
48 }
49 case *ast.TypeSpec:
50 if s.Name == id {
51 return s
52 }
53 }
54 }
55 return nil
56 }
57
58 func (p *Presentation) genSnippet(fset *token.FileSet, d *ast.GenDecl, id *ast.Ident) *Snippet {
59 s := findSpec(d.Specs, id)
60 if s == nil {
61 return nil
62 }
63
64
65 dd := &ast.GenDecl{
66 Doc: d.Doc,
67 TokPos: d.Pos(),
68 Tok: d.Tok,
69 Lparen: d.Lparen,
70 Specs: []ast.Spec{s},
71 Rparen: d.Rparen,
72 }
73
74 return p.newSnippet(fset, dd, id)
75 }
76
77 func (p *Presentation) funcSnippet(fset *token.FileSet, d *ast.FuncDecl, id *ast.Ident) *Snippet {
78 if d.Name != id {
79 return nil
80 }
81
82
83 dd := &ast.FuncDecl{
84 Doc: d.Doc,
85 Recv: d.Recv,
86 Name: d.Name,
87 Type: d.Type,
88 }
89
90 return p.newSnippet(fset, dd, id)
91 }
92
93
94
95
96 func NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
97
98
99 var p Presentation
100 p.TabWidth = 4
101 return p.NewSnippet(fset, decl, id)
102 }
103
104
105
106
107 func (p *Presentation) NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
108 var s *Snippet
109 switch d := decl.(type) {
110 case *ast.GenDecl:
111 s = p.genSnippet(fset, d, id)
112 case *ast.FuncDecl:
113 s = p.funcSnippet(fset, d, id)
114 }
115
116
117 if s == nil {
118 var buf bytes.Buffer
119 fmt.Fprintf(&buf, `<span class="alert">could not generate a snippet for <span class="highlight">%s</span></span>`, id.Name)
120 s = &Snippet{fset.Position(id.Pos()).Line, buf.String()}
121 }
122 return s
123 }
124
View as plain text