aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/go')
-rw-r--r--libgo/go/go/ast/print.go73
-rw-r--r--libgo/go/go/ast/print_test.go21
-rw-r--r--libgo/go/go/ast/resolve.go2
-rw-r--r--libgo/go/go/ast/walk.go3
-rw-r--r--libgo/go/go/build/build.go6
-rw-r--r--libgo/go/go/build/build_test.go29
-rw-r--r--libgo/go/go/build/doc.go2
-rw-r--r--libgo/go/go/doc/reader.go2
-rw-r--r--libgo/go/go/doc/testdata/error2.1.golden2
-rw-r--r--libgo/go/go/doc/testdata/error2.go2
-rw-r--r--libgo/go/go/printer/nodes.go7
-rw-r--r--libgo/go/go/printer/printer_test.go29
-rw-r--r--libgo/go/go/scanner/errors.go2
-rw-r--r--libgo/go/go/scanner/scanner.go2
14 files changed, 146 insertions, 36 deletions
diff --git a/libgo/go/go/ast/print.go b/libgo/go/go/ast/print.go
index 02cf9e022..2de9af299 100644
--- a/libgo/go/go/ast/print.go
+++ b/libgo/go/go/ast/print.go
@@ -34,7 +34,8 @@ func NotNilFilter(_ string, v reflect.Value) bool {
//
// A non-nil FieldFilter f may be provided to control the output:
// struct fields for which f(fieldname, fieldvalue) is true are
-// are printed; all others are filtered from the output.
+// are printed; all others are filtered from the output. Unexported
+// struct fields are never printed.
//
func Fprint(w io.Writer, fset *token.FileSet, x interface{}, f FieldFilter) (err error) {
// setup printer
@@ -145,15 +146,18 @@ func (p *printer) print(x reflect.Value) {
p.print(x.Elem())
case reflect.Map:
- p.printf("%s (len = %d) {\n", x.Type(), x.Len())
- p.indent++
- for _, key := range x.MapKeys() {
- p.print(key)
- p.printf(": ")
- p.print(x.MapIndex(key))
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.indent++
p.printf("\n")
+ for _, key := range x.MapKeys() {
+ p.print(key)
+ p.printf(": ")
+ p.print(x.MapIndex(key))
+ p.printf("\n")
+ }
+ p.indent--
}
- p.indent--
p.printf("}")
case reflect.Ptr:
@@ -169,32 +173,57 @@ func (p *printer) print(x reflect.Value) {
p.print(x.Elem())
}
+ case reflect.Array:
+ p.printf("%s {", x.Type())
+ if x.Len() > 0 {
+ p.indent++
+ p.printf("\n")
+ for i, n := 0, x.Len(); i < n; i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ p.printf("\n")
+ }
+ p.indent--
+ }
+ p.printf("}")
+
case reflect.Slice:
if s, ok := x.Interface().([]byte); ok {
p.printf("%#q", s)
return
}
- p.printf("%s (len = %d) {\n", x.Type(), x.Len())
- p.indent++
- for i, n := 0, x.Len(); i < n; i++ {
- p.printf("%d: ", i)
- p.print(x.Index(i))
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.indent++
p.printf("\n")
+ for i, n := 0, x.Len(); i < n; i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ p.printf("\n")
+ }
+ p.indent--
}
- p.indent--
p.printf("}")
case reflect.Struct:
- p.printf("%s {\n", x.Type())
- p.indent++
t := x.Type()
+ p.printf("%s {", t)
+ p.indent++
+ first := true
for i, n := 0, t.NumField(); i < n; i++ {
- name := t.Field(i).Name
- value := x.Field(i)
- if p.filter == nil || p.filter(name, value) {
- p.printf("%s: ", name)
- p.print(value)
- p.printf("\n")
+ // exclude non-exported fields because their
+ // values cannot be accessed via reflection
+ if name := t.Field(i).Name; IsExported(name) {
+ value := x.Field(i)
+ if p.filter == nil || p.filter(name, value) {
+ if first {
+ p.printf("\n")
+ first = false
+ }
+ p.printf("%s: ", name)
+ p.print(value)
+ p.printf("\n")
+ }
}
}
p.indent--
diff --git a/libgo/go/go/ast/print_test.go b/libgo/go/go/ast/print_test.go
index 71c028e75..210f16430 100644
--- a/libgo/go/go/ast/print_test.go
+++ b/libgo/go/go/ast/print_test.go
@@ -23,6 +23,7 @@ var tests = []struct {
{"foobar", "0 \"foobar\""},
// maps
+ {map[Expr]string{}, `0 map[ast.Expr]string (len = 0) {}`},
{map[string]int{"a": 1},
`0 map[string]int (len = 1) {
1 . "a": 1
@@ -31,7 +32,21 @@ var tests = []struct {
// pointers
{new(int), "0 *0"},
+ // arrays
+ {[0]int{}, `0 [0]int {}`},
+ {[3]int{1, 2, 3},
+ `0 [3]int {
+ 1 . 0: 1
+ 2 . 1: 2
+ 3 . 2: 3
+ 4 }`},
+ {[...]int{42},
+ `0 [1]int {
+ 1 . 0: 42
+ 2 }`},
+
// slices
+ {[]int{}, `0 []int (len = 0) {}`},
{[]int{1, 2, 3},
`0 []int (len = 3) {
1 . 0: 1
@@ -40,6 +55,12 @@ var tests = []struct {
4 }`},
// structs
+ {struct{}{}, `0 struct {} {}`},
+ {struct{ x int }{007}, `0 struct { x int } {}`},
+ {struct{ X, y int }{42, 991},
+ `0 struct { X int; y int } {
+ 1 . X: 42
+ 2 }`},
{struct{ X, Y int }{42, 991},
`0 struct { X int; Y int } {
1 . X: 42
diff --git a/libgo/go/go/ast/resolve.go b/libgo/go/go/ast/resolve.go
index 908e61c5d..54b5d7325 100644
--- a/libgo/go/go/ast/resolve.go
+++ b/libgo/go/go/ast/resolve.go
@@ -136,7 +136,7 @@ func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer,
for _, obj := range pkg.Data.(*Scope).Objects {
p.declare(fileScope, pkgScope, obj)
}
- } else {
+ } else if name != "_" {
// declare imported package object in file scope
// (do not re-use pkg in the file scope but create
// a new object instead; the Decl field is different
diff --git a/libgo/go/go/ast/walk.go b/libgo/go/go/ast/walk.go
index 181cfd149..66b1dc249 100644
--- a/libgo/go/go/ast/walk.go
+++ b/libgo/go/go/ast/walk.go
@@ -344,9 +344,6 @@ func Walk(v Visitor, node Node) {
}
Walk(v, n.Name)
walkDeclList(v, n.Decls)
- for _, g := range n.Comments {
- Walk(v, g)
- }
// don't walk n.Comments - they have been
// visited already through the individual
// nodes
diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go
index 7a81d5030..67e73c5e4 100644
--- a/libgo/go/go/build/build.go
+++ b/libgo/go/go/build/build.go
@@ -536,7 +536,7 @@ Found:
return p, err
}
- pkg := string(pf.Name.Name)
+ pkg := pf.Name.Name
if pkg == "documentation" {
continue
}
@@ -570,7 +570,7 @@ Found:
if !ok {
continue
}
- quoted := string(spec.Path.Value)
+ quoted := spec.Path.Value
path, err := strconv.Unquote(quoted)
if err != nil {
log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
@@ -678,7 +678,7 @@ func (ctxt *Context) shouldBuild(content []byte) bool {
}
line = bytes.TrimSpace(line)
if len(line) == 0 { // Blank line
- end = cap(content) - cap(line) // &line[0] - &content[0]
+ end = len(content) - len(p)
continue
}
if !bytes.HasPrefix(line, slashslash) { // Not comment line
diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go
index 560ebad5c..caa4f26f3 100644
--- a/libgo/go/go/build/build_test.go
+++ b/libgo/go/go/build/build_test.go
@@ -75,3 +75,32 @@ func TestLocalDirectory(t *testing.T) {
t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build")
}
}
+
+func TestShouldBuild(t *testing.T) {
+ const file1 = "// +build tag1\n\n" +
+ "package main\n"
+
+ const file2 = "// +build cgo\n\n" +
+ "// This package implements parsing of tags like\n" +
+ "// +build tag1\n" +
+ "package build"
+
+ const file3 = "// Copyright The Go Authors.\n\n" +
+ "package build\n\n" +
+ "// shouldBuild checks tags given by lines of the form\n" +
+ "// +build tag\n" +
+ "func shouldBuild(content []byte)\n"
+
+ ctx := &Context{BuildTags: []string{"tag1"}}
+ if !ctx.shouldBuild([]byte(file1)) {
+ t.Errorf("should not build file1, expected the contrary")
+ }
+ if ctx.shouldBuild([]byte(file2)) {
+ t.Errorf("should build file2, expected the contrary")
+ }
+
+ ctx = &Context{BuildTags: nil}
+ if !ctx.shouldBuild([]byte(file3)) {
+ t.Errorf("should not build file3, expected the contrary")
+ }
+}
diff --git a/libgo/go/go/build/doc.go b/libgo/go/go/build/doc.go
index 67c26ac7f..9b7a946f2 100644
--- a/libgo/go/go/build/doc.go
+++ b/libgo/go/go/build/doc.go
@@ -60,7 +60,7 @@
// A build constraint is a line comment beginning with the directive +build
// that lists the conditions under which a file should be included in the package.
// Constraints may appear in any kind of source file (not just Go), but
-// they must be appear near the top of the file, preceded
+// they must appear near the top of the file, preceded
// only by blank lines and other line comments.
//
// A build constraint is evaluated as the OR of space-separated options;
diff --git a/libgo/go/go/doc/reader.go b/libgo/go/go/doc/reader.go
index 5eaae37b7..60b174fec 100644
--- a/libgo/go/go/doc/reader.go
+++ b/libgo/go/go/doc/reader.go
@@ -494,7 +494,7 @@ func (r *reader) readPackage(pkg *ast.Package, mode Mode) {
r.funcs = make(methodSet)
// sort package files before reading them so that the
- // result result does not depend on map iteration order
+ // result does not depend on map iteration order
i := 0
for filename := range pkg.Files {
r.filenames[i] = filename
diff --git a/libgo/go/go/doc/testdata/error2.1.golden b/libgo/go/go/doc/testdata/error2.1.golden
index 776bd1b3e..dbcc1b03e 100644
--- a/libgo/go/go/doc/testdata/error2.1.golden
+++ b/libgo/go/go/doc/testdata/error2.1.golden
@@ -10,7 +10,7 @@ FILENAMES
TYPES
//
type I0 interface {
- // When embedded, the the locally declared error interface
+ // When embedded, the locally-declared error interface
// is only visible if all declarations are shown.
error
}
diff --git a/libgo/go/go/doc/testdata/error2.go b/libgo/go/go/doc/testdata/error2.go
index 6cc36feef..6ee96c245 100644
--- a/libgo/go/go/doc/testdata/error2.go
+++ b/libgo/go/go/doc/testdata/error2.go
@@ -5,7 +5,7 @@
package error2
type I0 interface {
- // When embedded, the the locally declared error interface
+ // When embedded, the locally-declared error interface
// is only visible if all declarations are shown.
error
}
diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go
index f13f9a5a8..e346b9364 100644
--- a/libgo/go/go/printer/nodes.go
+++ b/libgo/go/go/printer/nodes.go
@@ -325,9 +325,14 @@ func (p *printer) parameters(fields *ast.FieldList) {
}
func (p *printer) signature(params, result *ast.FieldList) {
- p.parameters(params)
+ if params != nil {
+ p.parameters(params)
+ } else {
+ p.print(token.LPAREN, token.RPAREN)
+ }
n := result.NumFields()
if n > 0 {
+ // result != nil
p.print(blank)
if n == 1 && result.List[0].Names == nil {
// single anonymous result; no ()'s
diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go
index 497d671f2..ab9e9b2ec 100644
--- a/libgo/go/go/printer/printer_test.go
+++ b/libgo/go/go/printer/printer_test.go
@@ -385,6 +385,35 @@ func (t *t) foo(a, b, c int) int {
}
}
+// TestFuncType tests that an ast.FuncType with a nil Params field
+// can be printed (per go/ast specification). Test case for issue 3870.
+func TestFuncType(t *testing.T) {
+ src := &ast.File{
+ Name: &ast.Ident{Name: "p"},
+ Decls: []ast.Decl{
+ &ast.FuncDecl{
+ Name: &ast.Ident{Name: "f"},
+ Type: &ast.FuncType{},
+ },
+ },
+ }
+
+ var buf bytes.Buffer
+ if err := Fprint(&buf, fset, src); err != nil {
+ t.Fatal(err)
+ }
+ got := buf.String()
+
+ const want = `package p
+
+func f()
+`
+
+ if got != want {
+ t.Fatalf("got:\n%s\nwant:\n%s\n", got, want)
+ }
+}
+
// TextX is a skeleton test that can be filled in for debugging one-off cases.
// Do not remove.
func TestX(t *testing.T) {
diff --git a/libgo/go/go/scanner/errors.go b/libgo/go/go/scanner/errors.go
index 8a75a9650..22de69c3c 100644
--- a/libgo/go/go/scanner/errors.go
+++ b/libgo/go/go/scanner/errors.go
@@ -120,7 +120,7 @@ func PrintError(w io.Writer, err error) {
for _, e := range list {
fmt.Fprintf(w, "%s\n", e)
}
- } else {
+ } else if err != nil {
fmt.Fprintf(w, "%s\n", err)
}
}
diff --git a/libgo/go/go/scanner/scanner.go b/libgo/go/go/scanner/scanner.go
index da508747a..6ef3e14d0 100644
--- a/libgo/go/go/scanner/scanner.go
+++ b/libgo/go/go/scanner/scanner.go
@@ -81,7 +81,7 @@ func (s *Scanner) next() {
}
}
-// A mode value is set of flags (or 0).
+// A mode value is a set of flags (or 0).
// They control scanner behavior.
//
type Mode uint