github.com/mattn/anko@v0.1.10/env/envTypes.go (about) 1 package env 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 ) 8 9 // DefineType defines type in current scope. 10 func (e *Env) DefineType(symbol string, aType interface{}) error { 11 var reflectType reflect.Type 12 if aType == nil { 13 reflectType = NilType 14 } else { 15 var ok bool 16 reflectType, ok = aType.(reflect.Type) 17 if !ok { 18 reflectType = reflect.TypeOf(aType) 19 } 20 } 21 22 return e.DefineReflectType(symbol, reflectType) 23 } 24 25 // DefineReflectType defines type in current scope. 26 func (e *Env) DefineReflectType(symbol string, reflectType reflect.Type) error { 27 if strings.Contains(symbol, ".") { 28 return ErrSymbolContainsDot 29 } 30 31 e.rwMutex.Lock() 32 if e.types == nil { 33 e.types = make(map[string]reflect.Type) 34 } 35 e.types[symbol] = reflectType 36 e.rwMutex.Unlock() 37 38 return nil 39 } 40 41 // DefineGlobalType defines type in global scope. 42 func (e *Env) DefineGlobalType(symbol string, aType interface{}) error { 43 for e.parent != nil { 44 e = e.parent 45 } 46 return e.DefineType(symbol, aType) 47 } 48 49 // DefineGlobalReflectType defines type in global scope. 50 func (e *Env) DefineGlobalReflectType(symbol string, reflectType reflect.Type) error { 51 for e.parent != nil { 52 e = e.parent 53 } 54 return e.DefineReflectType(symbol, reflectType) 55 } 56 57 // Type returns reflect type from the scope where symbol is frist found. 58 func (e *Env) Type(symbol string) (reflect.Type, error) { 59 e.rwMutex.RLock() 60 reflectType, ok := e.types[symbol] 61 e.rwMutex.RUnlock() 62 if ok { 63 return reflectType, nil 64 } 65 66 if e.externalLookup != nil { 67 var err error 68 reflectType, err = e.externalLookup.Type(symbol) 69 if err == nil { 70 return reflectType, nil 71 } 72 } 73 74 if e.parent == nil { 75 reflectType, ok = basicTypes[symbol] 76 if ok { 77 return reflectType, nil 78 } 79 return NilType, fmt.Errorf("undefined type '%s'", symbol) 80 } 81 82 return e.parent.Type(symbol) 83 } 84 85 86 // GetValueSymbols returns all value symbol in the current scope. 87 func (e *Env) GetTypeSymbols() []string { 88 symbols := make([]string, 0, len(e.values)) 89 e.rwMutex.RLock() 90 for symbol := range e.types { 91 symbols = append(symbols, symbol) 92 } 93 e.rwMutex.RUnlock() 94 return symbols 95 }