]> Cypherpunks repositories - gostls13.git/commitdiff
internal/lazyregexp: add a lazy Regexp package
authorDaniel Martí <mvdan@mvdan.cc>
Wed, 27 Feb 2019 12:09:22 +0000 (13:09 +0100)
committerDaniel Martí <mvdan@mvdan.cc>
Wed, 27 Feb 2019 15:58:10 +0000 (15:58 +0000)
This was implemented as part of go/doc, but it's going to be useful in
other packages. In particular, many packages under cmd/go like web and
vcs make somewhat heavy use of global regexes, which add a non-trivial
amount of init work to the cmd/go program.

A lazy wrapper around regexp.Regexp will make it trivial to get rid of
the extra cost with a trivial refactor, so make it possible for other
packages in the repository to make use of it. While naming the package,
give the members better names, such as lazyregexp.New and
lazyregexp.Regexp.

We're also considering adding some form of a lazy API to the public
regexp package, so this internal package will allow us to get some
initial experience across std and cmd.

For #29382.

Change-Id: I30b0e72871d5267c309786f95f4cb15c68b2393d
Reviewed-on: https://go-review.googlesource.com/c/164040
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/go/build/deps_test.go
src/go/doc/comment.go
src/go/doc/reader.go
src/internal/lazyregexp/lazyre.go [moved from src/go/doc/lazyre.go with 66% similarity]

index 2c29a3e6018f7785dee2cc112951e941ed5b483a..9d6d038dab12137a81bb5ec4500b92cc2a65f883 100644 (file)
@@ -192,10 +192,11 @@ var pkgDeps = map[string][]string{
        "runtime/trace":  {"L0", "context", "fmt"},
        "text/tabwriter": {"L2"},
 
-       "testing":          {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
-       "testing/iotest":   {"L2", "log"},
-       "testing/quick":    {"L2", "flag", "fmt", "reflect", "time"},
-       "internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
+       "testing":             {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
+       "testing/iotest":      {"L2", "log"},
+       "testing/quick":       {"L2", "flag", "fmt", "reflect", "time"},
+       "internal/testenv":    {"L2", "OS", "flag", "testing", "syscall"},
+       "internal/lazyregexp": {"L2", "OS", "regexp"},
 
        // L4 is defined as L3+fmt+log+time, because in general once
        // you're using L3 packages, use of fmt, log, or time is not a big deal.
@@ -208,7 +209,7 @@ var pkgDeps = map[string][]string{
 
        // Go parser.
        "go/ast":     {"L4", "OS", "go/scanner", "go/token"},
-       "go/doc":     {"L4", "OS", "go/ast", "go/token", "regexp", "text/template"},
+       "go/doc":     {"L4", "OS", "go/ast", "go/token", "regexp", "internal/lazyregexp", "text/template"},
        "go/parser":  {"L4", "OS", "go/ast", "go/scanner", "go/token"},
        "go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"},
        "go/scanner": {"L4", "OS", "go/token"},
index 73857330fa7158aa3dcfd647234cf815d7c96711..31ee93e44f819ee883d3350855bde3db39d16d9f 100644 (file)
@@ -8,6 +8,7 @@ package doc
 
 import (
        "bytes"
+       "internal/lazyregexp"
        "io"
        "strings"
        "text/template" // for HTMLEscape
@@ -69,7 +70,7 @@ const (
        urlRx = protoPart + `://` + hostPart + pathPart
 )
 
-var matchRx = newLazyRE(`(` + urlRx + `)|(` + identRx + `)`)
+var matchRx = lazyregexp.New(`(` + urlRx + `)|(` + identRx + `)`)
 
 var (
        html_a      = []byte(`<a href="`)
@@ -273,7 +274,7 @@ type block struct {
        lines []string
 }
 
-var nonAlphaNumRx = newLazyRE(`[^a-zA-Z0-9]`)
+var nonAlphaNumRx = lazyregexp.New(`[^a-zA-Z0-9]`)
 
 func anchorID(line string) string {
        // Add a "hdr-" prefix to avoid conflicting with IDs used for package symbols.
index 6db5c21c4a222cf8585aa9d21b81d0a576ba3a99..49d2af771a09cccdbb834befd2028a2f730e4e3c 100644 (file)
@@ -7,6 +7,7 @@ package doc
 import (
        "go/ast"
        "go/token"
+       "internal/lazyregexp"
        "sort"
        "strconv"
 )
@@ -439,9 +440,9 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
 }
 
 var (
-       noteMarker    = `([A-Z][A-Z]+)\(([^)]+)\):?`           // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
-       noteMarkerRx  = newLazyRE(`^[ \t]*` + noteMarker)      // MARKER(uid) at text start
-       noteCommentRx = newLazyRE(`^/[/*][ \t]*` + noteMarker) // MARKER(uid) at comment start
+       noteMarker    = `([A-Z][A-Z]+)\(([^)]+)\):?`                // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
+       noteMarkerRx  = lazyregexp.New(`^[ \t]*` + noteMarker)      // MARKER(uid) at text start
+       noteCommentRx = lazyregexp.New(`^/[/*][ \t]*` + noteMarker) // MARKER(uid) at comment start
 )
 
 // readNote collects a single note from a sequence of comments.
similarity index 66%
rename from src/go/doc/lazyre.go
rename to src/internal/lazyregexp/lazyre.go
index 3fd97d42de68876b9a93299c1b20d66d91b97a04..e4170683ebc8bcc5f783cf98af7037a66621084a 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package doc
+package lazyregexp
 
 import (
        "os"
@@ -11,38 +11,38 @@ import (
        "sync"
 )
 
-type lazyRE struct {
+type Regexp struct {
        str  string
        once sync.Once
        rx   *regexp.Regexp
 }
 
-func (r *lazyRE) re() *regexp.Regexp {
+func (r *Regexp) re() *regexp.Regexp {
        r.once.Do(r.build)
        return r.rx
 }
 
-func (r *lazyRE) build() {
+func (r *Regexp) build() {
        r.rx = regexp.MustCompile(r.str)
        r.str = ""
 }
 
-func (r *lazyRE) FindStringSubmatchIndex(s string) []int {
+func (r *Regexp) FindStringSubmatchIndex(s string) []int {
        return r.re().FindStringSubmatchIndex(s)
 }
 
-func (r *lazyRE) ReplaceAllString(src, repl string) string {
+func (r *Regexp) ReplaceAllString(src, repl string) string {
        return r.re().ReplaceAllString(src, repl)
 }
 
-func (r *lazyRE) MatchString(s string) bool {
+func (r *Regexp) MatchString(s string) bool {
        return r.re().MatchString(s)
 }
 
 var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
 
-func newLazyRE(str string) *lazyRE {
-       lr := &lazyRE{str: str}
+func New(str string) *Regexp {
+       lr := &Regexp{str: str}
        if inTest {
                // In tests, always compile the regexps early.
                lr.re()