PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/libgo/go/exp/types/errors.go

https://bitbucket.org/bluezoo/gcc
Go | 315 lines | 249 code | 49 blank | 17 comment | 38 complexity | 98958586173b2c0eedb742334e2516ec MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-1.0, GPL-3.0, BSD-3-Clause, LGPL-2.0
  1. // Copyright 2012 The Go 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. // This file implements various error reporters.
  5. package types
  6. import (
  7. "bytes"
  8. "fmt"
  9. "go/ast"
  10. "go/token"
  11. )
  12. // TODO(gri) eventually assert and unimplemented should disappear.
  13. func assert(p bool) {
  14. if !p {
  15. panic("assertion failed")
  16. }
  17. }
  18. func unimplemented() {
  19. // enable for debugging
  20. // panic("unimplemented")
  21. }
  22. func unreachable() {
  23. panic("unreachable")
  24. }
  25. func (check *checker) printTrace(format string, args []interface{}) {
  26. const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
  27. n := len(check.pos) - 1
  28. i := 2 * n
  29. for i > len(dots) {
  30. fmt.Print(dots)
  31. i -= len(dots)
  32. }
  33. // i <= len(dots)
  34. fmt.Printf("%s: ", check.fset.Position(check.pos[n]))
  35. fmt.Print(dots[0:i])
  36. fmt.Println(check.formatMsg(format, args))
  37. }
  38. func (check *checker) trace(pos token.Pos, format string, args ...interface{}) {
  39. check.pos = append(check.pos, pos)
  40. check.printTrace(format, args)
  41. }
  42. func (check *checker) untrace(format string, args ...interface{}) {
  43. if len(format) > 0 {
  44. check.printTrace(format, args)
  45. }
  46. check.pos = check.pos[:len(check.pos)-1]
  47. }
  48. func (check *checker) formatMsg(format string, args []interface{}) string {
  49. for i, arg := range args {
  50. switch a := arg.(type) {
  51. case token.Pos:
  52. args[i] = check.fset.Position(a)
  53. case ast.Expr:
  54. args[i] = exprString(a)
  55. case Type:
  56. args[i] = typeString(a)
  57. case operand:
  58. panic("internal error: should always pass *operand")
  59. }
  60. }
  61. return fmt.Sprintf(format, args...)
  62. }
  63. // dump is only needed for debugging
  64. func (check *checker) dump(format string, args ...interface{}) {
  65. fmt.Println(check.formatMsg(format, args))
  66. }
  67. func (check *checker) errorf(pos token.Pos, format string, args ...interface{}) {
  68. msg := check.formatMsg(format, args)
  69. if check.firsterr == nil {
  70. check.firsterr = fmt.Errorf("%s: %s", check.fset.Position(pos), msg)
  71. }
  72. if check.errh == nil {
  73. panic(bailout{}) // report only first error
  74. }
  75. check.errh(pos, msg)
  76. }
  77. func (check *checker) invalidAST(pos token.Pos, format string, args ...interface{}) {
  78. check.errorf(pos, "invalid AST: "+format, args...)
  79. }
  80. func (check *checker) invalidArg(pos token.Pos, format string, args ...interface{}) {
  81. check.errorf(pos, "invalid argument: "+format, args...)
  82. }
  83. func (check *checker) invalidOp(pos token.Pos, format string, args ...interface{}) {
  84. check.errorf(pos, "invalid operation: "+format, args...)
  85. }
  86. // exprString returns a (simplified) string representation for an expression.
  87. func exprString(expr ast.Expr) string {
  88. var buf bytes.Buffer
  89. writeExpr(&buf, expr)
  90. return buf.String()
  91. }
  92. // TODO(gri) Need to merge with typeString since some expressions are types (try: ([]int)(a))
  93. func writeExpr(buf *bytes.Buffer, expr ast.Expr) {
  94. switch x := expr.(type) {
  95. case *ast.Ident:
  96. buf.WriteString(x.Name)
  97. case *ast.BasicLit:
  98. buf.WriteString(x.Value)
  99. case *ast.FuncLit:
  100. buf.WriteString("(func literal)")
  101. case *ast.CompositeLit:
  102. buf.WriteString("(composite literal)")
  103. case *ast.ParenExpr:
  104. buf.WriteByte('(')
  105. writeExpr(buf, x.X)
  106. buf.WriteByte(')')
  107. case *ast.SelectorExpr:
  108. writeExpr(buf, x.X)
  109. buf.WriteByte('.')
  110. buf.WriteString(x.Sel.Name)
  111. case *ast.IndexExpr:
  112. writeExpr(buf, x.X)
  113. buf.WriteByte('[')
  114. writeExpr(buf, x.Index)
  115. buf.WriteByte(']')
  116. case *ast.SliceExpr:
  117. writeExpr(buf, x.X)
  118. buf.WriteByte('[')
  119. if x.Low != nil {
  120. writeExpr(buf, x.Low)
  121. }
  122. buf.WriteByte(':')
  123. if x.High != nil {
  124. writeExpr(buf, x.High)
  125. }
  126. buf.WriteByte(']')
  127. case *ast.TypeAssertExpr:
  128. writeExpr(buf, x.X)
  129. buf.WriteString(".(...)")
  130. case *ast.CallExpr:
  131. writeExpr(buf, x.Fun)
  132. buf.WriteByte('(')
  133. for i, arg := range x.Args {
  134. if i > 0 {
  135. buf.WriteString(", ")
  136. }
  137. writeExpr(buf, arg)
  138. }
  139. buf.WriteByte(')')
  140. case *ast.StarExpr:
  141. buf.WriteByte('*')
  142. writeExpr(buf, x.X)
  143. case *ast.UnaryExpr:
  144. buf.WriteString(x.Op.String())
  145. writeExpr(buf, x.X)
  146. case *ast.BinaryExpr:
  147. // The AST preserves source-level parentheses so there is
  148. // no need to introduce parentheses here for correctness.
  149. writeExpr(buf, x.X)
  150. buf.WriteByte(' ')
  151. buf.WriteString(x.Op.String())
  152. buf.WriteByte(' ')
  153. writeExpr(buf, x.Y)
  154. default:
  155. fmt.Fprintf(buf, "<expr %T>", x)
  156. }
  157. }
  158. // typeString returns a string representation for typ.
  159. func typeString(typ Type) string {
  160. var buf bytes.Buffer
  161. writeType(&buf, typ)
  162. return buf.String()
  163. }
  164. func writeParams(buf *bytes.Buffer, params ObjList, isVariadic bool) {
  165. buf.WriteByte('(')
  166. for i, par := range params {
  167. if i > 0 {
  168. buf.WriteString(", ")
  169. }
  170. if par.Name != "" {
  171. buf.WriteString(par.Name)
  172. buf.WriteByte(' ')
  173. }
  174. if isVariadic && i == len(params)-1 {
  175. buf.WriteString("...")
  176. }
  177. writeType(buf, par.Type.(Type))
  178. }
  179. buf.WriteByte(')')
  180. }
  181. func writeSignature(buf *bytes.Buffer, sig *Signature) {
  182. writeParams(buf, sig.Params, sig.IsVariadic)
  183. if len(sig.Results) == 0 {
  184. // no result
  185. return
  186. }
  187. buf.WriteByte(' ')
  188. if len(sig.Results) == 1 && sig.Results[0].Name == "" {
  189. // single unnamed result
  190. writeType(buf, sig.Results[0].Type.(Type))
  191. return
  192. }
  193. // multiple or named result(s)
  194. writeParams(buf, sig.Results, false)
  195. }
  196. func writeType(buf *bytes.Buffer, typ Type) {
  197. switch t := typ.(type) {
  198. case nil:
  199. buf.WriteString("<nil>")
  200. case *Basic:
  201. buf.WriteString(t.Name)
  202. case *Array:
  203. fmt.Fprintf(buf, "[%d]", t.Len)
  204. writeType(buf, t.Elt)
  205. case *Slice:
  206. buf.WriteString("[]")
  207. writeType(buf, t.Elt)
  208. case *Struct:
  209. buf.WriteString("struct{")
  210. for i, f := range t.Fields {
  211. if i > 0 {
  212. buf.WriteString("; ")
  213. }
  214. if !f.IsAnonymous {
  215. buf.WriteString(f.Name)
  216. buf.WriteByte(' ')
  217. }
  218. writeType(buf, f.Type)
  219. if f.Tag != "" {
  220. fmt.Fprintf(buf, " %q", f.Tag)
  221. }
  222. }
  223. buf.WriteByte('}')
  224. case *Pointer:
  225. buf.WriteByte('*')
  226. writeType(buf, t.Base)
  227. case *Result:
  228. writeParams(buf, t.Values, false)
  229. case *Signature:
  230. buf.WriteString("func")
  231. writeSignature(buf, t)
  232. case *builtin:
  233. fmt.Fprintf(buf, "<type of %s>", t.name)
  234. case *Interface:
  235. buf.WriteString("interface{")
  236. for i, m := range t.Methods {
  237. if i > 0 {
  238. buf.WriteString("; ")
  239. }
  240. buf.WriteString(m.Name)
  241. writeSignature(buf, m.Type.(*Signature))
  242. }
  243. buf.WriteByte('}')
  244. case *Map:
  245. buf.WriteString("map[")
  246. writeType(buf, t.Key)
  247. buf.WriteByte(']')
  248. writeType(buf, t.Elt)
  249. case *Chan:
  250. var s string
  251. switch t.Dir {
  252. case ast.SEND:
  253. s = "chan<- "
  254. case ast.RECV:
  255. s = "<-chan "
  256. default:
  257. s = "chan "
  258. }
  259. buf.WriteString(s)
  260. writeType(buf, t.Elt)
  261. case *NamedType:
  262. buf.WriteString(t.Obj.Name)
  263. default:
  264. fmt.Fprintf(buf, "<type %T>", t)
  265. }
  266. }