check.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. // Copyright 2022 The Gc 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 gc // modernc.org/gc/v3
  5. import (
  6. "fmt"
  7. "go/constant"
  8. "go/token"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "sync"
  13. )
  14. type ctx struct {
  15. ast *AST
  16. cfg *Config
  17. errs errList
  18. iota int64
  19. pkg *Package
  20. int32 Type // Set by newCtx
  21. untypedFloat Type // Set by newCtx
  22. untypedInt Type // Set by newCtx
  23. untypedString Type // Set by newCtx
  24. }
  25. func newCtx(cfg *Config) (r *ctx) {
  26. r = &ctx{
  27. cfg: cfg,
  28. iota: -1, // -> Invalid
  29. }
  30. r.int32 = r.newPredeclaredType(znode, Int32)
  31. r.untypedFloat = r.newPredeclaredType(znode, UntypedFloat)
  32. r.untypedInt = r.newPredeclaredType(znode, UntypedInt)
  33. r.untypedString = r.newPredeclaredType(znode, UntypedString)
  34. return r
  35. }
  36. func (c *ctx) err(n Node, msg string, args ...interface{}) {
  37. var pos token.Position
  38. if n != nil {
  39. pos = n.Position()
  40. }
  41. s := fmt.Sprintf(msg, args...)
  42. if trcTODOs && strings.HasPrefix(s, "TODO") {
  43. fmt.Fprintf(os.Stderr, "%v: %s (%v)\n", pos, s, origin(2))
  44. os.Stderr.Sync()
  45. }
  46. switch {
  47. case extendedErrors:
  48. c.errs.err(pos, "%s (%v: %v: %v)", s, origin(4), origin(3), origin(2))
  49. default:
  50. c.errs.err(pos, s)
  51. }
  52. }
  53. func (c *ctx) isBuiltin() bool { return c.pkg.Scope.kind == UniverseScope }
  54. func (c *ctx) isUnsafe() bool { return c.pkg.isUnsafe }
  55. func (c *ctx) lookup(sc *Scope, id Token) (pkg *Package, in *Scope, r named) {
  56. sc0 := sc
  57. pkg = c.pkg
  58. for {
  59. switch in, nm := sc.lookup(id); x := nm.n.(type) {
  60. case *TypeDefNode:
  61. if sc.kind == UniverseScope {
  62. if sc0.kind != UniverseScope && token.IsExported(id.Src()) {
  63. // trc("%v: %q %v %v", id.Position(), id.Src(), sc0.kind, sc.kind)
  64. return nil, nil, r
  65. }
  66. }
  67. return x.pkg, in, nm
  68. default:
  69. panic(todo("%v: %q %T", id.Position(), id.Src(), x))
  70. }
  71. }
  72. }
  73. func (n *Package) check(c *ctx) (err error) {
  74. if n == nil {
  75. return nil
  76. }
  77. c.pkg = n
  78. // trc("PKG %q", n.ImportPath)
  79. // defer func() { trc("PKG %q -> err: %v", n.ImportPath, err) }()
  80. for _, v := range n.GoFiles {
  81. path := filepath.Join(n.FSPath, v.Name())
  82. n.AST[path].check(c)
  83. }
  84. return c.errs.Err()
  85. }
  86. func (n *AST) check(c *ctx) {
  87. if n == nil {
  88. return
  89. }
  90. c.ast = n
  91. n.SourceFile.check(c)
  92. }
  93. func (n *SourceFileNode) check(c *ctx) {
  94. if n == nil {
  95. return
  96. }
  97. n.PackageClause.check(c)
  98. for l := n.ImportDeclList; l != nil; l = l.List {
  99. l.ImportDecl.check(c)
  100. }
  101. for l := n.TopLevelDeclList; l != nil; l = l.List {
  102. switch x := l.TopLevelDecl.(type) {
  103. case *TypeDeclNode:
  104. x.check(c)
  105. case *ConstDeclNode:
  106. x.check(c)
  107. case *VarDeclNode:
  108. x.check(c)
  109. case *FunctionDeclNode:
  110. x.check(c)
  111. case *MethodDeclNode:
  112. x.check(c)
  113. default:
  114. panic(todo("%v: %T %s", x.Position(), x, x.Source(false)))
  115. }
  116. }
  117. }
  118. func (n *MethodDeclNode) check(c *ctx) {
  119. if n == nil {
  120. return
  121. }
  122. n.Receiver.check(c)
  123. n.Signature.check(c)
  124. }
  125. func (n *FunctionDeclNode) check(c *ctx) {
  126. if n == nil {
  127. return
  128. }
  129. if c.isBuiltin() {
  130. switch nm := n.FunctionName.IDENT.Src(); nm {
  131. case
  132. "append",
  133. "cap",
  134. "close",
  135. "complex",
  136. "copy",
  137. "delete",
  138. "imag",
  139. "len",
  140. "make",
  141. "new",
  142. "panic",
  143. "print",
  144. "println",
  145. "real",
  146. "recover",
  147. // Go 1.21
  148. "max",
  149. "min",
  150. "clear":
  151. n.Signature.t = c.newPredeclaredType(n, Function)
  152. default:
  153. panic(todo("%v: %q %s", n.Position(), nm, n.Source(false)))
  154. }
  155. return
  156. }
  157. n.Signature.check(c)
  158. if n.TypeParameters != nil {
  159. panic(todo("%v: %T %s", n.Position(), n, n.Source(false)))
  160. }
  161. }
  162. func (n *SignatureNode) check(c *ctx) Type {
  163. if n == nil {
  164. return Invalid
  165. }
  166. if !n.enter(c, n) {
  167. return n.Type()
  168. }
  169. in := n.Parameters.check(c)
  170. out := n.Result.check(c)
  171. return n.setType(newTupleType(n.Parameters, []Type{in, out}))
  172. }
  173. func (n *ResultNode) check(c *ctx) Type {
  174. if n == nil {
  175. return Invalid
  176. }
  177. switch {
  178. case n.Parameters != nil:
  179. return n.Parameters.check(c)
  180. case n.TypeNode != nil:
  181. return n.TypeNode.check(c)
  182. default:
  183. panic(todo("%v: %T %s", n.Position(), n, n.Source(false)))
  184. }
  185. }
  186. func (n *ParametersNode) check(c *ctx) Type {
  187. if n == nil {
  188. return Invalid
  189. }
  190. r := newTupleType(n, nil)
  191. for l := n.ParameterDeclList; l != nil; l = l.List {
  192. r.Types = append(r.Types, l.ParameterDecl.check(c)...)
  193. }
  194. return r
  195. }
  196. func (n *ParameterDeclNode) check(c *ctx) (r []Type) {
  197. if n == nil {
  198. return nil
  199. }
  200. t := n.TypeNode.check(c)
  201. for l := n.IdentifierList; l != nil; l = l.List {
  202. r = append(r, t)
  203. }
  204. return r
  205. }
  206. func (n *VarDeclNode) check(c *ctx) {
  207. if n == nil {
  208. return
  209. }
  210. switch x := n.VarSpec.(type) {
  211. case *VarSpecNode:
  212. x.check(c)
  213. default:
  214. panic(todo("%v: %T %s", n.Position(), x, n.Source(false)))
  215. }
  216. }
  217. func (n *VarSpecNode) check(c *ctx) {
  218. if n == nil {
  219. return
  220. }
  221. if c.isBuiltin() {
  222. switch nm := n.IDENT.Src(); nm {
  223. case "nil":
  224. n.TypeNode = c.newPredeclaredType(n, UntypedNil)
  225. default:
  226. panic(todo("%v: %q", n.IDENT.Position(), nm))
  227. }
  228. return
  229. }
  230. if n.TypeNode != nil {
  231. c.err(n, "TODO %v", n.TypeNode.Source(false))
  232. }
  233. var e []Expression
  234. for l := n.ExpressionList; l != nil; l = l.List {
  235. e = append(e, l.Expression.checkExpr(c))
  236. }
  237. switch len(e) {
  238. default:
  239. panic(todo("", len(e)))
  240. c.err(n, "TODO %v", len(e))
  241. }
  242. }
  243. func (n *ConstDeclNode) check(c *ctx) {
  244. if n == nil {
  245. return
  246. }
  247. switch x := n.ConstSpec.(type) {
  248. case *ConstSpecListNode:
  249. var prev Node
  250. for l := x; l != nil; l = l.List {
  251. switch y := l.ConstSpec.(type) {
  252. case *ConstSpecNode:
  253. y.check(c, prev)
  254. if y.Expression != nil || y.TypeNode != nil {
  255. prev = y
  256. }
  257. default:
  258. panic(todo("%v: %T %s", n.Position(), y, n.Source(false)))
  259. }
  260. }
  261. case *ConstSpecNode:
  262. x.check(c, nil)
  263. default:
  264. panic(todo("%v: %T %s", n.Position(), x, n.Source(false)))
  265. }
  266. }
  267. func (n *ConstSpecNode) check(c *ctx, prev Node) {
  268. if n == nil {
  269. return
  270. }
  271. if !n.enter(c, n) {
  272. if n.guard == guardChecking {
  273. panic(todo("")) // report recursive
  274. }
  275. return
  276. }
  277. defer func() { n.guard = guardChecked }()
  278. if c.isBuiltin() {
  279. switch n.IDENT.Src() {
  280. case "true":
  281. switch x := n.Expression.(type) {
  282. case *BinaryExpressionNode:
  283. x.setValue(trueVal)
  284. x.setType(c.newPredeclaredType(x, UntypedBool))
  285. default:
  286. panic(todo("%v: %T %s", n.Position(), x, n.Source(false)))
  287. }
  288. case "false":
  289. switch x := n.Expression.(type) {
  290. case *BinaryExpressionNode:
  291. x.setValue(falseVal)
  292. x.setType(c.newPredeclaredType(x, UntypedBool))
  293. default:
  294. panic(todo("%v: %T %s", n.Position(), x, n.Source(false)))
  295. }
  296. case "iota":
  297. switch x := n.Expression.(type) {
  298. case *BasicLitNode:
  299. // ok
  300. default:
  301. panic(todo("%v: %T %s", n.Position(), x, n.Source(false)))
  302. }
  303. default:
  304. panic(todo("", n.Position(), n.Source(false)))
  305. }
  306. return
  307. }
  308. save := c.iota
  309. c.iota = n.iota
  310. defer func() { c.iota = save }()
  311. switch {
  312. case n.Expression != nil:
  313. n.Expression = n.Expression.checkExpr(c)
  314. if n.TypeNode == nil {
  315. n.TypeNode = n.Expression.Type()
  316. return
  317. }
  318. t := n.TypeNode.check(c)
  319. trc("", t)
  320. panic(todo("%v: %T %s", n.Position(), n, n.Source(false)))
  321. default:
  322. // var e Expression
  323. // var pe *Expression
  324. // switch {
  325. // case n.Expression != nil:
  326. // e = n.Expression
  327. // pe = &n.Expression
  328. // default:
  329. // switch x := prev.(type) {
  330. // case *ConstSpecNode:
  331. // e = x.Expression.clone()
  332. // pe = &e
  333. // default:
  334. // panic(todo("%v: %T %s", n.Position(), x, n.Source(false)))
  335. // }
  336. // }
  337. // ev, et := e.checkExpr(c, pe)
  338. // e = *pe
  339. // if ev.Kind() == constant.Unknown {
  340. // c.err(e, "%s is not a constant", e.Source(false))
  341. // n.t = Invalid
  342. // n.setValue(unknown)
  343. // return Invalid
  344. // }
  345. // switch {
  346. // case n.t == nil:
  347. // n.t = et
  348. // default:
  349. // c.err(n.Expression, "cannot assign %v (type %v) to type %v", ev, et, n.Type())
  350. // return Invalid
  351. // } else {
  352. // n.setValue(convertValue(c, e, ev, n.Type()))
  353. // }
  354. // }
  355. // return n.Type()
  356. panic(todo("%v: %T %s", n.Position(), n, n.Source(false)))
  357. }
  358. }
  359. func (n *TypeDeclNode) check(c *ctx) {
  360. if n == nil {
  361. return
  362. }
  363. for l := n.TypeSpecList; l != nil; l = l.List {
  364. switch x := l.TypeSpec.(type) {
  365. case *TypeDefNode:
  366. switch {
  367. case c.isBuiltin():
  368. x.pkg = c.pkg
  369. switch nm := x.IDENT.Src(); nm {
  370. case "bool":
  371. x.TypeNode = c.newPredeclaredType(x, Bool)
  372. case "int":
  373. x.TypeNode = c.newPredeclaredType(x, Int)
  374. c.cfg.int = x.TypeNode
  375. case "int8":
  376. x.TypeNode = c.newPredeclaredType(x, Int8)
  377. case "int16":
  378. x.TypeNode = c.newPredeclaredType(x, Int16)
  379. case "int32":
  380. x.TypeNode = c.newPredeclaredType(x, Int32)
  381. case "int64":
  382. x.TypeNode = c.newPredeclaredType(x, Int64)
  383. case "uint":
  384. x.TypeNode = c.newPredeclaredType(x, Uint)
  385. c.cfg.uint = x.TypeNode
  386. case "uint8":
  387. x.TypeNode = c.newPredeclaredType(x, Uint8)
  388. case "uint16":
  389. x.TypeNode = c.newPredeclaredType(x, Uint16)
  390. case "uint32":
  391. x.TypeNode = c.newPredeclaredType(x, Uint32)
  392. case "uint64":
  393. x.TypeNode = c.newPredeclaredType(x, Uint64)
  394. case "uintptr":
  395. x.TypeNode = c.newPredeclaredType(x, Uintptr)
  396. case "string":
  397. x.TypeNode = c.newPredeclaredType(x, String)
  398. case "float32":
  399. x.TypeNode = c.newPredeclaredType(x, Float32)
  400. case "float64":
  401. x.TypeNode = c.newPredeclaredType(x, Float64)
  402. case "complex64":
  403. x.TypeNode = c.newPredeclaredType(x, Complex64)
  404. case "complex128":
  405. x.TypeNode = c.newPredeclaredType(x, Complex128)
  406. case "comparable":
  407. x.TypeNode = c.newPredeclaredType(x, Interface)
  408. case "error":
  409. x.check(c)
  410. default:
  411. if token.IsExported(nm) {
  412. delete(c.pkg.Scope.nodes, nm)
  413. return
  414. }
  415. panic(todo("%v: %T %s", x.Position(), x, x.Source(false)))
  416. }
  417. case c.isUnsafe():
  418. switch nm := x.IDENT.Src(); nm {
  419. case "ArbitraryType", "IntegerType", "Pointer":
  420. x.TypeNode.check(c)
  421. default:
  422. panic(todo("%v: %T %s", x.Position(), x, x.Source(false)))
  423. }
  424. default:
  425. switch {
  426. case x.TypeParameters != nil:
  427. panic(todo("%v: %T %s", x.Position(), x, x.Source(false)))
  428. default:
  429. x.check(c)
  430. }
  431. }
  432. case *AliasDeclNode:
  433. x.check(c)
  434. default:
  435. panic(todo("%v: %T %s", x.Position(), x, x.Source(false)))
  436. }
  437. }
  438. }
  439. func (n *AliasDeclNode) check(c *ctx) {
  440. if n == nil {
  441. return
  442. }
  443. n.TypeNode.check(c)
  444. }
  445. func (n *ImportDeclNode) check(c *ctx) {
  446. if n == nil {
  447. return
  448. }
  449. type result struct {
  450. spec *ImportSpecNode
  451. pkg *Package
  452. err error
  453. }
  454. var a []*result
  455. var wg sync.WaitGroup
  456. for l := n.ImportSpecList; l != nil; l = l.List {
  457. r := &result{}
  458. a = append(a, r)
  459. wg.Add(1)
  460. go func(isln *ImportSpecListNode, r *result) {
  461. defer wg.Done()
  462. r.spec = isln.ImportSpec
  463. r.pkg, r.err = r.spec.check(c)
  464. r.spec.pkg = r.pkg
  465. }(l, r)
  466. }
  467. wg.Wait()
  468. fileScope := c.ast.FileScope
  469. pkgScope := c.pkg.Scope
  470. for _, v := range a {
  471. switch x := v.err.(type) {
  472. case nil:
  473. // ok
  474. default:
  475. panic(todo("%v: %T: %s", v.spec.Position(), x, x))
  476. }
  477. if c.pkg.ImportPath == "builtin" && v.spec.ImportPath.Src() == `"cmp"` {
  478. continue
  479. }
  480. switch ex := fileScope.declare(v.pkg.Name, v.spec, 0, nil, true); {
  481. case ex.declTok.IsValid():
  482. c.err(n, "%s redeclared, previous declaration at %v:", v.pkg.Name.Src(), ex.declTok.Position())
  483. continue
  484. }
  485. switch ex := pkgScope.declare(v.pkg.Name, v.spec, 0, nil, true); {
  486. case ex.declTok.IsValid():
  487. c.err(n, "%s redeclared, previous declaration at %v:", v.pkg.Name.Src(), ex.declTok.Position())
  488. continue
  489. }
  490. }
  491. }
  492. func (n *ImportSpecNode) check(c *ctx) (*Package, error) {
  493. if n == nil {
  494. return nil, nil
  495. }
  496. switch {
  497. case n.PERIOD.IsValid():
  498. panic(todo("", n.Position(), n.Source(false)))
  499. case n.PackageName.IsValid():
  500. //TODO version
  501. check := c.pkg.typeCheck
  502. switch check {
  503. case TypeCheckAll:
  504. // nop
  505. default:
  506. panic(todo("", check))
  507. }
  508. return c.cfg.newPackage(c.pkg.FSPath, constant.StringVal(n.ImportPath.Value()), "", nil, false, check, c.pkg.guard)
  509. default:
  510. //TODO version
  511. check := c.pkg.typeCheck
  512. switch check {
  513. case TypeCheckAll:
  514. // nop
  515. default:
  516. if c.pkg.ImportPath == "builtin" && n.ImportPath.Src() == `"cmp"` {
  517. return nil, nil
  518. }
  519. }
  520. return c.cfg.newPackage(c.pkg.FSPath, constant.StringVal(n.ImportPath.Value()), "", nil, false, check, c.pkg.guard)
  521. }
  522. }
  523. func (n *PackageClauseNode) check(c *ctx) {
  524. if n == nil {
  525. return
  526. }
  527. nm := n.PackageName.Src()
  528. if ex := c.pkg.Name; ex.IsValid() && ex.Src() != nm {
  529. c.err(n.PackageName, "found different packages %q and %q", ex.Src(), nm)
  530. return
  531. }
  532. c.pkg.Name = n.PackageName
  533. }