func ExprFromValue()

in rule/value.go [95:166]


func ExprFromValue(val interface{}) bzl.Expr {
	if e, ok := val.(bzl.Expr); ok {
		return e
	}
	if be, ok := val.(BzlExprValue); ok {
		return be.BzlExpr()
	}

	rv := reflect.ValueOf(val)
	switch rv.Kind() {
	case reflect.Bool:
		tok := "False"
		if rv.Bool() {
			tok = "True"
		}
		return &bzl.LiteralExpr{Token: tok}

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return &bzl.LiteralExpr{Token: fmt.Sprintf("%d", val)}

	case reflect.Float32, reflect.Float64:
		return &bzl.LiteralExpr{Token: fmt.Sprintf("%f", val)}

	case reflect.String:
		return &bzl.StringExpr{Value: val.(string)}

	case reflect.Slice, reflect.Array:
		var list []bzl.Expr
		for i := 0; i < rv.Len(); i++ {
			elem := ExprFromValue(rv.Index(i).Interface())
			list = append(list, elem)
		}
		return &bzl.ListExpr{List: list}

	case reflect.Map:
		rkeys := rv.MapKeys()
		sort.Sort(byString(rkeys))
		args := make([]*bzl.KeyValueExpr, len(rkeys))
		for i, rk := range rkeys {
			k := &bzl.StringExpr{Value: mapKeyString(rk)}
			v := ExprFromValue(rv.MapIndex(rk).Interface())
			if l, ok := v.(*bzl.ListExpr); ok {
				l.ForceMultiLine = true
			}
			args[i] = &bzl.KeyValueExpr{Key: k, Value: v}
		}
		return &bzl.DictExpr{List: args, ForceMultiLine: true}

	case reflect.Struct:
		switch val := val.(type) {
		case GlobValue:
			patternsValue := ExprFromValue(val.Patterns)
			globArgs := []bzl.Expr{patternsValue}
			if len(val.Excludes) > 0 {
				excludesValue := ExprFromValue(val.Excludes)
				globArgs = append(globArgs, &bzl.AssignExpr{
					LHS: &bzl.LiteralExpr{Token: "exclude"},
					Op:  "=",
					RHS: excludesValue,
				})
			}
			return &bzl.CallExpr{
				X:    &bzl.LiteralExpr{Token: "glob"},
				List: globArgs,
			}
		}
	}

	log.Panicf("type not supported: %T", val)
	return nil
}