adapter.go raw

   1  package syntax
   2  
   3  import (
   4  	"bytes"
   5  	"go/ast"
   6  	"go/token"
   7  )
   8  
   9  type commentEntry struct {
  10  	pos  Pos
  11  	text string
  12  }
  13  
  14  type pragmaData struct {
  15  	comments []commentEntry
  16  }
  17  
  18  func pragmaHandler(pos Pos, blank bool, text string, current Pragma) Pragma {
  19  	p, _ := current.(*pragmaData)
  20  	if p == nil {
  21  		p = &pragmaData{}
  22  	}
  23  	prefix := "//"
  24  	p.comments = append(p.comments, commentEntry{pos: pos, text: prefix + text})
  25  	return p
  26  }
  27  
  28  func (a *Adapter) pragmaToDoc(p Pragma) *ast.CommentGroup {
  29  	pd, _ := p.(*pragmaData)
  30  	if pd == nil || len(pd.comments) == 0 {
  31  		return nil
  32  	}
  33  	cg := &ast.CommentGroup{}
  34  	for _, c := range pd.comments {
  35  		cg.List = append(cg.List, &ast.Comment{
  36  			Slash: a.pos(c.pos),
  37  			Text:  c.text,
  38  		})
  39  	}
  40  	return cg
  41  }
  42  
  43  type Adapter struct {
  44  	fset *token.FileSet
  45  	file *token.File
  46  }
  47  
  48  // Convert parses src using the bootstrap parser and returns a go/ast.File
  49  // registered in fset. filename is used for position info.
  50  func Convert(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
  51  	af, _, err := ConvertAndKeep(fset, filename, src)
  52  	return af, err
  53  }
  54  
  55  // ConvertAndKeep is like Convert but also returns the parsed *syntax.File.
  56  // The syntax.File is used by the native type checker (B1) to annotate
  57  // expressions with type info without going through go/ast.
  58  func ConvertAndKeep(fset *token.FileSet, filename string, src []byte) (*ast.File, *File, error) {
  59  	base := NewFileBase(filename)
  60  	sf, err := Parse(base, bytes.NewReader(src), nil, pragmaHandler, 0)
  61  	if err != nil {
  62  		return nil, nil, err
  63  	}
  64  
  65  	a := &Adapter{fset: fset}
  66  	a.file = fset.AddFile(filename, -1, len(src))
  67  
  68  	var lines []int
  69  	lines = append(lines, 0)
  70  	for i, b := range src {
  71  		if b == '\n' && i+1 < len(src) {
  72  			lines = append(lines, i+1)
  73  		}
  74  	}
  75  	a.file.SetLines(lines)
  76  
  77  	af := a.convertFile(sf)
  78  	return af, sf, nil
  79  }
  80  
  81  func (a *Adapter) pos(p Pos) token.Pos {
  82  	// syntax Pos stores 0-based line/col from scanner snapshot
  83  	line := int(p.Line()) + 1
  84  	col := int(p.Col()) + 1
  85  	if line < 1 {
  86  		line = 1
  87  	}
  88  	if col < 1 {
  89  		col = 1
  90  	}
  91  	if line > a.file.LineCount() {
  92  		line = a.file.LineCount()
  93  	}
  94  	result := a.file.LineStart(line) + token.Pos(col-1)
  95  	return result
  96  }
  97  
  98  func (a *Adapter) ident(n *Name) *ast.Ident {
  99  	if n == nil {
 100  		return nil
 101  	}
 102  	return &ast.Ident{NamePos: a.pos(n.Pos()), Name: n.Value}
 103  }
 104  
 105  func (a *Adapter) convertFile(f *File) *ast.File {
 106  	af := &ast.File{
 107  		Package:   a.pos(f.Pos()),
 108  		Name:      a.ident(f.PkgName),
 109  		FileStart: token.Pos(a.file.Base()),
 110  		FileEnd:   token.Pos(a.file.Base() + a.file.Size()),
 111  	}
 112  
 113  	var imports []*ast.ImportSpec
 114  	groupMap := map[*Group]*ast.GenDecl{}
 115  
 116  	for _, d := range f.DeclList {
 117  		g := declGroup(d)
 118  		if g != nil {
 119  			if gd, ok := groupMap[g]; ok {
 120  				// Add spec to existing group
 121  				gd.Specs = append(gd.Specs, a.spec(d))
 122  				continue
 123  			}
 124  			// Start new group
 125  			gd := &ast.GenDecl{
 126  				TokPos: a.pos(d.Pos()),
 127  				Tok:    declToken(d),
 128  				Lparen: a.pos(d.Pos()),
 129  				Specs:  []ast.Spec{a.spec(d)},
 130  			}
 131  			groupMap[g] = gd
 132  			af.Decls = append(af.Decls, gd)
 133  			continue
 134  		}
 135  
 136  		ad := a.decl(d)
 137  		if ad != nil {
 138  			af.Decls = append(af.Decls, ad)
 139  		}
 140  	}
 141  
 142  	for _, d := range af.Decls {
 143  		switch d := d.(type) {
 144  		case *ast.GenDecl:
 145  			if d.Doc != nil {
 146  				af.Comments = append(af.Comments, d.Doc)
 147  			}
 148  			if d.Tok == token.IMPORT {
 149  				for _, s := range d.Specs {
 150  					if is, ok := s.(*ast.ImportSpec); ok {
 151  						imports = append(imports, is)
 152  					}
 153  				}
 154  			}
 155  		case *ast.FuncDecl:
 156  			if d.Doc != nil {
 157  				af.Comments = append(af.Comments, d.Doc)
 158  			}
 159  		}
 160  	}
 161  	af.Imports = imports
 162  	return af
 163  }
 164  
 165  func declGroup(d Decl) *Group {
 166  	switch d := d.(type) {
 167  	case *ImportDecl:
 168  		return d.Group
 169  	case *ConstDecl:
 170  		return d.Group
 171  	case *TypeDecl:
 172  		return d.Group
 173  	case *VarDecl:
 174  		return d.Group
 175  	}
 176  	return nil
 177  }
 178  
 179  func declToken(d Decl) token.Token {
 180  	switch d.(type) {
 181  	case *ImportDecl:
 182  		return token.IMPORT
 183  	case *ConstDecl:
 184  		return token.CONST
 185  	case *TypeDecl:
 186  		return token.TYPE
 187  	case *VarDecl:
 188  		return token.VAR
 189  	}
 190  	return token.ILLEGAL
 191  }
 192  
 193  func (a *Adapter) spec(d Decl) ast.Spec {
 194  	switch d := d.(type) {
 195  	case *ImportDecl:
 196  		spec := &ast.ImportSpec{Path: a.basicLit(d.Path)}
 197  		if d.LocalPkgName != nil {
 198  			spec.Name = a.ident(d.LocalPkgName)
 199  		}
 200  		return spec
 201  	case *ConstDecl:
 202  		return &ast.ValueSpec{
 203  			Names:  a.nameList(d.NameList),
 204  			Type:   a.expr(d.Type),
 205  			Values: a.exprList(d.Values),
 206  		}
 207  	case *TypeDecl:
 208  		ts := &ast.TypeSpec{
 209  			Name: a.ident(d.Name),
 210  			Type: a.expr(d.Type),
 211  		}
 212  		if d.Alias {
 213  			ts.Assign = a.pos(d.Pos())
 214  		}
 215  		if len(d.TParamList) > 0 {
 216  			ts.TypeParams = a.fieldList(d.TParamList)
 217  		}
 218  		return ts
 219  	case *VarDecl:
 220  		return &ast.ValueSpec{
 221  			Names:  a.nameList(d.NameList),
 222  			Type:   a.expr(d.Type),
 223  			Values: a.exprList(d.Values),
 224  		}
 225  	}
 226  	return nil
 227  }
 228  
 229  func (a *Adapter) decl(d Decl) ast.Decl {
 230  	switch d := d.(type) {
 231  	case *ImportDecl:
 232  		spec := &ast.ImportSpec{
 233  			Path: a.basicLit(d.Path),
 234  		}
 235  		if d.LocalPkgName != nil {
 236  			spec.Name = a.ident(d.LocalPkgName)
 237  		}
 238  		return &ast.GenDecl{
 239  			Doc:    a.pragmaToDoc(d.Pragma),
 240  			TokPos: a.pos(d.Pos()),
 241  			Tok:    token.IMPORT,
 242  			Specs:  []ast.Spec{spec},
 243  		}
 244  	case *ConstDecl:
 245  		vs := &ast.ValueSpec{
 246  			Names:  a.nameList(d.NameList),
 247  			Type:   a.expr(d.Type),
 248  			Values: a.exprList(d.Values),
 249  		}
 250  		return &ast.GenDecl{
 251  			Doc:    a.pragmaToDoc(d.Pragma),
 252  			TokPos: a.pos(d.Pos()),
 253  			Tok:    token.CONST,
 254  			Specs:  []ast.Spec{vs},
 255  		}
 256  	case *TypeDecl:
 257  		ts := &ast.TypeSpec{
 258  			Name:   a.ident(d.Name),
 259  			Assign: 0,
 260  			Type:   a.expr(d.Type),
 261  		}
 262  		if d.Alias {
 263  			ts.Assign = a.pos(d.Pos())
 264  		}
 265  		if len(d.TParamList) > 0 {
 266  			ts.TypeParams = a.fieldList(d.TParamList)
 267  		}
 268  		return &ast.GenDecl{
 269  			Doc:    a.pragmaToDoc(d.Pragma),
 270  			TokPos: a.pos(d.Pos()),
 271  			Tok:    token.TYPE,
 272  			Specs:  []ast.Spec{ts},
 273  		}
 274  	case *VarDecl:
 275  		vs := &ast.ValueSpec{
 276  			Names:  a.nameList(d.NameList),
 277  			Type:   a.expr(d.Type),
 278  			Values: a.exprList(d.Values),
 279  		}
 280  		return &ast.GenDecl{
 281  			Doc:    a.pragmaToDoc(d.Pragma),
 282  			TokPos: a.pos(d.Pos()),
 283  			Tok:    token.VAR,
 284  			Specs:  []ast.Spec{vs},
 285  		}
 286  	case *FuncDecl:
 287  		fd := &ast.FuncDecl{
 288  			Doc:  a.pragmaToDoc(d.Pragma),
 289  			Name: a.ident(d.Name),
 290  			Type: a.funcType(d.Type),
 291  			Body: a.blockStmt(d.Body),
 292  		}
 293  		if d.Recv != nil {
 294  			fd.Recv = &ast.FieldList{
 295  				List: []*ast.Field{a.field(d.Recv)},
 296  			}
 297  		}
 298  		if len(d.TParamList) > 0 {
 299  			fd.Type.TypeParams = a.fieldList(d.TParamList)
 300  		}
 301  		return fd
 302  	}
 303  	return nil
 304  }
 305  
 306  func (a *Adapter) nameList(names []*Name) []*ast.Ident {
 307  	var out []*ast.Ident
 308  	for _, n := range names {
 309  		out = append(out, a.ident(n))
 310  	}
 311  	return out
 312  }
 313  
 314  func (a *Adapter) exprList(e Expr) []ast.Expr {
 315  	if e == nil {
 316  		return nil
 317  	}
 318  	if l, ok := e.(*ListExpr); ok {
 319  		var out []ast.Expr
 320  		for _, el := range l.ElemList {
 321  			out = append(out, a.expr(el))
 322  		}
 323  		return out
 324  	}
 325  	return []ast.Expr{a.expr(e)}
 326  }
 327  
 328  func (a *Adapter) expr(e Expr) ast.Expr {
 329  	if e == nil {
 330  		return nil
 331  	}
 332  	switch e := e.(type) {
 333  	case *Name:
 334  		return a.ident(e)
 335  	case *BasicLit:
 336  		return a.basicLit(e)
 337  	case *CompositeLit:
 338  		cl := &ast.CompositeLit{
 339  			Type:   a.expr(e.Type),
 340  			Rbrace: a.pos(e.Rbrace),
 341  		}
 342  		for _, el := range e.ElemList {
 343  			cl.Elts = append(cl.Elts, a.expr(el))
 344  		}
 345  		return cl
 346  	case *KeyValueExpr:
 347  		return &ast.KeyValueExpr{
 348  			Key:   a.expr(e.Key),
 349  			Colon: a.pos(e.Pos()),
 350  			Value: a.expr(e.Value),
 351  		}
 352  	case *FuncLit:
 353  		return &ast.FuncLit{
 354  			Type: a.funcType(e.Type),
 355  			Body: a.blockStmt(e.Body),
 356  		}
 357  	case *ParenExpr:
 358  		return &ast.ParenExpr{
 359  			Lparen: a.pos(e.Pos()),
 360  			X:      a.expr(e.X),
 361  		}
 362  	case *SelectorExpr:
 363  		return &ast.SelectorExpr{
 364  			X:   a.expr(e.X),
 365  			Sel: a.ident(e.Sel),
 366  		}
 367  	case *IndexExpr:
 368  		if le, ok := e.Index.(*ListExpr); ok && len(le.ElemList) > 1 {
 369  			var indices []ast.Expr
 370  			for _, el := range le.ElemList {
 371  				indices = append(indices, a.expr(el))
 372  			}
 373  			return &ast.IndexListExpr{
 374  				X:       a.expr(e.X),
 375  				Indices: indices,
 376  			}
 377  		}
 378  		return &ast.IndexExpr{
 379  			X:     a.expr(e.X),
 380  			Index: a.expr(e.Index),
 381  		}
 382  	case *SliceExpr:
 383  		se := &ast.SliceExpr{
 384  			X:      a.expr(e.X),
 385  			Low:    a.expr(e.Index[0]),
 386  			High:   a.expr(e.Index[1]),
 387  			Max:    a.expr(e.Index[2]),
 388  			Slice3: e.Full,
 389  		}
 390  		return se
 391  	case *AssertExpr:
 392  		return &ast.TypeAssertExpr{
 393  			X:    a.expr(e.X),
 394  			Type: a.expr(e.Type),
 395  		}
 396  	case *TypeSwitchGuard:
 397  		return &ast.TypeAssertExpr{
 398  			X: a.expr(e.X),
 399  		}
 400  	case *Operation:
 401  		return a.operation(e)
 402  	case *CallExpr:
 403  		ce := &ast.CallExpr{
 404  			Fun: a.expr(e.Fun),
 405  		}
 406  		for _, arg := range e.ArgList {
 407  			ce.Args = append(ce.Args, a.expr(arg))
 408  		}
 409  		if e.HasDots {
 410  			ce.Ellipsis = a.pos(e.Pos())
 411  		}
 412  		return ce
 413  	case *ListExpr:
 414  		if len(e.ElemList) == 1 {
 415  			return a.expr(e.ElemList[0])
 416  		}
 417  		// multi-element list: shouldn't appear as a standalone expression
 418  		return a.expr(e.ElemList[0])
 419  	case *ArrayType:
 420  		if e.Len == nil {
 421  			return &ast.ArrayType{
 422  				Lbrack: a.pos(e.Pos()),
 423  				Len:    &ast.Ellipsis{Ellipsis: a.pos(e.Pos())},
 424  				Elt:    a.expr(e.Elem),
 425  			}
 426  		}
 427  		return &ast.ArrayType{
 428  			Lbrack: a.pos(e.Pos()),
 429  			Len:    a.expr(e.Len),
 430  			Elt:    a.expr(e.Elem),
 431  		}
 432  	case *SliceType:
 433  		return &ast.ArrayType{
 434  			Lbrack: a.pos(e.Pos()),
 435  			Elt:    a.expr(e.Elem),
 436  		}
 437  	case *DotsType:
 438  		return &ast.Ellipsis{
 439  			Ellipsis: a.pos(e.Pos()),
 440  			Elt:      a.expr(e.Elem),
 441  		}
 442  	case *StructType:
 443  		return &ast.StructType{
 444  			Struct: a.pos(e.Pos()),
 445  			Fields: a.structFieldList(e),
 446  		}
 447  	case *InterfaceType:
 448  		methods := a.fieldListFromFields(e.MethodList)
 449  		if methods == nil {
 450  			methods = &ast.FieldList{}
 451  		}
 452  		return &ast.InterfaceType{
 453  			Interface: a.pos(e.Pos()),
 454  			Methods:   methods,
 455  		}
 456  	case *FuncType:
 457  		return a.funcType(e)
 458  	case *MapType:
 459  		return &ast.MapType{
 460  			Map:   a.pos(e.Pos()),
 461  			Key:   a.expr(e.Key),
 462  			Value: a.expr(e.Value),
 463  		}
 464  	case *ChanType:
 465  		ct := &ast.ChanType{
 466  			Begin: a.pos(e.Pos()),
 467  			Value: a.expr(e.Elem),
 468  		}
 469  		switch e.Dir {
 470  		case SendOnly:
 471  			ct.Dir = ast.SEND
 472  		case RecvOnly:
 473  			ct.Dir = ast.RECV
 474  		default:
 475  			ct.Dir = ast.SEND | ast.RECV
 476  		}
 477  		return ct
 478  	case *BadExpr:
 479  		return &ast.BadExpr{From: a.pos(e.Pos())}
 480  	}
 481  	return &ast.BadExpr{}
 482  }
 483  
 484  func (a *Adapter) operation(e *Operation) ast.Expr {
 485  	if e.Y == nil {
 486  		if e.Op == Mul {
 487  			return &ast.StarExpr{
 488  				Star: a.pos(e.Pos()),
 489  				X:    a.expr(e.X),
 490  			}
 491  		}
 492  		if e.Op == And {
 493  			return &ast.UnaryExpr{
 494  				OpPos: a.pos(e.Pos()),
 495  				Op:    token.AND,
 496  				X:     a.expr(e.X),
 497  			}
 498  		}
 499  		return &ast.UnaryExpr{
 500  			OpPos: a.pos(e.Pos()),
 501  			Op:    operatorToToken(e.Op),
 502  			X:     a.expr(e.X),
 503  		}
 504  	}
 505  	return &ast.BinaryExpr{
 506  		X:     a.expr(e.X),
 507  		OpPos: a.pos(e.Pos()),
 508  		Op:    operatorToToken(e.Op),
 509  		Y:     a.expr(e.Y),
 510  	}
 511  }
 512  
 513  func operatorToToken(op Operator) token.Token {
 514  	switch op {
 515  	case Add:
 516  		return token.ADD
 517  	case Sub:
 518  		return token.SUB
 519  	case Mul:
 520  		return token.MUL
 521  	case Div:
 522  		return token.QUO
 523  	case Rem:
 524  		return token.REM
 525  	case And:
 526  		return token.AND
 527  	case Or:
 528  		return token.OR
 529  	case Xor:
 530  		return token.XOR
 531  	case Shl:
 532  		return token.SHL
 533  	case Shr:
 534  		return token.SHR
 535  	case AndNot:
 536  		return token.AND_NOT
 537  	case OrOr:
 538  		return token.LOR
 539  	case AndAnd:
 540  		return token.LAND
 541  	case Eql:
 542  		return token.EQL
 543  	case Neq:
 544  		return token.NEQ
 545  	case Lss:
 546  		return token.LSS
 547  	case Leq:
 548  		return token.LEQ
 549  	case Gtr:
 550  		return token.GTR
 551  	case Geq:
 552  		return token.GEQ
 553  	case Not:
 554  		return token.NOT
 555  	case Recv:
 556  		return token.ARROW
 557  	case Tilde:
 558  		return token.TILDE
 559  	}
 560  	return token.ILLEGAL
 561  }
 562  
 563  func (a *Adapter) basicLit(lit *BasicLit) *ast.BasicLit {
 564  	if lit == nil {
 565  		return nil
 566  	}
 567  	var kind token.Token
 568  	switch lit.Kind {
 569  	case IntLit:
 570  		kind = token.INT
 571  	case FloatLit:
 572  		kind = token.FLOAT
 573  	case ImagLit:
 574  		kind = token.IMAG
 575  	case RuneLit:
 576  		kind = token.CHAR
 577  	case StringLit:
 578  		kind = token.STRING
 579  	}
 580  	return &ast.BasicLit{
 581  		ValuePos: a.pos(lit.Pos()),
 582  		Kind:     kind,
 583  		Value:    lit.Value,
 584  	}
 585  }
 586  
 587  func (a *Adapter) funcType(ft *FuncType) *ast.FuncType {
 588  	if ft == nil {
 589  		return &ast.FuncType{Params: &ast.FieldList{}}
 590  	}
 591  	params := a.fieldListFromFields(ft.ParamList)
 592  	if params == nil {
 593  		params = &ast.FieldList{}
 594  	}
 595  	return &ast.FuncType{
 596  		Func:    a.pos(ft.Pos()),
 597  		Params:  params,
 598  		Results: a.fieldListFromFields(ft.ResultList),
 599  	}
 600  }
 601  
 602  func (a *Adapter) fieldListFromFields(fields []*Field) *ast.FieldList {
 603  	if len(fields) == 0 {
 604  		return nil
 605  	}
 606  	fl := &ast.FieldList{}
 607  	for _, f := range fields {
 608  		fl.List = append(fl.List, a.field(f))
 609  	}
 610  	return fl
 611  }
 612  
 613  func (a *Adapter) fieldList(fields []*Field) *ast.FieldList {
 614  	return a.fieldListFromFields(fields)
 615  }
 616  
 617  func (a *Adapter) field(f *Field) *ast.Field {
 618  	af := &ast.Field{
 619  		Type: a.expr(f.Type),
 620  	}
 621  	if f.Name != nil {
 622  		af.Names = []*ast.Ident{a.ident(f.Name)}
 623  	}
 624  	return af
 625  }
 626  
 627  func (a *Adapter) structFieldList(st *StructType) *ast.FieldList {
 628  	fl := &ast.FieldList{}
 629  	for i, f := range st.FieldList {
 630  		af := a.field(f)
 631  		if i < len(st.TagList) && st.TagList[i] != nil {
 632  			af.Tag = a.basicLit(st.TagList[i])
 633  		}
 634  		fl.List = append(fl.List, af)
 635  	}
 636  	return fl
 637  }
 638  
 639  func (a *Adapter) blockStmt(b *BlockStmt) *ast.BlockStmt {
 640  	if b == nil {
 641  		return nil
 642  	}
 643  	bs := &ast.BlockStmt{
 644  		Lbrace: a.pos(b.Pos()),
 645  		Rbrace: a.pos(b.Rbrace),
 646  	}
 647  	for _, s := range b.List {
 648  		as := a.stmt(s)
 649  		if as != nil {
 650  			bs.List = append(bs.List, as)
 651  		}
 652  	}
 653  	return bs
 654  }
 655  
 656  func (a *Adapter) stmt(s Stmt) ast.Stmt {
 657  	if s == nil {
 658  		return nil
 659  	}
 660  	switch s := s.(type) {
 661  	case *EmptyStmt:
 662  		return &ast.EmptyStmt{Semicolon: a.pos(s.Pos())}
 663  	case *LabeledStmt:
 664  		return &ast.LabeledStmt{
 665  			Label: a.ident(s.Label),
 666  			Colon: a.pos(s.Pos()),
 667  			Stmt:  a.stmt(s.Stmt),
 668  		}
 669  	case *BlockStmt:
 670  		return a.blockStmt(s)
 671  	case *ExprStmt:
 672  		return &ast.ExprStmt{X: a.expr(s.X)}
 673  	case *SendStmt:
 674  		return &ast.SendStmt{
 675  			Chan:  a.expr(s.Chan),
 676  			Arrow: a.pos(s.Pos()),
 677  			Value: a.expr(s.Value),
 678  		}
 679  	case *DeclStmt:
 680  		gd := &ast.GenDecl{TokPos: a.pos(s.Pos()), Tok: token.VAR}
 681  		for _, d := range s.DeclList {
 682  			ad := a.decl(d)
 683  			if gd2, ok := ad.(*ast.GenDecl); ok {
 684  				gd.Tok = gd2.Tok
 685  				gd.Specs = append(gd.Specs, gd2.Specs...)
 686  			}
 687  		}
 688  		return &ast.DeclStmt{Decl: gd}
 689  	case *AssignStmt:
 690  		if s.Rhs == nil {
 691  			// increment/decrement
 692  			tok := token.INC
 693  			if s.Op == Sub {
 694  				tok = token.DEC
 695  			}
 696  			return &ast.IncDecStmt{
 697  				X:      a.expr(s.Lhs),
 698  				TokPos: a.pos(s.Pos()),
 699  				Tok:    tok,
 700  			}
 701  		}
 702  		tok := token.ASSIGN
 703  		if s.Op == Def {
 704  			tok = token.DEFINE
 705  		} else if s.Op != 0 {
 706  			tok = assignOpToToken(s.Op)
 707  		}
 708  		return &ast.AssignStmt{
 709  			Lhs: a.exprList(s.Lhs),
 710  			Tok: tok,
 711  			Rhs: a.exprList(s.Rhs),
 712  		}
 713  	case *BranchStmt:
 714  		tok := token.BREAK
 715  		switch s.Tok {
 716  		case Continue:
 717  			tok = token.CONTINUE
 718  		case Fallthrough:
 719  			tok = token.FALLTHROUGH
 720  		case Goto:
 721  			tok = token.GOTO
 722  		}
 723  		return &ast.BranchStmt{
 724  			TokPos: a.pos(s.Pos()),
 725  			Tok:    tok,
 726  			Label:  a.ident(s.Label),
 727  		}
 728  	case *CallStmt:
 729  		ce := a.expr(s.Call).(*ast.CallExpr)
 730  		if s.Tok == Defer {
 731  			return &ast.DeferStmt{
 732  				Defer: a.pos(s.Pos()),
 733  				Call:  ce,
 734  			}
 735  		}
 736  		return &ast.GoStmt{
 737  			Go:   a.pos(s.Pos()),
 738  			Call: ce,
 739  		}
 740  	case *ReturnStmt:
 741  		return &ast.ReturnStmt{
 742  			Return:  a.pos(s.Pos()),
 743  			Results: a.exprList(s.Results),
 744  		}
 745  	case *IfStmt:
 746  		is := &ast.IfStmt{
 747  			If:   a.pos(s.Pos()),
 748  			Init: a.stmt(s.Init),
 749  			Cond: a.expr(s.Cond),
 750  			Body: a.blockStmt(s.Then),
 751  			Else: a.stmt(s.Else),
 752  		}
 753  		return is
 754  	case *ForStmt:
 755  		if rc, ok := s.Init.(*RangeClause); ok {
 756  			rs := &ast.RangeStmt{
 757  				For:  a.pos(s.Pos()),
 758  				X:    a.expr(rc.X),
 759  				Body: a.blockStmt(s.Body),
 760  			}
 761  			if rc.Lhs != nil {
 762  				lhs := a.exprList(rc.Lhs)
 763  				if len(lhs) > 0 {
 764  					rs.Key = lhs[0]
 765  				}
 766  				if len(lhs) > 1 {
 767  					rs.Value = lhs[1]
 768  				}
 769  				if rc.Def {
 770  					rs.Tok = token.DEFINE
 771  				} else {
 772  					rs.Tok = token.ASSIGN
 773  				}
 774  			}
 775  			return rs
 776  		}
 777  		return &ast.ForStmt{
 778  			For:  a.pos(s.Pos()),
 779  			Init: a.stmt(s.Init),
 780  			Cond: a.expr(s.Cond),
 781  			Post: a.stmt(s.Post),
 782  			Body: a.blockStmt(s.Body),
 783  		}
 784  	case *SwitchStmt:
 785  		if s.Tag != nil {
 786  			if _, ok := s.Tag.(*TypeSwitchGuard); ok {
 787  				return a.typeSwitchStmt(s)
 788  			}
 789  		}
 790  		ss := &ast.SwitchStmt{
 791  			Switch: a.pos(s.Pos()),
 792  			Init:   a.stmt(s.Init),
 793  			Tag:    a.expr(s.Tag),
 794  			Body:   a.switchBody(s.Body, s.Rbrace),
 795  		}
 796  		return ss
 797  	case *SelectStmt:
 798  		return &ast.SelectStmt{
 799  			Select: a.pos(s.Pos()),
 800  			Body:   a.selectBody(s.Body, s.Rbrace),
 801  		}
 802  	}
 803  	return &ast.EmptyStmt{Semicolon: a.pos(s.Pos())}
 804  }
 805  
 806  func (a *Adapter) typeSwitchStmt(s *SwitchStmt) *ast.TypeSwitchStmt {
 807  	tsg := s.Tag.(*TypeSwitchGuard)
 808  	var assign ast.Stmt
 809  	ta := &ast.TypeAssertExpr{X: a.expr(tsg.X)}
 810  	if tsg.Lhs != nil {
 811  		assign = &ast.AssignStmt{
 812  			Lhs: []ast.Expr{a.ident(tsg.Lhs)},
 813  			Tok: token.DEFINE,
 814  			Rhs: []ast.Expr{ta},
 815  		}
 816  	} else {
 817  		assign = &ast.ExprStmt{X: ta}
 818  	}
 819  	return &ast.TypeSwitchStmt{
 820  		Switch: a.pos(s.Pos()),
 821  		Init:   a.stmt(s.Init),
 822  		Assign: assign,
 823  		Body:   a.switchBody(s.Body, s.Rbrace),
 824  	}
 825  }
 826  
 827  func (a *Adapter) switchBody(clauses []*CaseClause, rbrace Pos) *ast.BlockStmt {
 828  	bs := &ast.BlockStmt{Rbrace: a.pos(rbrace)}
 829  	for _, c := range clauses {
 830  		cc := &ast.CaseClause{
 831  			Case:  a.pos(c.Pos()),
 832  			List:  a.exprList(c.Cases),
 833  			Colon: a.pos(c.Colon),
 834  		}
 835  		for _, s := range c.Body {
 836  			as := a.stmt(s)
 837  			if as != nil {
 838  				cc.Body = append(cc.Body, as)
 839  			}
 840  		}
 841  		bs.List = append(bs.List, cc)
 842  	}
 843  	return bs
 844  }
 845  
 846  func (a *Adapter) selectBody(clauses []*CommClause, rbrace Pos) *ast.BlockStmt {
 847  	bs := &ast.BlockStmt{Rbrace: a.pos(rbrace)}
 848  	for _, c := range clauses {
 849  		cc := &ast.CommClause{
 850  			Case:  a.pos(c.Pos()),
 851  			Comm:  a.stmt(c.Comm),
 852  			Colon: a.pos(c.Colon),
 853  		}
 854  		for _, s := range c.Body {
 855  			as := a.stmt(s)
 856  			if as != nil {
 857  				cc.Body = append(cc.Body, as)
 858  			}
 859  		}
 860  		bs.List = append(bs.List, cc)
 861  	}
 862  	return bs
 863  }
 864  
 865  func assignOpToToken(op Operator) token.Token {
 866  	switch op {
 867  	case Add:
 868  		return token.ADD_ASSIGN
 869  	case Sub:
 870  		return token.SUB_ASSIGN
 871  	case Mul:
 872  		return token.MUL_ASSIGN
 873  	case Div:
 874  		return token.QUO_ASSIGN
 875  	case Rem:
 876  		return token.REM_ASSIGN
 877  	case And:
 878  		return token.AND_ASSIGN
 879  	case Or:
 880  		return token.OR_ASSIGN
 881  	case Xor:
 882  		return token.XOR_ASSIGN
 883  	case Shl:
 884  		return token.SHL_ASSIGN
 885  	case Shr:
 886  		return token.SHR_ASSIGN
 887  	case AndNot:
 888  		return token.AND_NOT_ASSIGN
 889  	}
 890  	return token.ASSIGN
 891  }
 892