Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 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 // Extract example functions from file ASTs. | 5 // Extract example functions from file ASTs. |
6 | 6 |
7 package doc | 7 package doc |
8 | 8 |
9 import ( | 9 import ( |
10 "go/ast" | 10 "go/ast" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 hasTests = true | 49 hasTests = true |
50 continue | 50 continue |
51 } | 51 } |
52 if !isTest(name, "Example") { | 52 if !isTest(name, "Example") { |
53 continue | 53 continue |
54 } | 54 } |
55 var doc string | 55 var doc string |
56 if f.Doc != nil { | 56 if f.Doc != nil { |
57 doc = f.Doc.Text() | 57 doc = f.Doc.Text() |
58 } | 58 } |
59 » » » output, emptyOutput := exampleOutput(f.Body, file.Commen ts) | 59 » » » output, hasOutput := exampleOutput(f.Body, file.Comments ) |
adg
2013/01/11 03:10:37
output, hasOutput := exampleOutput...
ryanslade
2013/01/11 12:10:31
Done.
| |
60 flist = append(flist, &Example{ | 60 flist = append(flist, &Example{ |
61 Name: name[len("Example"):], | 61 Name: name[len("Example"):], |
62 Doc: doc, | 62 Doc: doc, |
63 Code: f.Body, | 63 Code: f.Body, |
64 Play: playExample(file, f.Body), | 64 Play: playExample(file, f.Body), |
65 Comments: file.Comments, | 65 Comments: file.Comments, |
66 Output: output, | 66 Output: output, |
67 » » » » EmptyOutput: emptyOutput, | 67 » » » » EmptyOutput: output == "" && hasOutput, |
adg
2013/01/11 03:10:37
output == "" && hasOutput
ryanslade
2013/01/11 12:10:31
Done.
| |
68 }) | 68 }) |
69 } | 69 } |
70 if !hasTests && numDecl > 1 && len(flist) == 1 { | 70 if !hasTests && numDecl > 1 && len(flist) == 1 { |
71 // If this file only has one example function, some | 71 // If this file only has one example function, some |
72 // other top-level declarations, and no tests or | 72 // other top-level declarations, and no tests or |
73 // benchmarks, use the whole file as the example. | 73 // benchmarks, use the whole file as the example. |
74 flist[0].Code = file | 74 flist[0].Code = file |
75 flist[0].Play = playExampleFile(file) | 75 flist[0].Play = playExampleFile(file) |
76 } | 76 } |
77 list = append(list, flist...) | 77 list = append(list, flist...) |
78 } | 78 } |
79 sort.Sort(exampleByName(list)) | 79 sort.Sort(exampleByName(list)) |
80 return list | 80 return list |
81 } | 81 } |
82 | 82 |
83 var outputPrefix = regexp.MustCompile(`(?i)^[[:space:]]*output:`) | 83 var outputPrefix = regexp.MustCompile(`(?i)^[[:space:]]*output:`) |
84 | 84 |
85 // Extracts the expected output along with a bool indicating whether we expect i t to be empty | 85 // Extracts the expected output and whether there was a valid output comment |
86 func exampleOutput(b *ast.BlockStmt, comments []*ast.CommentGroup) (string, bool ) { | 86 func exampleOutput(b *ast.BlockStmt, comments []*ast.CommentGroup) (output strin g, ok bool) { |
adg
2013/01/11 03:10:37
the return values should be (output string, ok boo
ryanslade
2013/01/11 12:10:31
Done.
| |
87 if _, last := lastComment(b, comments); last != nil { | 87 if _, last := lastComment(b, comments); last != nil { |
88 // test that it begins with the correct prefix | 88 // test that it begins with the correct prefix |
89 text := last.Text() | 89 text := last.Text() |
90 if loc := outputPrefix.FindStringIndex(text); loc != nil { | 90 if loc := outputPrefix.FindStringIndex(text); loc != nil { |
91 text = text[loc[1]:] | 91 text = text[loc[1]:] |
92 // Strip zero or more spaces followed by \n or a single space. | 92 // Strip zero or more spaces followed by \n or a single space. |
93 text = strings.TrimLeft(text, " ") | 93 text = strings.TrimLeft(text, " ") |
94 if len(text) > 0 && text[0] == '\n' { | 94 if len(text) > 0 && text[0] == '\n' { |
95 text = text[1:] | 95 text = text[1:] |
96 } | 96 } |
97 » » » return text, false | 97 » » » return text, true |
98 » » } | 98 » » } |
99 » } | 99 » } |
100 » return "", true // no suitable comment found | 100 » return "", false // no suitable comment found |
101 } | 101 } |
102 | 102 |
103 // isTest tells whether name looks like a test, example, or benchmark. | 103 // isTest tells whether name looks like a test, example, or benchmark. |
104 // It is a Test (say) if there is a character after Test that is not a | 104 // It is a Test (say) if there is a character after Test that is not a |
105 // lower-case letter. (We don't want Testiness.) | 105 // lower-case letter. (We don't want Testiness.) |
106 func isTest(name, prefix string) bool { | 106 func isTest(name, prefix string) bool { |
107 if !strings.HasPrefix(name, prefix) { | 107 if !strings.HasPrefix(name, prefix) { |
108 return false | 108 return false |
109 } | 109 } |
110 if len(name) == len(prefix) { // "Test" is ok | 110 if len(name) == len(prefix) { // "Test" is ok |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 if cg.Pos() < pos { | 323 if cg.Pos() < pos { |
324 continue | 324 continue |
325 } | 325 } |
326 if cg.End() > end { | 326 if cg.End() > end { |
327 break | 327 break |
328 } | 328 } |
329 i, last = j, cg | 329 i, last = j, cg |
330 } | 330 } |
331 return | 331 return |
332 } | 332 } |
LEFT | RIGHT |