gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/mibk/dupl/syntax/golang/golang.go (about)

     1  package golang
     2  
     3  import (
     4  	"go/ast"
     5  	"go/parser"
     6  	"go/token"
     7  
     8  	"github.com/mibk/dupl/syntax"
     9  )
    10  
    11  const (
    12  	BadNode = iota
    13  	File
    14  	ArrayType
    15  	AssignStmt
    16  	BasicLit
    17  	BinaryExpr
    18  	BlockStmt
    19  	BranchStmt
    20  	CallExpr
    21  	CaseClause
    22  	ChanType
    23  	CommClause
    24  	CompositeLit
    25  	DeclStmt
    26  	DeferStmt
    27  	Ellipsis
    28  	EmptyStmt
    29  	ExprStmt
    30  	Field
    31  	FieldList
    32  	ForStmt
    33  	FuncDecl
    34  	FuncLit
    35  	FuncType
    36  	GenDecl
    37  	GoStmt
    38  	Ident
    39  	IfStmt
    40  	IncDecStmt
    41  	IndexExpr
    42  	InterfaceType
    43  	KeyValueExpr
    44  	LabeledStmt
    45  	MapType
    46  	ParenExpr
    47  	RangeStmt
    48  	ReturnStmt
    49  	SelectStmt
    50  	SelectorExpr
    51  	SendStmt
    52  	SliceExpr
    53  	StarExpr
    54  	StructType
    55  	SwitchStmt
    56  	TypeAssertExpr
    57  	TypeSpec
    58  	TypeSwitchStmt
    59  	UnaryExpr
    60  	ValueSpec
    61  )
    62  
    63  // Parse the given file and return uniform syntax tree.
    64  func Parse(filename string) (*syntax.Node, error) {
    65  	fset := token.NewFileSet()
    66  	file, err := parser.ParseFile(fset, filename, nil, 0)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	t := &transformer{
    71  		fileset:  fset,
    72  		filename: filename,
    73  	}
    74  	return t.trans(file), nil
    75  }
    76  
    77  type transformer struct {
    78  	fileset  *token.FileSet
    79  	filename string
    80  }
    81  
    82  // trans transforms given golang AST to uniform tree structure.
    83  func (t *transformer) trans(node ast.Node) (o *syntax.Node) {
    84  	o = syntax.NewNode()
    85  	o.Filename = t.filename
    86  	st, end := node.Pos(), node.End()
    87  	o.Pos, o.End = t.fileset.File(st).Offset(st), t.fileset.File(end).Offset(end)
    88  
    89  	switch n := node.(type) {
    90  	case *ast.ArrayType:
    91  		o.Type = ArrayType
    92  		if n.Len != nil {
    93  			o.AddChildren(t.trans(n.Len))
    94  		}
    95  		o.AddChildren(t.trans(n.Elt))
    96  
    97  	case *ast.AssignStmt:
    98  		o.Type = AssignStmt
    99  		for _, e := range n.Rhs {
   100  			o.AddChildren(t.trans(e))
   101  		}
   102  
   103  		for _, e := range n.Lhs {
   104  			o.AddChildren(t.trans(e))
   105  		}
   106  
   107  	case *ast.BasicLit:
   108  		o.Type = BasicLit
   109  
   110  	case *ast.BinaryExpr:
   111  		o.Type = BinaryExpr
   112  		o.AddChildren(t.trans(n.X), t.trans(n.Y))
   113  
   114  	case *ast.BlockStmt:
   115  		o.Type = BlockStmt
   116  		for _, stmt := range n.List {
   117  			o.AddChildren(t.trans(stmt))
   118  		}
   119  
   120  	case *ast.BranchStmt:
   121  		o.Type = BranchStmt
   122  		if n.Label != nil {
   123  			o.AddChildren(t.trans(n.Label))
   124  		}
   125  
   126  	case *ast.CallExpr:
   127  		o.Type = CallExpr
   128  		o.AddChildren(t.trans(n.Fun))
   129  		for _, arg := range n.Args {
   130  			o.AddChildren(t.trans(arg))
   131  		}
   132  
   133  	case *ast.CaseClause:
   134  		o.Type = CaseClause
   135  		for _, e := range n.List {
   136  			o.AddChildren(t.trans(e))
   137  		}
   138  		for _, stmt := range n.Body {
   139  			o.AddChildren(t.trans(stmt))
   140  		}
   141  
   142  	case *ast.ChanType:
   143  		o.Type = ChanType
   144  		o.AddChildren(t.trans(n.Value))
   145  
   146  	case *ast.CommClause:
   147  		o.Type = CommClause
   148  		if n.Comm != nil {
   149  			o.AddChildren(t.trans(n.Comm))
   150  		}
   151  		for _, stmt := range n.Body {
   152  			o.AddChildren(t.trans(stmt))
   153  		}
   154  
   155  	case *ast.CompositeLit:
   156  		o.Type = CompositeLit
   157  		if n.Type != nil {
   158  			o.AddChildren(t.trans(n.Type))
   159  		}
   160  		for _, e := range n.Elts {
   161  			o.AddChildren(t.trans(e))
   162  		}
   163  
   164  	case *ast.DeclStmt:
   165  		o.Type = DeclStmt
   166  		o.AddChildren(t.trans(n.Decl))
   167  
   168  	case *ast.DeferStmt:
   169  		o.Type = DeferStmt
   170  		o.AddChildren(t.trans(n.Call))
   171  
   172  	case *ast.Ellipsis:
   173  		o.Type = Ellipsis
   174  		if n.Elt != nil {
   175  			o.AddChildren(t.trans(n.Elt))
   176  		}
   177  
   178  	case *ast.EmptyStmt:
   179  		o.Type = EmptyStmt
   180  
   181  	case *ast.ExprStmt:
   182  		o.Type = ExprStmt
   183  		o.AddChildren(t.trans(n.X))
   184  
   185  	case *ast.Field:
   186  		o.Type = Field
   187  		for _, name := range n.Names {
   188  			o.AddChildren(t.trans(name))
   189  		}
   190  		o.AddChildren(t.trans(n.Type))
   191  
   192  	case *ast.FieldList:
   193  		o.Type = FieldList
   194  		for _, field := range n.List {
   195  			o.AddChildren(t.trans(field))
   196  		}
   197  
   198  	case *ast.File:
   199  		o.Type = File
   200  		for _, decl := range n.Decls {
   201  			if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT {
   202  				// skip import declarations
   203  				continue
   204  			}
   205  			o.AddChildren(t.trans(decl))
   206  		}
   207  
   208  	case *ast.ForStmt:
   209  		o.Type = ForStmt
   210  		if n.Init != nil {
   211  			o.AddChildren(t.trans(n.Init))
   212  		}
   213  		if n.Cond != nil {
   214  			o.AddChildren(t.trans(n.Cond))
   215  		}
   216  		if n.Post != nil {
   217  			o.AddChildren(t.trans(n.Post))
   218  		}
   219  		o.AddChildren(t.trans(n.Body))
   220  
   221  	case *ast.FuncDecl:
   222  		o.Type = FuncDecl
   223  		if n.Recv != nil {
   224  			o.AddChildren(t.trans(n.Recv))
   225  		}
   226  		o.AddChildren(t.trans(n.Name), t.trans(n.Type))
   227  		if n.Body != nil {
   228  			o.AddChildren(t.trans(n.Body))
   229  		}
   230  
   231  	case *ast.FuncLit:
   232  		o.Type = FuncLit
   233  		o.AddChildren(t.trans(n.Type), t.trans(n.Body))
   234  
   235  	case *ast.FuncType:
   236  		o.Type = FuncType
   237  		o.AddChildren(t.trans(n.Params))
   238  		if n.Results != nil {
   239  			o.AddChildren(t.trans(n.Results))
   240  		}
   241  
   242  	case *ast.GenDecl:
   243  		o.Type = GenDecl
   244  		for _, spec := range n.Specs {
   245  			o.AddChildren(t.trans(spec))
   246  		}
   247  
   248  	case *ast.GoStmt:
   249  		o.Type = GoStmt
   250  		o.AddChildren(t.trans(n.Call))
   251  
   252  	case *ast.Ident:
   253  		o.Type = Ident
   254  
   255  	case *ast.IfStmt:
   256  		o.Type = IfStmt
   257  		if n.Init != nil {
   258  			o.AddChildren(t.trans(n.Init))
   259  		}
   260  		o.AddChildren(t.trans(n.Cond), t.trans(n.Body))
   261  		if n.Else != nil {
   262  			o.AddChildren(t.trans(n.Else))
   263  		}
   264  
   265  	case *ast.IncDecStmt:
   266  		o.Type = IncDecStmt
   267  		o.AddChildren(t.trans(n.X))
   268  
   269  	case *ast.IndexExpr:
   270  		o.Type = IndexExpr
   271  		o.AddChildren(t.trans(n.X), t.trans(n.Index))
   272  
   273  	case *ast.InterfaceType:
   274  		o.Type = InterfaceType
   275  		o.AddChildren(t.trans(n.Methods))
   276  
   277  	case *ast.KeyValueExpr:
   278  		o.Type = KeyValueExpr
   279  		o.AddChildren(t.trans(n.Key), t.trans(n.Value))
   280  
   281  	case *ast.LabeledStmt:
   282  		o.Type = LabeledStmt
   283  		o.AddChildren(t.trans(n.Label), t.trans(n.Stmt))
   284  
   285  	case *ast.MapType:
   286  		o.Type = MapType
   287  		o.AddChildren(t.trans(n.Key), t.trans(n.Value))
   288  
   289  	case *ast.ParenExpr:
   290  		o.Type = ParenExpr
   291  		o.AddChildren(t.trans(n.X))
   292  
   293  	case *ast.RangeStmt:
   294  		o.Type = RangeStmt
   295  		if n.Key != nil {
   296  			o.AddChildren(t.trans(n.Key))
   297  		}
   298  		if n.Value != nil {
   299  			o.AddChildren(t.trans(n.Value))
   300  		}
   301  		o.AddChildren(t.trans(n.X), t.trans(n.Body))
   302  
   303  	case *ast.ReturnStmt:
   304  		o.Type = ReturnStmt
   305  		for _, e := range n.Results {
   306  			o.AddChildren(t.trans(e))
   307  		}
   308  
   309  	case *ast.SelectStmt:
   310  		o.Type = SelectStmt
   311  		o.AddChildren(t.trans(n.Body))
   312  
   313  	case *ast.SelectorExpr:
   314  		o.Type = SelectorExpr
   315  		o.AddChildren(t.trans(n.X), t.trans(n.Sel))
   316  
   317  	case *ast.SendStmt:
   318  		o.Type = SendStmt
   319  		o.AddChildren(t.trans(n.Chan), t.trans(n.Value))
   320  
   321  	case *ast.SliceExpr:
   322  		o.Type = SliceExpr
   323  		o.AddChildren(t.trans(n.X))
   324  		if n.Low != nil {
   325  			o.AddChildren(t.trans(n.Low))
   326  		}
   327  		if n.High != nil {
   328  			o.AddChildren(t.trans(n.High))
   329  		}
   330  		if n.Max != nil {
   331  			o.AddChildren(t.trans(n.Max))
   332  		}
   333  
   334  	case *ast.StarExpr:
   335  		o.Type = StarExpr
   336  		o.AddChildren(t.trans(n.X))
   337  
   338  	case *ast.StructType:
   339  		o.Type = StructType
   340  		o.AddChildren(t.trans(n.Fields))
   341  
   342  	case *ast.SwitchStmt:
   343  		o.Type = SwitchStmt
   344  		if n.Init != nil {
   345  			o.AddChildren(t.trans(n.Init))
   346  		}
   347  		if n.Tag != nil {
   348  			o.AddChildren(t.trans(n.Tag))
   349  		}
   350  		o.AddChildren(t.trans(n.Body))
   351  
   352  	case *ast.TypeAssertExpr:
   353  		o.Type = TypeAssertExpr
   354  		o.AddChildren(t.trans(n.X))
   355  		if n.Type != nil {
   356  			o.AddChildren(t.trans(n.Type))
   357  		}
   358  
   359  	case *ast.TypeSpec:
   360  		o.Type = TypeSpec
   361  		o.AddChildren(t.trans(n.Name), t.trans(n.Type))
   362  
   363  	case *ast.TypeSwitchStmt:
   364  		o.Type = TypeSwitchStmt
   365  		if n.Init != nil {
   366  			o.AddChildren(t.trans(n.Init))
   367  		}
   368  		o.AddChildren(t.trans(n.Assign), t.trans(n.Body))
   369  
   370  	case *ast.UnaryExpr:
   371  		o.Type = UnaryExpr
   372  		o.AddChildren(t.trans(n.X))
   373  
   374  	case *ast.ValueSpec:
   375  		o.Type = ValueSpec
   376  		for _, name := range n.Names {
   377  			o.AddChildren(t.trans(name))
   378  		}
   379  		if n.Type != nil {
   380  			o.AddChildren(t.trans(n.Type))
   381  		}
   382  		for _, val := range n.Values {
   383  			o.AddChildren(t.trans(val))
   384  		}
   385  
   386  	default:
   387  		o.Type = BadNode
   388  
   389  	}
   390  
   391  	return o
   392  }