diff options
Diffstat (limited to 'src/pkg/go/printer/printer.go')
-rw-r--r-- | src/pkg/go/printer/printer.go | 472 |
1 files changed, 236 insertions, 236 deletions
diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go index 50f0007a6..994dabaa8 100644 --- a/src/pkg/go/printer/printer.go +++ b/src/pkg/go/printer/printer.go @@ -6,50 +6,50 @@ package printer import ( - "bytes"; - "fmt"; - "go/ast"; - "go/token"; - "io"; - "os"; - "reflect"; - "runtime"; - "strings"; - "tabwriter"; + "bytes" + "fmt" + "go/ast" + "go/token" + "io" + "os" + "reflect" + "runtime" + "strings" + "tabwriter" ) const ( - debug = false; // enable for debugging - maxNewlines = 3; // maximum vertical white space + debug = false // enable for debugging + maxNewlines = 3 // maximum vertical white space ) type whiteSpace int const ( - ignore = whiteSpace(0); - blank = whiteSpace(' '); - vtab = whiteSpace('\v'); - newline = whiteSpace('\n'); - formfeed = whiteSpace('\f'); - indent = whiteSpace('>'); - unindent = whiteSpace('<'); + ignore = whiteSpace(0) + blank = whiteSpace(' ') + vtab = whiteSpace('\v') + newline = whiteSpace('\n') + formfeed = whiteSpace('\f') + indent = whiteSpace('>') + unindent = whiteSpace('<') ) var ( - esc = []byte{tabwriter.Escape}; - htab = []byte{'\t'}; - htabs = [...]byte{'\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t'}; - newlines = [...]byte{'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'}; // more than maxNewlines - formfeeds = [...]byte{'\f', '\f', '\f', '\f', '\f', '\f', '\f', '\f'}; // more than maxNewlines - - esc_quot = strings.Bytes("""); // shorter than """ - esc_apos = strings.Bytes("'"); // shorter than "'" - esc_amp = strings.Bytes("&"); - esc_lt = strings.Bytes("<"); - esc_gt = strings.Bytes(">"); + esc = []byte{tabwriter.Escape} + htab = []byte{'\t'} + htabs = [...]byte{'\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t'} + newlines = [...]byte{'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'} // more than maxNewlines + formfeeds = [...]byte{'\f', '\f', '\f', '\f', '\f', '\f', '\f', '\f'} // more than maxNewlines + + esc_quot = strings.Bytes(""") // shorter than """ + esc_apos = strings.Bytes("'") // shorter than "'" + esc_amp = strings.Bytes("&") + esc_lt = strings.Bytes("<") + esc_gt = strings.Bytes(">") ) @@ -63,49 +63,49 @@ var ignoreMultiLine = new(bool) type printer struct { // Configuration (does not change after initialization) - output io.Writer; - Config; - errors chan os.Error; + output io.Writer + Config + errors chan os.Error // Current state - written int; // number of bytes written - indent int; // current indentation - escape bool; // true if in escape sequence + written int // number of bytes written + indent int // current indentation + escape bool // true if in escape sequence // Buffered whitespace - buffer []whiteSpace; + buffer []whiteSpace // The (possibly estimated) position in the generated output; // in AST space (i.e., pos is set whenever a token position is // known accurately, and updated dependending on what has been // written) - pos token.Position; + pos token.Position // The value of pos immediately after the last item has been // written using writeItem. - last token.Position; + last token.Position // HTML support - lastTaggedLine int; // last line for which a line tag was written + lastTaggedLine int // last line for which a line tag was written // The list of comments; or nil. - comment *ast.CommentGroup; + comment *ast.CommentGroup } func (p *printer) init(output io.Writer, cfg *Config) { - p.output = output; - p.Config = *cfg; - p.errors = make(chan os.Error); - p.buffer = make([]whiteSpace, 0, 16); // whitespace sequences are short + p.output = output + p.Config = *cfg + p.errors = make(chan os.Error) + p.buffer = make([]whiteSpace, 0, 16) // whitespace sequences are short } func (p *printer) internalError(msg ...) { if debug { - fmt.Print(p.pos.String() + ": "); - fmt.Println(msg); - panic(); + fmt.Print(p.pos.String() + ": ") + fmt.Println(msg) + panic() } } @@ -114,11 +114,11 @@ func (p *printer) internalError(msg ...) { // write0 does not indent after newlines, and does not HTML-escape or update p.pos. // func (p *printer) write0(data []byte) { - n, err := p.output.Write(data); - p.written += n; + n, err := p.output.Write(data) + p.written += n if err != nil { - p.errors <- err; - runtime.Goexit(); + p.errors <- err + runtime.Goexit() } } @@ -128,43 +128,43 @@ func (p *printer) write0(data []byte) { // escapes characters if GenHTML is set. It updates p.pos as a side-effect. // func (p *printer) write(data []byte) { - i0 := 0; + i0 := 0 for i, b := range data { switch b { case '\n', '\f': // write segment ending in b - p.write0(data[i0 : i+1]); + p.write0(data[i0 : i+1]) // update p.pos - p.pos.Offset += i + 1 - i0; - p.pos.Line++; - p.pos.Column = 1; + p.pos.Offset += i + 1 - i0 + p.pos.Line++ + p.pos.Column = 1 if !p.escape { // write indentation // use "hard" htabs - indentation columns // must not be discarded by the tabwriter - j := p.indent; + j := p.indent for ; j > len(htabs); j -= len(htabs) { p.write0(&htabs) } - p.write0(htabs[0:j]); + p.write0(htabs[0:j]) // update p.pos - p.pos.Offset += p.indent; - p.pos.Column += p.indent; + p.pos.Offset += p.indent + p.pos.Column += p.indent } // next segment start - i0 = i + 1; + i0 = i + 1 case '"', '\'', '&', '<', '>': if p.Mode&GenHTML != 0 { // write segment ending in b - p.write0(data[i0:i]); + p.write0(data[i0:i]) // write HTML-escaped b - var esc []byte; + var esc []byte switch b { case '"': esc = esc_quot @@ -177,15 +177,15 @@ func (p *printer) write(data []byte) { case '>': esc = esc_gt } - p.write0(esc); + p.write0(esc) // update p.pos - d := i + 1 - i0; - p.pos.Offset += d; - p.pos.Column += d; + d := i + 1 - i0 + p.pos.Offset += d + p.pos.Column += d // next segment start - i0 = i + 1; + i0 = i + 1 } case tabwriter.Escape: @@ -194,12 +194,12 @@ func (p *printer) write(data []byte) { } // write remaining segment - p.write0(data[i0:]); + p.write0(data[i0:]) // update p.pos - d := len(data) - i0; - p.pos.Offset += d; - p.pos.Column += d; + d := len(data) - i0 + p.pos.Offset += d + p.pos.Column += d } @@ -208,7 +208,7 @@ func (p *printer) writeNewlines(n int) { if n > maxNewlines { n = maxNewlines } - p.write(newlines[0:n]); + p.write(newlines[0:n]) } } @@ -218,7 +218,7 @@ func (p *printer) writeFormfeeds(n int) { if n > maxNewlines { n = maxNewlines } - p.write(formfeeds[0:n]); + p.write(formfeeds[0:n]) } } @@ -229,7 +229,7 @@ func (p *printer) writeTaggedItem(data []byte, tag HTMLTag) { if tag.Start != "" { p.write0(strings.Bytes(tag.Start)) } - p.write(data); + p.write(data) // write end tag, if any if tag.End != "" { p.write0(strings.Bytes(tag.End)) @@ -245,7 +245,7 @@ func (p *printer) writeTaggedItem(data []byte, tag HTMLTag) { // immediately following the data. // func (p *printer) writeItem(pos token.Position, data []byte, tag HTMLTag) { - p.pos = pos; + p.pos = pos if debug { // do not update p.pos - use write0 p.write0(strings.Bytes(fmt.Sprintf("[%d:%d]", pos.Line, pos.Column))) @@ -255,14 +255,14 @@ func (p *printer) writeItem(pos token.Position, data []byte, tag HTMLTag) { // 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 { - p.writeTaggedItem(p.Styler.LineTag(pos.Line)); - p.lastTaggedLine = pos.Line; + p.writeTaggedItem(p.Styler.LineTag(pos.Line)) + p.lastTaggedLine = pos.Line } - p.writeTaggedItem(data, tag); + p.writeTaggedItem(data, tag) } else { p.write(data) } - p.last = p.pos; + p.last = p.pos } @@ -284,28 +284,28 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor if pos.Line == p.last.Line { // comment on the same line as last item: // separate with at least one separator - hasSep := false; + hasSep := false if isFirst { - j := 0; + j := 0 for i, ch := range p.buffer { switch ch { case blank: // ignore any blanks before a comment - p.buffer[i] = ignore; - continue; + p.buffer[i] = ignore + continue case vtab: // respect existing tabs - important // for proper formatting of commented structs - hasSep = true; - continue; + hasSep = true + continue case indent: // apply pending indentation continue } - j = i; - break; + j = i + break } - p.writeWhitespace(j); + p.writeWhitespace(j) } // make sure there is at least one separator if !hasSep { @@ -323,13 +323,13 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor // comment on a different line: // separate with at least one line break if isFirst { - j := 0; + j := 0 for i, ch := range p.buffer { switch ch { case blank, vtab: // ignore any horizontal whitespace before line breaks - p.buffer[i] = ignore; - continue; + p.buffer[i] = ignore + continue case indent: // apply pending indentation continue @@ -347,31 +347,31 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor // TODO(gri): may want to keep formfeed info in some cases p.buffer[i] = ignore } - j = i; - break; + j = i + break } - p.writeWhitespace(j); + p.writeWhitespace(j) } // use formfeeds to break columns before a comment; // this is analogous to using formfeeds to separate // individual lines of /*-style comments - p.writeFormfeeds(pos.Line - p.last.Line); + p.writeFormfeeds(pos.Line - p.last.Line) } } func (p *printer) writeCommentLine(comment *ast.Comment, pos token.Position, line []byte) { // line must pass through unchanged, bracket it with tabwriter.Escape - esc := []byte{tabwriter.Escape}; - line = bytes.Join([][]byte{esc, line, esc}, nil); + esc := []byte{tabwriter.Escape} + line = bytes.Join([][]byte{esc, line, esc}, nil) // apply styler, if any - var tag HTMLTag; + var tag HTMLTag if p.Styler != nil { line, tag = p.Styler.Comment(comment, line) } - p.writeItem(pos, line, tag); + p.writeItem(pos, line, tag) } @@ -382,7 +382,7 @@ func (p *printer) writeCommentLine(comment *ast.Comment, pos token.Position, lin // Split comment text into lines func split(text []byte) [][]byte { // count lines (comment text never ends in a newline) - n := 1; + n := 1 for _, c := range text { if c == '\n' { n++ @@ -390,19 +390,19 @@ func split(text []byte) [][]byte { } // split - lines := make([][]byte, n); - n = 0; - i := 0; + lines := make([][]byte, n) + n = 0 + i := 0 for j, c := range text { if c == '\n' { - lines[n] = text[i:j]; // exclude newline - i = j + 1; // discard newline - n++; + lines[n] = text[i:j] // exclude newline + i = j + 1 // discard newline + n++ } } - lines[n] = text[i:]; + lines[n] = text[i:] - return lines; + return lines } @@ -412,22 +412,22 @@ func isBlank(s []byte) bool { return false } } - return true; + return true } func commonPrefix(a, b []byte) []byte { - i := 0; + i := 0 for i < len(a) && i < len(b) && a[i] == b[i] && (a[i] <= ' ' || a[i] == '*') { i++ } - return a[0:i]; + return a[0:i] } func stripCommonPrefix(lines [][]byte) { if len(lines) < 2 { - return // at most one line - nothing to do + return // at most one line - nothing to do } // The heuristic in this function tries to handle a few @@ -441,7 +441,7 @@ func stripCommonPrefix(lines [][]byte) { // Compute maximum common white prefix of all but the first, // last, and blank lines, and replace blank lines with empty // lines (the first line starts with /* and has no prefix). - var prefix []byte; + var prefix []byte for i, line := range lines { switch { case i == 0 || i == len(lines)-1: @@ -458,14 +458,14 @@ func stripCommonPrefix(lines [][]byte) { /* * Check for vertical "line of stars" and correct prefix accordingly. */ - lineOfStars := false; + lineOfStars := false if i := bytes.Index(prefix, []byte{'*'}); i >= 0 { // Line of stars present. if i > 0 && prefix[i-1] == ' ' { - i-- // remove trailing blank from prefix so stars remain aligned + i-- // remove trailing blank from prefix so stars remain aligned } - prefix = prefix[0:i]; - lineOfStars = true; + prefix = prefix[0:i] + lineOfStars = true } else { // No line of stars present. // Determine the white space on the first line after the /* @@ -474,36 +474,36 @@ func stripCommonPrefix(lines [][]byte) { // the /* is a tab. If the first comment line is empty but // for the opening /*, assume up to 3 blanks or a tab. This // whitespace may be found as suffix in the common prefix. - first := lines[0]; + first := lines[0] if isBlank(first[2:]) { // no comment text on the first line: // reduce prefix by up to 3 blanks or a tab // if present - this keeps comment text indented // relative to the /* and */'s if it was indented // in the first place - i := len(prefix); + i := len(prefix) for n := 0; n < 3 && i > 0 && prefix[i-1] == ' '; n++ { i-- } if i == len(prefix) && i > 0 && prefix[i-1] == '\t' { i-- } - prefix = prefix[0:i]; + prefix = prefix[0:i] } else { // comment text on the first line - suffix := make([]byte, len(first)); - n := 2; + suffix := make([]byte, len(first)) + n := 2 for n < len(first) && first[n] <= ' ' { - suffix[n] = first[n]; - n++; + suffix[n] = first[n] + n++ } if n > 2 && suffix[2] == '\t' { // assume the '\t' compensates for the /* suffix = suffix[2:n] } else { // otherwise assume two blanks - suffix[0], suffix[1] = ' ', ' '; - suffix = suffix[0:n]; + suffix[0], suffix[1] = ' ', ' ' + suffix = suffix[0:n] } // Shorten the computed common prefix by the length of // suffix, if it is found as suffix of the prefix. @@ -516,17 +516,17 @@ func stripCommonPrefix(lines [][]byte) { // Handle last line: If it only contains a closing */, align it // with the opening /*, otherwise align the text with the other // lines. - last := lines[len(lines)-1]; - closing := []byte{'*', '/'}; - i := bytes.Index(last, closing); + last := lines[len(lines)-1] + closing := []byte{'*', '/'} + i := bytes.Index(last, closing) if isBlank(last[0:i]) { // last line only contains closing */ - var sep []byte; + var sep []byte if lineOfStars { // insert an aligning blank sep = []byte{' '} } - lines[len(lines)-1] = bytes.Join([][]byte{prefix, closing}, sep); + lines[len(lines)-1] = bytes.Join([][]byte{prefix, closing}, sep) } else { // last line contains more comment text - assume // it is aligned like the other lines @@ -543,27 +543,27 @@ func stripCommonPrefix(lines [][]byte) { func (p *printer) writeComment(comment *ast.Comment) { - text := comment.Text; + text := comment.Text // shortcut common case of //-style comments if text[1] == '/' { - p.writeCommentLine(comment, comment.Pos(), text); - return; + p.writeCommentLine(comment, comment.Pos(), text) + return } // for /*-style comments, print line by line and let the // write function take care of the proper indentation - lines := split(text); - stripCommonPrefix(lines); + lines := split(text) + stripCommonPrefix(lines) // write comment lines, separated by formfeed, // without a line break after the last line - linebreak := formfeeds[0:1]; - pos := comment.Pos(); + linebreak := formfeeds[0:1] + pos := comment.Pos() for i, line := range lines { if i > 0 { - p.write(linebreak); - pos = p.pos; + p.write(linebreak) + pos = p.pos } if len(line) > 0 { p.writeCommentLine(comment, pos, line) @@ -594,7 +594,7 @@ func (p *printer) writeCommentSuffix(needsLinebreak bool) { } } } - p.writeWhitespace(len(p.buffer)); + p.writeWhitespace(len(p.buffer)) // make sure we have a line break if needsLinebreak { @@ -610,16 +610,16 @@ func (p *printer) writeCommentSuffix(needsLinebreak bool) { // token is a keyword or not. // func (p *printer) intersperseComments(next token.Position, isKeyword bool) { - isFirst := true; - needsLinebreak := false; - var last *ast.Comment; + isFirst := true + needsLinebreak := false + var last *ast.Comment for ; p.commentBefore(next); p.comment = p.comment.Next { for _, c := range p.comment.List { - p.writeCommentPrefix(c.Pos(), next, isFirst, isKeyword); - isFirst = false; - p.writeComment(c); - needsLinebreak = c.Text[1] == '/'; - last = c; + p.writeCommentPrefix(c.Pos(), next, isFirst, isKeyword) + isFirst = false + p.writeComment(c) + needsLinebreak = c.Text[1] == '/' + last = c } } if last != nil && !needsLinebreak && last.Pos().Line == next.Line { @@ -627,14 +627,14 @@ func (p *printer) intersperseComments(next token.Position, isKeyword bool) { // follows on the same line: separate with an extra blank p.write([]byte{' '}) } - p.writeCommentSuffix(needsLinebreak); + p.writeCommentSuffix(needsLinebreak) } // whiteWhitespace writes the first n whitespace entries. func (p *printer) writeWhitespace(n int) { // write entries - var data [1]byte; + var data [1]byte for i := 0; i < n; i++ { switch ch := p.buffer[i]; ch { case ignore: @@ -642,10 +642,10 @@ func (p *printer) writeWhitespace(n int) { case indent: p.indent++ case unindent: - p.indent--; + p.indent-- if p.indent < 0 { - p.internalError("negative indentation:", p.indent); - p.indent = 0; + p.internalError("negative indentation:", p.indent) + p.indent = 0 } case newline, formfeed: // A line break immediately followed by a "correcting" @@ -660,24 +660,24 @@ func (p *printer) writeWhitespace(n int) { // to a wide column may increase the indentation column // of lines before the label; effectively leading to wrong // indentation. - p.buffer[i], p.buffer[i+1] = unindent, formfeed; - i--; // do it again - continue; + p.buffer[i], p.buffer[i+1] = unindent, formfeed + i-- // do it again + continue } - fallthrough; + fallthrough default: - data[0] = byte(ch); - p.write(&data); + data[0] = byte(ch) + p.write(&data) } } // shift remaining entries down - i := 0; + i := 0 for ; n < len(p.buffer); n++ { - p.buffer[i] = p.buffer[n]; - i++; + p.buffer[i] = p.buffer[n] + i++ } - p.buffer = p.buffer[0:i]; + p.buffer = p.buffer[0:i] } @@ -696,14 +696,14 @@ func (p *printer) writeWhitespace(n int) { // printed, followed by the actual token. // func (p *printer) print(args ...) { - v := reflect.NewValue(args).(*reflect.StructValue); + v := reflect.NewValue(args).(*reflect.StructValue) for i := 0; i < v.NumField(); i++ { - f := v.Field(i); + f := v.Field(i) - next := p.pos; // estimated position of next item - var data []byte; - var tag HTMLTag; - isKeyword := false; + next := p.pos // estimated position of next item + var data []byte + var tag HTMLTag + isKeyword := false switch x := f.Interface().(type) { case whiteSpace: if x == ignore { @@ -712,16 +712,16 @@ func (p *printer) print(args ...) { // LabeledStmt) break } - i := len(p.buffer); + i := len(p.buffer) if i == cap(p.buffer) { // Whitespace sequences are very short so this should // never happen. Handle gracefully (but possibly with // bad comment placement) if it does happen. - p.writeWhitespace(i); - i = 0; + p.writeWhitespace(i) + i = 0 } - p.buffer = p.buffer[0 : i+1]; - p.buffer[i] = x; + p.buffer = p.buffer[0 : i+1] + p.buffer[i] = x case []byte: // TODO(gri): remove this case once commentList // handles comments correctly @@ -746,32 +746,32 @@ func (p *printer) print(args ...) { // (note that valid Go programs cannot contain esc ('\xff') // bytes since they do not appear in legal UTF-8 sequences) // TODO(gri): this this more efficiently. - data = strings.Bytes("\xff" + string(data) + "\xff"); + data = strings.Bytes("\xff" + string(data) + "\xff") case token.Token: if p.Styler != nil { data, tag = p.Styler.Token(x) } else { data = strings.Bytes(x.String()) } - isKeyword = x.IsKeyword(); + isKeyword = x.IsKeyword() case token.Position: if x.IsValid() { - next = x // accurate position of next item + next = x // accurate position of next item } default: panicln("print: unsupported argument type", f.Type().String()) } - p.pos = next; + p.pos = next if data != nil { - p.flush(next, isKeyword); + p.flush(next, isKeyword) // intersperse extra newlines if present in the source // (don't do this in flush as it will cause extra newlines // at the end of a file) - p.writeNewlines(next.Line - p.pos.Line); + p.writeNewlines(next.Line - p.pos.Line) - p.writeItem(next, data, tag); + p.writeItem(next, data, tag) } } } @@ -794,7 +794,7 @@ func (p *printer) flush(next token.Position, isKeyword bool) { p.intersperseComments(next, isKeyword) } // write any leftover whitespace - p.writeWhitespace(len(p.buffer)); + p.writeWhitespace(len(p.buffer)) } @@ -807,8 +807,8 @@ func (p *printer) flush(next token.Position, isKeyword bool) { // is used). // type trimmer struct { - output io.Writer; - buf bytes.Buffer; + output io.Writer + buf bytes.Buffer } @@ -821,12 +821,12 @@ type trimmer struct { func (p *trimmer) Write(data []byte) (n int, err os.Error) { // m < 0: no unwritten data except for whitespace // m >= 0: data[m:n] unwritten and no whitespace - m := 0; + m := 0 if p.buf.Len() > 0 { m = -1 } - var b byte; + var b byte for n, b = range data { switch b { default: @@ -835,13 +835,13 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { if _, err = p.output.Write(p.buf.Bytes()); err != nil { return } - p.buf.Reset(); - m = n; + p.buf.Reset() + m = n } case '\v': - b = '\t'; // convert to htab - fallthrough; + b = '\t' // convert to htab + fallthrough case '\t', ' ', tabwriter.Escape: // write any pending (non-whitespace) data @@ -849,22 +849,22 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { if _, err = p.output.Write(data[m:n]); err != nil { return } - m = -1; + m = -1 } // collect whitespace but discard tabrwiter.Escapes. if b != tabwriter.Escape { - p.buf.WriteByte(b) // WriteByte returns no errors + p.buf.WriteByte(b) // WriteByte returns no errors } case '\f', '\n': // discard whitespace - p.buf.Reset(); + p.buf.Reset() // write any pending (non-whitespace) data if m >= 0 { if _, err = p.output.Write(data[m:n]); err != nil { return } - m = -1; + m = -1 } // convert formfeed into newline if _, err = p.output.Write(newlines[0:1]); err != nil { @@ -872,7 +872,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { } } } - n = len(data); + n = len(data) // write any pending non-whitespace if m >= 0 { @@ -881,7 +881,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { } } - return; + return } @@ -890,17 +890,17 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { // General printing is controlled with these Config.Mode flags. const ( - GenHTML uint = 1 << iota; // generate HTML - RawFormat; // do not use a tabwriter; if set, UseSpaces is ignored - TabIndent; // use tabs for indentation independent of UseSpaces - UseSpaces; // use spaces instead of tabs for alignment - NoSemis; // don't print semicolons at the end of a line + GenHTML uint = 1 << iota // generate HTML + RawFormat // do not use a tabwriter; if set, UseSpaces is ignored + TabIndent // use tabs for indentation independent of UseSpaces + UseSpaces // use spaces instead of tabs for alignment + NoSemis // don't print semicolons at the end of a line ) // An HTMLTag specifies a start and end tag. type HTMLTag struct { - Start, End string; // empty if tags are absent + Start, End string // empty if tags are absent } @@ -908,19 +908,19 @@ type HTMLTag struct { // A format consists of text and a (possibly empty) surrounding HTML tag. // type Styler interface { - LineTag(line int) ([]byte, HTMLTag); - Comment(c *ast.Comment, line []byte) ([]byte, HTMLTag); - BasicLit(x *ast.BasicLit) ([]byte, HTMLTag); - Ident(id *ast.Ident) ([]byte, HTMLTag); - Token(tok token.Token) ([]byte, HTMLTag); + LineTag(line int) ([]byte, HTMLTag) + Comment(c *ast.Comment, line []byte) ([]byte, HTMLTag) + BasicLit(x *ast.BasicLit) ([]byte, HTMLTag) + Ident(id *ast.Ident) ([]byte, HTMLTag) + Token(tok token.Token) ([]byte, HTMLTag) } // A Config node controls the output of Fprint. type Config struct { - Mode uint; // default: 0 - Tabwidth int; // default: 8 - Styler Styler; // default: nil + Mode uint // default: 0 + Tabwidth int // default: 8 + Styler Styler // default: nil } @@ -934,34 +934,34 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) { // (Input to a tabwriter must be untrimmed since trailing tabs provide // formatting information. The tabwriter could provide trimming // functionality but no tabwriter is used when RawFormat is set.) - output = &trimmer{output: output}; + output = &trimmer{output: output} // setup tabwriter if needed and redirect output - var tw *tabwriter.Writer; + var tw *tabwriter.Writer if cfg.Mode&RawFormat == 0 { - minwidth := cfg.Tabwidth; + minwidth := cfg.Tabwidth - padchar := byte('\t'); + padchar := byte('\t') if cfg.Mode&UseSpaces != 0 { padchar = ' ' } - twmode := tabwriter.DiscardEmptyColumns; + twmode := tabwriter.DiscardEmptyColumns if cfg.Mode&GenHTML != 0 { twmode |= tabwriter.FilterHTML } if cfg.Mode&TabIndent != 0 { - minwidth = 0; - twmode |= tabwriter.TabIndent; + minwidth = 0 + twmode |= tabwriter.TabIndent } - tw = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode); - output = tw; + tw = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode) + output = tw } // setup printer and print node - var p printer; - p.init(output, cfg); + var p printer + p.init(output, cfg) go func() { switch n := node.(type) { case ast.Expr: @@ -971,23 +971,23 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) { case ast.Decl: p.decl(n, atTop, ignoreMultiLine) case *ast.File: - p.comment = n.Comments; - p.file(n); + p.comment = n.Comments + p.file(n) default: - p.errors <- os.NewError(fmt.Sprintf("printer.Fprint: unsupported node type %T", n)); - runtime.Goexit(); + p.errors <- os.NewError(fmt.Sprintf("printer.Fprint: unsupported node type %T", n)) + runtime.Goexit() } - p.flush(token.Position{Offset: 1 << 30, Line: 1 << 30}, false); // flush to "infinity" - p.errors <- nil; // no errors - }(); - err := <-p.errors; // wait for completion of goroutine + p.flush(token.Position{Offset: 1 << 30, Line: 1 << 30}, false) // flush to "infinity" + p.errors <- nil // no errors + }() + err := <-p.errors // wait for completion of goroutine // flush tabwriter, if any if tw != nil { - tw.Flush() // ignore errors + tw.Flush() // ignore errors } - return p.written, err; + return p.written, err } @@ -995,6 +995,6 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) { // It calls Config.Fprint with default settings. // func Fprint(output io.Writer, node interface{}) os.Error { - _, err := (&Config{Tabwidth: 8}).Fprint(output, node); // don't care about number of bytes written - return err; + _, err := (&Config{Tabwidth: 8}).Fprint(output, node) // don't care about number of bytes written + return err } |