MCPcopy Create free account
hub / github.com/goadesign/goa / collectProjectedTypes

Function collectProjectedTypes

codegen/service/service_data.go:1831–1883  ·  view source on GitHub ↗

collectProjectedTypes builds a projected type for every user type found when recursing through the attributes. The projected types live in the views package and support the marshaling and unmarshalling of result types that make use of views. We need to build projected types for all user types - not

(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope, seen map[string]*ProjectedTypeData)

Source from the content-addressed store, hash-verified

1829// just result types - because user types may contain result types and thus may
1830// need to be marshalled in different ways depending on the view being used.
1831func collectProjectedTypes(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope, seen map[string]*ProjectedTypeData) []*ProjectedTypeData {
1832 collect := func(projected, att *expr.AttributeExpr) []*ProjectedTypeData {
1833 return collectProjectedTypes(projected, att, viewspkg, scope, viewScope, seen)
1834 }
1835 var data []*ProjectedTypeData
1836 switch pt := projected.Type.(type) {
1837 case expr.UserType:
1838 dt := att.Type.(expr.UserType)
1839 if pd, ok := seen[dt.ID()]; ok {
1840 // a projected type is already created for this user type. We change the
1841 // attribute type to this seen projected type. The seen projected type
1842 // can be nil if the attribute type has a circular type definition in
1843 // which case we don't change the attribute type until the projected type
1844 // is created during the recursion.
1845 if pd != nil {
1846 projected.Type = pd.Type
1847 }
1848 return data
1849 }
1850 seen[dt.ID()] = nil
1851 pt.Rename(pt.Name() + "View")
1852 // We recurse before building the projected type so that user types within
1853 // a projected type is also converted to their respective projected types.
1854 types := collect(pt.Attribute(), dt.Attribute())
1855 pd := buildProjectedType(projected, att, viewspkg, scope, viewScope)
1856 seen[dt.ID()] = pd
1857 data = append(data, pd)
1858 data = append(data, types...)
1859 case *expr.Array:
1860 dt := att.Type.(*expr.Array)
1861 types := collect(pt.ElemType, dt.ElemType)
1862 data = append(data, types...)
1863 case *expr.Map:
1864 dt := att.Type.(*expr.Map)
1865 types := collect(pt.KeyType, dt.KeyType)
1866 data = append(data, types...)
1867 types = collect(pt.ElemType, dt.ElemType)
1868 data = append(data, types...)
1869 case *expr.Object:
1870 dt := att.Type.(*expr.Object)
1871 for _, n := range *pt {
1872 types := collect(n.Attribute, dt.Attribute(n.Name))
1873 data = append(data, types...)
1874 }
1875 case *expr.Union:
1876 dt := att.Type.(*expr.Union)
1877 for i, n := range pt.Values {
1878 types := collect(n.Attribute, dt.Values[i].Attribute)
1879 data = append(data, types...)
1880 }
1881 }
1882 return data
1883}
1884
1885// hasResultType returns true if the given attribute has a result type recursively.
1886func hasResultType(att *expr.AttributeExpr, seens ...map[string]struct{}) bool {

Callers 1

analyzeMethod · 0.85

Calls 5

buildProjectedTypeFunction · 0.85
IDMethod · 0.65
RenameMethod · 0.65
NameMethod · 0.65
AttributeMethod · 0.65

Tested by

no test coverage detected