Browse Source

add TypeByPackageName

Tao Wen 7 năm trước cách đây
mục cha
commit
0b92968f4b
2 tập tin đã thay đổi với 40 bổ sung3 xóa
  1. 34 3
      type_map.go
  2. 6 0
      type_map_test.go

+ 34 - 3
type_map.go

@@ -16,6 +16,7 @@ func typelinks1() [][]unsafe.Pointer
 func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
 
 var types = map[string]reflect.Type{}
+var packages = map[string]map[string]reflect.Type{}
 
 func init() {
 	ver := runtime.Version()
@@ -36,11 +37,25 @@ func loadGo15Types() {
 			(*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr
 			typ := obj.(reflect.Type)
 			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
-				types[typ.Elem().String()] = typ.Elem()
+				loadedType := typ.Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
 			}
 			if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr &&
 				typ.Elem().Elem().Kind() == reflect.Struct {
-				types[typ.Elem().Elem().String()] = typ.Elem().Elem()
+				loadedType := typ.Elem().Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
 			}
 		}
 	}
@@ -55,7 +70,14 @@ func loadGo17Types() {
 			(*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off)
 			typ := obj.(reflect.Type)
 			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
-				types[typ.Elem().String()] = typ.Elem()
+				loadedType := typ.Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
 			}
 		}
 	}
@@ -70,3 +92,12 @@ type emptyInterface struct {
 func TypeByName(typeName string) Type {
 	return Type2(types[typeName])
 }
+
+// TypeByPackageName return the type by its package and name
+func TypeByPackageName(pkgPath string, name string) Type {
+	pkgTypes := packages[pkgPath]
+	if pkgTypes == nil {
+		return nil
+	}
+	return Type2(pkgTypes[name])
+}

+ 6 - 0
type_map_test.go

@@ -14,4 +14,10 @@ func TestTypeByName(t *testing.T) {
 	if typByName != typByPtr {
 		t.Fail()
 	}
+	typByPkg := reflect2.TypeByPackageName(
+		"github.com/modern-go/reflect2_test",
+		"MyStruct")
+	if typByPkg != typByPtr {
+		t.Fail()
+	}
 }