Upgrade dependent version: github.com/open-policy-agent/opa (#5315)
Upgrade dependent version: github.com/open-policy-agent/opa v0.18.0 -> v0.45.0 Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
58
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/blockstring.go
generated
vendored
Normal file
58
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/blockstring.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
package lexer
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// blockStringValue produces the value of a block string from its parsed raw value, similar to
|
||||
// Coffeescript's block string, Python's docstring trim or Ruby's strip_heredoc.
|
||||
//
|
||||
// This implements the GraphQL spec's BlockStringValue() static algorithm.
|
||||
func blockStringValue(raw string) string {
|
||||
lines := strings.Split(raw, "\n")
|
||||
|
||||
commonIndent := math.MaxInt32
|
||||
for _, line := range lines {
|
||||
indent := leadingWhitespace(line)
|
||||
if indent < len(line) && indent < commonIndent {
|
||||
commonIndent = indent
|
||||
if commonIndent == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if commonIndent != math.MaxInt32 && len(lines) > 0 {
|
||||
for i := 1; i < len(lines); i++ {
|
||||
if len(lines[i]) < commonIndent {
|
||||
lines[i] = ""
|
||||
} else {
|
||||
lines[i] = lines[i][commonIndent:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start := 0
|
||||
end := len(lines)
|
||||
|
||||
for start < end && leadingWhitespace(lines[start]) == math.MaxInt32 {
|
||||
start++
|
||||
}
|
||||
|
||||
for start < end && leadingWhitespace(lines[end-1]) == math.MaxInt32 {
|
||||
end--
|
||||
}
|
||||
|
||||
return strings.Join(lines[start:end], "\n")
|
||||
}
|
||||
|
||||
func leadingWhitespace(str string) int {
|
||||
for i, r := range str {
|
||||
if r != ' ' && r != '\t' {
|
||||
return i
|
||||
}
|
||||
}
|
||||
// this line is made up entirely of whitespace, its leading whitespace doesnt count.
|
||||
return math.MaxInt32
|
||||
}
|
||||
517
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/lexer.go
generated
vendored
Normal file
517
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/lexer.go
generated
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
package lexer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/gqlparser/ast"
|
||||
"github.com/open-policy-agent/opa/internal/gqlparser/gqlerror"
|
||||
)
|
||||
|
||||
// Lexer turns graphql request and schema strings into tokens
|
||||
type Lexer struct {
|
||||
*ast.Source
|
||||
// An offset into the string in bytes
|
||||
start int
|
||||
// An offset into the string in runes
|
||||
startRunes int
|
||||
// An offset into the string in bytes
|
||||
end int
|
||||
// An offset into the string in runes
|
||||
endRunes int
|
||||
// the current line number
|
||||
line int
|
||||
// An offset into the string in rune
|
||||
lineStartRunes int
|
||||
}
|
||||
|
||||
func New(src *ast.Source) Lexer {
|
||||
return Lexer{
|
||||
Source: src,
|
||||
line: 1,
|
||||
}
|
||||
}
|
||||
|
||||
// take one rune from input and advance end
|
||||
func (s *Lexer) peek() (rune, int) {
|
||||
return utf8.DecodeRuneInString(s.Input[s.end:])
|
||||
}
|
||||
|
||||
func (s *Lexer) makeToken(kind Type) (Token, error) {
|
||||
return s.makeValueToken(kind, s.Input[s.start:s.end])
|
||||
}
|
||||
|
||||
func (s *Lexer) makeValueToken(kind Type, value string) (Token, error) {
|
||||
return Token{
|
||||
Kind: kind,
|
||||
Value: value,
|
||||
Pos: ast.Position{
|
||||
Start: s.startRunes,
|
||||
End: s.endRunes,
|
||||
Line: s.line,
|
||||
Column: s.startRunes - s.lineStartRunes + 1,
|
||||
Src: s.Source,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Lexer) makeError(format string, args ...interface{}) (Token, error) {
|
||||
column := s.endRunes - s.lineStartRunes + 1
|
||||
return Token{
|
||||
Kind: Invalid,
|
||||
Pos: ast.Position{
|
||||
Start: s.startRunes,
|
||||
End: s.endRunes,
|
||||
Line: s.line,
|
||||
Column: column,
|
||||
Src: s.Source,
|
||||
},
|
||||
}, gqlerror.ErrorLocf(s.Source.Name, s.line, column, format, args...)
|
||||
}
|
||||
|
||||
// ReadToken gets the next token from the source starting at the given position.
|
||||
//
|
||||
// This skips over whitespace and comments until it finds the next lexable
|
||||
// token, then lexes punctuators immediately or calls the appropriate helper
|
||||
// function for more complicated tokens.
|
||||
func (s *Lexer) ReadToken() (token Token, err error) {
|
||||
|
||||
s.ws()
|
||||
s.start = s.end
|
||||
s.startRunes = s.endRunes
|
||||
|
||||
if s.end >= len(s.Input) {
|
||||
return s.makeToken(EOF)
|
||||
}
|
||||
r := s.Input[s.start]
|
||||
s.end++
|
||||
s.endRunes++
|
||||
switch r {
|
||||
case '!':
|
||||
return s.makeValueToken(Bang, "")
|
||||
|
||||
case '$':
|
||||
return s.makeValueToken(Dollar, "")
|
||||
case '&':
|
||||
return s.makeValueToken(Amp, "")
|
||||
case '(':
|
||||
return s.makeValueToken(ParenL, "")
|
||||
case ')':
|
||||
return s.makeValueToken(ParenR, "")
|
||||
case '.':
|
||||
if len(s.Input) > s.start+2 && s.Input[s.start:s.start+3] == "..." {
|
||||
s.end += 2
|
||||
s.endRunes += 2
|
||||
return s.makeValueToken(Spread, "")
|
||||
}
|
||||
case ':':
|
||||
return s.makeValueToken(Colon, "")
|
||||
case '=':
|
||||
return s.makeValueToken(Equals, "")
|
||||
case '@':
|
||||
return s.makeValueToken(At, "")
|
||||
case '[':
|
||||
return s.makeValueToken(BracketL, "")
|
||||
case ']':
|
||||
return s.makeValueToken(BracketR, "")
|
||||
case '{':
|
||||
return s.makeValueToken(BraceL, "")
|
||||
case '}':
|
||||
return s.makeValueToken(BraceR, "")
|
||||
case '|':
|
||||
return s.makeValueToken(Pipe, "")
|
||||
case '#':
|
||||
if comment, err := s.readComment(); err != nil {
|
||||
return comment, err
|
||||
}
|
||||
return s.ReadToken()
|
||||
|
||||
case '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':
|
||||
return s.readName()
|
||||
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
return s.readNumber()
|
||||
|
||||
case '"':
|
||||
if len(s.Input) > s.start+2 && s.Input[s.start:s.start+3] == `"""` {
|
||||
return s.readBlockString()
|
||||
}
|
||||
|
||||
return s.readString()
|
||||
}
|
||||
|
||||
s.end--
|
||||
s.endRunes--
|
||||
|
||||
if r < 0x0020 && r != 0x0009 && r != 0x000a && r != 0x000d {
|
||||
return s.makeError(`Cannot contain the invalid character "\u%04d"`, r)
|
||||
}
|
||||
|
||||
if r == '\'' {
|
||||
return s.makeError(`Unexpected single quote character ('), did you mean to use a double quote (")?`)
|
||||
}
|
||||
|
||||
return s.makeError(`Cannot parse the unexpected character "%s".`, string(r))
|
||||
}
|
||||
|
||||
// ws reads from body starting at startPosition until it finds a non-whitespace
|
||||
// or commented character, and updates the token end to include all whitespace
|
||||
func (s *Lexer) ws() {
|
||||
for s.end < len(s.Input) {
|
||||
switch s.Input[s.end] {
|
||||
case '\t', ' ', ',':
|
||||
s.end++
|
||||
s.endRunes++
|
||||
case '\n':
|
||||
s.end++
|
||||
s.endRunes++
|
||||
s.line++
|
||||
s.lineStartRunes = s.endRunes
|
||||
case '\r':
|
||||
s.end++
|
||||
s.endRunes++
|
||||
s.line++
|
||||
s.lineStartRunes = s.endRunes
|
||||
// skip the following newline if its there
|
||||
if s.end < len(s.Input) && s.Input[s.end] == '\n' {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
}
|
||||
// byte order mark, given ws is hot path we aren't relying on the unicode package here.
|
||||
case 0xef:
|
||||
if s.end+2 < len(s.Input) && s.Input[s.end+1] == 0xBB && s.Input[s.end+2] == 0xBF {
|
||||
s.end += 3
|
||||
s.endRunes++
|
||||
} else {
|
||||
return
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// readComment from the input
|
||||
//
|
||||
// #[\u0009\u0020-\uFFFF]*
|
||||
func (s *Lexer) readComment() (Token, error) {
|
||||
for s.end < len(s.Input) {
|
||||
r, w := s.peek()
|
||||
|
||||
// SourceCharacter but not LineTerminator
|
||||
if r > 0x001f || r == '\t' {
|
||||
s.end += w
|
||||
s.endRunes++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return s.makeToken(Comment)
|
||||
}
|
||||
|
||||
// readNumber from the input, either a float
|
||||
// or an int depending on whether a decimal point appears.
|
||||
//
|
||||
// Int: -?(0|[1-9][0-9]*)
|
||||
// Float: -?(0|[1-9][0-9]*)(\.[0-9]+)?((E|e)(+|-)?[0-9]+)?
|
||||
func (s *Lexer) readNumber() (Token, error) {
|
||||
float := false
|
||||
|
||||
// backup to the first digit
|
||||
s.end--
|
||||
s.endRunes--
|
||||
|
||||
s.acceptByte('-')
|
||||
|
||||
if s.acceptByte('0') {
|
||||
if consumed := s.acceptDigits(); consumed != 0 {
|
||||
s.end -= consumed
|
||||
s.endRunes -= consumed
|
||||
return s.makeError("Invalid number, unexpected digit after 0: %s.", s.describeNext())
|
||||
}
|
||||
} else {
|
||||
if consumed := s.acceptDigits(); consumed == 0 {
|
||||
return s.makeError("Invalid number, expected digit but got: %s.", s.describeNext())
|
||||
}
|
||||
}
|
||||
|
||||
if s.acceptByte('.') {
|
||||
float = true
|
||||
|
||||
if consumed := s.acceptDigits(); consumed == 0 {
|
||||
return s.makeError("Invalid number, expected digit but got: %s.", s.describeNext())
|
||||
}
|
||||
}
|
||||
|
||||
if s.acceptByte('e', 'E') {
|
||||
float = true
|
||||
|
||||
s.acceptByte('-', '+')
|
||||
|
||||
if consumed := s.acceptDigits(); consumed == 0 {
|
||||
return s.makeError("Invalid number, expected digit but got: %s.", s.describeNext())
|
||||
}
|
||||
}
|
||||
|
||||
if float {
|
||||
return s.makeToken(Float)
|
||||
}
|
||||
return s.makeToken(Int)
|
||||
|
||||
}
|
||||
|
||||
// acceptByte if it matches any of given bytes, returning true if it found anything
|
||||
func (s *Lexer) acceptByte(bytes ...uint8) bool {
|
||||
if s.end >= len(s.Input) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, accepted := range bytes {
|
||||
if s.Input[s.end] == accepted {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// acceptDigits from the input, returning the number of digits it found
|
||||
func (s *Lexer) acceptDigits() int {
|
||||
consumed := 0
|
||||
for s.end < len(s.Input) && s.Input[s.end] >= '0' && s.Input[s.end] <= '9' {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
consumed++
|
||||
}
|
||||
|
||||
return consumed
|
||||
}
|
||||
|
||||
// describeNext peeks at the input and returns a human readable string. This should will alloc
|
||||
// and should only be used in errors
|
||||
func (s *Lexer) describeNext() string {
|
||||
if s.end < len(s.Input) {
|
||||
return `"` + string(s.Input[s.end]) + `"`
|
||||
}
|
||||
return "<EOF>"
|
||||
}
|
||||
|
||||
// readString from the input
|
||||
//
|
||||
// "([^"\\\u000A\u000D]|(\\(u[0-9a-fA-F]{4}|["\\/bfnrt])))*"
|
||||
func (s *Lexer) readString() (Token, error) {
|
||||
inputLen := len(s.Input)
|
||||
|
||||
// this buffer is lazily created only if there are escape characters.
|
||||
var buf *bytes.Buffer
|
||||
|
||||
// skip the opening quote
|
||||
s.start++
|
||||
s.startRunes++
|
||||
|
||||
for s.end < inputLen {
|
||||
r := s.Input[s.end]
|
||||
if r == '\n' || r == '\r' {
|
||||
break
|
||||
}
|
||||
if r < 0x0020 && r != '\t' {
|
||||
return s.makeError(`Invalid character within String: "\u%04d".`, r)
|
||||
}
|
||||
switch r {
|
||||
default:
|
||||
var char = rune(r)
|
||||
var w = 1
|
||||
|
||||
// skip unicode overhead if we are in the ascii range
|
||||
if r >= 127 {
|
||||
char, w = utf8.DecodeRuneInString(s.Input[s.end:])
|
||||
}
|
||||
s.end += w
|
||||
s.endRunes++
|
||||
|
||||
if buf != nil {
|
||||
buf.WriteRune(char)
|
||||
}
|
||||
|
||||
case '"':
|
||||
t, err := s.makeToken(String)
|
||||
// the token should not include the quotes in its value, but should cover them in its position
|
||||
t.Pos.Start--
|
||||
t.Pos.End++
|
||||
|
||||
if buf != nil {
|
||||
t.Value = buf.String()
|
||||
}
|
||||
|
||||
// skip the close quote
|
||||
s.end++
|
||||
s.endRunes++
|
||||
|
||||
return t, err
|
||||
|
||||
case '\\':
|
||||
if s.end+1 >= inputLen {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
return s.makeError(`Invalid character escape sequence.`)
|
||||
}
|
||||
|
||||
if buf == nil {
|
||||
buf = bytes.NewBufferString(s.Input[s.start:s.end])
|
||||
}
|
||||
|
||||
escape := s.Input[s.end+1]
|
||||
|
||||
if escape == 'u' {
|
||||
if s.end+6 >= inputLen {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
return s.makeError("Invalid character escape sequence: \\%s.", s.Input[s.end:])
|
||||
}
|
||||
|
||||
r, ok := unhex(s.Input[s.end+2 : s.end+6])
|
||||
if !ok {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
return s.makeError("Invalid character escape sequence: \\%s.", s.Input[s.end:s.end+5])
|
||||
}
|
||||
buf.WriteRune(r)
|
||||
s.end += 6
|
||||
s.endRunes += 6
|
||||
} else {
|
||||
switch escape {
|
||||
case '"', '/', '\\':
|
||||
buf.WriteByte(escape)
|
||||
case 'b':
|
||||
buf.WriteByte('\b')
|
||||
case 'f':
|
||||
buf.WriteByte('\f')
|
||||
case 'n':
|
||||
buf.WriteByte('\n')
|
||||
case 'r':
|
||||
buf.WriteByte('\r')
|
||||
case 't':
|
||||
buf.WriteByte('\t')
|
||||
default:
|
||||
s.end++
|
||||
s.endRunes++
|
||||
return s.makeError("Invalid character escape sequence: \\%s.", string(escape))
|
||||
}
|
||||
s.end += 2
|
||||
s.endRunes += 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s.makeError("Unterminated string.")
|
||||
}
|
||||
|
||||
// readBlockString from the input
|
||||
//
|
||||
// """("?"?(\\"""|\\(?!=""")|[^"\\]))*"""
|
||||
func (s *Lexer) readBlockString() (Token, error) {
|
||||
inputLen := len(s.Input)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
// skip the opening quote
|
||||
s.start += 3
|
||||
s.startRunes += 3
|
||||
s.end += 2
|
||||
s.endRunes += 2
|
||||
|
||||
for s.end < inputLen {
|
||||
r := s.Input[s.end]
|
||||
|
||||
// Closing triple quote (""")
|
||||
if r == '"' && s.end+3 <= inputLen && s.Input[s.end:s.end+3] == `"""` {
|
||||
t, err := s.makeValueToken(BlockString, blockStringValue(buf.String()))
|
||||
|
||||
// the token should not include the quotes in its value, but should cover them in its position
|
||||
t.Pos.Start -= 3
|
||||
t.Pos.End += 3
|
||||
|
||||
// skip the close quote
|
||||
s.end += 3
|
||||
s.endRunes += 3
|
||||
return t, err
|
||||
}
|
||||
|
||||
// SourceCharacter
|
||||
if r < 0x0020 && r != '\t' && r != '\n' && r != '\r' {
|
||||
return s.makeError(`Invalid character within String: "\u%04d".`, r)
|
||||
}
|
||||
|
||||
if r == '\\' && s.end+4 <= inputLen && s.Input[s.end:s.end+4] == `\"""` {
|
||||
buf.WriteString(`"""`)
|
||||
s.end += 4
|
||||
s.endRunes += 4
|
||||
} else if r == '\r' {
|
||||
if s.end+1 < inputLen && s.Input[s.end+1] == '\n' {
|
||||
s.end++
|
||||
s.endRunes++
|
||||
}
|
||||
|
||||
buf.WriteByte('\n')
|
||||
s.end++
|
||||
s.endRunes++
|
||||
s.line++
|
||||
s.lineStartRunes = s.endRunes
|
||||
} else {
|
||||
var char = rune(r)
|
||||
var w = 1
|
||||
|
||||
// skip unicode overhead if we are in the ascii range
|
||||
if r >= 127 {
|
||||
char, w = utf8.DecodeRuneInString(s.Input[s.end:])
|
||||
}
|
||||
s.end += w
|
||||
s.endRunes++
|
||||
buf.WriteRune(char)
|
||||
if r == '\n' {
|
||||
s.line++
|
||||
s.lineStartRunes = s.endRunes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s.makeError("Unterminated string.")
|
||||
}
|
||||
|
||||
func unhex(b string) (v rune, ok bool) {
|
||||
for _, c := range b {
|
||||
v <<= 4
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
v |= c - '0'
|
||||
case 'a' <= c && c <= 'f':
|
||||
v |= c - 'a' + 10
|
||||
case 'A' <= c && c <= 'F':
|
||||
v |= c - 'A' + 10
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
return v, true
|
||||
}
|
||||
|
||||
// readName from the input
|
||||
//
|
||||
// [_A-Za-z][_0-9A-Za-z]*
|
||||
func (s *Lexer) readName() (Token, error) {
|
||||
for s.end < len(s.Input) {
|
||||
r, w := s.peek()
|
||||
|
||||
if (r >= '0' && r <= '9') || (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || r == '_' {
|
||||
s.end += w
|
||||
s.endRunes++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return s.makeToken(Name)
|
||||
}
|
||||
692
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/lexer_test.yml
generated
vendored
Normal file
692
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/lexer_test.yml
generated
vendored
Normal file
@@ -0,0 +1,692 @@
|
||||
encoding:
|
||||
- name: disallows uncommon control characters
|
||||
input: "\u0007"
|
||||
error:
|
||||
message: 'Cannot contain the invalid character "\u0007"'
|
||||
locations: [{line: 1, column: 1}]
|
||||
|
||||
- name: accepts BOM header
|
||||
input: "\uFEFF foo"
|
||||
tokens:
|
||||
-
|
||||
kind: NAME
|
||||
start: 2
|
||||
end: 5
|
||||
value: 'foo'
|
||||
|
||||
simple tokens:
|
||||
- name: records line and column
|
||||
input: "\n \r\n \r foo\n"
|
||||
tokens:
|
||||
-
|
||||
kind: NAME
|
||||
start: 8
|
||||
end: 11
|
||||
line: 4
|
||||
column: 3
|
||||
value: 'foo'
|
||||
|
||||
- name: skips whitespace
|
||||
input: "\n\n foo\n\n\n"
|
||||
tokens:
|
||||
-
|
||||
kind: NAME
|
||||
start: 6
|
||||
end: 9
|
||||
value: 'foo'
|
||||
|
||||
- name: skips comments
|
||||
input: "\n #comment\n foo#comment\n"
|
||||
tokens:
|
||||
-
|
||||
kind: NAME
|
||||
start: 18
|
||||
end: 21
|
||||
value: 'foo'
|
||||
|
||||
- name: skips commas
|
||||
input: ",,,foo,,,"
|
||||
tokens:
|
||||
-
|
||||
kind: NAME
|
||||
start: 3
|
||||
end: 6
|
||||
value: 'foo'
|
||||
|
||||
- name: errors respect whitespace
|
||||
input: "\n\n ?\n\n\n"
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character "?".'
|
||||
locations: [{line: 3, column: 5}]
|
||||
string: |
|
||||
Syntax Error: Cannot parse the unexpected character "?".
|
||||
GraphQL request (3:5)
|
||||
2:
|
||||
3: ?
|
||||
^
|
||||
4:
|
||||
|
||||
- name: lex reports useful information for dashes in names
|
||||
input: "a-b"
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: "b".'
|
||||
locations: [{ line: 1, column: 3 }]
|
||||
tokens:
|
||||
-
|
||||
kind: Name
|
||||
start: 0
|
||||
end: 1
|
||||
value: a
|
||||
|
||||
lexes strings:
|
||||
- name: basic
|
||||
input: '"simple"'
|
||||
tokens:
|
||||
-
|
||||
kind: STRING
|
||||
start: 0
|
||||
end: 8
|
||||
value: 'simple'
|
||||
|
||||
- name: whitespace
|
||||
input: '" white space "'
|
||||
tokens:
|
||||
-
|
||||
kind: STRING
|
||||
start: 0
|
||||
end: 15
|
||||
value: ' white space '
|
||||
|
||||
- name: quote
|
||||
input: '"quote \""'
|
||||
tokens:
|
||||
-
|
||||
kind: STRING
|
||||
start: 0
|
||||
end: 10
|
||||
value: 'quote "'
|
||||
|
||||
- name: escaped
|
||||
input: '"escaped \n\r\b\t\f"'
|
||||
tokens:
|
||||
-
|
||||
kind: STRING
|
||||
start: 0
|
||||
end: 20
|
||||
value: "escaped \n\r\b\t\f"
|
||||
|
||||
- name: slashes
|
||||
input: '"slashes \\ \/"'
|
||||
tokens:
|
||||
-
|
||||
kind: STRING
|
||||
start: 0
|
||||
end: 15
|
||||
value: 'slashes \ /'
|
||||
|
||||
- name: unicode
|
||||
input: '"unicode \u1234\u5678\u90AB\uCDEF"'
|
||||
tokens:
|
||||
-
|
||||
kind: STRING
|
||||
start: 0
|
||||
end: 34
|
||||
value: "unicode \u1234\u5678\u90AB\uCDEF"
|
||||
|
||||
lex reports useful string errors:
|
||||
- name: unterminated
|
||||
input: '"'
|
||||
error:
|
||||
message: "Unterminated string."
|
||||
locations: [{ line: 1, column: 2 }]
|
||||
|
||||
- name: no end quote
|
||||
input: '"no end quote'
|
||||
error:
|
||||
message: 'Unterminated string.'
|
||||
locations: [{ line: 1, column: 14 }]
|
||||
|
||||
- name: single quotes
|
||||
input: "'single quotes'"
|
||||
error:
|
||||
message: "Unexpected single quote character ('), did you mean to use a double quote (\")?"
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
- name: control characters
|
||||
input: "\"contains unescaped \u0007 control char\""
|
||||
error:
|
||||
message: 'Invalid character within String: "\u0007".'
|
||||
locations: [{ line: 1, column: 21 }]
|
||||
|
||||
- name: null byte
|
||||
input: "\"null-byte is not \u0000 end of file\""
|
||||
error:
|
||||
message: 'Invalid character within String: "\u0000".'
|
||||
locations: [{ line: 1, column: 19 }]
|
||||
|
||||
- name: unterminated newline
|
||||
input: "\"multi\nline\""
|
||||
error:
|
||||
message: 'Unterminated string.'
|
||||
locations: [{line: 1, column: 7 }]
|
||||
|
||||
- name: unterminated carriage return
|
||||
input: "\"multi\rline\""
|
||||
error:
|
||||
message: 'Unterminated string.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: bad escape character
|
||||
input: '"bad \z esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \z.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: hex escape sequence
|
||||
input: '"bad \x esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \x.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: short escape sequence
|
||||
input: '"bad \u1 esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \u1 es.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: invalid escape sequence 1
|
||||
input: '"bad \u0XX1 esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \u0XX1.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: invalid escape sequence 2
|
||||
input: '"bad \uXXXX esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \uXXXX.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: invalid escape sequence 3
|
||||
input: '"bad \uFXXX esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \uFXXX.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
- name: invalid character escape sequence
|
||||
input: '"bad \uXXXF esc"'
|
||||
error:
|
||||
message: 'Invalid character escape sequence: \uXXXF.'
|
||||
locations: [{ line: 1, column: 7 }]
|
||||
|
||||
lexes block strings:
|
||||
- name: simple
|
||||
input: '"""simple"""'
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 12
|
||||
value: 'simple'
|
||||
|
||||
- name: white space
|
||||
input: '""" white space """'
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 19
|
||||
value: ' white space '
|
||||
|
||||
- name: contains quote
|
||||
input: '"""contains " quote"""'
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 22
|
||||
value: 'contains " quote'
|
||||
|
||||
- name: contains triplequote
|
||||
input: "\"\"\"contains \\\"\"\" triplequote\"\"\""
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 31
|
||||
value: 'contains """ triplequote'
|
||||
|
||||
- name: multi line
|
||||
input: "\"\"\"multi\nline\"\"\""
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 16
|
||||
value: "multi\nline"
|
||||
|
||||
- name: multi line normalized
|
||||
input: "\"\"\"multi\rline\r\nnormalized\"\"\""
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 28
|
||||
value: "multi\nline\nnormalized"
|
||||
|
||||
- name: unescaped
|
||||
input: '"""unescaped \n\r\b\t\f\u1234"""'
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 32
|
||||
value: 'unescaped \n\r\b\t\f\u1234'
|
||||
|
||||
- name: slashes
|
||||
input: '"""slashes \\ \/"""'
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 19
|
||||
value: 'slashes \\ \/'
|
||||
|
||||
- name: multiple lines
|
||||
input: |
|
||||
"""
|
||||
|
||||
spans
|
||||
multiple
|
||||
lines
|
||||
|
||||
"""
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
start: 0
|
||||
end: 36
|
||||
value: "spans\n multiple\n lines"
|
||||
|
||||
- name: records correct line and column after block string
|
||||
input: |
|
||||
"""
|
||||
|
||||
some
|
||||
description
|
||||
|
||||
""" foo
|
||||
tokens:
|
||||
-
|
||||
kind: BLOCK_STRING
|
||||
value: "some\ndescription"
|
||||
-
|
||||
kind: NAME
|
||||
start: 27
|
||||
end: 30
|
||||
line: 6
|
||||
column: 5
|
||||
value: 'foo'
|
||||
|
||||
lex reports useful block string errors:
|
||||
- name: unterminated string
|
||||
input: '"""'
|
||||
error:
|
||||
message: "Unterminated string."
|
||||
locations: [{ line: 1, column: 4 }]
|
||||
|
||||
- name: unescaped control characters
|
||||
input: "\"\"\"contains unescaped \u0007 control char\"\"\""
|
||||
error:
|
||||
message: 'Invalid character within String: "\u0007".'
|
||||
locations: [{ line: 1, column: 23 }]
|
||||
|
||||
- name: null byte
|
||||
input: "\"\"\"null-byte is not \u0000 end of file\"\"\""
|
||||
error:
|
||||
message: 'Invalid character within String: "\u0000".'
|
||||
locations: [{ line: 1, column: 21 }]
|
||||
|
||||
lexes numbers:
|
||||
- name: integer
|
||||
input: "4"
|
||||
tokens:
|
||||
-
|
||||
kind: INT
|
||||
start: 0
|
||||
end: 1
|
||||
value: '4'
|
||||
|
||||
- name: float
|
||||
input: "4.123"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 5
|
||||
value: '4.123'
|
||||
|
||||
- name: negative
|
||||
input: "-4"
|
||||
tokens:
|
||||
-
|
||||
kind: INT
|
||||
start: 0
|
||||
end: 2
|
||||
value: '-4'
|
||||
|
||||
- name: nine
|
||||
input: "9"
|
||||
tokens:
|
||||
-
|
||||
kind: INT
|
||||
start: 0
|
||||
end: 1
|
||||
value: '9'
|
||||
|
||||
- name: zero
|
||||
input: "0"
|
||||
tokens:
|
||||
-
|
||||
kind: INT
|
||||
start: 0
|
||||
end: 1
|
||||
value: '0'
|
||||
|
||||
- name: negative float
|
||||
input: "-4.123"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 6
|
||||
value: '-4.123'
|
||||
|
||||
- name: float leading zero
|
||||
input: "0.123"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 5
|
||||
value: '0.123'
|
||||
|
||||
- name: exponent whole
|
||||
input: "123e4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 5
|
||||
value: '123e4'
|
||||
|
||||
- name: exponent uppercase
|
||||
input: "123E4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 5
|
||||
value: '123E4'
|
||||
|
||||
- name: exponent negative power
|
||||
input: "123e-4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 6
|
||||
value: '123e-4'
|
||||
|
||||
- name: exponent positive power
|
||||
input: "123e+4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 6
|
||||
value: '123e+4'
|
||||
|
||||
- name: exponent negative base
|
||||
input: "-1.123e4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 8
|
||||
value: '-1.123e4'
|
||||
|
||||
- name: exponent negative base upper
|
||||
input: "-1.123E4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 8
|
||||
value: '-1.123E4'
|
||||
|
||||
- name: exponent negative base negative power
|
||||
input: "-1.123e-4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 9
|
||||
value: '-1.123e-4'
|
||||
|
||||
- name: exponent negative base positive power
|
||||
input: "-1.123e+4"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 9
|
||||
value: '-1.123e+4'
|
||||
|
||||
- name: exponent negative base large power
|
||||
input: "-1.123e4567"
|
||||
tokens:
|
||||
-
|
||||
kind: FLOAT
|
||||
start: 0
|
||||
end: 11
|
||||
value: '-1.123e4567'
|
||||
|
||||
lex reports useful number errors:
|
||||
- name: zero
|
||||
input: "00"
|
||||
error:
|
||||
message: 'Invalid number, unexpected digit after 0: "0".'
|
||||
locations: [{ line: 1, column: 2 }]
|
||||
|
||||
- name: positive
|
||||
input: "+1"
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character "+".'
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
- name: trailing dot
|
||||
input: "1."
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: <EOF>.'
|
||||
locations: [{ line: 1, column: 3 }]
|
||||
|
||||
- name: traililng dot exponent
|
||||
input: "1.e1"
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: "e".'
|
||||
locations: [{ line: 1, column: 3 }]
|
||||
|
||||
- name: missing leading zero
|
||||
input: ".123"
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character ".".'
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
- name: characters
|
||||
input: "1.A"
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: "A".'
|
||||
locations: [{ line: 1, column: 3 }]
|
||||
|
||||
- name: negative characters
|
||||
input: "-A"
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: "A".'
|
||||
locations: [{ line: 1, column: 2 }]
|
||||
|
||||
- name: missing exponent
|
||||
input: '1.0e'
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: <EOF>.'
|
||||
locations: [{ line: 1, column: 5 }]
|
||||
|
||||
- name: character exponent
|
||||
input: "1.0eA"
|
||||
error:
|
||||
message: 'Invalid number, expected digit but got: "A".'
|
||||
locations: [{ line: 1, column: 5 }]
|
||||
|
||||
lexes punctuation:
|
||||
- name: bang
|
||||
input: "!"
|
||||
tokens:
|
||||
-
|
||||
kind: BANG
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: dollar
|
||||
input: "$"
|
||||
tokens:
|
||||
-
|
||||
kind: DOLLAR
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: open paren
|
||||
input: "("
|
||||
tokens:
|
||||
-
|
||||
kind: PAREN_L
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: close paren
|
||||
input: ")"
|
||||
tokens:
|
||||
-
|
||||
kind: PAREN_R
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: spread
|
||||
input: "..."
|
||||
tokens:
|
||||
-
|
||||
kind: SPREAD
|
||||
start: 0
|
||||
end: 3
|
||||
value: undefined
|
||||
|
||||
- name: colon
|
||||
input: ":"
|
||||
tokens:
|
||||
-
|
||||
kind: COLON
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: equals
|
||||
input: "="
|
||||
tokens:
|
||||
-
|
||||
kind: EQUALS
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: at
|
||||
input: "@"
|
||||
tokens:
|
||||
-
|
||||
kind: AT
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: open bracket
|
||||
input: "["
|
||||
tokens:
|
||||
-
|
||||
kind: BRACKET_L
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: close bracket
|
||||
input: "]"
|
||||
tokens:
|
||||
-
|
||||
kind: BRACKET_R
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: open brace
|
||||
input: "{"
|
||||
tokens:
|
||||
-
|
||||
kind: BRACE_L
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: close brace
|
||||
input: "}"
|
||||
tokens:
|
||||
-
|
||||
kind: BRACE_R
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
- name: pipe
|
||||
input: "|"
|
||||
tokens:
|
||||
-
|
||||
kind: PIPE
|
||||
start: 0
|
||||
end: 1
|
||||
value: undefined
|
||||
|
||||
lex reports useful unknown character error:
|
||||
- name: not a spread
|
||||
input: ".."
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character ".".'
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
- name: question mark
|
||||
input: "?"
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character "?".'
|
||||
message: 'Cannot parse the unexpected character "?".'
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
- name: unicode 203
|
||||
input: "\u203B"
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character "â".'
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
- name: unicode 200
|
||||
input: "\u200b"
|
||||
error:
|
||||
message: 'Cannot parse the unexpected character "â".'
|
||||
locations: [{ line: 1, column: 1 }]
|
||||
|
||||
148
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/token.go
generated
vendored
Normal file
148
vendor/github.com/open-policy-agent/opa/internal/gqlparser/lexer/token.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
package lexer
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/gqlparser/ast"
|
||||
)
|
||||
|
||||
const (
|
||||
Invalid Type = iota
|
||||
EOF
|
||||
Bang
|
||||
Dollar
|
||||
Amp
|
||||
ParenL
|
||||
ParenR
|
||||
Spread
|
||||
Colon
|
||||
Equals
|
||||
At
|
||||
BracketL
|
||||
BracketR
|
||||
BraceL
|
||||
BraceR
|
||||
Pipe
|
||||
Name
|
||||
Int
|
||||
Float
|
||||
String
|
||||
BlockString
|
||||
Comment
|
||||
)
|
||||
|
||||
func (t Type) Name() string {
|
||||
switch t {
|
||||
case Invalid:
|
||||
return "Invalid"
|
||||
case EOF:
|
||||
return "EOF"
|
||||
case Bang:
|
||||
return "Bang"
|
||||
case Dollar:
|
||||
return "Dollar"
|
||||
case Amp:
|
||||
return "Amp"
|
||||
case ParenL:
|
||||
return "ParenL"
|
||||
case ParenR:
|
||||
return "ParenR"
|
||||
case Spread:
|
||||
return "Spread"
|
||||
case Colon:
|
||||
return "Colon"
|
||||
case Equals:
|
||||
return "Equals"
|
||||
case At:
|
||||
return "At"
|
||||
case BracketL:
|
||||
return "BracketL"
|
||||
case BracketR:
|
||||
return "BracketR"
|
||||
case BraceL:
|
||||
return "BraceL"
|
||||
case BraceR:
|
||||
return "BraceR"
|
||||
case Pipe:
|
||||
return "Pipe"
|
||||
case Name:
|
||||
return "Name"
|
||||
case Int:
|
||||
return "Int"
|
||||
case Float:
|
||||
return "Float"
|
||||
case String:
|
||||
return "String"
|
||||
case BlockString:
|
||||
return "BlockString"
|
||||
case Comment:
|
||||
return "Comment"
|
||||
}
|
||||
return "Unknown " + strconv.Itoa(int(t))
|
||||
}
|
||||
|
||||
func (t Type) String() string {
|
||||
switch t {
|
||||
case Invalid:
|
||||
return "<Invalid>"
|
||||
case EOF:
|
||||
return "<EOF>"
|
||||
case Bang:
|
||||
return "!"
|
||||
case Dollar:
|
||||
return "$"
|
||||
case Amp:
|
||||
return "&"
|
||||
case ParenL:
|
||||
return "("
|
||||
case ParenR:
|
||||
return ")"
|
||||
case Spread:
|
||||
return "..."
|
||||
case Colon:
|
||||
return ":"
|
||||
case Equals:
|
||||
return "="
|
||||
case At:
|
||||
return "@"
|
||||
case BracketL:
|
||||
return "["
|
||||
case BracketR:
|
||||
return "]"
|
||||
case BraceL:
|
||||
return "{"
|
||||
case BraceR:
|
||||
return "}"
|
||||
case Pipe:
|
||||
return "|"
|
||||
case Name:
|
||||
return "Name"
|
||||
case Int:
|
||||
return "Int"
|
||||
case Float:
|
||||
return "Float"
|
||||
case String:
|
||||
return "String"
|
||||
case BlockString:
|
||||
return "BlockString"
|
||||
case Comment:
|
||||
return "Comment"
|
||||
}
|
||||
return "Unknown " + strconv.Itoa(int(t))
|
||||
}
|
||||
|
||||
// Kind represents a type of token. The types are predefined as constants.
|
||||
type Type int
|
||||
|
||||
type Token struct {
|
||||
Kind Type // The token type.
|
||||
Value string // The literal value consumed.
|
||||
Pos ast.Position // The file and line this token was read from
|
||||
}
|
||||
|
||||
func (t Token) String() string {
|
||||
if t.Value != "" {
|
||||
return t.Kind.String() + " " + strconv.Quote(t.Value)
|
||||
}
|
||||
return t.Kind.String()
|
||||
}
|
||||
Reference in New Issue
Block a user