StructTypeField returns field type for given field.
(tpe ast.BaseTerm, field ast.Constant)
| 212 | |
| 213 | // StructTypeField returns field type for given field. |
| 214 | func StructTypeField(tpe ast.BaseTerm, field ast.Constant) (ast.BaseTerm, error) { |
| 215 | if IsUnionTypeExpression(tpe) { // Project |
| 216 | src, _ := UnionTypeArgs(tpe) |
| 217 | alternatives := []ast.BaseTerm{} |
| 218 | for _, s := range src { |
| 219 | projected, err := StructTypeField(s, field) |
| 220 | if err != nil { |
| 221 | continue |
| 222 | } |
| 223 | alternatives = append(alternatives, projected) |
| 224 | } |
| 225 | if len(alternatives) == 1 { |
| 226 | return alternatives[0], nil |
| 227 | } |
| 228 | return NewUnionType(alternatives...), nil |
| 229 | } |
| 230 | if debug && !IsStructTypeExpression(tpe) { |
| 231 | return nil, fmt.Errorf("not a struct type expression: %v", tpe) |
| 232 | } |
| 233 | elems := typeArgs(tpe) |
| 234 | for i := 0; i < len(elems); i++ { |
| 235 | var key ast.BaseTerm |
| 236 | arg := elems[i] |
| 237 | if IsOptional(arg) { |
| 238 | key = arg.(ast.ApplyFn).Args[0] |
| 239 | } else { |
| 240 | key = arg |
| 241 | } |
| 242 | if key.Equals(field) { |
| 243 | if IsOptional(arg) { |
| 244 | return arg.(ast.ApplyFn).Args[1], nil |
| 245 | } |
| 246 | i++ |
| 247 | return elems[i], nil |
| 248 | } |
| 249 | } |
| 250 | return nil, fmt.Errorf("no field %v in %v", field, tpe) |
| 251 | } |
| 252 | |
| 253 | // FunTypeResult returns result type of function type. |
| 254 | func FunTypeResult(tpe ast.BaseTerm) (ast.BaseTerm, error) { |