Update and fix staticcheck
This commit is contained in:
221
vendor/honnef.co/go/tools/pattern/lexer.go
vendored
Normal file
221
vendor/honnef.co/go/tools/pattern/lexer.go
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
package pattern
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type lexer struct {
|
||||
f *token.File
|
||||
|
||||
input string
|
||||
start int
|
||||
pos int
|
||||
width int
|
||||
items chan item
|
||||
}
|
||||
|
||||
type itemType int
|
||||
|
||||
const eof = -1
|
||||
|
||||
const (
|
||||
itemError itemType = iota
|
||||
itemLeftParen
|
||||
itemRightParen
|
||||
itemLeftBracket
|
||||
itemRightBracket
|
||||
itemTypeName
|
||||
itemVariable
|
||||
itemAt
|
||||
itemColon
|
||||
itemBlank
|
||||
itemString
|
||||
itemEOF
|
||||
)
|
||||
|
||||
func (typ itemType) String() string {
|
||||
switch typ {
|
||||
case itemError:
|
||||
return "ERROR"
|
||||
case itemLeftParen:
|
||||
return "("
|
||||
case itemRightParen:
|
||||
return ")"
|
||||
case itemLeftBracket:
|
||||
return "["
|
||||
case itemRightBracket:
|
||||
return "]"
|
||||
case itemTypeName:
|
||||
return "TYPE"
|
||||
case itemVariable:
|
||||
return "VAR"
|
||||
case itemAt:
|
||||
return "@"
|
||||
case itemColon:
|
||||
return ":"
|
||||
case itemBlank:
|
||||
return "_"
|
||||
case itemString:
|
||||
return "STRING"
|
||||
case itemEOF:
|
||||
return "EOF"
|
||||
default:
|
||||
return fmt.Sprintf("itemType(%d)", typ)
|
||||
}
|
||||
}
|
||||
|
||||
type item struct {
|
||||
typ itemType
|
||||
val string
|
||||
pos int
|
||||
}
|
||||
|
||||
type stateFn func(*lexer) stateFn
|
||||
|
||||
func (l *lexer) run() {
|
||||
for state := lexStart; state != nil; {
|
||||
state = state(l)
|
||||
}
|
||||
close(l.items)
|
||||
}
|
||||
|
||||
func (l *lexer) emitValue(t itemType, value string) {
|
||||
l.items <- item{t, value, l.start}
|
||||
l.start = l.pos
|
||||
}
|
||||
|
||||
func (l *lexer) emit(t itemType) {
|
||||
l.items <- item{t, l.input[l.start:l.pos], l.start}
|
||||
l.start = l.pos
|
||||
}
|
||||
|
||||
func lexStart(l *lexer) stateFn {
|
||||
switch r := l.next(); {
|
||||
case r == eof:
|
||||
l.emit(itemEOF)
|
||||
return nil
|
||||
case unicode.IsSpace(r):
|
||||
l.ignore()
|
||||
case r == '(':
|
||||
l.emit(itemLeftParen)
|
||||
case r == ')':
|
||||
l.emit(itemRightParen)
|
||||
case r == '[':
|
||||
l.emit(itemLeftBracket)
|
||||
case r == ']':
|
||||
l.emit(itemRightBracket)
|
||||
case r == '@':
|
||||
l.emit(itemAt)
|
||||
case r == ':':
|
||||
l.emit(itemColon)
|
||||
case r == '_':
|
||||
l.emit(itemBlank)
|
||||
case r == '"':
|
||||
l.backup()
|
||||
return lexString
|
||||
case unicode.IsUpper(r):
|
||||
l.backup()
|
||||
return lexType
|
||||
case unicode.IsLower(r):
|
||||
l.backup()
|
||||
return lexVariable
|
||||
default:
|
||||
return l.errorf("unexpected character %c", r)
|
||||
}
|
||||
return lexStart
|
||||
}
|
||||
|
||||
func (l *lexer) next() (r rune) {
|
||||
if l.pos >= len(l.input) {
|
||||
l.width = 0
|
||||
return eof
|
||||
}
|
||||
r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
|
||||
|
||||
if r == '\n' {
|
||||
l.f.AddLine(l.pos)
|
||||
}
|
||||
|
||||
l.pos += l.width
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (l *lexer) ignore() {
|
||||
l.start = l.pos
|
||||
}
|
||||
|
||||
func (l *lexer) backup() {
|
||||
l.pos -= l.width
|
||||
}
|
||||
|
||||
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
|
||||
// TODO(dh): emit position information in errors
|
||||
l.items <- item{
|
||||
itemError,
|
||||
fmt.Sprintf(format, args...),
|
||||
l.start,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isAlphaNumeric(r rune) bool {
|
||||
return r >= '0' && r <= '9' ||
|
||||
r >= 'a' && r <= 'z' ||
|
||||
r >= 'A' && r <= 'Z'
|
||||
}
|
||||
|
||||
func lexString(l *lexer) stateFn {
|
||||
l.next() // skip quote
|
||||
escape := false
|
||||
|
||||
var runes []rune
|
||||
for {
|
||||
switch r := l.next(); r {
|
||||
case eof:
|
||||
return l.errorf("unterminated string")
|
||||
case '"':
|
||||
if !escape {
|
||||
l.emitValue(itemString, string(runes))
|
||||
return lexStart
|
||||
} else {
|
||||
runes = append(runes, '"')
|
||||
escape = false
|
||||
}
|
||||
case '\\':
|
||||
if escape {
|
||||
runes = append(runes, '\\')
|
||||
escape = false
|
||||
} else {
|
||||
escape = true
|
||||
}
|
||||
default:
|
||||
runes = append(runes, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func lexType(l *lexer) stateFn {
|
||||
l.next()
|
||||
for {
|
||||
if !isAlphaNumeric(l.next()) {
|
||||
l.backup()
|
||||
l.emit(itemTypeName)
|
||||
return lexStart
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func lexVariable(l *lexer) stateFn {
|
||||
l.next()
|
||||
for {
|
||||
if !isAlphaNumeric(l.next()) {
|
||||
l.backup()
|
||||
l.emit(itemVariable)
|
||||
return lexStart
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user