summaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorAdin Scannell <ascannell@google.com>2020-12-11 12:04:46 -0800
committergVisor bot <gvisor-bot@google.com>2020-12-11 12:06:49 -0800
commit4cba3904f414775371f86571a549454aafad19bf (patch)
tree3f6953bb76029dc5b9705ffb38e95c7190255818 /tools
parent76c2f21cecf6c690aaf3aba8eccbc593eb3a6305 (diff)
Remove existing nogo exceptions.
PiperOrigin-RevId: 347047550
Diffstat (limited to 'tools')
-rw-r--r--tools/checkescape/test1/test1.go13
-rw-r--r--tools/go_marshal/gomarshal/generator.go50
-rw-r--r--tools/go_marshal/gomarshal/generator_interfaces.go4
-rw-r--r--tools/go_marshal/gomarshal/generator_tests.go4
-rw-r--r--tools/nogo/filter/main.go9
5 files changed, 62 insertions, 18 deletions
diff --git a/tools/checkescape/test1/test1.go b/tools/checkescape/test1/test1.go
index 27991649f..f46eba39b 100644
--- a/tools/checkescape/test1/test1.go
+++ b/tools/checkescape/test1/test1.go
@@ -36,17 +36,20 @@ func (t Type) Foo() {
fmt.Printf("%v", t) // Never executed.
}
+// InterfaceFunction is passed an interface argument.
// +checkescape:all,hard
//go:nosplit
func InterfaceFunction(i Interface) {
// Do nothing; exported for tests.
}
+// TypeFunction is passed a concrete pointer argument.
// +checkesacape:all,hard
//go:nosplit
func TypeFunction(t *Type) {
}
+// BuiltinMap creates a new map.
// +mustescape:local,builtin
//go:noinline
//go:nosplit
@@ -61,7 +64,8 @@ func builtinMapRec(x int) map[string]bool {
return BuiltinMap(x)
}
-// +temustescapestescape:local,builtin
+// BuiltinClosure returns a closure around x.
+// +mustescape:local,builtin
//go:noinline
//go:nosplit
func BuiltinClosure(x int) func() {
@@ -77,6 +81,7 @@ func builtinClosureRec(x int) func() {
return BuiltinClosure(x)
}
+// BuiltinMakeSlice makes a new slice.
// +mustescape:local,builtin
//go:noinline
//go:nosplit
@@ -91,6 +96,7 @@ func builtinMakeSliceRec(x int) []byte {
return BuiltinMakeSlice(x)
}
+// BuiltinAppend calls append on a slice.
// +mustescape:local,builtin
//go:noinline
//go:nosplit
@@ -105,6 +111,7 @@ func builtinAppendRec() []byte {
return BuiltinAppend(nil)
}
+// BuiltinChan makes a channel.
// +mustescape:local,builtin
//go:noinline
//go:nosplit
@@ -119,6 +126,7 @@ func builtinChanRec() chan int {
return BuiltinChan()
}
+// Heap performs an explicit heap allocation.
// +mustescape:local,heap
//go:noinline
//go:nosplit
@@ -134,6 +142,7 @@ func heapRec() *Type {
return Heap()
}
+// Dispatch dispatches via an interface.
// +mustescape:local,interface
//go:noinline
//go:nosplit
@@ -148,6 +157,7 @@ func dispatchRec(i Interface) {
Dispatch(i)
}
+// Dynamic invokes a dynamic function.
// +mustescape:local,dynamic
//go:noinline
//go:nosplit
@@ -167,6 +177,7 @@ func dynamicRec(f func()) {
func internalFunc() {
}
+// Split includes a guaranteed stack split.
// +mustescape:local,stack
//go:noinline
func Split() {
diff --git a/tools/go_marshal/gomarshal/generator.go b/tools/go_marshal/gomarshal/generator.go
index 4a53d25be..6f41b1b79 100644
--- a/tools/go_marshal/gomarshal/generator.go
+++ b/tools/go_marshal/gomarshal/generator.go
@@ -213,10 +213,11 @@ type sliceAPI struct {
type marshallableType struct {
spec *ast.TypeSpec
slice *sliceAPI
+ recv string
}
-func newMarshallableType(fset *token.FileSet, tagLine *ast.Comment, spec *ast.TypeSpec) marshallableType {
- mt := marshallableType{
+func newMarshallableType(fset *token.FileSet, tagLine *ast.Comment, spec *ast.TypeSpec) *marshallableType {
+ mt := &marshallableType{
spec: spec,
slice: nil,
}
@@ -261,12 +262,31 @@ func newMarshallableType(fset *token.FileSet, tagLine *ast.Comment, spec *ast.Ty
// collectMarshallableTypes walks the parsed AST and collects a list of type
// declarations for which we need to generate the Marshallable interface.
-func (g *Generator) collectMarshallableTypes(a *ast.File, f *token.FileSet) []marshallableType {
- var types []marshallableType
+func (g *Generator) collectMarshallableTypes(a *ast.File, f *token.FileSet) map[*ast.TypeSpec]*marshallableType {
+ recv := make(map[string]string) // Type name to recevier name.
+ types := make(map[*ast.TypeSpec]*marshallableType)
for _, decl := range a.Decls {
gdecl, ok := decl.(*ast.GenDecl)
// Type declaration?
if !ok || gdecl.Tok != token.TYPE {
+ // Is this a function declaration? We remember receiver names.
+ d, ok := decl.(*ast.FuncDecl)
+ if ok && d.Recv != nil && len(d.Recv.List) == 1 {
+ // Accept concrete methods & pointer methods.
+ ident, ok := d.Recv.List[0].Type.(*ast.Ident)
+ if !ok {
+ var st *ast.StarExpr
+ st, ok = d.Recv.List[0].Type.(*ast.StarExpr)
+ if ok {
+ ident, ok = st.X.(*ast.Ident)
+ }
+ }
+ // The receiver name may be not present.
+ if ok && len(d.Recv.List[0].Names) == 1 {
+ // Recover the type receiver name in this case.
+ recv[ident.Name] = d.Recv.List[0].Names[0].Name
+ }
+ }
debugfAt(f.Position(decl.Pos()), "Skipping declaration since it's not a type declaration.\n")
continue
}
@@ -305,9 +325,19 @@ func (g *Generator) collectMarshallableTypes(a *ast.File, f *token.FileSet) []ma
// don't support it.
abortAt(f.Position(t.Pos()), fmt.Sprintf("Marshalling codegen was requested on type '%s', but go-marshal doesn't support this kind of declaration.\n", t.Name))
}
- types = append(types, newMarshallableType(f, tagLine, t))
-
+ types[t] = newMarshallableType(f, tagLine, t)
+ }
+ }
+ // Update the types with the last seen receiver. As long as the
+ // receiver name is consistent for the type, then we will generate
+ // code that is still consistent with itself.
+ for t, mt := range types {
+ r, ok := recv[t.Name.Name]
+ if !ok {
+ mt.recv = receiverName(t) // Default.
+ continue
}
+ mt.recv = r // Last seen.
}
return types
}
@@ -345,8 +375,8 @@ func (g *Generator) collectImports(a *ast.File, f *token.FileSet) map[string]imp
}
-func (g *Generator) generateOne(t marshallableType, fset *token.FileSet) *interfaceGenerator {
- i := newInterfaceGenerator(t.spec, fset)
+func (g *Generator) generateOne(t *marshallableType, fset *token.FileSet) *interfaceGenerator {
+ i := newInterfaceGenerator(t.spec, t.recv, fset)
switch ty := t.spec.Type.(type) {
case *ast.StructType:
i.validateStruct(t.spec, ty)
@@ -376,8 +406,8 @@ func (g *Generator) generateOne(t marshallableType, fset *token.FileSet) *interf
// generateOneTestSuite generates a test suite for the automatically generated
// implementations type t.
-func (g *Generator) generateOneTestSuite(t marshallableType) *testGenerator {
- i := newTestGenerator(t.spec)
+func (g *Generator) generateOneTestSuite(t *marshallableType) *testGenerator {
+ i := newTestGenerator(t.spec, t.recv)
i.emitTests(t.slice)
return i
}
diff --git a/tools/go_marshal/gomarshal/generator_interfaces.go b/tools/go_marshal/gomarshal/generator_interfaces.go
index 36447b86b..65f5ea34d 100644
--- a/tools/go_marshal/gomarshal/generator_interfaces.go
+++ b/tools/go_marshal/gomarshal/generator_interfaces.go
@@ -54,10 +54,10 @@ func (g *interfaceGenerator) typeName() string {
}
// newinterfaceGenerator creates a new interface generator.
-func newInterfaceGenerator(t *ast.TypeSpec, fset *token.FileSet) *interfaceGenerator {
+func newInterfaceGenerator(t *ast.TypeSpec, r string, fset *token.FileSet) *interfaceGenerator {
g := &interfaceGenerator{
t: t,
- r: receiverName(t),
+ r: r,
f: fset,
is: make(map[string]struct{}),
ms: make(map[string]struct{}),
diff --git a/tools/go_marshal/gomarshal/generator_tests.go b/tools/go_marshal/gomarshal/generator_tests.go
index 631295373..6cf00843f 100644
--- a/tools/go_marshal/gomarshal/generator_tests.go
+++ b/tools/go_marshal/gomarshal/generator_tests.go
@@ -53,10 +53,10 @@ type testGenerator struct {
decl *importStmt
}
-func newTestGenerator(t *ast.TypeSpec) *testGenerator {
+func newTestGenerator(t *ast.TypeSpec, r string) *testGenerator {
g := &testGenerator{
t: t,
- r: receiverName(t),
+ r: r,
imports: newImportTable(),
}
diff --git a/tools/nogo/filter/main.go b/tools/nogo/filter/main.go
index 9cf41b3b0..8be38ca6d 100644
--- a/tools/nogo/filter/main.go
+++ b/tools/nogo/filter/main.go
@@ -16,6 +16,7 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"io/ioutil"
@@ -76,12 +77,14 @@ func main() {
log.Fatalf("unable to read %s: %v", filename, err)
}
var newConfig nogo.Config // For current file.
- if err := yaml.Unmarshal(content, &newConfig); err != nil {
+ dec := yaml.NewDecoder(bytes.NewBuffer(content))
+ dec.SetStrict(true)
+ if err := dec.Decode(&newConfig); err != nil {
log.Fatalf("unable to decode %s: %v", filename, err)
}
config.Merge(&newConfig)
if showConfig {
- bytes, err := yaml.Marshal(&newConfig)
+ content, err := yaml.Marshal(&newConfig)
if err != nil {
log.Fatalf("error marshalling config: %v", err)
}
@@ -89,7 +92,7 @@ func main() {
if err != nil {
log.Fatalf("error marshalling config: %v", err)
}
- fmt.Fprintf(os.Stdout, "Loaded configuration from %s:\n%s\n", filename, string(bytes))
+ fmt.Fprintf(os.Stdout, "Loaded configuration from %s:\n%s\n", filename, string(content))
fmt.Fprintf(os.Stdout, "Merged configuration:\n%s\n", string(mergedBytes))
}
}