From 8c101739d9c68dc2feae3b63e482c245fda7a987 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 15 Oct 2009 10:41:07 -0700 Subject: [PATCH] - bug fix: must not insert indentation tabs into multi-line strings in RawFormat (always write tabwriter.Escape chars so formatting is driven correctly; but strip them again in the end if no tabwriter is used) - added testcase for RawFormat printing R=rsc DELTA=227 (198 added, 6 deleted, 23 changed) OCL=35772 CL=35774 --- src/pkg/go/printer/printer.go | 29 ++-- src/pkg/go/printer/printer_test.go | 40 +++-- src/pkg/go/printer/testdata/expressions.raw | 181 ++++++++++++++++++++ 3 files changed, 221 insertions(+), 29 deletions(-) create mode 100644 src/pkg/go/printer/testdata/expressions.raw diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go index 36400ca42d..bddb73b4d4 100644 --- a/src/pkg/go/printer/printer.go +++ b/src/pkg/go/printer/printer.go @@ -971,16 +971,10 @@ func (p *printer) expr1(expr ast.Expr, prec1 int) (optSemi bool) { } case *ast.BasicLit: - if p.mode & RawFormat == 0 { - // tabwriter is used: escape all literals - // so they pass through unchanged - // (note that a legal Go program cannot contain an '\xff' byte in - // literal source text since '\xff' is not a legal byte in correct - // UTF-8 encoded text) - p.print(esc, x.Value, esc); - } else { - p.print(x.Value); - } + // escape all literals so they pass through unchanged + // (note that valid Go programs cannot contain esc ('\xff') + // bytes since they do not appear in legal UTF-8 sequences) + p.print(esc, x.Value, esc); case *ast.StringList: p.stringList(x.Strings); @@ -1536,9 +1530,10 @@ func (p *printer) file(src *ast.File) { // ---------------------------------------------------------------------------- // Trimmer -// A trimmer is an io.Writer filter for stripping trailing blanks -// and tabs, and for converting formfeed and vtab characters into -// newlines and htabs (in case no tabwriter is used). +// A trimmer is an io.Writer filter for stripping tabwriter.Escape +// characters, trailing blanks and tabs, and for converting formfeed +// and vtab characters into newlines and htabs (in case no tabwriter +// is used). // type trimmer struct { output io.Writer; @@ -1577,7 +1572,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { b = '\t'; // convert to htab fallthrough; - case '\t', ' ': + case '\t', ' ', tabwriter.Escape: // write any pending (non-whitespace) data if m >= 0 { if _, err = p.output.Write(data[m:n]); err != nil { @@ -1585,8 +1580,10 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { } m = -1; } - // collect whitespace - p.buf.WriteByte(b); // WriteByte returns no errors + // collect whitespace but discard tabrwiter.Escapes. + if b != tabwriter.Escape { + p.buf.WriteByte(b); // WriteByte returns no errors + } case '\f', '\n': // discard whitespace diff --git a/src/pkg/go/printer/printer_test.go b/src/pkg/go/printer/printer_test.go index df42c398eb..9fbc1ad233 100644 --- a/src/pkg/go/printer/printer_test.go +++ b/src/pkg/go/printer/printer_test.go @@ -33,7 +33,14 @@ func lineString(text []byte, i int) string { } -func check(t *testing.T, source, golden string, exports bool) { +type checkMode uint; +const ( + export checkMode = 1<>4; + _ = "foo"+s; + _ = s+"foo"; + _ = 'a'+'b'; + _ = len(s)/2; + _ = len(t0.x)/a; + + // spaces around expressions of different precedence or expressions containing spaces + _ = a + -b; + _ = a - ^b; + _ = a / *p; + _ = a + b*c; + _ = 1 + b*c; + _ = a + 2*c; + _ = a + c*2; + _ = 1 + 2*3; + _ = s[1 : 2*3]; + _ = s[a : b-c]; + _ = s[a+b : len(s)]; + _ = s[len(s) : -a]; + _ = s[a : len(s)+1]; + _ = s[a : len(s)+1]+s; + + // spaces around operators with equal or lower precedence than comparisons + _ = a == b; + _ = a != b; + _ = a > b; + _ = a >= b; + _ = a < b; + _ = a <= b; + _ = a < b && c > d; + _ = a < b || c > d; + + // spaces around "long" operands + _ = a + longIdentifier1; + _ = longIdentifier1 + a; + _ = longIdentifier1 + longIdentifier2 * longIdentifier3; + _ = s + "a longer string"; + + // some selected cases + _ = a + t0.x; + _ = a + t0.x + t1.x * t2.x; + _ = a + b + c + d + e + 2*3; + _ = a + b + c + 2*3 + d + e; + _ = (a+b+c)*2; + _ = a - b + c - d + (a+b+c) + d&e; + _ = under_bar - 1; + _ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666); + _ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx); +} + + +func _() { + _ = T{}; + _ = struct{}{}; + _ = [10]T{}; + _ = [...]T{}; + _ = []T{}; + _ = map[int]T{}; + + _ = (T){}; + _ = (struct{}){}; + _ = ([10]T){}; + _ = ([...]T){}; + _ = ([]T){}; + _ = (map[int]T){}; +} + + +func _() { + // do not modify literals + _ = "tab1 tab2 tab3 end"; // string contains 3 tabs + _ = "tab1 tab2 tab3 end"; // same string with 3 blanks - may be unaligned because editors see tabs in strings + _ = ""; // this comment should be aligned with the one on the previous line + _ = ``; + _ = ` +`; + _ = `foo + bar`; +} + + +func _() { + // not not add extra indentation to multi-line string lists + _ = "foo" "bar"; + _ = "foo" + "bar" + "bah"; + _ = []string{ + "abc" + "def", + "foo" + "bar", + }; +} + + +func _() { + // respect source lines in multi-line expressions + _ = a + + b + + c; + _ = a < b || + b < a; + _ = "1234567890" + "1234567890"; + // this comment should be indented +} + + +func same(t, u *Time) bool { + // respect source lines in multi-line expressions + return t.Year == u.Year && + t.Month == u.Month && + t.Day == u.Day && + t.Hour == u.Hour && + t.Minute == u.Minute && + t.Second == u.Second && + t.Weekday == u.Weekday && + t.ZoneOffset == u.ZoneOffset && + t.Zone == u.Zone; +} + + +func (p *parser) charClass() { + // respect source lines in multi-line expressions + if cc.negate && len(cc.ranges) == 2 && + cc.ranges[0] == '\n' && cc.ranges[1] == '\n' { + nl := new(_NotNl); + p.re.add(nl); + } +} + + +func addState(s []state, inst instr, match []int) { + // handle comments correctly in multi-line expressions + for i := 0; i < l; i++ { + if s[i].inst.index() == index && + // same instruction + s[i].match[0] < pos { // earlier match already going; leftmost wins + return s; + } + } +} -- 2.50.0