Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / expect / expect.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/expect/expect.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/expect/expect.go
new file mode 100644 (file)
index 0000000..bb203f5
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package expect provides support for interpreting structured comments in Go
+source code as test expectations.
+
+This is primarily intended for writing tests of things that process Go source
+files, although it does not directly depend on the testing package.
+
+Collect notes with the Extract or Parse functions, and use the
+MatchBefore function to find matches within the lines the comments were on.
+
+The interpretation of the notes depends on the application.
+For example, the test suite for a static checking tool might
+use a @diag note to indicate an expected diagnostic:
+
+   fmt.Printf("%s", 1) //@ diag("%s wants a string, got int")
+
+By contrast, the test suite for a source code navigation tool
+might use notes to indicate the positions of features of
+interest, the actions to be performed by the test,
+and their expected outcomes:
+
+   var x = 1 //@ x_decl
+   ...
+   print(x) //@ definition("x", x_decl)
+   print(x) //@ typeof("x", "int")
+
+
+Note comment syntax
+
+Note comments always start with the special marker @, which must be the
+very first character after the comment opening pair, so //@ or /*@ with no
+spaces.
+
+This is followed by a comma separated list of notes.
+
+A note always starts with an identifier, which is optionally followed by an
+argument list. The argument list is surrounded with parentheses and contains a
+comma-separated list of arguments.
+The empty parameter list and the missing parameter list are distinguishable if
+needed; they result in a nil or an empty list in the Args parameter respectively.
+
+Arguments are either identifiers or literals.
+The literals supported are the basic value literals, of string, float, integer
+true, false or nil. All the literals match the standard go conventions, with
+all bases of integers, and both quote and backtick strings.
+There is one extra literal type, which is a string literal preceded by the
+identifier "re" which is compiled to a regular expression.
+*/
+package expect
+
+import (
+       "bytes"
+       "fmt"
+       "go/token"
+       "regexp"
+)
+
+// Note is a parsed note from an expect comment.
+// It knows the position of the start of the comment, and the name and
+// arguments that make up the note.
+type Note struct {
+       Pos  token.Pos     // The position at which the note identifier appears
+       Name string        // the name associated with the note
+       Args []interface{} // the arguments for the note
+}
+
+// ReadFile is the type of a function that can provide file contents for a
+// given filename.
+// This is used in MatchBefore to look up the content of the file in order to
+// find the line to match the pattern against.
+type ReadFile func(filename string) ([]byte, error)
+
+// MatchBefore attempts to match a pattern in the line before the supplied pos.
+// It uses the FileSet and the ReadFile to work out the contents of the line
+// that end is part of, and then matches the pattern against the content of the
+// start of that line up to the supplied position.
+// The pattern may be either a simple string, []byte or a *regexp.Regexp.
+// MatchBefore returns the range of the line that matched the pattern, and
+// invalid positions if there was no match, or an error if the line could not be
+// found.
+func MatchBefore(fset *token.FileSet, readFile ReadFile, end token.Pos, pattern interface{}) (token.Pos, token.Pos, error) {
+       f := fset.File(end)
+       content, err := readFile(f.Name())
+       if err != nil {
+               return token.NoPos, token.NoPos, fmt.Errorf("invalid file: %v", err)
+       }
+       position := f.Position(end)
+       startOffset := f.Offset(f.LineStart(position.Line))
+       endOffset := f.Offset(end)
+       line := content[startOffset:endOffset]
+       matchStart, matchEnd := -1, -1
+       switch pattern := pattern.(type) {
+       case string:
+               bytePattern := []byte(pattern)
+               matchStart = bytes.Index(line, bytePattern)
+               if matchStart >= 0 {
+                       matchEnd = matchStart + len(bytePattern)
+               }
+       case []byte:
+               matchStart = bytes.Index(line, pattern)
+               if matchStart >= 0 {
+                       matchEnd = matchStart + len(pattern)
+               }
+       case *regexp.Regexp:
+               match := pattern.FindIndex(line)
+               if len(match) > 0 {
+                       matchStart = match[0]
+                       matchEnd = match[1]
+               }
+       }
+       if matchStart < 0 {
+               return token.NoPos, token.NoPos, nil
+       }
+       return f.Pos(startOffset + matchStart), f.Pos(startOffset + matchEnd), nil
+}
+
+func lineEnd(f *token.File, line int) token.Pos {
+       if line >= f.LineCount() {
+               return token.Pos(f.Base() + f.Size())
+       }
+       return f.LineStart(line + 1)
+}