type_register.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. package checker
  2. import (
  3. "sort"
  4. "strings"
  5. "kumachan/standalone/util"
  6. "kumachan/interpreter/lang/ast"
  7. "kumachan/interpreter/lang/common/name"
  8. "kumachan/interpreter/lang/common/limits"
  9. "kumachan/interpreter/lang/common/source"
  10. "kumachan/interpreter/lang/common/attr"
  11. "kumachan/interpreter/compiler/loader"
  12. "kumachan/interpreter/compiler/checker/typsys"
  13. )
  14. type TypeRegistry (map[name.TypeName] TypeDef)
  15. type typeList ([] TypeDef)
  16. type TypeDef struct {
  17. *typsys.TypeDef
  18. AstNode *ast.DeclType
  19. }
  20. func (l typeList) Less(i int, j int) bool {
  21. var u = l[i].Name
  22. var v = l[j].Name
  23. if u.ModuleName < v.ModuleName {
  24. return true
  25. } else if u.ModuleName == v.ModuleName {
  26. return (u.ItemName < v.ItemName)
  27. } else {
  28. return false
  29. }
  30. }
  31. func (l typeList) Len() int {
  32. return len(l)
  33. }
  34. func (l typeList) Swap(i int, j int) {
  35. var I = &(l[i])
  36. var J = &(l[j])
  37. var t = *I
  38. *I = *J
  39. *J = t
  40. }
  41. var defaultInit, defaultWrite = (func() (typsys.Type, func(typsys.Type)(typsys.Type)) {
  42. return nil,
  43. func(t typsys.Type) typsys.Type { return t }
  44. })()
  45. var contentInit, contentWrite = (func() (typsys.TypeDefContent, func(typsys.TypeDefContent)(typsys.TypeDefContent)) {
  46. return nil,
  47. func(c typsys.TypeDefContent) typsys.TypeDefContent { return c }
  48. })()
  49. func collectTypes (
  50. entry *loader.Module,
  51. mic ModuleInfoCollection,
  52. ) (TypeRegistry, typeList, source.Errors) {
  53. var step_ = func(types typeList) (func(func(TypeDef)(*source.Error)) source.Errors) {
  54. return func(f func(TypeDef) *source.Error) source.Errors {
  55. var errs source.Errors
  56. for _, def := range types {
  57. source.ErrorsJoin(&errs, f(def))
  58. }
  59. return errs
  60. }
  61. }
  62. var check = func() (struct{}, func(func()(source.Errors)) source.Errors) {
  63. return struct{}{}, func(f func()(source.Errors)) source.Errors {
  64. return f()
  65. }
  66. }
  67. // ************************
  68. // --- register types ---
  69. var reg = make(TypeRegistry)
  70. var mvs = make(ModuleVisitedSet)
  71. { var err = registerTypes(entry, mic, mvs, reg)
  72. if err != nil {
  73. return nil, nil, err
  74. } }
  75. // --- create an ordered type definition list ---
  76. var types = make(typeList, 0, len(reg))
  77. for _, def := range reg {
  78. types = append(types, def)
  79. }
  80. sort.Sort(types)
  81. // ************************
  82. // --- main steps ---
  83. var step = step_(types)
  84. // 1. fill implemented interface list
  85. // (1) a type cannot have two or more identical implemented types.
  86. // (2) an implemented type must be an interface type.
  87. // (3) compatible parameters are required for implemented interfaces.
  88. var step1_fill_impl = step
  89. // 2. construct default parameter types
  90. // (1) construct the default type for each type parameter.
  91. var step2_construct_default = step
  92. // 3. construct contents
  93. // (1) construct the inner type for each box type.
  94. // (2) construct the methods record for each interface type.
  95. // (3) contents of enum types should have been constructed.
  96. // (4) construct a unique content for each native type.
  97. var step3_construct_content = step
  98. // --- additional checks ---
  99. // 1. check for circular definition
  100. // (1) a box must NOT unbox to a ref to itself directly or indirectly.
  101. // (2) an interface must NOT include itself directly or indirectly.
  102. var must_check_circular_box, check1_circular_box = check()
  103. var must_check_circular_interface, check2_circular_interface = check()
  104. // 2. check for variance validity
  105. // (1) variance defined on parameters of a box must be valid.
  106. // (2) variance defined on parameters of an interface must be valid.
  107. var must_check_boxed_variance, check3_boxed_variance = check()
  108. var must_check_interface_variance, check4_interface_variance = check()
  109. // ************************
  110. { var err = step1_fill_impl(func(def TypeDef) *source.Error {
  111. var num_impl = uint(len(def.AstNode.Impl))
  112. if num_impl > limits.MaxImplemented {
  113. return source.MakeError(def.Location,
  114. E_TooManyImplemented { SizeLimitError {
  115. Given: num_impl,
  116. Limit: limits.MaxImplemented,
  117. }})
  118. }
  119. var impl_names = make([] name.TypeName, len(def.AstNode.Impl))
  120. for i, ref := range def.AstNode.Impl {
  121. var mi = mic.GetTypeModuleInfo(def)
  122. var n, err = NameFrom(ref.Module, ref.Item,mi)
  123. if err != nil { return err }
  124. impl_names[i] = name.TypeName {
  125. Name: n,
  126. }
  127. }
  128. var impl_defs = make([] *typsys.TypeDef, len(impl_names))
  129. var occurred_names = make(map[name.TypeName] struct{})
  130. for i, n := range impl_names {
  131. var ctx = TypeConsContext {
  132. ModInfo: mic.GetTypeModuleInfo(def),
  133. TypeReg: reg,
  134. }
  135. var loc = def.AstNode.Impl[i].Location
  136. var _, occurred = occurred_names[n]
  137. if occurred {
  138. return source.MakeError(loc,
  139. E_DuplicateImplemented { Which: n.String() })
  140. }
  141. occurred_names[n] = struct{}{}
  142. var impl_def, n_desc, exists = ctx.ResolveTypeDefName(n.Name)
  143. if !(exists) {
  144. return source.MakeError(loc,
  145. E_TypeNotFound { Which: n_desc() })
  146. }
  147. var ok = (func() bool {
  148. var ast_content, specified = impl_def.AstNode.TypeDef.(ast.VariousTypeDef)
  149. if !(specified) { return false }
  150. var _, ok = ast_content.TypeDef.(ast.InterfaceType)
  151. return ok
  152. })()
  153. if !(ok) {
  154. return source.MakeError(loc,
  155. E_BadImplemented { Which: n.String() })
  156. }
  157. var impl_params = impl_def.Parameters
  158. if len(impl_params) != len(def.Parameters) {
  159. return source.MakeError(loc,
  160. E_ImplementedIncompatibleParameters {
  161. TypeName: def.Name.String(),
  162. InterfaceName: n.String(),
  163. })
  164. }
  165. for j := range impl_params {
  166. var vi = impl_params[j].Variance
  167. var v = def.Parameters[j].Variance
  168. if vi != typsys.Invariant && v != vi {
  169. return source.MakeError(loc,
  170. E_ImplementedIncompatibleParameters {
  171. TypeName: def.Name.String(),
  172. InterfaceName: n.String(),
  173. })
  174. }
  175. }
  176. impl_defs[i] = impl_def.TypeDef
  177. }
  178. def.Implements = impl_defs
  179. return nil
  180. })
  181. if err != nil { return nil, nil, err } }
  182. // ---------
  183. { var err = step2_construct_default(func(def TypeDef) *source.Error {
  184. var ctx = TypeConsContext {
  185. ModInfo: mic.GetTypeModuleInfo(def),
  186. TypeReg: reg,
  187. }
  188. var defaults = make([] struct { *typsys.Parameter; typsys.Type }, 0)
  189. var err = def.ForEachParameter(func(i uint, p *typsys.Parameter) *source.Error {
  190. var p_node = (func() *ast.TypeParam {
  191. if def.Enum != nil {
  192. return &(def.CaseParams[i])
  193. } else {
  194. return &(def.AstNode.Params[i])
  195. }
  196. })()
  197. var default_, has_default = p_node.Default.(ast.VariousType)
  198. if has_default {
  199. var t, err = newType(default_, ctx)
  200. if err != nil { return err }
  201. defaults = append(defaults, struct { *typsys.Parameter; typsys.Type } {
  202. Parameter: p,
  203. Type: t,
  204. })
  205. }
  206. return nil
  207. })
  208. if err != nil { return err }
  209. // note: write all at once (avoid interference)
  210. for _, item := range defaults {
  211. item.Parameter.Default = defaultWrite(item.Type)
  212. }
  213. return nil
  214. })
  215. if err != nil { return nil, nil, err } }
  216. // ---------
  217. { var err = step3_construct_content(func(def TypeDef) *source.Error {
  218. var ctx = TypeConsContext {
  219. ModInfo: mic.GetTypeModuleInfo(def),
  220. TypeReg: reg,
  221. ParamVec: def.Parameters,
  222. }
  223. var content_node, _ = def.AstNode.TypeDef.(ast.VariousTypeDef)
  224. var content, err = (func() (typsys.TypeDefContent, *source.Error) {
  225. switch content := content_node.TypeDef.(type) {
  226. case nil:
  227. return &typsys.Box {
  228. BoxKind: typsys.Isomorphic,
  229. WeakWrapping: false,
  230. InnerType: typsys.UnitType {},
  231. }, nil
  232. case ast.BoxedType:
  233. var kind = typsys.Isomorphic
  234. if content.Protected { kind = typsys.Protected }
  235. if content.Opaque { kind = typsys.Opaque }
  236. var weak = content.Weak
  237. var inner, err = newType(content.Inner, ctx)
  238. if err != nil { return nil, err }
  239. _ = must_check_circular_box
  240. _ = must_check_boxed_variance
  241. return &typsys.Box {
  242. BoxKind: kind,
  243. WeakWrapping: weak,
  244. InnerType: inner,
  245. }, nil
  246. case ast.InterfaceType:
  247. var methods_t, err = newTypeFromRepr(content.Methods, ctx)
  248. if err != nil { return nil, err }
  249. var methods = methods_t.(*typsys.NestedType).Content.(typsys.Record)
  250. var included = make([] *typsys.Interface, len(def.Implements))
  251. for i, impl_def := range def.Implements {
  252. included[i] = impl_def.Content.(*typsys.Interface)
  253. }
  254. var num_methods = uint(len(methods.Fields))
  255. if num_methods > limits.MaxInterfaceSize {
  256. return nil, source.MakeError(def.AstNode.Location,
  257. E_TooManyInterfaceMethods { SizeLimitError {
  258. Given: num_methods,
  259. Limit: limits.MaxInterfaceSize,
  260. }})
  261. }
  262. _ = must_check_circular_interface
  263. _ = must_check_interface_variance
  264. return &typsys.Interface { Methods: methods }, nil
  265. case ast.EnumType:
  266. // content already generated
  267. if def.Content == nil { panic("something went wrong") }
  268. return def.Content, nil
  269. case ast.NativeType:
  270. return &typsys.Native {}, nil
  271. default:
  272. panic("impossible branch")
  273. }
  274. })()
  275. if err != nil { return err }
  276. def.Content = contentWrite(content)
  277. return nil
  278. })
  279. if err != nil { return nil, nil, err } }
  280. // ************************
  281. var check_circular = func(get_deps func(*typsys.TypeDef)([] *typsys.TypeDef)) ([] *typsys.TypeDef) {
  282. var dep_vector = make(map[*typsys.TypeDef] ([] *typsys.TypeDef))
  283. var dep_quantity = make(map[*typsys.TypeDef] uint)
  284. var q = make([] *typsys.TypeDef, 0)
  285. for _, item := range types {
  286. var x = item.TypeDef
  287. var deps = get_deps(x)
  288. dep_vector[x] = deps
  289. dep_quantity[x] = uint(len(deps))
  290. }
  291. for _, item := range types {
  292. var x = item.TypeDef
  293. if dep_quantity[x] == 0 {
  294. q = append(q, x)
  295. }
  296. }
  297. for len(q) > 0 {
  298. var x = q[0]
  299. q = q[1:]
  300. for _, item := range types {
  301. var y = item.TypeDef
  302. var y_deps = dep_vector[y]
  303. var y_deps_x = false
  304. for _, y_dep := range y_deps {
  305. if y_dep == x {
  306. y_deps_x = true
  307. break
  308. }
  309. }
  310. if y_deps_x {
  311. dep_quantity[y] --
  312. if dep_quantity[y] == 0 {
  313. q = append(q, y)
  314. }
  315. }
  316. }
  317. }
  318. var bad = make([] *typsys.TypeDef, 0)
  319. for _, item := range types {
  320. var x = item.TypeDef
  321. if dep_quantity[x] > 0 {
  322. bad = append(bad, x)
  323. }
  324. }
  325. return bad
  326. }
  327. var defs_to_strings = func(defs ([] *typsys.TypeDef)) ([] string) {
  328. var result = make([] string, len(defs))
  329. for i, def := range defs {
  330. result[i] = def.Name.String()
  331. }
  332. return result
  333. }
  334. // ---------
  335. { var errs source.Errors
  336. { var err = check1_circular_box(func() source.Errors {
  337. var bad = check_circular(func(def *typsys.TypeDef) ([] *typsys.TypeDef) {
  338. var box, is_box = def.Content.(*typsys.Box)
  339. if is_box {
  340. var nested, is_nested = box.InnerType.(*typsys.NestedType)
  341. if is_nested {
  342. var ref, is_ref = nested.Content.(typsys.Ref)
  343. if is_ref {
  344. return [] *typsys.TypeDef { ref.Def }
  345. }
  346. }
  347. }
  348. return nil
  349. })
  350. if len(bad) > 0 {
  351. var err = source.MakeError(bad[0].Location,
  352. E_CircularSubtypingDefinition { Which: defs_to_strings(bad) })
  353. return source.ErrorsFrom(err)
  354. } else {
  355. return nil
  356. }
  357. })
  358. source.ErrorsJoinAll(&errs, err) }
  359. // ---------
  360. { var err = check2_circular_interface(func() source.Errors {
  361. var bad = check_circular(func(def *typsys.TypeDef) ([] *typsys.TypeDef) {
  362. var _, is_interface = def.Content.(*typsys.Interface)
  363. if is_interface {
  364. return def.Implements
  365. } else {
  366. return nil
  367. }
  368. })
  369. if len(bad) > 0 {
  370. var err = source.MakeError(bad[0].Location,
  371. E_CircularInterfaceDefinition { Which: defs_to_strings(bad) })
  372. return source.ErrorsFrom(err)
  373. } else {
  374. return nil
  375. }
  376. })
  377. source.ErrorsJoinAll(&errs, err) }
  378. // ---------
  379. { var err = check3_boxed_variance(func() source.Errors {
  380. var errs source.Errors
  381. for _, def := range types {
  382. var box, is_box = def.Content.(*typsys.Box)
  383. if is_box {
  384. var v = typsys.GetAllVariance(box.InnerType, def.Parameters)
  385. var ok, invalid = typsys.MatchVariance(def.Parameters, v)
  386. if !(ok) {
  387. var loc = def.AstNode.Name.Location
  388. var err = source.MakeError(loc,
  389. E_InvalidVarianceOnParameters { Which: invalid })
  390. source.ErrorsJoin(&errs, err)
  391. }
  392. }
  393. }
  394. return errs
  395. })
  396. source.ErrorsJoinAll(&errs, err) }
  397. // ---------
  398. { var err = check4_interface_variance(func() source.Errors {
  399. var errs source.Errors
  400. for _, def := range types {
  401. var interface_, is_interface = def.Content.(*typsys.Interface)
  402. if is_interface {
  403. var t = &typsys.NestedType { Content: interface_.Methods }
  404. var v = typsys.GetAllVariance(t, def.Parameters)
  405. var ok, invalid = typsys.MatchVariance(def.Parameters, v)
  406. if !(ok) {
  407. var loc = def.AstNode.Name.Location
  408. var err = source.MakeError(loc,
  409. E_InvalidVarianceOnParameters { Which: invalid })
  410. source.ErrorsJoin(&errs, err)
  411. }
  412. }
  413. }
  414. return errs
  415. })
  416. source.ErrorsJoinAll(&errs, err) }
  417. if errs != nil { return nil, nil, errs } }
  418. // ---------
  419. return reg, types, nil
  420. }
  421. func registerTypes (
  422. mod *loader.Module,
  423. mic ModuleInfoCollection,
  424. mvs ModuleVisitedSet,
  425. reg TypeRegistry,
  426. ) source.Errors {
  427. return traverseStatements(mod, mic, mvs, func(stmt ast.VariousStatement, mi *ModuleInfo) *source.Error {
  428. var decl, is_type_decl = stmt.Statement.(ast.DeclType)
  429. if !(is_type_decl) { return nil }
  430. var _, err = registerType(&decl, mi, reg, (typsys.CaseInfo {}))
  431. return err
  432. })
  433. }
  434. func registerType (
  435. decl *ast.DeclType,
  436. mi *ModuleInfo,
  437. reg TypeRegistry,
  438. ci typsys.CaseInfo,
  439. ) (*typsys.TypeDef, *source.Error) {
  440. var loc = decl.Name.Location
  441. var type_item_name = ast.Id2String(decl.Name)
  442. if !(isValidTypeItemName(type_item_name)) {
  443. return nil, source.MakeError(loc,
  444. E_InvalidTypeName { Name: type_item_name })
  445. }
  446. var type_name = name.MakeTypeName(mi.ModName, type_item_name)
  447. var _, exists = reg[type_name]
  448. if exists {
  449. return nil, source.MakeError(loc,
  450. E_DuplicateTypeDefinition { Which: type_name.String() })
  451. }
  452. var def = new(typsys.TypeDef)
  453. reg[type_name] = TypeDef {
  454. TypeDef: def,
  455. AstNode: decl,
  456. }
  457. var doc = ast.GetDocContent(decl.Docs)
  458. var meta attr.TypeMetadata
  459. var meta_text = ast.GetMetadataContent(decl.Meta)
  460. var meta_err = util.UnmarshalJsonAllowEmpty(meta_text, &meta)
  461. if meta_err != nil {
  462. return nil, source.MakeError(decl.Meta.Location,
  463. E_InvalidMetadata { Reason: meta_err.Error() })
  464. }
  465. var data_config attr.TypeDataConfig
  466. var service_config attr.TypeServiceConfig
  467. { if strings.HasPrefix(type_item_name, "#") {
  468. var is_interface = (func() bool {
  469. var ast_content, ok = decl.TypeDef.(ast.VariousTypeDef)
  470. if !(ok) { return false }
  471. var _, is_interface = ast_content.TypeDef.(ast.InterfaceType)
  472. return is_interface
  473. })()
  474. if is_interface {
  475. service_config.Name = strings.TrimPrefix(type_item_name, "#")
  476. } else {
  477. data_config.Name = strings.TrimPrefix(type_item_name, "#")
  478. }
  479. } }
  480. var attrs = attr.TypeAttrs {
  481. Attrs: attr.Attrs {
  482. Location: decl.Location,
  483. Doc: doc,
  484. },
  485. Metadata: meta,
  486. DataConfig: data_config,
  487. ServiceConfig: service_config,
  488. }
  489. var params, params_err = (func() ([] typsys.Parameter, *source.Error) {
  490. if ci.Enum != nil {
  491. if len(decl.Params) > 0 {
  492. return nil, source.MakeError(loc,
  493. E_TypeParametersOnCaseType {})
  494. }
  495. return ci.Enum.Parameters, nil
  496. } else {
  497. var arity = len(decl.Params)
  498. if arity > limits.MaxTypeParameters {
  499. return nil, source.MakeError(loc,
  500. E_TooManyTypeParameters { SizeLimitError {
  501. Given: uint(arity),
  502. Limit: limits.MaxTypeParameters,
  503. }})
  504. }
  505. var params = make([] typsys.Parameter, arity)
  506. for i, p := range decl.Params {
  507. if p.In && p.Out { panic("something went wrong") }
  508. var v = typsys.Invariant
  509. if p.In {
  510. v = typsys.Contravariant
  511. }
  512. if p.Out {
  513. v = typsys.Covariant
  514. }
  515. var p_name = ast.Id2String(p.Name)
  516. if !(isValidTypeItemName(p_name)) {
  517. return nil, source.MakeError(p.Name.Location,
  518. E_InvalidTypeName { Name: p_name })
  519. }
  520. params[i] = typsys.Parameter {
  521. Name: p_name,
  522. Default: defaultInit,
  523. Variance: v,
  524. }
  525. }
  526. return params, nil
  527. }
  528. })()
  529. if params_err != nil { return nil, params_err }
  530. *def = typsys.TypeDef {
  531. TypeAttrs: attrs,
  532. Name: type_name,
  533. Parameters: params,
  534. Content: contentInit,
  535. CaseInfo: ci,
  536. }
  537. var enum, is_enum = (func() (ast.EnumType, bool) {
  538. var ast_content, specified = decl.TypeDef.(ast.VariousTypeDef)
  539. if !(specified) { return ast.EnumType {}, false }
  540. var enum, is_enum = ast_content.TypeDef.(ast.EnumType)
  541. return enum, is_enum
  542. })()
  543. var case_defs = make([] *typsys.TypeDef, len(enum.Cases))
  544. if is_enum {
  545. var num_cases = uint(len(enum.Cases))
  546. if num_cases > limits.MaxEnumSize {
  547. return nil, source.MakeError(enum.Location,
  548. E_TooManyEnumCases { SizeLimitError {
  549. Given: num_cases,
  550. Limit: limits.MaxEnumSize,
  551. }})
  552. }
  553. for i := range enum.Cases {
  554. var c = &(enum.Cases[i])
  555. var param_nodes = (func() ([] ast.TypeParam) {
  556. if ci.Enum != nil {
  557. return ci.CaseParams
  558. } else {
  559. return decl.Params
  560. }
  561. })()
  562. var ct, err = registerType(c, mi, reg, typsys.CaseInfo {
  563. Enum: def,
  564. CaseIndex: uint(i),
  565. CaseParams: param_nodes, // required for default type creation
  566. })
  567. case_defs[i] = ct
  568. if err != nil { return nil, err }
  569. }
  570. def.Content = contentWrite(&typsys.Enum {
  571. CaseTypes: case_defs,
  572. })
  573. }
  574. return def, nil
  575. }