parser

package module
v0.0.0-...-533fc4e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2023 License: MIT Imports: 16 Imported by: 0

README

Go Parser

The go-parser package is a small wrapper around the parser and ast packages.

Installation

To install this package, run:

go get github.com/zpatrick/go-parser

Motivation

If you've ever tried to implement code generation in Go, you're probably familiar with the parser and ast packages. These packages analyze and parse Go source files. The main problems I have with these packages are:

  • They aren't very intuitive
  • The amount of type assertions required to use them causes code to look cluttered and confusing

This package is meant to fix both of those issues. For example, the following two snippets of code perform the same function:

Using go-parser

    goFile, err := parser.ParseFile("user.go")
    if err != nil {
        log.Fatal(err)
    }

    for _, goStruct := range goFile.Structs {
        for _, goField := range goStruct.Fields {
            log.Println(goField.Name, goField.Type, goField.Tag)
        }
    }

Using ast and parser

    src, err := ioutil.ReadFile("user.go")
    if err != nil {
        log.Fatal(err)
    }

    file, err := parser.ParseFile(token.NewFileSet(), path, nil, 0)
    if err != nil {
        log.Fatal(err)
    }

    for _, d := range file.Decls {
        if typeDecl, ok := d.(*ast.GenDecl); ok {
            for _, s := range typeDecl.Specs {
                if typeSpec, ok := s.(*ast.TypeSpec); ok {
                    if structDecl, ok := typeSpec.Type.(*ast.StructType); ok {
                        for _, field := range structDecl.Fields.List {
                            for _, name := range field.Names {
                                name := name.String()
                                _type := string(src[field.Type.Pos()-1 : field.Type.End()-1])
                                tag := ""
                                if field.Tag != nil{
                                    tag = field.Tag.Value
                                }
                                
                                fmt.Printf(name, _type, tag)
                            }
                        }
                    }
                }
            }
        }
    }

Disclaimer & Contributing

I have been adding coverage on an as-needed basis. As such, this package is very much incomplete relative to the amount of coverage available in the ast and parser packages. However, merge requests are strongly encouraged! I've added a lot of comments to the parsing code to hopefully make it easier to read and contribute to.

License

This work is published under the MIT license.

Please see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type GoField

type GoField struct {
	Struct *GoStruct
	Name   string
	Type   string
	Tag    *GoTag
}

type GoFile

type GoFile struct {
	Package         string
	Path            string
	GlobalConstants []*GoType
	GlobalVariables []*GoType
	Structs         []*GoStruct
	Interfaces      []*GoInterface
	Imports         []*GoImport
	StructMethods   []*GoStructMethod
}

func ParseDir

func ParseDir(path string, withComments bool, filterFiles func(fs.FileInfo) bool) ([]*GoFile, error)

ParseFiles parses files at the same time

func ParseSingleFile

func ParseSingleFile(path string, withComments bool) (*GoFile, error)

ParseSingleFile parses a single file at the same time

func ParseSource

func ParseSource(source string, filepath string, withComments bool) (*GoFile, error)

func (*GoFile) ImportPath

func (g *GoFile) ImportPath() (importPath string, isExternalPackage bool, err error)

type GoImport

type GoImport struct {
	File *GoFile
	Name string
	Path string
}

func (*GoImport) Prefix

func (g *GoImport) Prefix() string

For an import - guess what prefix will be used in type declarations. For examples:

"strings" -> "strings"
"net/http/httptest" -> "httptest"

Libraries where the package name does not match will be mis-identified.

type GoInterface

type GoInterface struct {
	File     *GoFile
	Name     string
	Comments string
	Methods  []*GoMethod
}

type GoMethod

type GoMethod struct {
	Name     string
	Params   []*GoType
	Comments string
	Results  []*GoType
}

type GoStruct

type GoStruct struct {
	File     *GoFile
	Name     string
	Comments string
	Fields   []*GoField
}

type GoStructMethod

type GoStructMethod struct {
	GoMethod
	Receivers []string
}

type GoTag

type GoTag struct {
	Field *GoField
	Value string
}

func (*GoTag) Get

func (g *GoTag) Get(key string) string

type GoType

type GoType struct {
	Name       string
	Type       string
	Underlying string
	Inner      []*GoType
}

type PackImporter

type PackImporter struct {
	Fset *token.FileSet
}

func (*PackImporter) Import

func (this *PackImporter) Import(path string) (*types.Package, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL