buildTypeInits builds the data to generate the constructor code to initialize a result type from a projected type.
(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope)
| 2119 | // buildTypeInits builds the data to generate the constructor code to |
| 2120 | // initialize a result type from a projected type. |
| 2121 | func buildTypeInits(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope) []*InitData { |
| 2122 | prt := projected.Type.(*expr.ResultTypeExpr) |
| 2123 | pobj := expr.AsObject(projected.Type) |
| 2124 | parr := expr.AsArray(projected.Type) |
| 2125 | if parr != nil { |
| 2126 | // result type collection |
| 2127 | pobj = expr.AsObject(parr.ElemType.Type) |
| 2128 | } |
| 2129 | |
| 2130 | // For every view defined in the result type, build a constructor function |
| 2131 | // to create the result type from a projected type based on the view. |
| 2132 | init := make([]*InitData, 0, len(prt.Views)) |
| 2133 | for _, view := range prt.Views { |
| 2134 | var typ expr.DataType |
| 2135 | obj := &expr.Object{} |
| 2136 | walkViewAttrs(pobj, view, func(name string, att, _ *expr.AttributeExpr) { |
| 2137 | obj.Set(name, att) |
| 2138 | }) |
| 2139 | typ = obj |
| 2140 | if parr != nil { |
| 2141 | typ = &expr.Array{ElemType: &expr.AttributeExpr{ |
| 2142 | Type: &expr.ResultTypeExpr{ |
| 2143 | UserTypeExpr: &expr.UserTypeExpr{ |
| 2144 | AttributeExpr: &expr.AttributeExpr{Type: obj}, |
| 2145 | TypeName: scope.GoTypeName(parr.ElemType), |
| 2146 | }, |
| 2147 | }, |
| 2148 | }} |
| 2149 | } |
| 2150 | src := &expr.AttributeExpr{ |
| 2151 | Type: &expr.ResultTypeExpr{ |
| 2152 | UserTypeExpr: &expr.UserTypeExpr{ |
| 2153 | AttributeExpr: &expr.AttributeExpr{Type: typ}, |
| 2154 | TypeName: scope.GoTypeName(projected), |
| 2155 | }, |
| 2156 | Views: prt.Views, |
| 2157 | Identifier: prt.Identifier, |
| 2158 | }, |
| 2159 | } |
| 2160 | |
| 2161 | srcCtx := projectedTypeContext(viewspkg, true, viewScope) |
| 2162 | tgtCtx := typeContext(scope) |
| 2163 | resvar := scope.GoTypeName(att) |
| 2164 | name := "new" + resvar |
| 2165 | if view.Name != expr.DefaultView { |
| 2166 | name += codegen.Goify(view.Name, true) |
| 2167 | } |
| 2168 | code, helpers := buildConstructorCode(src, att, "vres", "res", srcCtx, tgtCtx, view.Name) |
| 2169 | |
| 2170 | pkg := "" |
| 2171 | if loc := codegen.UserTypeLocation(att.Type); loc != nil { |
| 2172 | pkg = loc.PackageName() |
| 2173 | } |
| 2174 | init = append(init, &InitData{ |
| 2175 | Name: name, |
| 2176 | Description: fmt.Sprintf("%s converts projected type %s to service type %s.", name, resvar, resvar), |
| 2177 | Args: []*InitArgData{{Name: "vres", Ref: viewScope.GoFullTypeRef(projected, viewspkg)}}, |
| 2178 | ReturnTypeRef: scope.GoFullTypeRef(att, pkg), |
no test coverage detected