PageRenderTime 174ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 1ms

/third_party/gotools/go/types/api.go

http://github.com/axw/llgo
Go | 365 lines | 131 code | 41 blank | 193 comment | 27 complexity | afc46522d2ec767948aae03eaae1a91d MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  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. // Package types declares the data types and implements
  5. // the algorithms for type-checking of Go packages.
  6. // Use Check and Config.Check to invoke the type-checker.
  7. //
  8. // Type-checking consists of several interdependent phases:
  9. //
  10. // Name resolution maps each identifier (ast.Ident) in the program to the
  11. // language object (Object) it denotes.
  12. // Use Info.{Defs,Uses,Implicits} for the results of name resolution.
  13. //
  14. // Constant folding computes the exact constant value (exact.Value) for
  15. // every expression (ast.Expr) that is a compile-time constant.
  16. // Use Info.Types[expr].Value for the results of constant folding.
  17. //
  18. // Type inference computes the type (Type) of every expression (ast.Expr)
  19. // and checks for compliance with the language specification.
  20. // Use Info.Types[expr].Type for the results of type inference.
  21. //
  22. package types // import "llvm.org/llgo/third_party/gotools/go/types"
  23. import (
  24. "bytes"
  25. "fmt"
  26. "go/ast"
  27. "go/token"
  28. "llvm.org/llgo/third_party/gotools/go/exact"
  29. )
  30. // Check type-checks a package and returns the resulting complete package
  31. // object, or a nil package and the first error. The package is specified
  32. // by a list of *ast.Files and corresponding file set, and the import path
  33. // the package is identified with. The clean path must not be empty or dot (".").
  34. //
  35. // For more control over type-checking and results, use Config.Check.
  36. func Check(path string, fset *token.FileSet, files []*ast.File) (*Package, error) {
  37. var conf Config
  38. pkg, err := conf.Check(path, fset, files, nil)
  39. if err != nil {
  40. return nil, err
  41. }
  42. return pkg, nil
  43. }
  44. // An Error describes a type-checking error; it implements the error interface.
  45. // A "soft" error is an error that still permits a valid interpretation of a
  46. // package (such as "unused variable"); "hard" errors may lead to unpredictable
  47. // behavior if ignored.
  48. type Error struct {
  49. Fset *token.FileSet // file set for interpretation of Pos
  50. Pos token.Pos // error position
  51. Msg string // error message
  52. Soft bool // if set, error is "soft"
  53. }
  54. // Error returns an error string formatted as follows:
  55. // filename:line:column: message
  56. func (err Error) Error() string {
  57. return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg)
  58. }
  59. // An importer resolves import paths to Packages.
  60. // The imports map records packages already known,
  61. // indexed by package path. The type-checker
  62. // will invoke Import with Config.Packages.
  63. // An importer must determine the canonical package path and
  64. // check imports to see if it is already present in the map.
  65. // If so, the Importer can return the map entry. Otherwise,
  66. // the importer must load the package data for the given path
  67. // into a new *Package, record it in imports map, and return
  68. // the package.
  69. // TODO(gri) Need to be clearer about requirements of completeness.
  70. type Importer func(map[string]*Package, string) (*Package, error)
  71. // A Config specifies the configuration for type checking.
  72. // The zero value for Config is a ready-to-use default configuration.
  73. type Config struct {
  74. // If IgnoreFuncBodies is set, function bodies are not
  75. // type-checked.
  76. IgnoreFuncBodies bool
  77. // If FakeImportC is set, `import "C"` (for packages requiring Cgo)
  78. // declares an empty "C" package and errors are omitted for qualified
  79. // identifiers referring to package C (which won't find an object).
  80. // This feature is intended for the standard library cmd/api tool.
  81. //
  82. // Caution: Effects may be unpredictable due to follow-up errors.
  83. // Do not use casually!
  84. FakeImportC bool
  85. // Packages is used to look up (and thus canonicalize) packages by
  86. // package path. If Packages is nil, it is set to a new empty map.
  87. // During type-checking, imported packages are added to the map.
  88. Packages map[string]*Package
  89. // If Error != nil, it is called with each error found
  90. // during type checking; err has dynamic type Error.
  91. // Secondary errors (for instance, to enumerate all types
  92. // involved in an invalid recursive type declaration) have
  93. // error strings that start with a '\t' character.
  94. // If Error == nil, type-checking stops with the first
  95. // error found.
  96. Error func(err error)
  97. // If Import != nil, it is called for each imported package.
  98. // Otherwise, DefaultImport is called.
  99. Import Importer
  100. // If Sizes != nil, it provides the sizing functions for package unsafe.
  101. // Otherwise &StdSizes{WordSize: 8, MaxAlign: 8} is used instead.
  102. Sizes Sizes
  103. // If DisableUnusedImportCheck is set, packages are not checked
  104. // for unused imports.
  105. DisableUnusedImportCheck bool
  106. }
  107. // DefaultImport is the default importer invoked if Config.Import == nil.
  108. // The declaration:
  109. //
  110. // import _ "llvm.org/llgo/third_party/gotools/go/gcimporter"
  111. //
  112. // in a client of go/types will initialize DefaultImport to gcimporter.Import.
  113. var DefaultImport Importer
  114. // Info holds result type information for a type-checked package.
  115. // Only the information for which a map is provided is collected.
  116. // If the package has type errors, the collected information may
  117. // be incomplete.
  118. type Info struct {
  119. // Types maps expressions to their types, and for constant
  120. // expressions, their values. Invalid expressions are omitted.
  121. //
  122. // For (possibly parenthesized) identifiers denoting built-in
  123. // functions, the recorded signatures are call-site specific:
  124. // if the call result is not a constant, the recorded type is
  125. // an argument-specific signature. Otherwise, the recorded type
  126. // is invalid.
  127. //
  128. // Identifiers on the lhs of declarations (i.e., the identifiers
  129. // which are being declared) are collected in the Defs map.
  130. // Identifiers denoting packages are collected in the Uses maps.
  131. Types map[ast.Expr]TypeAndValue
  132. // Defs maps identifiers to the objects they define (including
  133. // package names, dots "." of dot-imports, and blank "_" identifiers).
  134. // For identifiers that do not denote objects (e.g., the package name
  135. // in package clauses, or symbolic variables t in t := x.(type) of
  136. // type switch headers), the corresponding objects are nil.
  137. //
  138. // For an anonymous field, Defs returns the field *Var it defines.
  139. //
  140. // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
  141. Defs map[*ast.Ident]Object
  142. // Uses maps identifiers to the objects they denote.
  143. //
  144. // For an anonymous field, Uses returns the *TypeName it denotes.
  145. //
  146. // Invariant: Uses[id].Pos() != id.Pos()
  147. Uses map[*ast.Ident]Object
  148. // Implicits maps nodes to their implicitly declared objects, if any.
  149. // The following node and object types may appear:
  150. //
  151. // node declared object
  152. //
  153. // *ast.ImportSpec *PkgName for dot-imports and imports without renames
  154. // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default)
  155. // *ast.Field anonymous struct field or parameter *Var
  156. //
  157. Implicits map[ast.Node]Object
  158. // Selections maps selector expressions (excluding qualified identifiers)
  159. // to their corresponding selections.
  160. Selections map[*ast.SelectorExpr]*Selection
  161. // Scopes maps ast.Nodes to the scopes they define. Package scopes are not
  162. // associated with a specific node but with all files belonging to a package.
  163. // Thus, the package scope can be found in the type-checked Package object.
  164. // Scopes nest, with the Universe scope being the outermost scope, enclosing
  165. // the package scope, which contains (one or more) files scopes, which enclose
  166. // function scopes which in turn enclose statement and function literal scopes.
  167. // Note that even though package-level functions are declared in the package
  168. // scope, the function scopes are embedded in the file scope of the file
  169. // containing the function declaration.
  170. //
  171. // The following node types may appear in Scopes:
  172. //
  173. // *ast.File
  174. // *ast.FuncType
  175. // *ast.BlockStmt
  176. // *ast.IfStmt
  177. // *ast.SwitchStmt
  178. // *ast.TypeSwitchStmt
  179. // *ast.CaseClause
  180. // *ast.CommClause
  181. // *ast.ForStmt
  182. // *ast.RangeStmt
  183. //
  184. Scopes map[ast.Node]*Scope
  185. // InitOrder is the list of package-level initializers in the order in which
  186. // they must be executed. Initializers referring to variables related by an
  187. // initialization dependency appear in topological order, the others appear
  188. // in source order. Variables without an initialization expression do not
  189. // appear in this list.
  190. InitOrder []*Initializer
  191. }
  192. // TypeOf returns the type of expression e, or nil if not found.
  193. // Precondition: the Types, Uses and Defs maps are populated.
  194. //
  195. func (info *Info) TypeOf(e ast.Expr) Type {
  196. if t, ok := info.Types[e]; ok {
  197. return t.Type
  198. }
  199. if id, _ := e.(*ast.Ident); id != nil {
  200. if obj := info.ObjectOf(id); obj != nil {
  201. return obj.Type()
  202. }
  203. }
  204. return nil
  205. }
  206. // ObjectOf returns the object denoted by the specified id,
  207. // or nil if not found.
  208. //
  209. // If id is an anonymous struct field, ObjectOf returns the field (*Var)
  210. // it uses, not the type (*TypeName) it defines.
  211. //
  212. // Precondition: the Uses and Defs maps are populated.
  213. //
  214. func (info *Info) ObjectOf(id *ast.Ident) Object {
  215. if obj, _ := info.Defs[id]; obj != nil {
  216. return obj
  217. }
  218. return info.Uses[id]
  219. }
  220. // TypeAndValue reports the type and value (for constants)
  221. // of the corresponding expression.
  222. type TypeAndValue struct {
  223. mode operandMode
  224. Type Type
  225. Value exact.Value
  226. }
  227. // TODO(gri) Consider eliminating the IsVoid predicate. Instead, report
  228. // "void" values as regular values but with the empty tuple type.
  229. // IsVoid reports whether the corresponding expression
  230. // is a function call without results.
  231. func (tv TypeAndValue) IsVoid() bool {
  232. return tv.mode == novalue
  233. }
  234. // IsType reports whether the corresponding expression specifies a type.
  235. func (tv TypeAndValue) IsType() bool {
  236. return tv.mode == typexpr
  237. }
  238. // IsBuiltin reports whether the corresponding expression denotes
  239. // a (possibly parenthesized) built-in function.
  240. func (tv TypeAndValue) IsBuiltin() bool {
  241. return tv.mode == builtin
  242. }
  243. // IsValue reports whether the corresponding expression is a value.
  244. // Builtins are not considered values. Constant values have a non-
  245. // nil Value.
  246. func (tv TypeAndValue) IsValue() bool {
  247. switch tv.mode {
  248. case constant, variable, mapindex, value, commaok:
  249. return true
  250. }
  251. return false
  252. }
  253. // IsNil reports whether the corresponding expression denotes the
  254. // predeclared value nil.
  255. func (tv TypeAndValue) IsNil() bool {
  256. return tv.mode == value && tv.Type == Typ[UntypedNil]
  257. }
  258. // Addressable reports whether the corresponding expression
  259. // is addressable (http://golang.org/ref/spec#Address_operators).
  260. func (tv TypeAndValue) Addressable() bool {
  261. return tv.mode == variable
  262. }
  263. // Assignable reports whether the corresponding expression
  264. // is assignable to (provided a value of the right type).
  265. func (tv TypeAndValue) Assignable() bool {
  266. return tv.mode == variable || tv.mode == mapindex
  267. }
  268. // HasOk reports whether the corresponding expression may be
  269. // used on the lhs of a comma-ok assignment.
  270. func (tv TypeAndValue) HasOk() bool {
  271. return tv.mode == commaok || tv.mode == mapindex
  272. }
  273. // An Initializer describes a package-level variable, or a list of variables in case
  274. // of a multi-valued initialization expression, and the corresponding initialization
  275. // expression.
  276. type Initializer struct {
  277. Lhs []*Var // var Lhs = Rhs
  278. Rhs ast.Expr
  279. }
  280. func (init *Initializer) String() string {
  281. var buf bytes.Buffer
  282. for i, lhs := range init.Lhs {
  283. if i > 0 {
  284. buf.WriteString(", ")
  285. }
  286. buf.WriteString(lhs.Name())
  287. }
  288. buf.WriteString(" = ")
  289. WriteExpr(&buf, init.Rhs)
  290. return buf.String()
  291. }
  292. // Check type-checks a package and returns the resulting package object,
  293. // the first error if any, and if info != nil, additional type information.
  294. // The package is marked as complete if no errors occurred, otherwise it is
  295. // incomplete. See Config.Error for controlling behavior in the presence of
  296. // errors.
  297. //
  298. // The package is specified by a list of *ast.Files and corresponding
  299. // file set, and the package path the package is identified with.
  300. // The clean path must not be empty or dot (".").
  301. func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) {
  302. pkg := NewPackage(path, "")
  303. return pkg, NewChecker(conf, fset, pkg, info).Files(files)
  304. }
  305. // AssertableTo reports whether a value of type V can be asserted to have type T.
  306. func AssertableTo(V *Interface, T Type) bool {
  307. m, _ := assertableTo(V, T)
  308. return m == nil
  309. }
  310. // AssignableTo reports whether a value of type V is assignable to a variable of type T.
  311. func AssignableTo(V, T Type) bool {
  312. x := operand{mode: value, typ: V}
  313. return x.assignableTo(nil, T) // config not needed for non-constant x
  314. }
  315. // ConvertibleTo reports whether a value of type V is convertible to a value of type T.
  316. func ConvertibleTo(V, T Type) bool {
  317. x := operand{mode: value, typ: V}
  318. return x.convertibleTo(nil, T) // config not needed for non-constant x
  319. }
  320. // Implements reports whether type V implements interface T.
  321. func Implements(V Type, T *Interface) bool {
  322. f, _ := MissingMethod(V, T, true)
  323. return f == nil
  324. }