GoFullTypeName returns the Go type name of the given data type qualified with the given package name if applicable and if not the empty string.
(att *expr.AttributeExpr, pkg string)
| 294 | // GoFullTypeName returns the Go type name of the given data type qualified with |
| 295 | // the given package name if applicable and if not the empty string. |
| 296 | func (s *NameScope) GoFullTypeName(att *expr.AttributeExpr, pkg string) string { |
| 297 | switch actual := att.Type.(type) { |
| 298 | case expr.Primitive: |
| 299 | if t, _ := GetMetaType(att); t != "" { |
| 300 | return t |
| 301 | } |
| 302 | return GoNativeTypeName(actual) |
| 303 | case *expr.Array: |
| 304 | return "[]" + s.GoFullTypeRef(actual.ElemType, pkgWithDefault(actual.ElemType.Type, pkg)) |
| 305 | case *expr.Map: |
| 306 | return fmt.Sprintf("map[%s]%s", |
| 307 | s.GoFullTypeRef(actual.KeyType, pkgWithDefault(actual.KeyType.Type, pkg)), |
| 308 | s.GoFullTypeRef(actual.ElemType, pkgWithDefault(actual.ElemType.Type, pkg))) |
| 309 | case *expr.Object: |
| 310 | return s.GoTypeDef(att, false, false) |
| 311 | case expr.UserType, *expr.Union: |
| 312 | if actual == expr.ErrorResult { |
| 313 | return "goa.ServiceError" |
| 314 | } |
| 315 | // Qualified type references (pkg.Type) do not compete in the local |
| 316 | // identifier namespace. |
| 317 | // |
| 318 | // When generating qualified references, we must not blindly apply local |
| 319 | // scoping (suffixing) to the referenced type name, otherwise we can emit |
| 320 | // identifiers that do not exist in the referenced package (e.g., pkg.Foo2). |
| 321 | // |
| 322 | // However, when the scope already assigned a unique name to the referenced |
| 323 | // type (i.e., the type is defined in this scope and got suffixed due to a |
| 324 | // collision), qualified references must use that assigned name to stay |
| 325 | // consistent across packages. This is critical for transport packages that |
| 326 | // refer to types defined in the service package (e.g., grpc referencing a |
| 327 | // payload type defined as Request2). |
| 328 | base := Goify(actual.Name(), true) |
| 329 | if pkg == "" { |
| 330 | return s.HashedUnique(actual, base, "") |
| 331 | } |
| 332 | if UserTypeLocation(actual) == nil { |
| 333 | if n, ok := s.names[actual.Hash()]; ok { |
| 334 | return pkg + "." + n |
| 335 | } |
| 336 | } |
| 337 | return pkg + "." + base |
| 338 | case expr.CompositeExpr: |
| 339 | return s.GoFullTypeName(actual.Attribute(), pkgWithDefault(actual.Attribute().Type, pkg)) |
| 340 | default: |
| 341 | panic(fmt.Sprintf("unknown data type %T", actual)) // bug |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | // pkgWithDefault returns the package defining the given type. If the types is a |
| 346 | // user type with "struct:pkg:path" metadata then it returns the corresponding |