PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/go/internal/gccgoimporter/parser.go

http://github.com/axw/llgo
Go | 855 lines | 667 code | 111 blank | 77 comment | 131 complexity | dd6ee8fc245ecf601273b4770de10caf MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. // Copyright 2013 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 gccgoimporter
  5. import (
  6. "bytes"
  7. "errors"
  8. "fmt"
  9. "go/constant"
  10. "go/token"
  11. "go/types"
  12. "io"
  13. "strconv"
  14. "strings"
  15. "text/scanner"
  16. )
  17. type parser struct {
  18. scanner scanner.Scanner
  19. tok rune // current token
  20. lit string // literal string; only valid for Ident, Int, String tokens
  21. pkgpath string // package path of imported package
  22. pkgname string // name of imported package
  23. pkg *types.Package // reference to imported package
  24. imports map[string]*types.Package // package path -> package object
  25. typeMap map[int]types.Type // type number -> type
  26. initdata InitData // package init priority data
  27. }
  28. func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
  29. p.scanner.Init(src)
  30. p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
  31. p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
  32. p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
  33. p.scanner.Filename = filename // for good error messages
  34. p.next()
  35. p.imports = imports
  36. p.typeMap = make(map[int]types.Type)
  37. }
  38. type importError struct {
  39. pos scanner.Position
  40. err error
  41. }
  42. func (e importError) Error() string {
  43. return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
  44. }
  45. func (p *parser) error(err interface{}) {
  46. if s, ok := err.(string); ok {
  47. err = errors.New(s)
  48. }
  49. // panic with a runtime.Error if err is not an error
  50. panic(importError{p.scanner.Pos(), err.(error)})
  51. }
  52. func (p *parser) errorf(format string, args ...interface{}) {
  53. p.error(fmt.Errorf(format, args...))
  54. }
  55. func (p *parser) expect(tok rune) string {
  56. lit := p.lit
  57. if p.tok != tok {
  58. p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
  59. }
  60. p.next()
  61. return lit
  62. }
  63. func (p *parser) expectKeyword(keyword string) {
  64. lit := p.expect(scanner.Ident)
  65. if lit != keyword {
  66. p.errorf("expected keyword %s, got %q", keyword, lit)
  67. }
  68. }
  69. func (p *parser) parseString() string {
  70. str, err := strconv.Unquote(p.expect(scanner.String))
  71. if err != nil {
  72. p.error(err)
  73. }
  74. return str
  75. }
  76. // unquotedString = { unquotedStringChar } .
  77. // unquotedStringChar = <neither a whitespace nor a ';' char> .
  78. func (p *parser) parseUnquotedString() string {
  79. if p.tok == scanner.EOF {
  80. p.error("unexpected EOF")
  81. }
  82. var buf bytes.Buffer
  83. buf.WriteString(p.scanner.TokenText())
  84. // This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
  85. // we need to let it be consumed by p.next().
  86. for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
  87. buf.WriteRune(ch)
  88. p.scanner.Next()
  89. }
  90. p.next()
  91. return buf.String()
  92. }
  93. func (p *parser) next() {
  94. p.tok = p.scanner.Scan()
  95. switch p.tok {
  96. case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท':
  97. p.lit = p.scanner.TokenText()
  98. default:
  99. p.lit = ""
  100. }
  101. }
  102. func (p *parser) parseQualifiedName() (path, name string) {
  103. return p.parseQualifiedNameStr(p.parseString())
  104. }
  105. func (p *parser) parseUnquotedQualifiedName() (path, name string) {
  106. return p.parseQualifiedNameStr(p.parseUnquotedString())
  107. }
  108. // qualifiedName = [ ["."] unquotedString "." ] unquotedString .
  109. //
  110. // The above production uses greedy matching.
  111. func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
  112. parts := strings.Split(unquotedName, ".")
  113. if parts[0] == "" {
  114. parts = parts[1:]
  115. }
  116. switch len(parts) {
  117. case 0:
  118. p.errorf("malformed qualified name: %q", unquotedName)
  119. case 1:
  120. // unqualified name
  121. pkgpath = p.pkgpath
  122. name = parts[0]
  123. default:
  124. // qualified name, which may contain periods
  125. pkgpath = strings.Join(parts[0:len(parts)-1], ".")
  126. name = parts[len(parts)-1]
  127. }
  128. return
  129. }
  130. // getPkg returns the package for a given path. If the package is
  131. // not found but we have a package name, create the package and
  132. // add it to the p.imports map.
  133. //
  134. func (p *parser) getPkg(pkgpath, name string) *types.Package {
  135. // package unsafe is not in the imports map - handle explicitly
  136. if pkgpath == "unsafe" {
  137. return types.Unsafe
  138. }
  139. pkg := p.imports[pkgpath]
  140. if pkg == nil && name != "" {
  141. pkg = types.NewPackage(pkgpath, name)
  142. p.imports[pkgpath] = pkg
  143. }
  144. return pkg
  145. }
  146. // parseExportedName is like parseQualifiedName, but
  147. // the package path is resolved to an imported *types.Package.
  148. //
  149. // ExportedName = string [string] .
  150. func (p *parser) parseExportedName() (pkg *types.Package, name string) {
  151. path, name := p.parseQualifiedName()
  152. var pkgname string
  153. if p.tok == scanner.String {
  154. pkgname = p.parseString()
  155. }
  156. pkg = p.getPkg(path, pkgname)
  157. if pkg == nil {
  158. p.errorf("package %s (path = %q) not found", name, path)
  159. }
  160. return
  161. }
  162. // Name = QualifiedName | "?" .
  163. func (p *parser) parseName() string {
  164. if p.tok == '?' {
  165. // Anonymous.
  166. p.next()
  167. return ""
  168. }
  169. // The package path is redundant for us. Don't try to parse it.
  170. _, name := p.parseUnquotedQualifiedName()
  171. return name
  172. }
  173. func deref(typ types.Type) types.Type {
  174. if p, _ := typ.(*types.Pointer); p != nil {
  175. typ = p.Elem()
  176. }
  177. return typ
  178. }
  179. // Field = Name Type [string] .
  180. func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
  181. name := p.parseName()
  182. typ := p.parseType(pkg)
  183. anon := false
  184. if name == "" {
  185. anon = true
  186. switch typ := deref(typ).(type) {
  187. case *types.Basic:
  188. name = typ.Name()
  189. case *types.Named:
  190. name = typ.Obj().Name()
  191. default:
  192. p.error("anonymous field expected")
  193. }
  194. }
  195. field = types.NewField(token.NoPos, pkg, name, typ, anon)
  196. if p.tok == scanner.String {
  197. tag = p.parseString()
  198. }
  199. return
  200. }
  201. // Param = Name ["..."] Type .
  202. func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
  203. name := p.parseName()
  204. if p.tok == '.' {
  205. p.next()
  206. p.expect('.')
  207. p.expect('.')
  208. isVariadic = true
  209. }
  210. typ := p.parseType(pkg)
  211. if isVariadic {
  212. typ = types.NewSlice(typ)
  213. }
  214. param = types.NewParam(token.NoPos, pkg, name, typ)
  215. return
  216. }
  217. // Var = Name Type .
  218. func (p *parser) parseVar(pkg *types.Package) *types.Var {
  219. name := p.parseName()
  220. return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
  221. }
  222. // ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) .
  223. // FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
  224. func (p *parser) parseConstValue() (val constant.Value, typ types.Type) {
  225. switch p.tok {
  226. case scanner.String:
  227. str := p.parseString()
  228. val = constant.MakeString(str)
  229. typ = types.Typ[types.UntypedString]
  230. return
  231. case scanner.Ident:
  232. b := false
  233. switch p.lit {
  234. case "false":
  235. case "true":
  236. b = true
  237. default:
  238. p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
  239. }
  240. p.next()
  241. val = constant.MakeBool(b)
  242. typ = types.Typ[types.UntypedBool]
  243. return
  244. }
  245. sign := ""
  246. if p.tok == '-' {
  247. p.next()
  248. sign = "-"
  249. }
  250. switch p.tok {
  251. case scanner.Int:
  252. val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
  253. if val == nil {
  254. p.error("could not parse integer literal")
  255. }
  256. p.next()
  257. if p.tok == '\'' {
  258. p.next()
  259. typ = types.Typ[types.UntypedRune]
  260. } else {
  261. typ = types.Typ[types.UntypedInt]
  262. }
  263. case scanner.Float:
  264. re := sign + p.lit
  265. p.next()
  266. var im string
  267. switch p.tok {
  268. case '+':
  269. p.next()
  270. im = p.expect(scanner.Float)
  271. case '-':
  272. p.next()
  273. im = "-" + p.expect(scanner.Float)
  274. case scanner.Ident:
  275. // re is in fact the imaginary component. Expect "i" below.
  276. im = re
  277. re = "0"
  278. default:
  279. val = constant.MakeFromLiteral(re, token.FLOAT, 0)
  280. if val == nil {
  281. p.error("could not parse float literal")
  282. }
  283. typ = types.Typ[types.UntypedFloat]
  284. return
  285. }
  286. p.expectKeyword("i")
  287. reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
  288. if reval == nil {
  289. p.error("could not parse real component of complex literal")
  290. }
  291. imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
  292. if imval == nil {
  293. p.error("could not parse imag component of complex literal")
  294. }
  295. val = constant.BinaryOp(reval, token.ADD, imval)
  296. typ = types.Typ[types.UntypedComplex]
  297. default:
  298. p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
  299. }
  300. return
  301. }
  302. // Const = Name [Type] "=" ConstValue .
  303. func (p *parser) parseConst(pkg *types.Package) *types.Const {
  304. name := p.parseName()
  305. var typ types.Type
  306. if p.tok == '<' {
  307. typ = p.parseType(pkg)
  308. }
  309. p.expect('=')
  310. val, vtyp := p.parseConstValue()
  311. if typ == nil {
  312. typ = vtyp
  313. }
  314. return types.NewConst(token.NoPos, pkg, name, typ, val)
  315. }
  316. // TypeName = ExportedName .
  317. func (p *parser) parseTypeName() *types.TypeName {
  318. pkg, name := p.parseExportedName()
  319. scope := pkg.Scope()
  320. if obj := scope.Lookup(name); obj != nil {
  321. return obj.(*types.TypeName)
  322. }
  323. obj := types.NewTypeName(token.NoPos, pkg, name, nil)
  324. // a named type may be referred to before the underlying type
  325. // is known - set it up
  326. types.NewNamed(obj, nil, nil)
  327. scope.Insert(obj)
  328. return obj
  329. }
  330. // NamedType = TypeName Type { Method } .
  331. // Method = "func" "(" Param ")" Name ParamList ResultList ";" .
  332. func (p *parser) parseNamedType(n int) types.Type {
  333. obj := p.parseTypeName()
  334. pkg := obj.Pkg()
  335. typ := obj.Type()
  336. p.typeMap[n] = typ
  337. nt, ok := typ.(*types.Named)
  338. if !ok {
  339. // This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
  340. pt := p.parseType(pkg)
  341. if pt != typ {
  342. p.error("unexpected underlying type for non-named TypeName")
  343. }
  344. return typ
  345. }
  346. underlying := p.parseType(pkg)
  347. if nt.Underlying() == nil {
  348. nt.SetUnderlying(underlying.Underlying())
  349. }
  350. for p.tok == scanner.Ident {
  351. // collect associated methods
  352. p.expectKeyword("func")
  353. p.expect('(')
  354. receiver, _ := p.parseParam(pkg)
  355. p.expect(')')
  356. name := p.parseName()
  357. params, isVariadic := p.parseParamList(pkg)
  358. results := p.parseResultList(pkg)
  359. p.expect(';')
  360. sig := types.NewSignature(receiver, params, results, isVariadic)
  361. nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
  362. }
  363. return nt
  364. }
  365. func (p *parser) parseInt() int64 {
  366. lit := p.expect(scanner.Int)
  367. n, err := strconv.ParseInt(lit, 10, 0)
  368. if err != nil {
  369. p.error(err)
  370. }
  371. return n
  372. }
  373. // ArrayOrSliceType = "[" [ int ] "]" Type .
  374. func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type {
  375. p.expect('[')
  376. if p.tok == ']' {
  377. p.next()
  378. return types.NewSlice(p.parseType(pkg))
  379. }
  380. n := p.parseInt()
  381. p.expect(']')
  382. return types.NewArray(p.parseType(pkg), n)
  383. }
  384. // MapType = "map" "[" Type "]" Type .
  385. func (p *parser) parseMapType(pkg *types.Package) types.Type {
  386. p.expectKeyword("map")
  387. p.expect('[')
  388. key := p.parseType(pkg)
  389. p.expect(']')
  390. elem := p.parseType(pkg)
  391. return types.NewMap(key, elem)
  392. }
  393. // ChanType = "chan" ["<-" | "-<"] Type .
  394. func (p *parser) parseChanType(pkg *types.Package) types.Type {
  395. p.expectKeyword("chan")
  396. dir := types.SendRecv
  397. switch p.tok {
  398. case '-':
  399. p.next()
  400. p.expect('<')
  401. dir = types.SendOnly
  402. case '<':
  403. // don't consume '<' if it belongs to Type
  404. if p.scanner.Peek() == '-' {
  405. p.next()
  406. p.expect('-')
  407. dir = types.RecvOnly
  408. }
  409. }
  410. return types.NewChan(dir, p.parseType(pkg))
  411. }
  412. // StructType = "struct" "{" { Field } "}" .
  413. func (p *parser) parseStructType(pkg *types.Package) types.Type {
  414. p.expectKeyword("struct")
  415. var fields []*types.Var
  416. var tags []string
  417. p.expect('{')
  418. for p.tok != '}' && p.tok != scanner.EOF {
  419. field, tag := p.parseField(pkg)
  420. p.expect(';')
  421. fields = append(fields, field)
  422. tags = append(tags, tag)
  423. }
  424. p.expect('}')
  425. return types.NewStruct(fields, tags)
  426. }
  427. // ParamList = "(" [ { Parameter "," } Parameter ] ")" .
  428. func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
  429. var list []*types.Var
  430. isVariadic := false
  431. p.expect('(')
  432. for p.tok != ')' && p.tok != scanner.EOF {
  433. if len(list) > 0 {
  434. p.expect(',')
  435. }
  436. par, variadic := p.parseParam(pkg)
  437. list = append(list, par)
  438. if variadic {
  439. if isVariadic {
  440. p.error("... not on final argument")
  441. }
  442. isVariadic = true
  443. }
  444. }
  445. p.expect(')')
  446. return types.NewTuple(list...), isVariadic
  447. }
  448. // ResultList = Type | ParamList .
  449. func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
  450. switch p.tok {
  451. case '<':
  452. return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
  453. case '(':
  454. params, _ := p.parseParamList(pkg)
  455. return params
  456. default:
  457. return nil
  458. }
  459. }
  460. // FunctionType = ParamList ResultList .
  461. func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
  462. params, isVariadic := p.parseParamList(pkg)
  463. results := p.parseResultList(pkg)
  464. return types.NewSignature(nil, params, results, isVariadic)
  465. }
  466. // Func = Name FunctionType .
  467. func (p *parser) parseFunc(pkg *types.Package) *types.Func {
  468. name := p.parseName()
  469. if strings.ContainsRune(name, '$') {
  470. // This is a Type$equal or Type$hash function, which we don't want to parse,
  471. // except for the types.
  472. p.discardDirectiveWhileParsingTypes(pkg)
  473. return nil
  474. }
  475. return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
  476. }
  477. // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
  478. func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
  479. p.expectKeyword("interface")
  480. var methods []*types.Func
  481. var typs []*types.Named
  482. p.expect('{')
  483. for p.tok != '}' && p.tok != scanner.EOF {
  484. if p.tok == '?' {
  485. p.next()
  486. typs = append(typs, p.parseType(pkg).(*types.Named))
  487. } else {
  488. method := p.parseFunc(pkg)
  489. methods = append(methods, method)
  490. }
  491. p.expect(';')
  492. }
  493. p.expect('}')
  494. return types.NewInterface(methods, typs)
  495. }
  496. // PointerType = "*" ("any" | Type) .
  497. func (p *parser) parsePointerType(pkg *types.Package) types.Type {
  498. p.expect('*')
  499. if p.tok == scanner.Ident {
  500. p.expectKeyword("any")
  501. return types.Typ[types.UnsafePointer]
  502. }
  503. return types.NewPointer(p.parseType(pkg))
  504. }
  505. // TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
  506. func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type {
  507. var t types.Type
  508. switch p.tok {
  509. case scanner.String:
  510. t = p.parseNamedType(n)
  511. case scanner.Ident:
  512. switch p.lit {
  513. case "map":
  514. t = p.parseMapType(pkg)
  515. case "chan":
  516. t = p.parseChanType(pkg)
  517. case "struct":
  518. t = p.parseStructType(pkg)
  519. case "interface":
  520. t = p.parseInterfaceType(pkg)
  521. }
  522. case '*':
  523. t = p.parsePointerType(pkg)
  524. case '[':
  525. t = p.parseArrayOrSliceType(pkg)
  526. case '(':
  527. t = p.parseFunctionType(pkg)
  528. }
  529. p.typeMap[n] = t
  530. return t
  531. }
  532. const (
  533. // From gofrontend/go/export.h
  534. // Note that these values are negative in the gofrontend and have been made positive
  535. // in the gccgoimporter.
  536. gccgoBuiltinINT8 = 1
  537. gccgoBuiltinINT16 = 2
  538. gccgoBuiltinINT32 = 3
  539. gccgoBuiltinINT64 = 4
  540. gccgoBuiltinUINT8 = 5
  541. gccgoBuiltinUINT16 = 6
  542. gccgoBuiltinUINT32 = 7
  543. gccgoBuiltinUINT64 = 8
  544. gccgoBuiltinFLOAT32 = 9
  545. gccgoBuiltinFLOAT64 = 10
  546. gccgoBuiltinINT = 11
  547. gccgoBuiltinUINT = 12
  548. gccgoBuiltinUINTPTR = 13
  549. gccgoBuiltinBOOL = 15
  550. gccgoBuiltinSTRING = 16
  551. gccgoBuiltinCOMPLEX64 = 17
  552. gccgoBuiltinCOMPLEX128 = 18
  553. gccgoBuiltinERROR = 19
  554. gccgoBuiltinBYTE = 20
  555. gccgoBuiltinRUNE = 21
  556. )
  557. func lookupBuiltinType(typ int) types.Type {
  558. return [...]types.Type{
  559. gccgoBuiltinINT8: types.Typ[types.Int8],
  560. gccgoBuiltinINT16: types.Typ[types.Int16],
  561. gccgoBuiltinINT32: types.Typ[types.Int32],
  562. gccgoBuiltinINT64: types.Typ[types.Int64],
  563. gccgoBuiltinUINT8: types.Typ[types.Uint8],
  564. gccgoBuiltinUINT16: types.Typ[types.Uint16],
  565. gccgoBuiltinUINT32: types.Typ[types.Uint32],
  566. gccgoBuiltinUINT64: types.Typ[types.Uint64],
  567. gccgoBuiltinFLOAT32: types.Typ[types.Float32],
  568. gccgoBuiltinFLOAT64: types.Typ[types.Float64],
  569. gccgoBuiltinINT: types.Typ[types.Int],
  570. gccgoBuiltinUINT: types.Typ[types.Uint],
  571. gccgoBuiltinUINTPTR: types.Typ[types.Uintptr],
  572. gccgoBuiltinBOOL: types.Typ[types.Bool],
  573. gccgoBuiltinSTRING: types.Typ[types.String],
  574. gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64],
  575. gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
  576. gccgoBuiltinERROR: types.Universe.Lookup("error").Type(),
  577. gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(),
  578. gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(),
  579. }[typ]
  580. }
  581. // Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
  582. func (p *parser) parseType(pkg *types.Package) (t types.Type) {
  583. p.expect('<')
  584. p.expectKeyword("type")
  585. switch p.tok {
  586. case scanner.Int:
  587. n := p.parseInt()
  588. if p.tok == '>' {
  589. t = p.typeMap[int(n)]
  590. } else {
  591. t = p.parseTypeDefinition(pkg, int(n))
  592. }
  593. case '-':
  594. p.next()
  595. n := p.parseInt()
  596. t = lookupBuiltinType(int(n))
  597. default:
  598. p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
  599. return nil
  600. }
  601. p.expect('>')
  602. return
  603. }
  604. // PackageInit = unquotedString unquotedString int .
  605. func (p *parser) parsePackageInit() PackageInit {
  606. name := p.parseUnquotedString()
  607. initfunc := p.parseUnquotedString()
  608. priority := int(p.parseInt())
  609. return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
  610. }
  611. // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
  612. func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
  613. for {
  614. switch p.tok {
  615. case ';':
  616. return
  617. case '<':
  618. p.parseType(p.pkg)
  619. case scanner.EOF:
  620. p.error("unexpected EOF")
  621. default:
  622. p.next()
  623. }
  624. }
  625. }
  626. // Create the package if we have parsed both the package path and package name.
  627. func (p *parser) maybeCreatePackage() {
  628. if p.pkgname != "" && p.pkgpath != "" {
  629. p.pkg = p.getPkg(p.pkgpath, p.pkgname)
  630. }
  631. }
  632. // InitDataDirective = "v1" ";" |
  633. // "priority" int ";" |
  634. // "init" { PackageInit } ";" |
  635. // "checksum" unquotedString ";" .
  636. func (p *parser) parseInitDataDirective() {
  637. if p.tok != scanner.Ident {
  638. // unexpected token kind; panic
  639. p.expect(scanner.Ident)
  640. }
  641. switch p.lit {
  642. case "v1":
  643. p.next()
  644. p.expect(';')
  645. case "priority":
  646. p.next()
  647. p.initdata.Priority = int(p.parseInt())
  648. p.expect(';')
  649. case "init":
  650. p.next()
  651. for p.tok != ';' && p.tok != scanner.EOF {
  652. p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
  653. }
  654. p.expect(';')
  655. case "checksum":
  656. // Don't let the scanner try to parse the checksum as a number.
  657. defer func(mode uint) {
  658. p.scanner.Mode = mode
  659. }(p.scanner.Mode)
  660. p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
  661. p.next()
  662. p.parseUnquotedString()
  663. p.expect(';')
  664. default:
  665. p.errorf("unexpected identifier: %q", p.lit)
  666. }
  667. }
  668. // Directive = InitDataDirective |
  669. // "package" unquotedString ";" |
  670. // "pkgpath" unquotedString ";" |
  671. // "import" unquotedString unquotedString string ";" |
  672. // "func" Func ";" |
  673. // "type" Type ";" |
  674. // "var" Var ";" |
  675. // "const" Const ";" .
  676. func (p *parser) parseDirective() {
  677. if p.tok != scanner.Ident {
  678. // unexpected token kind; panic
  679. p.expect(scanner.Ident)
  680. }
  681. switch p.lit {
  682. case "v1", "priority", "init", "checksum":
  683. p.parseInitDataDirective()
  684. case "package":
  685. p.next()
  686. p.pkgname = p.parseUnquotedString()
  687. p.maybeCreatePackage()
  688. p.expect(';')
  689. case "pkgpath":
  690. p.next()
  691. p.pkgpath = p.parseUnquotedString()
  692. p.maybeCreatePackage()
  693. p.expect(';')
  694. case "import":
  695. p.next()
  696. pkgname := p.parseUnquotedString()
  697. pkgpath := p.parseUnquotedString()
  698. p.getPkg(pkgpath, pkgname)
  699. p.parseString()
  700. p.expect(';')
  701. case "func":
  702. p.next()
  703. fun := p.parseFunc(p.pkg)
  704. if fun != nil {
  705. p.pkg.Scope().Insert(fun)
  706. }
  707. p.expect(';')
  708. case "type":
  709. p.next()
  710. p.parseType(p.pkg)
  711. p.expect(';')
  712. case "var":
  713. p.next()
  714. v := p.parseVar(p.pkg)
  715. p.pkg.Scope().Insert(v)
  716. p.expect(';')
  717. case "const":
  718. p.next()
  719. c := p.parseConst(p.pkg)
  720. p.pkg.Scope().Insert(c)
  721. p.expect(';')
  722. default:
  723. p.errorf("unexpected identifier: %q", p.lit)
  724. }
  725. }
  726. // Package = { Directive } .
  727. func (p *parser) parsePackage() *types.Package {
  728. for p.tok != scanner.EOF {
  729. p.parseDirective()
  730. }
  731. for _, typ := range p.typeMap {
  732. if it, ok := typ.(*types.Interface); ok {
  733. it.Complete()
  734. }
  735. }
  736. p.pkg.MarkComplete()
  737. return p.pkg
  738. }
  739. // InitData = { InitDataDirective } .
  740. func (p *parser) parseInitData() {
  741. for p.tok != scanner.EOF {
  742. p.parseInitDataDirective()
  743. }
  744. }