envTypes.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package env
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. )
  7. // DefineType defines type in current scope.
  8. func (e *Env) DefineType(symbol string, aType interface{}) error {
  9. var reflectType reflect.Type
  10. if aType == nil {
  11. reflectType = NilType
  12. } else {
  13. var ok bool
  14. reflectType, ok = aType.(reflect.Type)
  15. if !ok {
  16. reflectType = reflect.TypeOf(aType)
  17. }
  18. }
  19. return e.DefineReflectType(symbol, reflectType)
  20. }
  21. // DefineReflectType defines type in current scope.
  22. func (e *Env) DefineReflectType(symbol string, reflectType reflect.Type) error {
  23. if strings.Contains(symbol, ".") {
  24. return ErrSymbolContainsDot
  25. }
  26. e.rwMutex.Lock()
  27. if e.types == nil {
  28. e.types = make(map[string]reflect.Type)
  29. }
  30. e.types[symbol] = reflectType
  31. e.rwMutex.Unlock()
  32. return nil
  33. }
  34. // DefineGlobalType defines type in global scope.
  35. func (e *Env) DefineGlobalType(symbol string, aType interface{}) error {
  36. for e.parent != nil {
  37. e = e.parent
  38. }
  39. return e.DefineType(symbol, aType)
  40. }
  41. // DefineGlobalReflectType defines type in global scope.
  42. func (e *Env) DefineGlobalReflectType(symbol string, reflectType reflect.Type) error {
  43. for e.parent != nil {
  44. e = e.parent
  45. }
  46. return e.DefineReflectType(symbol, reflectType)
  47. }
  48. // Type returns reflect type from the scope where symbol is frist found.
  49. func (e *Env) Type(symbol string) (reflect.Type, error) {
  50. e.rwMutex.RLock()
  51. reflectType, ok := e.types[symbol]
  52. e.rwMutex.RUnlock()
  53. if ok {
  54. return reflectType, nil
  55. }
  56. if e.externalLookup != nil {
  57. var err error
  58. reflectType, err = e.externalLookup.Type(symbol)
  59. if err == nil {
  60. return reflectType, nil
  61. }
  62. }
  63. if e.parent == nil {
  64. reflectType, ok = basicTypes[symbol]
  65. if ok {
  66. return reflectType, nil
  67. }
  68. return NilType, fmt.Errorf("undefined type '%s'", symbol)
  69. }
  70. return e.parent.Type(symbol)
  71. }