github.com/goplus/gossa@v0.3.25/cmd/qexp/export.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"go/format"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"sort"
    10  	"strings"
    11  )
    12  
    13  func writeFile(dir string, file string, data []byte) error {
    14  	err := os.MkdirAll(dir, 0777)
    15  	if err != nil {
    16  		return fmt.Errorf("make dir %v error: %v", dir, err)
    17  	}
    18  	filename := filepath.Join(dir, file)
    19  	err = ioutil.WriteFile(filename, data, 0777)
    20  	if err != nil {
    21  		return fmt.Errorf("write file %v error: %v", filename, err)
    22  	}
    23  	return nil
    24  }
    25  
    26  func joinList(list []string) string {
    27  	if len(list) == 0 {
    28  		return ""
    29  	}
    30  	sort.Strings(list)
    31  	return "\n\t" + strings.Join(list, ",\n\t") + ",\n"
    32  }
    33  
    34  func exportPkg(pkg *Package, sname string, id string, tagList []string) ([]byte, error) {
    35  	imports := []string{fmt.Sprintf("%v %q\n", sname, pkg.Path)}
    36  	imports = append(imports, `"reflect"`)
    37  	if len(pkg.UntypedConsts) > 0 || len(pkg.TypedConsts) > 0 {
    38  		imports = append(imports, `"go/constant"`)
    39  		var hasToken bool
    40  		for _, c := range pkg.UntypedConsts {
    41  			if strings.Index(c, "token.") >= 0 {
    42  				hasToken = true
    43  				break
    44  			}
    45  		}
    46  		if hasToken {
    47  			imports = append(imports, `"go/token"`)
    48  		}
    49  	}
    50  
    51  	r := strings.NewReplacer("$PKGNAME", pkg.Name,
    52  		"$IMPORTS", strings.Join(imports, "\n"),
    53  		"$PKGPATH", pkg.Path,
    54  		"$DEPS", joinList(pkg.Deps),
    55  		"$NAMEDTYPES", joinList(pkg.NamedTypes),
    56  		"$INTERFACES", joinList(pkg.Interfaces),
    57  		"$ALIASTYPES", joinList(pkg.AliasTypes),
    58  		"$VARS", joinList(pkg.Vars),
    59  		"$FUNCS", joinList(pkg.Funcs),
    60  		"$METHODS", joinList(pkg.Methods),
    61  		"$TYPEDCONSTS", joinList(pkg.TypedConsts),
    62  		"$UNTYPEDCONSTS", joinList(pkg.UntypedConsts),
    63  		"$TAGS", strings.Join(tagList, "\n"),
    64  		"$ID", id)
    65  	src := r.Replace(template_pkg)
    66  	data, err := format.Source([]byte(src))
    67  	if err != nil {
    68  		return nil, fmt.Errorf("format pkg %v error: %v", src, err)
    69  	}
    70  	return data, nil
    71  }
    72  
    73  func exportSource(pkgPath string, id string, tagList []string, extList []string, typList []string) ([]byte, error) {
    74  	plist := strings.Split(pkgPath, "/")
    75  	pkgName := plist[len(plist)-1]
    76  	var em string
    77  	if len(extList) > 0 {
    78  		sort.Strings(extList)
    79  		em = "\n\t" + strings.Join(extList, ",\n\t") + ",\n"
    80  	}
    81  	var tl string
    82  	if len(typList) > 0 {
    83  		sort.Strings(typList)
    84  		tl = "\n\t" + strings.Join(typList, ",\n\t") + ",\n"
    85  	}
    86  	r := strings.NewReplacer("$PKGNAME", pkgName,
    87  		"$PKGPATH", pkgPath,
    88  		"$EXTMAP", em,
    89  		"$TYPLIST", tl,
    90  		"$TAGS", strings.Join(tagList, "\n"),
    91  		"$ID", id)
    92  	var template string
    93  	if len(typList) == 0 && len(extList) == 0 {
    94  		template = template_empty
    95  	} else {
    96  		template = template_tags
    97  	}
    98  	src := r.Replace(template)
    99  	data, err := format.Source([]byte(src))
   100  	if err != nil {
   101  		return nil, fmt.Errorf("format pkg %v error: %v", pkgPath, err)
   102  	}
   103  	return data, nil
   104  }
   105  
   106  var template_export = `// export by github.com/goplus/gossa/cmd/qexp
   107  package $PKGNAME
   108  
   109  import (
   110  	"$PKGPATH"
   111  
   112  	"github.com/goplus/gossa"
   113  )
   114  
   115  func init() {
   116  	gossa.RegisterPackage("$PKGPATH",extMap,typList)
   117  }
   118  
   119  var extMap = map[string]interface{}{$EXTMAP}
   120  
   121  var typList = []interface{}{$TYPLIST}
   122  `
   123  
   124  var template_tags = `// export by github.com/goplus/gossa/cmd/qexp
   125  
   126  $TAGS
   127  
   128  package $PKGNAME
   129  
   130  import (
   131  	"$PKGPATH"
   132  
   133  	"github.com/goplus/gossa"
   134  )
   135  
   136  func init() {
   137  	gossa.RegisterPackage("$PKGPATH",extMap$ID,typList$ID)
   138  }
   139  
   140  var extMap$ID = map[string]interface{}{$EXTMAP}
   141  
   142  var typList$ID = []interface{}{$TYPLIST}
   143  `
   144  
   145  var template_empty = `// export by github.com/goplus/gossa/cmd/qexp
   146  
   147  $TAGS
   148  
   149  package $PKGNAME
   150  
   151  import (
   152  	"github.com/goplus/gossa"
   153  )
   154  
   155  func init() {
   156  	gossa.RegisterPackage("$PKGPATH",nil,nil)
   157  }
   158  `
   159  
   160  /*
   161  type TypedConst struct {
   162  	Typ   reflect.Type
   163  	Value constant.Value
   164  }
   165  
   166  type UntypedConst struct {
   167  	Typ   string
   168  	Value constant.Value
   169  }
   170  
   171  type Package struct {
   172  	Name          string
   173  	Path          string
   174  	Types         []reflect.Type
   175  	AliasTypes    map[string]reflect.Type
   176  	Vars          map[string]reflect.Value
   177  	Funcs         map[string]reflect.Value
   178  	Methods       map[string]reflect.Value
   179  	TypedConsts   map[string]TypedConst
   180  	UntypedConsts map[string]UntypedConst
   181  	Deps          map[string]string
   182  }
   183  */
   184  
   185  var template_pkg = `// export by github.com/goplus/gossa/cmd/qexp
   186  
   187  $TAGS
   188  
   189  package $PKGNAME
   190  
   191  import (
   192  	$IMPORTS
   193  
   194  	"github.com/goplus/gossa"
   195  )
   196  
   197  func init() {
   198  	gossa.RegisterPackage(&gossa.Package {
   199  		Name: "$PKGNAME",
   200  		Path: "$PKGPATH",
   201  		Deps: map[string]string{$DEPS},
   202  		Interfaces: map[string]reflect.Type{$INTERFACES},
   203  		NamedTypes: map[string]gossa.NamedType{$NAMEDTYPES},
   204  		AliasTypes: map[string]reflect.Type{$ALIASTYPES},
   205  		Vars: map[string]reflect.Value{$VARS},
   206  		Funcs: map[string]reflect.Value{$FUNCS},
   207  		TypedConsts: map[string]gossa.TypedConst{$TYPEDCONSTS},
   208  		UntypedConsts: map[string]gossa.UntypedConst{$UNTYPEDCONSTS},
   209  	})
   210  }
   211  `