github.com/neilgarb/delve@v1.9.2-nobreaks/service/dap/daptest/gen/main.go (about)

     1  // Binary gen generates service/dap/daptest/responses.go.
     2  package main
     3  
     4  import (
     5  	"bytes"
     6  	"flag"
     7  	"fmt"
     8  	"go/format"
     9  	"go/types"
    10  	"io/ioutil"
    11  	"os"
    12  	"text/template"
    13  
    14  	"golang.org/x/tools/go/packages"
    15  
    16  	_ "github.com/google/go-dap"
    17  )
    18  
    19  var oFlag = flag.String("o", "", "output file name")
    20  
    21  var tmpl = template.Must(template.New("assert").Parse(`package daptest
    22  
    23  // Code generated by go generate; DO NOT EDIT.
    24  // The code generator program is in ./gen directory.
    25  
    26  import (
    27  	"testing"
    28  
    29  	"github.com/google/go-dap"
    30  )
    31  {{range .}}
    32  // Expect{{.}} reads a protocol message from the connection
    33  // and fails the test if the read message is not *{{.}}.
    34  func (c *Client) Expect{{.}}(t *testing.T) *dap.{{.}} {
    35  	t.Helper()
    36  	m := c.ExpectMessage(t)
    37  	return c.Check{{.}}(t, m)
    38  }
    39  
    40  // Check{{.}} fails the test if m is not *{{.}}.
    41  func (c *Client) Check{{.}}(t *testing.T, m dap.Message) *dap.{{.}} {
    42  	t.Helper(){{if or (or (eq . "StepInResponse") (eq . "StepOutResponse")) (eq . "NextResponse") }}
    43  	_, ok := m.(*dap.ContinuedEvent)
    44  	if !ok {
    45  		t.Fatalf("got %#v, want *dap.ContinuedEvent", m)
    46  	}
    47  	m = c.ExpectMessage(t){{else}}{{if (eq . "ConfigurationDoneResponse") }}
    48  	oe, ok := m.(*dap.OutputEvent)
    49  	if !ok {
    50  		t.Fatalf("got %#v, want *dap.OutputEvent", m)
    51  	}
    52  	if oe.Body.Output != "Type 'dlv help' for list of commands.\n" {
    53  		t.Fatalf("got %#v, want Output=%q", m, "Type 'dlv help' for list of commands.\n")
    54  	}
    55  	m = c.ExpectMessage(t){{end}}{{end}}
    56  	r, ok := m.(*dap.{{.}})
    57  	if !ok {
    58  		t.Fatalf("got %#v, want *dap.{{.}}", m)
    59  	}
    60  	return r
    61  }{{end}}
    62  `))
    63  
    64  func main() {
    65  	flag.Parse()
    66  
    67  	if *oFlag == "" {
    68  		fmt.Fprintf(os.Stderr, "-o must be provided\n")
    69  	}
    70  
    71  	pkgs, err := packages.Load(&packages.Config{
    72  		Mode: packages.NeedTypes,
    73  	}, "github.com/google/go-dap")
    74  	if err != nil {
    75  		fmt.Fprintf(os.Stderr, "load: %v\n", err)
    76  		os.Exit(1)
    77  	}
    78  	if len(pkgs) != 1 || pkgs[0].Types == nil {
    79  		fmt.Fprintf(os.Stderr, "invalid package was loaded: %#v\n", pkgs)
    80  		os.Exit(1)
    81  	}
    82  
    83  	messages := []string{}
    84  	scope := pkgs[0].Types.Scope()
    85  	for _, name := range scope.Names() {
    86  		// Find only types that are embedding go-dap.Respose message.
    87  		obj := scope.Lookup(name)
    88  		if !obj.Exported() {
    89  			continue // skip unexported
    90  		}
    91  		u, ok := obj.Type().Underlying().(*types.Struct)
    92  		if !ok {
    93  			continue
    94  		}
    95  		for i := 0; i < u.NumFields(); i++ {
    96  			if f := u.Field(i); f.Embedded() && (f.Type().String() == "github.com/google/go-dap.Response" ||
    97  				f.Type().String() == "github.com/google/go-dap.Event") {
    98  				messages = append(messages, obj.Name())
    99  				break
   100  			}
   101  		}
   102  	}
   103  
   104  	buf := &bytes.Buffer{}
   105  	if err := tmpl.Execute(buf, messages); err != nil {
   106  		fmt.Fprintf(os.Stderr, "Failed to generate: %v\n", err)
   107  		os.Exit(1)
   108  	}
   109  	formatted, err := format.Source(buf.Bytes())
   110  	if err != nil {
   111  		fmt.Fprintf(os.Stderr, "Generated invalid go code: %v\n", err)
   112  		os.Exit(1)
   113  	}
   114  	if err := ioutil.WriteFile(*oFlag, formatted, 0644); err != nil {
   115  		fmt.Fprintf(os.Stderr, "Failed to write: %v\n", err)
   116  		os.Exit(1)
   117  	}
   118  }