本文整理汇总了Golang中go/token.Position.IsValid方法的典型用法代码示例。如果您正苦于以下问题:Golang Position.IsValid方法的具体用法?Golang Position.IsValid怎么用?Golang Position.IsValid使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类go/token.Position
的用法示例。
在下文中一共展示了Position.IsValid方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: distance
// distance returns the column difference between from and to if both
// are on the same line; if they are on different lines (or unknown)
// the result is infinity.
func (p *printer) distance(from0 token.Pos, to token.Position) int {
from := p.posFor(from0)
if from.IsValid() && to.IsValid() && from.Line == to.Line {
return to.Column - from.Column
}
return infinity
}
示例2: parseCallOrConversion
func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
if p.trace {
defer un(trace(p, "CallOrConversion"))
}
lparen := p.expect(token.LPAREN)
p.exprLev++
var list vector.Vector
var ellipsis token.Position
for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
list.Push(p.parseExpr())
if p.tok == token.ELLIPSIS {
ellipsis = p.pos
p.next()
}
if p.tok != token.COMMA {
break
}
p.next()
}
p.exprLev--
rparen := p.expect(token.RPAREN)
return &ast.CallExpr{fun, lparen, makeExprList(&list), ellipsis, rparen}
}
示例3: writeItem
// writeItem writes data at position pos. data is the text corresponding to
// a single lexical token, but may also be comment text. pos is the actual
// (or at least very accurately estimated) position of the data in the original
// source text. If tags are present and GenHTML is set, the tags are written
// before and after the data. writeItem updates p.last to the position
// immediately following the data.
//
func (p *printer) writeItem(pos token.Position, data []byte, tag HTMLTag) {
fileChanged := false
if pos.IsValid() {
// continue with previous position if we don't have a valid pos
if p.last.IsValid() && p.last.Filename != pos.Filename {
// the file has changed - reset state
// (used when printing merged ASTs of different files
// e.g., the result of ast.MergePackageFiles)
p.indent = 0
p.mode = 0
p.buffer = p.buffer[0:0]
fileChanged = true
}
p.pos = pos
}
if debug {
// do not update p.pos - use write0
_, filename := path.Split(pos.Filename)
p.write0([]byte(fmt.Sprintf("[%s:%d:%d]", filename, pos.Line, pos.Column)))
}
if p.Mode&GenHTML != 0 {
// write line tag if on a new line
// TODO(gri): should write line tags on each line at the start
// will be more useful (e.g. to show line numbers)
if p.Styler != nil && (pos.Line != p.lastTaggedLine || fileChanged) {
p.writeTaggedItem(p.Styler.LineTag(pos.Line))
p.lastTaggedLine = pos.Line
}
p.writeTaggedItem(data, tag)
} else {
p.write(data)
}
p.last = p.pos
}
示例4: error
func error(pos token.Position, msg string, args ...interface{}) {
nerrors++
if pos.IsValid() {
fmt.Fprintf(os.Stderr, "%s: ", pos)
}
fmt.Fprintf(os.Stderr, msg, args)
fmt.Fprintf(os.Stderr, "\n")
}
示例5: beforeComment
// Obtain a (single) token position before the next comment.
// Use this function to correct a token position such that the
// token is placed before the next comment (which may be a line
// comment introducing a newline and possibly introducing a
// semicolon). Use moveCommentsAfter() to move a comment past
// more than a single token. beforeComment() is preferable if
// if can be used as it produces better results.
//
// Remove this after transitioning to new semicolon syntax and
// some reasonable grace period (12/11/09).
func (p *printer) beforeComment(pos token.Position) token.Position {
if p.comment != nil {
p := p.comment.List[0].Position
if !pos.IsValid() || pos.Offset > p.Offset {
return p
}
}
return pos
}
示例6: writeString
// writeString writes the string s to p.output and updates p.pos, p.out,
// and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters
// to protect s from being interpreted by the tabwriter.
//
// Note: writeString is only used to write Go tokens, literals, and
// comments, all of which must be written literally. Thus, it is correct
// to always set isLit = true. However, setting it explicitly only when
// needed (i.e., when we don't know that s contains no tabs or line breaks)
// avoids processing extra escape characters and reduces run time of the
// printer benchmark by up to 10%.
//
func (p *printer) writeString(pos token.Position, s string, isLit bool) {
if p.out.Column == 1 {
p.atLineBegin(pos)
}
if pos.IsValid() {
// update p.pos (if pos is invalid, continue with existing p.pos)
// Note: Must do this after handling line beginnings because
// atLineBegin updates p.pos if there's indentation, but p.pos
// is the position of s.
p.pos = pos
}
if isLit {
// Protect s such that is passes through the tabwriter
// unchanged. Note that valid Go programs cannot contain
// tabwriter.Escape bytes since they do not appear in legal
// UTF-8 sequences.
p.output = append(p.output, tabwriter.Escape)
}
if debug {
p.output = append(p.output, fmt.Sprintf("/*%s*/", pos)...) // do not update p.pos!
}
p.output = append(p.output, s...)
// update positions
nlines := 0
var li int // index of last newline; valid if nlines > 0
for i := 0; i < len(s); i++ {
// Go tokens cannot contain '\f' - no need to look for it
if s[i] == '\n' {
nlines++
li = i
}
}
p.pos.Offset += len(s)
if nlines > 0 {
p.pos.Line += nlines
p.out.Line += nlines
c := len(s) - li
p.pos.Column = c
p.out.Column = c
} else {
p.pos.Column += len(s)
p.out.Column += len(s)
}
if isLit {
p.output = append(p.output, tabwriter.Escape)
}
p.last = p.pos
}
示例7: PositionRange
// FIXME: arrange to put in ast
func PositionRange(start token.Position, end token.Position) string {
s := ""
if start.IsValid() {
s = start.Filename + ":" + PositionRangeSansFile(start, end)
} else if end.IsValid() {
s = "-"
if end.Filename != "" {
s += end.Filename + ":"
}
s += fmt.Sprintf("%d:%d", end.Line, end.Column)
}
if s == "" {
s = "-"
}
return s
}
示例8: writeItem
// writeItem writes data at position pos. data is the text corresponding to
// a single lexical token, but may also be comment text. pos is the actual
// (or at least very accurately estimated) position of the data in the original
// source text. writeItem updates p.last to the position immediately following
// the data.
//
func (p *printer) writeItem(pos token.Position, data string) {
if pos.IsValid() {
// continue with previous position if we don't have a valid pos
if p.last.IsValid() && p.last.Filename != pos.Filename {
// the file has changed - reset state
// (used when printing merged ASTs of different files
// e.g., the result of ast.MergePackageFiles)
p.indent = 0
p.mode = 0
p.wsbuf = p.wsbuf[0:0]
}
p.pos = pos
}
if debug {
// do not update p.pos - use write0
_, filename := filepath.Split(pos.Filename)
p.write0([]byte(fmt.Sprintf("[%s:%d:%d]", filename, pos.Line, pos.Column)))
}
p.write([]byte(data))
p.last = p.pos
}
示例9: atLineBegin
// atLineBegin emits a //line comment if necessary and prints indentation.
func (p *printer) atLineBegin(pos token.Position) {
// write a //line comment if necessary
if p.Config.Mode&SourcePos != 0 && pos.IsValid() && (p.out.Line != pos.Line || p.out.Filename != pos.Filename) {
p.output = append(p.output, tabwriter.Escape) // protect '\n' in //line from tabwriter interpretation
p.output = append(p.output, fmt.Sprintf("//line %s:%d\n", pos.Filename, pos.Line)...)
p.output = append(p.output, tabwriter.Escape)
// p.out must match the //line comment
p.out.Filename = pos.Filename
p.out.Line = pos.Line
}
// write indentation
// use "hard" htabs - indentation columns
// must not be discarded by the tabwriter
for i := 0; i < p.indent; i++ {
p.output = append(p.output, '\t')
}
// update positions
i := p.indent
p.pos.Offset += i
p.pos.Column += i
p.out.Column += i
}
示例10: PositionRangeSansFile
func PositionRangeSansFile(start token.Position, end token.Position) string {
s := ""
if start.IsValid() {
s += fmt.Sprintf("%d:%d", start.Line, start.Column)
if start.Filename == end.Filename && end.IsValid() {
// this is what we expect
if start.Line == end.Line {
if start.Column != end.Column {
s += fmt.Sprintf("-%d", end.Column)
}
} else {
s += fmt.Sprintf("-%d:%d", end.Line, end.Column)
}
}
} else if end.IsValid() {
s = "-"
s += fmt.Sprintf("%d:%d", end.Line, end.Column)
}
if s == "" {
s = "-"
}
return s
}
示例11: writeCommentPrefix
// writeCommentPrefix writes the whitespace before a comment.
// If there is any pending whitespace, it consumes as much of
// it as is likely to help position the comment nicely.
// pos is the comment position, next the position of the item
// after all pending comments, prev is the previous comment in
// a group of comments (or nil), and tok is the next token.
//
func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, tok token.Token) {
if len(p.output) == 0 {
// the comment is the first item to be printed - don't write any whitespace
return
}
if pos.IsValid() && pos.Filename != p.last.Filename {
// comment in a different file - separate with newlines
p.writeByte('\f', maxNewlines)
return
}
if pos.Line == p.last.Line && (prev == nil || prev.Text[1] != '/') {
// comment on the same line as last item:
// separate with at least one separator
hasSep := false
if prev == nil {
// first comment of a comment group
j := 0
for i, ch := range p.wsbuf {
switch ch {
case blank:
// ignore any blanks before a comment
p.wsbuf[i] = ignore
continue
case vtab:
// respect existing tabs - important
// for proper formatting of commented structs
hasSep = true
continue
case indent:
// apply pending indentation
continue
}
j = i
break
}
p.writeWhitespace(j)
}
// make sure there is at least one separator
if !hasSep {
sep := byte('\t')
if pos.Line == next.Line {
// next item is on the same line as the comment
// (which must be a /*-style comment): separate
// with a blank instead of a tab
sep = ' '
}
p.writeByte(sep, 1)
}
} else {
// comment on a different line:
// separate with at least one line break
droppedLinebreak := false
j := 0
for i, ch := range p.wsbuf {
switch ch {
case blank, vtab:
// ignore any horizontal whitespace before line breaks
p.wsbuf[i] = ignore
continue
case indent:
// apply pending indentation
continue
case unindent:
// if this is not the last unindent, apply it
// as it is (likely) belonging to the last
// construct (e.g., a multi-line expression list)
// and is not part of closing a block
if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent {
continue
}
// if the next token is not a closing }, apply the unindent
// if it appears that the comment is aligned with the
// token; otherwise assume the unindent is part of a
// closing block and stop (this scenario appears with
// comments before a case label where the comments
// apply to the next case instead of the current one)
if tok != token.RBRACE && pos.Column == next.Column {
continue
}
case newline, formfeed:
p.wsbuf[i] = ignore
droppedLinebreak = prev == nil // record only if first comment of a group
}
j = i
break
}
p.writeWhitespace(j)
// determine number of linebreaks before the comment
n := 0
//.........这里部分代码省略.........
示例12: writeCommentPrefix
// writeCommentPrefix writes the whitespace before a comment.
// If there is any pending whitespace, it consumes as much of
// it as is likely to help position the comment nicely.
// pos is the comment position, next the position of the item
// after all pending comments, prev is the previous comment in
// a group of comments (or nil), and isKeyword indicates if the
// next item is a keyword.
//
func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, isKeyword bool) {
if p.written == 0 {
// the comment is the first item to be printed - don't write any whitespace
return
}
if pos.IsValid() && pos.Filename != p.last.Filename {
// comment in a different file - separate with newlines (writeNewlines will limit the number)
p.writeNewlines(10, true)
return
}
if pos.Line == p.last.Line && (prev == nil || prev.Text[1] != '/') {
// comment on the same line as last item:
// separate with at least one separator
hasSep := false
if prev == nil {
// first comment of a comment group
j := 0
for i, ch := range p.wsbuf {
switch ch {
case blank:
// ignore any blanks before a comment
p.wsbuf[i] = ignore
continue
case vtab:
// respect existing tabs - important
// for proper formatting of commented structs
hasSep = true
continue
case indent:
// apply pending indentation
continue
}
j = i
break
}
p.writeWhitespace(j)
}
// make sure there is at least one separator
if !hasSep {
if pos.Line == next.Line {
// next item is on the same line as the comment
// (which must be a /*-style comment): separate
// with a blank instead of a tab
p.write([]byte{' '})
} else {
p.write(htab)
}
}
} else {
// comment on a different line:
// separate with at least one line break
if prev == nil {
// first comment of a comment group
j := 0
for i, ch := range p.wsbuf {
switch ch {
case blank, vtab:
// ignore any horizontal whitespace before line breaks
p.wsbuf[i] = ignore
continue
case indent:
// apply pending indentation
continue
case unindent:
// if the next token is a keyword, apply the outdent
// if it appears that the comment is aligned with the
// keyword; otherwise assume the outdent is part of a
// closing block and stop (this scenario appears with
// comments before a case label where the comments
// apply to the next case instead of the current one)
if isKeyword && pos.Column == next.Column {
continue
}
case newline, formfeed:
// TODO(gri): may want to keep formfeed info in some cases
p.wsbuf[i] = ignore
}
j = i
break
}
p.writeWhitespace(j)
}
// use formfeeds to break columns before a comment;
// this is analogous to using formfeeds to separate
// individual lines of /*-style comments - but make
// sure there is at least one line break if the previous
// comment was a line comment
n := pos.Line - p.last.Line // if !pos.IsValid(), pos.Line == 0, and n will be 0
if n <= 0 && prev != nil && prev.Text[1] == '/' {
//.........这里部分代码省略.........
示例13: writeString
// writeString writes the string s to p.output and updates p.pos, p.out,
// and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters
// to protect s from being interpreted by the tabwriter.
//
// Note: writeString is only used to write Go tokens, literals, and
// comments, all of which must be written literally. Thus, it is correct
// to always set isLit = true. However, setting it explicitly only when
// needed (i.e., when we don't know that s contains no tabs or line breaks)
// avoids processing extra escape characters and reduces run time of the
// printer benchmark by up to 10%.
//
func (p *printer) writeString(pos token.Position, s string, isLit bool, sType int) {
if p.out.Column == 1 {
p.atLineBegin(pos)
}
if pos.IsValid() {
// update p.pos (if pos is invalid, continue with existing p.pos)
// Note: Must do this after handling line beginnings because
// atLineBegin updates p.pos if there's indentation, but p.pos
// is the position of s.
p.pos = pos
}
if isLit {
// Protect s such that is passes through the tabwriter
// unchanged. Note that valid Go programs cannot contain
// tabwriter.Escape bytes since they do not appear in legal
// UTF-8 sequences.
p.output = append(p.output, tabwriter.Escape)
}
if debug {
p.output = append(p.output, fmt.Sprintf("/*%s*/", pos)...) // do not update p.pos!
}
if p.HTML {
es := html.EscapeString(s)
var wrap []byte
switch sType {
case typeLiteral:
wrap = literalWrap
case typeToken:
if len(s) > 2 {
// Don't color small tokens like * { or [
wrap = tokenWrap
}
case typeBuiltin:
wrap = builtinWrap
case typeComment:
wrap = commentWrap
if p.Linker != nil {
es = p.Linker.Linkify(es, p.comment)
}
// Disabled for now, cause output problems. Handled via RE for now.
/* case typeConst:
wrap = constWrap
case typeVar:
wrap = varWrap
*/
}
if wrap != nil {
p.output = append(p.output, wrap...)
if sType == typeConst || sType == typeVar {
p.output = append(p.output, es...)
p.output = append(p.output, closeWrap...)
}
p.output = append(p.output, es...)
p.output = append(p.output, endWrap...)
} else {
p.output = append(p.output, es...)
}
} else {
p.output = append(p.output, s...)
}
// update positions
nlines := 0
var li int // index of last newline; valid if nlines > 0
for i := 0; i < len(s); i++ {
// Go tokens cannot contain '\f' - no need to look for it
if s[i] == '\n' {
nlines++
li = i
}
}
p.pos.Offset += len(s)
if nlines > 0 {
p.pos.Line += nlines
p.out.Line += nlines
c := len(s) - li
p.pos.Column = c
p.out.Column = c
} else {
p.pos.Column += len(s)
p.out.Column += len(s)
}
if isLit {
p.output = append(p.output, tabwriter.Escape)
}
//.........这里部分代码省略.........
示例14: exprList
// Print a list of expressions. If the list spans multiple
// source lines, the original line breaks are respected between
// expressions. Sets multiLine to true if the list spans multiple
// lines.
//
// TODO(gri) Consider rewriting this to be independent of []ast.Expr
// so that we can use the algorithm for any kind of list
// (e.g., pass list via a channel over which to range).
func (p *printer) exprList(prev token.Position, list []ast.Expr, depth int, mode exprListMode, multiLine *bool, next token.Position) {
if len(list) == 0 {
return
}
if mode&blankStart != 0 {
p.print(blank)
}
line := list[0].Pos().Line
endLine := next.Line
if endLine == 0 {
// TODO(gri): endLine may be incorrect as it is really the beginning
// of the last list entry. There may be only one, very long
// entry in which case line == endLine.
endLine = list[len(list)-1].Pos().Line
}
if prev.IsValid() && prev.Line == line && line == endLine {
// all list entries on a single line
for i, x := range list {
if i > 0 {
if mode&commaSep != 0 {
p.print(token.COMMA)
}
p.print(blank)
}
p.expr0(x, depth, multiLine)
}
if mode&blankEnd != 0 {
p.print(blank)
}
return
}
// list entries span multiple lines;
// use source code positions to guide line breaks
// don't add extra indentation if noIndent is set;
// i.e., pretend that the first line is already indented
ws := ignore
if mode&noIndent == 0 {
ws = indent
}
// the first linebreak is always a formfeed since this section must not
// depend on any previous formatting
prevBreak := -1 // index of last expression that was followed by a linebreak
linebreakMin := 1
if mode&periodSep != 0 {
// Make fragments like
//
// a.Bar(1,
// 2).Foo
//
// format correctly (a linebreak shouldn't be added before Foo) when
// doing period-separated expr lists by setting minimum linebreak to 0
// lines for them.
linebreakMin = 0
}
if prev.IsValid() && prev.Line < line && p.linebreak(line, linebreakMin, ws, true) {
ws = ignore
*multiLine = true
prevBreak = 0
}
// initialize expression/key size: a zero value indicates expr/key doesn't fit on a single line
size := 0
// print all list elements
for i, x := range list {
prevLine := line
line = x.Pos().Line
// determine if the next linebreak, if any, needs to use formfeed:
// in general, use the entire node size to make the decision; for
// key:value expressions, use the key size
// TODO(gri) for a better result, should probably incorporate both
// the key and the node size into the decision process
useFF := true
// determine size
prevSize := size
const infinity = 1e6 // larger than any source line
size = p.nodeSize(x, infinity)
pair, isPair := x.(*ast.KeyValueExpr)
if size <= infinity {
// x fits on a single line
if isPair {
size = p.nodeSize(pair.Key, infinity) // size <= infinity
}
} else {
//.........这里部分代码省略.........
示例15: exprList
// Print a list of expressions. If the list spans multiple
// source lines, the original line breaks are respected between
// expressions. Sets multiLine to true if the list spans multiple
// lines.
func (p *printer) exprList(prev token.Position, list []ast.Expr, depth int, mode exprListMode, multiLine *bool, next token.Position) {
if len(list) == 0 {
return
}
if mode&blankStart != 0 {
p.print(blank)
}
line := list[0].Pos().Line
endLine := next.Line
if endLine == 0 {
// TODO(gri): endLine may be incorrect as it is really the beginning
// of the last list entry. There may be only one, very long
// entry in which case line == endLine.
endLine = list[len(list)-1].Pos().Line
}
if prev.IsValid() && prev.Line == line && line == endLine {
// all list entries on a single line
for i, x := range list {
if i > 0 {
if mode&plusSep != 0 {
p.print(blank, token.ADD)
}
if mode&commaSep != 0 {
p.print(token.COMMA)
}
p.print(blank)
}
p.expr0(x, depth, multiLine)
}
if mode&blankEnd != 0 {
p.print(blank)
}
return
}
// list entries span multiple lines;
// use source code positions to guide line breaks
// don't add extra indentation if noIndent is set;
// i.e., pretend that the first line is already indented
ws := ignore
if mode&noIndent == 0 {
ws = indent
}
if prev.IsValid() && prev.Line < line && p.linebreak(line, 1, 2, ws, true) {
ws = ignore
*multiLine = true
}
for i, x := range list {
prev := line
line = x.Pos().Line
if i > 0 {
if mode&plusSep != 0 {
p.print(blank, p.beforeComment(noPos), token.ADD)
}
if mode&commaSep != 0 {
p.print(token.COMMA)
}
if prev < line && prev > 0 && line > 0 {
if p.linebreak(line, 1, 2, ws, true) {
ws = ignore
*multiLine = true
}
} else {
p.print(blank)
}
}
p.expr0(x, depth, multiLine)
}
if mode&commaTerm != 0 && next.IsValid() && p.pos.Line < next.Line {
// print a terminating comma if the next token is on a new line
p.print(token.COMMA)
if ws == ignore && mode&noIndent == 0 {
// unindent if we indented
p.print(unindent)
}
p.print(formfeed) // terminating comma needs a line break to look good
return
}
if mode&blankEnd != 0 {
p.print(blank)
}
if ws == ignore && mode&noIndent == 0 {
// unindent if we indented
p.print(unindent)
}
}