github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/format/stmt.go (about)

     1  // Copyright 2017 The Neugram Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package format
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  
    11  	"neugram.io/ng/syntax/stmt"
    12  )
    13  
    14  func (p *printer) stmt(s stmt.Stmt) {
    15  	switch s := s.(type) {
    16  	case *stmt.Import:
    17  		if s.Name != "" {
    18  			fmt.Fprintf(p.buf, "import %s %q", s.Name, s.Path)
    19  		} else {
    20  			fmt.Fprintf(p.buf, "import %q", s.Path)
    21  		}
    22  	case *stmt.ImportSet:
    23  		p.buf.WriteString("import (")
    24  		if len(s.Imports) == 0 {
    25  			p.buf.WriteString(")")
    26  			return
    27  		}
    28  		p.indent++
    29  		for _, imp := range s.Imports {
    30  			p.newline()
    31  			if imp.Name != "" {
    32  				fmt.Fprintf(p.buf, "%s %q", imp.Name, imp.Path)
    33  			} else {
    34  				fmt.Fprintf(p.buf, "%q", imp.Path)
    35  			}
    36  		}
    37  		p.indent--
    38  		p.newline()
    39  		p.buf.WriteString(")")
    40  	case *stmt.TypeDecl:
    41  		p.buf.WriteString("type ")
    42  		p.buf.WriteString(s.Name)
    43  		p.buf.WriteString(" ")
    44  		p.tipe(s.Type.Type)
    45  	case *stmt.MethodikDecl:
    46  		p.buf.WriteString("methodik ")
    47  		p.buf.WriteString(s.Name)
    48  		p.buf.WriteString(" ")
    49  		p.tipe(s.Type.Type)
    50  		if len(s.Methods) == 0 {
    51  			p.buf.WriteString(" {}")
    52  			return
    53  		}
    54  		p.buf.WriteString(" {")
    55  		p.indent++
    56  		for _, m := range s.Methods {
    57  			p.newline()
    58  			p.expr(m)
    59  		}
    60  		p.indent--
    61  		p.newline()
    62  		p.buf.WriteString("}")
    63  	case *stmt.Simple:
    64  		p.expr(s.Expr)
    65  	case *stmt.Return:
    66  		p.buf.WriteString("return")
    67  		if len(s.Exprs) > 0 {
    68  			p.buf.WriteByte(' ')
    69  		}
    70  		for i, e := range s.Exprs {
    71  			if i > 0 {
    72  				p.buf.WriteString(", ")
    73  			}
    74  			p.expr(e)
    75  		}
    76  	case *stmt.Assign:
    77  		for i, e := range s.Left {
    78  			if i > 0 {
    79  				p.buf.WriteString(", ")
    80  			}
    81  			p.expr(e)
    82  		}
    83  		p.buf.WriteString(" ")
    84  		if s.Decl {
    85  			p.buf.WriteString(":")
    86  		}
    87  		p.buf.WriteString("= ")
    88  		for i, e := range s.Right {
    89  			if i > 0 {
    90  				p.buf.WriteString(", ")
    91  			}
    92  			p.expr(e)
    93  		}
    94  	case *stmt.Send:
    95  		p.expr(s.Chan)
    96  		p.buf.WriteString("<-")
    97  		p.expr(s.Value)
    98  	case *stmt.Switch:
    99  		p.buf.WriteString("switch ")
   100  		if s.Init != nil {
   101  			p.stmt(s.Init)
   102  			if s.Cond != nil {
   103  				p.buf.WriteString("; ")
   104  			}
   105  		}
   106  		if s.Cond != nil {
   107  			p.expr(s.Cond)
   108  		}
   109  		p.buf.WriteString("{")
   110  		if len(s.Cases) > 0 {
   111  			p.buf.WriteString("\n")
   112  		}
   113  		for _, c := range s.Cases {
   114  			switch c.Default {
   115  			case true:
   116  				p.buf.WriteString("default:")
   117  			default:
   118  				p.buf.WriteString("case ")
   119  				for i, e := range c.Conds {
   120  					if i > 0 {
   121  						p.buf.WriteString(", ")
   122  					}
   123  					p.expr(e)
   124  				}
   125  				p.buf.WriteString(":\n")
   126  			}
   127  			p.stmt(c.Body)
   128  		}
   129  		p.buf.WriteString("}")
   130  	case *stmt.TypeSwitch:
   131  		p.buf.WriteString("switch ")
   132  		if s.Init != nil {
   133  			p.stmt(s.Init)
   134  			if s.Assign != nil {
   135  				p.buf.WriteString("; ")
   136  			}
   137  		}
   138  		if s.Assign != nil {
   139  			p.stmt(s.Assign)
   140  			p.buf.WriteString(" ")
   141  		}
   142  		p.buf.WriteString("{")
   143  		if len(s.Cases) > 0 {
   144  			p.buf.WriteString("\n")
   145  		}
   146  		for _, c := range s.Cases {
   147  			switch c.Default {
   148  			case true:
   149  				p.buf.WriteString("default:\n")
   150  			default:
   151  				p.buf.WriteString("case ")
   152  				for i, typ := range c.Types {
   153  					if i > 0 {
   154  						p.buf.WriteString(", ")
   155  					}
   156  					p.tipe(typ)
   157  				}
   158  				p.buf.WriteString(":\n")
   159  			}
   160  			if len(c.Body.Stmts) > 0 {
   161  				p.stmt(c.Body)
   162  				p.buf.WriteString("\n")
   163  			}
   164  		}
   165  		p.buf.WriteString("}")
   166  	case *stmt.Select:
   167  		p.buf.WriteString("select {")
   168  		if len(s.Cases) > 0 {
   169  			p.buf.WriteString("\n")
   170  		}
   171  		for _, c := range s.Cases {
   172  			switch c.Default {
   173  			case true:
   174  				p.buf.WriteString("default:")
   175  			default:
   176  				p.buf.WriteString("case ")
   177  				p.stmt(c.Stmt)
   178  				p.buf.WriteString(":")
   179  			}
   180  			p.stmt(c.Body)
   181  		}
   182  		p.buf.WriteString("}")
   183  	case *stmt.Block:
   184  		p.buf.WriteString("{")
   185  		for _, s := range s.Stmts {
   186  			p.stmt(s)
   187  		}
   188  		p.buf.WriteString("}")
   189  	default:
   190  		p.printf("format: unknown stmt %T: ", s)
   191  		WriteDebug(p.buf, s)
   192  	}
   193  }
   194  
   195  func WriteStmt(buf *bytes.Buffer, s stmt.Stmt) {
   196  	p := &printer{
   197  		buf: buf,
   198  	}
   199  	p.stmt(s)
   200  }
   201  
   202  func Stmt(e stmt.Stmt) string {
   203  	buf := new(bytes.Buffer)
   204  	WriteStmt(buf, e)
   205  	return buf.String()
   206  }