buildProjections builds the data to generate the constructor code to project a result type to a projected type based on a view.
(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope)
| 2186 | // buildProjections builds the data to generate the constructor code to |
| 2187 | // project a result type to a projected type based on a view. |
| 2188 | func buildProjections(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope) []*InitData { |
| 2189 | rt := att.Type.(*expr.ResultTypeExpr) |
| 2190 | projections := make([]*InitData, 0, len(rt.Views)) |
| 2191 | for _, view := range rt.Views { |
| 2192 | var typ expr.DataType |
| 2193 | obj := &expr.Object{} |
| 2194 | pobj := expr.AsObject(projected.Type) |
| 2195 | parr := expr.AsArray(projected.Type) |
| 2196 | if parr != nil { |
| 2197 | // result type collection |
| 2198 | pobj = expr.AsObject(parr.ElemType.Type) |
| 2199 | } |
| 2200 | walkViewAttrs(pobj, view, func(name string, att, _ *expr.AttributeExpr) { |
| 2201 | obj.Set(name, att) |
| 2202 | }) |
| 2203 | typ = obj |
| 2204 | if parr != nil { |
| 2205 | typ = &expr.Array{ElemType: &expr.AttributeExpr{ |
| 2206 | Type: &expr.ResultTypeExpr{ |
| 2207 | UserTypeExpr: &expr.UserTypeExpr{ |
| 2208 | AttributeExpr: &expr.AttributeExpr{Type: obj}, |
| 2209 | TypeName: parr.ElemType.Type.Name(), |
| 2210 | }, |
| 2211 | }, |
| 2212 | }} |
| 2213 | } |
| 2214 | tgt := &expr.AttributeExpr{ |
| 2215 | Type: &expr.ResultTypeExpr{ |
| 2216 | UserTypeExpr: &expr.UserTypeExpr{ |
| 2217 | AttributeExpr: &expr.AttributeExpr{Type: typ}, |
| 2218 | TypeName: projected.Type.Name(), |
| 2219 | }, |
| 2220 | Views: rt.Views, |
| 2221 | Identifier: rt.Identifier, |
| 2222 | }, |
| 2223 | } |
| 2224 | |
| 2225 | srcCtx := typeContext(scope) |
| 2226 | tgtCtx := projectedTypeContext(viewspkg, true, viewScope) |
| 2227 | tname := scope.GoTypeName(projected) |
| 2228 | name := "new" + tname |
| 2229 | if view.Name != expr.DefaultView { |
| 2230 | name += codegen.Goify(view.Name, true) |
| 2231 | } |
| 2232 | code, helpers := buildConstructorCode(att, tgt, "res", "vres", srcCtx, tgtCtx, view.Name) |
| 2233 | |
| 2234 | pkg := "" |
| 2235 | if loc := codegen.UserTypeLocation(att.Type); loc != nil { |
| 2236 | pkg = loc.PackageName() |
| 2237 | } |
| 2238 | projections = append(projections, &InitData{ |
| 2239 | Name: name, |
| 2240 | Description: fmt.Sprintf("%s projects result type %s to projected type %s using the %q view.", name, scope.GoTypeName(att), tname, view.Name), |
| 2241 | Args: []*InitArgData{{Name: "res", Ref: scope.GoFullTypeRef(att, pkg)}}, |
| 2242 | ReturnTypeRef: viewScope.GoFullTypeRef(projected, viewspkg), |
| 2243 | Code: code, |
| 2244 | Helpers: helpers, |
| 2245 | }) |
no test coverage detected