Skip to content

Commit f40cb19

Browse files
committed
internal/lazyregexp: add a lazy Regexp package
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í <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 0d8c363 commit f40cb19

File tree

4 files changed

+22
-19
lines changed

4 files changed

+22
-19
lines changed

src/go/build/deps_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,11 @@ var pkgDeps = map[string][]string{
192192
"runtime/trace": {"L0", "context", "fmt"},
193193
"text/tabwriter": {"L2"},
194194

195-
"testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
196-
"testing/iotest": {"L2", "log"},
197-
"testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
198-
"internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
195+
"testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
196+
"testing/iotest": {"L2", "log"},
197+
"testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
198+
"internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
199+
"internal/lazyregexp": {"L2", "OS", "regexp"},
199200

200201
// L4 is defined as L3+fmt+log+time, because in general once
201202
// 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{
208209

209210
// Go parser.
210211
"go/ast": {"L4", "OS", "go/scanner", "go/token"},
211-
"go/doc": {"L4", "OS", "go/ast", "go/token", "regexp", "text/template"},
212+
"go/doc": {"L4", "OS", "go/ast", "go/token", "regexp", "internal/lazyregexp", "text/template"},
212213
"go/parser": {"L4", "OS", "go/ast", "go/scanner", "go/token"},
213214
"go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"},
214215
"go/scanner": {"L4", "OS", "go/token"},

src/go/doc/comment.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package doc
88

99
import (
1010
"bytes"
11+
"internal/lazyregexp"
1112
"io"
1213
"strings"
1314
"text/template" // for HTMLEscape
@@ -69,7 +70,7 @@ const (
6970
urlRx = protoPart + `://` + hostPart + pathPart
7071
)
7172

72-
var matchRx = newLazyRE(`(` + urlRx + `)|(` + identRx + `)`)
73+
var matchRx = lazyregexp.New(`(` + urlRx + `)|(` + identRx + `)`)
7374

7475
var (
7576
html_a = []byte(`<a href="`)
@@ -273,7 +274,7 @@ type block struct {
273274
lines []string
274275
}
275276

276-
var nonAlphaNumRx = newLazyRE(`[^a-zA-Z0-9]`)
277+
var nonAlphaNumRx = lazyregexp.New(`[^a-zA-Z0-9]`)
277278

278279
func anchorID(line string) string {
279280
// Add a "hdr-" prefix to avoid conflicting with IDs used for package symbols.

src/go/doc/reader.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package doc
77
import (
88
"go/ast"
99
"go/token"
10+
"internal/lazyregexp"
1011
"sort"
1112
"strconv"
1213
)
@@ -439,9 +440,9 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
439440
}
440441

441442
var (
442-
noteMarker = `([A-Z][A-Z]+)\(([^)]+)\):?` // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
443-
noteMarkerRx = newLazyRE(`^[ \t]*` + noteMarker) // MARKER(uid) at text start
444-
noteCommentRx = newLazyRE(`^/[/*][ \t]*` + noteMarker) // MARKER(uid) at comment start
443+
noteMarker = `([A-Z][A-Z]+)\(([^)]+)\):?` // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
444+
noteMarkerRx = lazyregexp.New(`^[ \t]*` + noteMarker) // MARKER(uid) at text start
445+
noteCommentRx = lazyregexp.New(`^/[/*][ \t]*` + noteMarker) // MARKER(uid) at comment start
445446
)
446447

447448
// readNote collects a single note from a sequence of comments.

src/go/doc/lazyre.go renamed to src/internal/lazyregexp/lazyre.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
package doc
5+
package lazyregexp
66

77
import (
88
"os"
@@ -11,38 +11,38 @@ import (
1111
"sync"
1212
)
1313

14-
type lazyRE struct {
14+
type Regexp struct {
1515
str string
1616
once sync.Once
1717
rx *regexp.Regexp
1818
}
1919

20-
func (r *lazyRE) re() *regexp.Regexp {
20+
func (r *Regexp) re() *regexp.Regexp {
2121
r.once.Do(r.build)
2222
return r.rx
2323
}
2424

25-
func (r *lazyRE) build() {
25+
func (r *Regexp) build() {
2626
r.rx = regexp.MustCompile(r.str)
2727
r.str = ""
2828
}
2929

30-
func (r *lazyRE) FindStringSubmatchIndex(s string) []int {
30+
func (r *Regexp) FindStringSubmatchIndex(s string) []int {
3131
return r.re().FindStringSubmatchIndex(s)
3232
}
3333

34-
func (r *lazyRE) ReplaceAllString(src, repl string) string {
34+
func (r *Regexp) ReplaceAllString(src, repl string) string {
3535
return r.re().ReplaceAllString(src, repl)
3636
}
3737

38-
func (r *lazyRE) MatchString(s string) bool {
38+
func (r *Regexp) MatchString(s string) bool {
3939
return r.re().MatchString(s)
4040
}
4141

4242
var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
4343

44-
func newLazyRE(str string) *lazyRE {
45-
lr := &lazyRE{str: str}
44+
func New(str string) *Regexp {
45+
lr := &Regexp{str: str}
4646
if inTest {
4747
// In tests, always compile the regexps early.
4848
lr.re()

0 commit comments

Comments
 (0)