| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- // Copyright (c) 2025 Tulir Asokan
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- //go:build ignore
- package main
- import (
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "os"
- "strings"
- "go.mau.fi/util/exerrors"
- )
- const header = `// GENERATED BY internals_generate.go; DO NOT EDIT
- //go:generate go run internals_generate.go
- //go:generate goimports -local go.mau.fi/whatsmeow -w internals.go
- package whatsmeow
- `
- const postImportHeader = `
- type DangerousInternalClient struct {
- c *Client
- }
- // DangerousInternals allows access to all unexported methods in Client.
- //
- // Deprecated: dangerous
- func (cli *Client) DangerousInternals() *DangerousInternalClient {
- return &DangerousInternalClient{cli}
- }
- type DangerousInfoQuery = infoQuery
- type DangerousInfoQueryType = infoQueryType
- `
- func getTypeName(expr ast.Expr) string {
- switch e := expr.(type) {
- case *ast.Ident:
- return e.Name
- case *ast.StarExpr:
- return "*" + getTypeName(e.X)
- case *ast.ArrayType:
- if e.Len != nil {
- return fmt.Sprintf("[%s]%s", getTypeName(e.Len), getTypeName(e.Elt))
- }
- return "[]" + getTypeName(e.Elt)
- case *ast.MapType:
- return fmt.Sprintf("map[%s]%s", getTypeName(e.Key), getTypeName(e.Value))
- case *ast.ChanType:
- if e.Dir == ast.SEND {
- return fmt.Sprintf("chan<- %s", getTypeName(e.Value))
- } else if e.Dir == ast.RECV {
- return fmt.Sprintf("<-chan %s", getTypeName(e.Value))
- }
- return fmt.Sprintf("chan %s", getTypeName(e.Value))
- case *ast.FuncType:
- var params []string
- for _, param := range e.Params.List {
- params = append(params, getTypeName(param.Type))
- }
- var results []string
- if e.Results != nil {
- for _, result := range e.Results.List {
- results = append(results, getTypeName(result.Type))
- }
- }
- retVals := strings.Join(results, ", ")
- if len(results) > 1 {
- retVals = fmt.Sprintf("(%s)", retVals)
- }
- return fmt.Sprintf("func(%s) %s", strings.Join(params, ", "), retVals)
- case *ast.SelectorExpr:
- return fmt.Sprintf("%s.%s", getTypeName(e.X), e.Sel.Name)
- case *ast.StructType:
- // This isn't technically correct, but struct literals shouldn't be used for anything else
- return "struct{}"
- case *ast.Ellipsis:
- return fmt.Sprintf("...%s", getTypeName(e.Elt))
- case *ast.BasicLit:
- return e.Value
- default:
- panic(fmt.Errorf("unknown type %T", e))
- }
- }
- var write func(str string)
- var writef func(format string, args ...any)
- func main() {
- fset := token.NewFileSet()
- fileNames := []string{
- "appstate.go", "armadillomessage.go", "broadcast.go", "call.go", "client.go",
- "connectionevents.go", "download.go", "download-to-file.go", "group.go", "handshake.go",
- "keepalive.go", "mediaconn.go", "mediaretry.go", "message.go", "msgsecret.go",
- "newsletter.go", "notification.go", "pair-code.go", "pair.go", "prekeys.go",
- "presence.go", "privacysettings.go", "push.go", "qrchan.go", "receipt.go", "request.go",
- "retry.go", "sendfb.go", "send.go", "upload.go", "user.go", "reportingtoken.go",
- }
- files := make([]*ast.File, len(fileNames))
- for i, name := range fileNames {
- files[i] = exerrors.Must(parser.ParseFile(fset, name, nil, parser.SkipObjectResolution))
- }
- file := exerrors.Must(os.OpenFile("internals.go", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644))
- write = func(str string) {
- exerrors.Must(file.WriteString(str))
- }
- writef = func(format string, args ...any) {
- exerrors.Must(fmt.Fprintf(file, format, args...))
- }
- write(header)
- write("import (\n")
- for _, i := range files[0].Imports {
- write("\t")
- if i.Name != nil {
- writef("%s ", i.Name.Name)
- }
- writef("%s\n", i.Path.Value)
- }
- write(")\n")
- write(postImportHeader)
- for _, f := range files {
- processFile(f)
- }
- exerrors.PanicIfNotNil(file.Close())
- }
- func processFile(f *ast.File) {
- ast.Inspect(f, func(node ast.Node) (retVal bool) {
- retVal = true
- funcDecl, ok := node.(*ast.FuncDecl)
- if !ok || funcDecl.Name.IsExported() {
- return
- }
- if funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 || len(funcDecl.Recv.List[0].Names) == 0 ||
- funcDecl.Recv.List[0].Names[0].Name != "cli" {
- return
- }
- writef("\nfunc (int *DangerousInternalClient) %s%s(", strings.ToUpper(funcDecl.Name.Name[0:1]), funcDecl.Name.Name[1:])
- for i, param := range funcDecl.Type.Params.List {
- if i != 0 {
- write(", ")
- }
- for j, name := range param.Names {
- if j != 0 {
- write(", ")
- }
- write(name.Name)
- }
- if len(param.Names) > 0 {
- write(" ")
- }
- write(getTypeName(param.Type))
- }
- write(") ")
- if funcDecl.Type.Results != nil && len(funcDecl.Type.Results.List) > 0 {
- needsParentheses := len(funcDecl.Type.Results.List) > 1 || len(funcDecl.Type.Results.List[0].Names) > 0
- if needsParentheses {
- write("(")
- }
- for i, result := range funcDecl.Type.Results.List {
- if i != 0 {
- write(", ")
- }
- for j, name := range result.Names {
- if j != 0 {
- write(", ")
- }
- write(name.Name)
- }
- if len(result.Names) > 0 {
- write(" ")
- }
- write(getTypeName(result.Type))
- }
- if needsParentheses {
- write(")")
- }
- write(" ")
- }
- write("{\n\t")
- if funcDecl.Type.Results != nil {
- write("return ")
- }
- writef("int.c.%s(", funcDecl.Name.Name)
- for i, param := range funcDecl.Type.Params.List {
- for j, name := range param.Names {
- if i != 0 || j != 0 {
- write(", ")
- }
- write(name.Name)
- _, isEllipsis := param.Type.(*ast.Ellipsis)
- if isEllipsis {
- write("...")
- }
- }
- }
- write(")\n}\n")
- return
- })
- }
|