From 1b834c47a38cf92cf2a01e3b9c208232f97b95f9 Mon Sep 17 00:00:00 2001 From: caixw Date: Tue, 12 Jul 2016 19:39:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E5=88=86=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/app.go | 2 +- input/block.go | 9 +++++---- input/lang.go | 13 ++++++++----- input/lang_test.go | 26 +++++++++++++++++++++++++- input/lexer.go | 4 ++-- input/pascal.go | 2 ++ input/swift.go | 1 + 7 files changed, 44 insertions(+), 13 deletions(-) diff --git a/app/app.go b/app/app.go index 09918858..6095df19 100644 --- a/app/app.go +++ b/app/app.go @@ -17,7 +17,7 @@ const ( // 版本号 // // 版本号按照 http://semver.org 中的规则 - Version = "2.16.6+20160712" + Version = "2.16.7+20160712" // 程序的正式名称 Name = "apidoc" diff --git a/input/block.go b/input/block.go index 3fa3bbc2..c8767c3e 100644 --- a/input/block.go +++ b/input/block.go @@ -5,6 +5,7 @@ package input import ( + "fmt" "strings" "unicode" "unicode/utf8" @@ -27,6 +28,8 @@ type blocker interface { } // block 定义了与语言相关的三种类型的代码块:单行注释,多行注释,字符串。 +// +// block 作为 blocker 的默认实现,能适应大部分语言的定义。 type block struct { Type int8 // 代码块的类型,可以是字符串,单行注释或是多行注释 Begin string // 块的起始字符串 @@ -38,8 +41,6 @@ func (b *block) BeginFunc(l *lexer) bool { return l.match(b.Begin) } -// 返回从当前位置到定义结束的所有字符 -// 返回值 bool 提示是否正常找到结束标记 func (b *block) EndFunc(l *lexer) ([]rune, bool) { switch b.Type { case blockTypeString: @@ -48,9 +49,9 @@ func (b *block) EndFunc(l *lexer) ([]rune, bool) { return b.endMComments(l) case blockTypeSComment: return b.endSComments(l) + default: + panic(fmt.Sprint("定义了一个无效的 block.Type 值:", b.Type)) } - - return nil, false } // 从 l 的当前位置开始往后查找,直到找到 b 中定义的 end 字符串, diff --git a/input/lang.go b/input/lang.go index 205e5e2b..c3c9540a 100644 --- a/input/lang.go +++ b/input/lang.go @@ -13,7 +13,7 @@ import ( // 所有支持的语言模型定义 // -// NOTE: 应该保持键名为小写,按字母顺序排列,方便查找。 +// NOTE: 应该保持键名为非大写,按字母顺序排列,方便查找。 // langs 应该和 langExts 保持一一对应关系。 var langs = map[string][]blocker{ // C# @@ -43,7 +43,7 @@ var langs = map[string][]blocker{ &block{Type: blockTypeString, Begin: "/", End: "/", Escape: `\`}, // 正则表达式 }, - // pascal + // pascal/delphi "pascal": []blocker{ newPascalStringBlock('\''), newPascalStringBlock('"'), @@ -105,7 +105,9 @@ var cStyle = []blocker{ // 各语言默认支持的文件扩展名。 // -// NOTE: 应该保持键名、键值均为小写 +// NOTE: 键名与 langs 中的键一一对应。 +// 键值为可能的文件扩展名列表,应该使用非大写状态。 +// `go test` 会作大量名称是否规范的检测。 var langExts = map[string][]string{ "c#": []string{".cs"}, "c++": []string{".h", ".c", ".cpp", ".cxx", "hpp"}, @@ -121,7 +123,7 @@ var langExts = map[string][]string{ "swift": []string{".swift"}, } -// 返回所有支持的语言 +// Langs 返回所有支持的语言 func Langs() []string { ret := make([]string, 0, len(langs)) for l := range langs { @@ -131,9 +133,10 @@ func Langs() []string { return ret } -// 检测指定目录下的语言类型。 +// DetectDirLang 检测指定目录下的语言类型。 // // 检测依据为根据扩展名来做统计,数量最大且被支持的获胜。 +// 不会分析子目录。 func DetectDirLang(dir string) (string, error) { fs, err := ioutil.ReadDir(dir) if err != nil { diff --git a/input/lang_test.go b/input/lang_test.go index 54a29f69..670b206a 100644 --- a/input/lang_test.go +++ b/input/lang_test.go @@ -6,6 +6,7 @@ package input import ( "testing" + "unicode" "github.com/issue9/assert" ) @@ -17,6 +18,7 @@ func TestLangs(t *testing.T) { a.Contains(list, "go", "php") } +// 检测 block.Type 的取值是否正确。 func TestChkBlockType(t *testing.T) { a := assert.New(t) @@ -26,12 +28,34 @@ func TestChkBlockType(t *testing.T) { if !ok { continue } - v := b.Type != blockTypeString || b.Type != blockTypeMComment || b.Type != blockTypeSComment + v := (b.Type == blockTypeString || b.Type == blockTypeMComment || b.Type == blockTypeSComment) a.True(v, "langs[%v].[%v].Type 值为非法值", name, index) } } } +func isNotUpperString(str string) bool { + for _, r := range str { + if unicode.IsUpper(r) { + return false + } + } + + return true +} + +func TestNameAndExtsIsnotUpper(t *testing.T) { + a := assert.New(t) + + for name, exts := range langExts { + a.True(isNotUpperString(name), "非小写名称:%v", name) + for _, ext := range exts { + a.True(isNotUpperString(ext)) + } + } + +} + // 比较 langs 和 langExts 中的语言类型是否都一样。 func TestCompareLangsAndLangExts(t *testing.T) { a := assert.New(t) diff --git a/input/lexer.go b/input/lexer.go index 3e815f86..e006746d 100644 --- a/input/lexer.go +++ b/input/lexer.go @@ -11,7 +11,7 @@ import ( "github.com/caixw/apidoc/app" ) -// NOTE: 非线程安全 +// lexer 是对一个文本内容的包装,方便 blocker 等接口操作。 type lexer struct { data []byte pos int @@ -71,7 +71,7 @@ func (l *lexer) lineNumber() int { return l.ln } -// 构建一个语法错误的信息。 +// 构建一条语法错误的信息。 func (l *lexer) syntaxError(msg string) *app.SyntaxError { return &app.SyntaxError{ Line: l.lineNumber(), diff --git a/input/pascal.go b/input/pascal.go index 0b5af6e2..091fd430 100644 --- a/input/pascal.go +++ b/input/pascal.go @@ -4,6 +4,8 @@ package input +// 描述了 pascal/delphi 语言的注释,在 pascal 中 +// 转义字符即引号本身,不适合直接在 block 中定义。 type pascalStringBlock struct { symbol string escape string diff --git a/input/swift.go b/input/swift.go index 092ee0c3..6c441b06 100644 --- a/input/swift.go +++ b/input/swift.go @@ -4,6 +4,7 @@ package input +// swift 嵌套风格的块注释。会忽略掉内嵌的注释块。 type swiftNestMCommentBlock struct { begin string end string