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 }