error.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package loader
  2. import (
  3. . "kumachan/error"
  4. "kumachan/parser"
  5. "os"
  6. )
  7. type Context struct {
  8. ImportPoint MaybeErrorPoint
  9. LocalAlias string
  10. BreadCrumbs [] Ancestor
  11. }
  12. type Ancestor struct {
  13. ModuleName string
  14. FileInfo os.FileInfo
  15. FilePath string
  16. }
  17. func MakeEntryContext() Context {
  18. return Context {
  19. ImportPoint: nil,
  20. BreadCrumbs: make([]Ancestor, 0),
  21. }
  22. }
  23. func (ctx Context) GetErrorDescription() ErrorMessage {
  24. var _, ok = ctx.ImportPoint.(ErrorPoint)
  25. if ok {
  26. var desc = make(ErrorMessage, 0)
  27. desc.WriteText(TS_ERROR, "Unable to import module")
  28. desc.Write(T_SPACE)
  29. desc.WriteText(TS_INLINE_CODE, ctx.LocalAlias)
  30. return desc
  31. } else {
  32. var msg = make(ErrorMessage, 0)
  33. msg.WriteText(TS_ERROR, "*** Unable to load given source file")
  34. return msg
  35. }
  36. }
  37. func (ctx Context) GetFullErrorMessage(detail ErrorMessage) ErrorMessage {
  38. var desc = ctx.GetErrorDescription()
  39. desc.Write(T_LF)
  40. desc.WriteAll(detail)
  41. var p, ok = ctx.ImportPoint.(ErrorPoint)
  42. if ok {
  43. return FormatErrorAt(p, desc)
  44. } else {
  45. return desc
  46. }
  47. }
  48. type Error struct {
  49. Context Context
  50. Concrete ConcreteError
  51. }
  52. type ConcreteError interface { LoaderError() }
  53. func (e E_ReadFileFailed) LoaderError() {}
  54. type E_ReadFileFailed struct {
  55. FilePath string
  56. Message string
  57. }
  58. func (e E_ParseFailed) LoaderError() {}
  59. type E_ParseFailed struct {
  60. ParserError *parser.Error
  61. }
  62. func (e E_NameConflict) LoaderError() {}
  63. type E_NameConflict struct {
  64. ModuleName string
  65. FilePath1 string
  66. FilePath2 string
  67. }
  68. func (e E_CircularImport) LoaderError() {}
  69. type E_CircularImport struct {
  70. ModuleName string
  71. }
  72. func (e E_ConflictAlias) LoaderError() {}
  73. type E_ConflictAlias struct {
  74. LocalAlias string
  75. }
  76. func (e E_DuplicateImport) LoaderError() {}
  77. type E_DuplicateImport struct {
  78. ModuleName string
  79. }
  80. func (err *Error) Desc() ErrorMessage {
  81. var msg = make(ErrorMessage, 0)
  82. msg.WriteText(TS_NORMAL, "**\n")
  83. switch e := err.Concrete.(type) {
  84. case E_ReadFileFailed:
  85. msg.WriteText(TS_ERROR, "Cannot open source file:")
  86. msg.WriteEndText(TS_ERROR, e.Message)
  87. case E_ParseFailed:
  88. msg.WriteAll(e.ParserError.Message())
  89. case E_NameConflict:
  90. msg.WriteText(TS_ERROR, "The module name")
  91. msg.WriteInnerText(TS_INLINE_CODE, e.ModuleName)
  92. msg.WriteText(TS_ERROR, "is used by both source files")
  93. msg.WriteInnerText(TS_INLINE, e.FilePath2)
  94. msg.WriteText(TS_ERROR, "and")
  95. msg.WriteEndText(TS_INLINE, e.FilePath1)
  96. case E_CircularImport:
  97. msg.WriteText(TS_ERROR, "Circular import of module")
  98. msg.WriteEndText(TS_INLINE_CODE, e.ModuleName)
  99. case E_ConflictAlias:
  100. msg.WriteText(TS_ERROR, "A module already imported as name")
  101. msg.WriteInnerText(TS_INLINE_CODE, e.LocalAlias)
  102. msg.WriteText(TS_ERROR, "in current module")
  103. case E_DuplicateImport:
  104. msg.WriteText(TS_ERROR, "Duplicate import of module")
  105. msg.WriteInnerText(TS_INLINE_CODE, e.ModuleName)
  106. default:
  107. panic("unknown error kind")
  108. }
  109. return msg
  110. }
  111. func (err *Error) Message() ErrorMessage {
  112. return err.Context.GetFullErrorMessage(err.Desc())
  113. }
  114. func (err *Error) Error() string {
  115. var msg = MsgFailedToCompile(err.Concrete, []ErrorMessage {
  116. err.Message(),
  117. })
  118. return msg.String()
  119. }