mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
vendor: update github.com/hashicorp/hcl/v2 to v2.19.1
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
231
vendor/github.com/zclconf/go-cty/cty/value_ops.go
generated
vendored
231
vendor/github.com/zclconf/go-cty/cty/value_ops.go
generated
vendored
@ -33,7 +33,17 @@ func (val Value) GoString() string {
|
||||
return "cty.DynamicVal"
|
||||
}
|
||||
if !val.IsKnown() {
|
||||
return fmt.Sprintf("cty.UnknownVal(%#v)", val.ty)
|
||||
rfn := val.v.(*unknownType).refinement
|
||||
var suffix string
|
||||
if rfn != nil {
|
||||
calls := rfn.GoString()
|
||||
if calls == ".NotNull()" {
|
||||
suffix = ".RefineNotNull()"
|
||||
} else {
|
||||
suffix = ".Refine()" + rfn.GoString() + ".NewValue()"
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("cty.UnknownVal(%#v)%s", val.ty, suffix)
|
||||
}
|
||||
|
||||
// By the time we reach here we've dealt with all of the exceptions around
|
||||
@ -47,6 +57,9 @@ func (val Value) GoString() string {
|
||||
}
|
||||
return "cty.False"
|
||||
case Number:
|
||||
if f, ok := val.v.(big.Float); ok {
|
||||
panic(fmt.Sprintf("number value contains big.Float value %s, rather than pointer to big.Float", f.Text('g', -1)))
|
||||
}
|
||||
fv := val.v.(*big.Float)
|
||||
// We'll try to use NumberIntVal or NumberFloatVal if we can, since
|
||||
// the fully-general initializer call is pretty ugly-looking.
|
||||
@ -122,13 +135,38 @@ func (val Value) Equals(other Value) Value {
|
||||
return val.Equals(other).WithMarks(valMarks, otherMarks)
|
||||
}
|
||||
|
||||
// Start by handling Unknown values before considering types.
|
||||
// This needs to be done since Null values are always equal regardless of
|
||||
// type.
|
||||
// Some easy cases with comparisons to null.
|
||||
switch {
|
||||
case val.IsNull() && definitelyNotNull(other):
|
||||
return False
|
||||
case other.IsNull() && definitelyNotNull(val):
|
||||
return False
|
||||
}
|
||||
// If we have one known value and one unknown value then we may be
|
||||
// able to quickly disqualify equality based on the range of the unknown
|
||||
// value.
|
||||
if val.IsKnown() && !other.IsKnown() {
|
||||
otherRng := other.Range()
|
||||
if ok := otherRng.Includes(val); ok.IsKnown() && ok.False() {
|
||||
return False
|
||||
}
|
||||
} else if other.IsKnown() && !val.IsKnown() {
|
||||
valRng := val.Range()
|
||||
if ok := valRng.Includes(other); ok.IsKnown() && ok.False() {
|
||||
return False
|
||||
}
|
||||
}
|
||||
|
||||
// We need to deal with unknown values before anything else with nulls
|
||||
// because any unknown value that hasn't yet been refined as non-null
|
||||
// could become null, and nulls of any types are equal to one another.
|
||||
unknownResult := func() Value {
|
||||
return UnknownVal(Bool).Refine().NotNull().NewValue()
|
||||
}
|
||||
switch {
|
||||
case !val.IsKnown() && !other.IsKnown():
|
||||
// both unknown
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
case val.IsKnown() && !other.IsKnown():
|
||||
switch {
|
||||
case val.IsNull(), other.ty.HasDynamicTypes():
|
||||
@ -136,13 +174,13 @@ func (val Value) Equals(other Value) Value {
|
||||
// nulls of any type are equal.
|
||||
// An unknown with a dynamic type compares as unknown, which we need
|
||||
// to check before the type comparison below.
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
case !val.ty.Equals(other.ty):
|
||||
// There is no null comparison or dynamic types, so unequal types
|
||||
// will never be equal.
|
||||
return False
|
||||
default:
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
case other.IsKnown() && !val.IsKnown():
|
||||
switch {
|
||||
@ -151,13 +189,13 @@ func (val Value) Equals(other Value) Value {
|
||||
// nulls of any type are equal.
|
||||
// An unknown with a dynamic type compares as unknown, which we need
|
||||
// to check before the type comparison below.
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
case !other.ty.Equals(val.ty):
|
||||
// There's no null comparison or dynamic types, so unequal types
|
||||
// will never be equal.
|
||||
return False
|
||||
default:
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +217,7 @@ func (val Value) Equals(other Value) Value {
|
||||
return BoolVal(false)
|
||||
}
|
||||
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
|
||||
if !val.ty.Equals(other.ty) {
|
||||
@ -213,7 +251,7 @@ func (val Value) Equals(other Value) Value {
|
||||
}
|
||||
eq := lhs.Equals(rhs)
|
||||
if !eq.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
if eq.False() {
|
||||
result = false
|
||||
@ -234,7 +272,7 @@ func (val Value) Equals(other Value) Value {
|
||||
}
|
||||
eq := lhs.Equals(rhs)
|
||||
if !eq.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
if eq.False() {
|
||||
result = false
|
||||
@ -256,7 +294,7 @@ func (val Value) Equals(other Value) Value {
|
||||
}
|
||||
eq := lhs.Equals(rhs)
|
||||
if !eq.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
if eq.False() {
|
||||
result = false
|
||||
@ -265,16 +303,16 @@ func (val Value) Equals(other Value) Value {
|
||||
}
|
||||
}
|
||||
case ty.IsSetType():
|
||||
s1 := val.v.(set.Set)
|
||||
s2 := other.v.(set.Set)
|
||||
s1 := val.v.(set.Set[interface{}])
|
||||
s2 := other.v.(set.Set[interface{}])
|
||||
equal := true
|
||||
|
||||
// Two sets are equal if all of their values are known and all values
|
||||
// in one are also in the other.
|
||||
for it := s1.Iterator(); it.Next(); {
|
||||
rv := it.Value()
|
||||
if rv == unknown { // "unknown" is the internal representation of unknown-ness
|
||||
return UnknownVal(Bool)
|
||||
if _, unknown := rv.(*unknownType); unknown { // "*unknownType" is the internal representation of unknown-ness
|
||||
return unknownResult()
|
||||
}
|
||||
if !s2.Has(rv) {
|
||||
equal = false
|
||||
@ -282,8 +320,8 @@ func (val Value) Equals(other Value) Value {
|
||||
}
|
||||
for it := s2.Iterator(); it.Next(); {
|
||||
rv := it.Value()
|
||||
if rv == unknown { // "unknown" is the internal representation of unknown-ness
|
||||
return UnknownVal(Bool)
|
||||
if _, unknown := rv.(*unknownType); unknown { // "*unknownType" is the internal representation of unknown-ness
|
||||
return unknownResult()
|
||||
}
|
||||
if !s1.Has(rv) {
|
||||
equal = false
|
||||
@ -310,7 +348,7 @@ func (val Value) Equals(other Value) Value {
|
||||
}
|
||||
eq := lhs.Equals(rhs)
|
||||
if !eq.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return unknownResult()
|
||||
}
|
||||
if eq.False() {
|
||||
result = false
|
||||
@ -390,7 +428,17 @@ func (val Value) RawEquals(other Value) bool {
|
||||
other = other.unmarkForce()
|
||||
|
||||
if (!val.IsKnown()) && (!other.IsKnown()) {
|
||||
return true
|
||||
// If either unknown value has refinements then they must match.
|
||||
valRfn := val.v.(*unknownType).refinement
|
||||
otherRfn := other.v.(*unknownType).refinement
|
||||
switch {
|
||||
case (valRfn == nil) != (otherRfn == nil):
|
||||
return false
|
||||
case valRfn != nil:
|
||||
return valRfn.rawEqual(otherRfn)
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (val.IsKnown() && !other.IsKnown()) || (other.IsKnown() && !val.IsKnown()) {
|
||||
return false
|
||||
@ -545,7 +593,8 @@ func (val Value) Add(other Value) Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
ret := shortCircuit.RefineWith(numericRangeArithmetic(Value.Add, val.Range(), other.Range()))
|
||||
return ret.RefineNotNull()
|
||||
}
|
||||
|
||||
ret := new(big.Float)
|
||||
@ -564,7 +613,8 @@ func (val Value) Subtract(other Value) Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
ret := shortCircuit.RefineWith(numericRangeArithmetic(Value.Subtract, val.Range(), other.Range()))
|
||||
return ret.RefineNotNull()
|
||||
}
|
||||
|
||||
return val.Add(other.Negate())
|
||||
@ -580,7 +630,7 @@ func (val Value) Negate() Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
ret := new(big.Float).Neg(val.v.(*big.Float))
|
||||
@ -597,8 +647,14 @@ func (val Value) Multiply(other Value) Value {
|
||||
}
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
|
||||
// If either value is exactly zero then the result must either be
|
||||
// zero or an error.
|
||||
if val == Zero || other == Zero {
|
||||
return Zero
|
||||
}
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
ret := shortCircuit.RefineWith(numericRangeArithmetic(Value.Multiply, val.Range(), other.Range()))
|
||||
return ret.RefineNotNull()
|
||||
}
|
||||
|
||||
// find the larger precision of the arguments
|
||||
@ -643,7 +699,10 @@ func (val Value) Divide(other Value) Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
// TODO: We could potentially refine the range of the result here, but
|
||||
// we don't right now because our division operation is not monotone
|
||||
// if the denominator could potentially be zero.
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
ret := new(big.Float)
|
||||
@ -675,7 +734,7 @@ func (val Value) Modulo(other Value) Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
// We cheat a bit here with infinities, just abusing the Multiply operation
|
||||
@ -713,7 +772,7 @@ func (val Value) Absolute() Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Number, val); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Number)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).Refine().NotNull().NumberRangeInclusive(Zero, UnknownVal(Number)).NewValue()
|
||||
}
|
||||
|
||||
ret := (&big.Float{}).Abs(val.v.(*big.Float))
|
||||
@ -886,23 +945,23 @@ func (val Value) HasIndex(key Value) Value {
|
||||
}
|
||||
|
||||
if val.ty == DynamicPseudoType {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
switch {
|
||||
case val.Type().IsListType():
|
||||
if key.Type() == DynamicPseudoType {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
if key.Type() != Number {
|
||||
return False
|
||||
}
|
||||
if !key.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
if !val.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
index, accuracy := key.v.(*big.Float).Int64()
|
||||
@ -913,17 +972,17 @@ func (val Value) HasIndex(key Value) Value {
|
||||
return BoolVal(int(index) < len(val.v.([]interface{})) && index >= 0)
|
||||
case val.Type().IsMapType():
|
||||
if key.Type() == DynamicPseudoType {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
if key.Type() != String {
|
||||
return False
|
||||
}
|
||||
if !key.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
if !val.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
keyStr := key.v.(string)
|
||||
@ -932,14 +991,14 @@ func (val Value) HasIndex(key Value) Value {
|
||||
return BoolVal(exists)
|
||||
case val.Type().IsTupleType():
|
||||
if key.Type() == DynamicPseudoType {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
if key.Type() != Number {
|
||||
return False
|
||||
}
|
||||
if !key.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
|
||||
index, accuracy := key.v.(*big.Float).Int64()
|
||||
@ -974,16 +1033,16 @@ func (val Value) HasElement(elem Value) Value {
|
||||
panic("not a set type")
|
||||
}
|
||||
if !val.IsKnown() || !elem.IsKnown() {
|
||||
return UnknownVal(Bool)
|
||||
return UnknownVal(Bool).RefineNotNull()
|
||||
}
|
||||
if val.IsNull() {
|
||||
panic("can't call HasElement on a nil value")
|
||||
panic("can't call HasElement on a null value")
|
||||
}
|
||||
if !ty.ElementType().Equals(elem.Type()) {
|
||||
return False
|
||||
}
|
||||
|
||||
s := val.v.(set.Set)
|
||||
s := val.v.(set.Set[interface{}])
|
||||
return BoolVal(s.Has(elem.v))
|
||||
}
|
||||
|
||||
@ -1009,7 +1068,10 @@ func (val Value) Length() Value {
|
||||
}
|
||||
|
||||
if !val.IsKnown() {
|
||||
return UnknownVal(Number)
|
||||
// If the whole collection isn't known then the length isn't known
|
||||
// either, but we can still put some bounds on the range of the result.
|
||||
rng := val.Range()
|
||||
return UnknownVal(Number).RefineWith(valueRefineLengthResult(rng))
|
||||
}
|
||||
if val.Type().IsSetType() {
|
||||
// The Length rules are a little different for sets because if any
|
||||
@ -1017,7 +1079,7 @@ func (val Value) Length() Value {
|
||||
// may or may not be equal to other elements in the set, and thus they
|
||||
// may or may not coalesce with other elements and produce fewer
|
||||
// items in the resulting set.
|
||||
storeLength := int64(val.v.(set.Set).Length())
|
||||
storeLength := int64(val.v.(set.Set[interface{}]).Length())
|
||||
if storeLength == 1 || val.IsWhollyKnown() {
|
||||
// If our set is wholly known then we know its length.
|
||||
//
|
||||
@ -1027,13 +1089,26 @@ func (val Value) Length() Value {
|
||||
// unknown value cannot represent more than one known value.
|
||||
return NumberIntVal(storeLength)
|
||||
}
|
||||
// Otherwise, we cannot predict the length.
|
||||
return UnknownVal(Number)
|
||||
// Otherwise, we cannot predict the length exactly but we can at
|
||||
// least constrain both bounds of its range, because value coalescing
|
||||
// can only ever reduce the number of elements in the set.
|
||||
return UnknownVal(Number).Refine().NotNull().NumberRangeInclusive(NumberIntVal(1), NumberIntVal(storeLength)).NewValue()
|
||||
}
|
||||
|
||||
return NumberIntVal(int64(val.LengthInt()))
|
||||
}
|
||||
|
||||
func valueRefineLengthResult(collRng ValueRange) func(*RefinementBuilder) *RefinementBuilder {
|
||||
return func(b *RefinementBuilder) *RefinementBuilder {
|
||||
return b.
|
||||
NotNull().
|
||||
NumberRangeInclusive(
|
||||
NumberIntVal(int64(collRng.LengthLowerBound())),
|
||||
NumberIntVal(int64(collRng.LengthUpperBound())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// LengthInt is like Length except it returns an int. It has the same behavior
|
||||
// as Length except that it will panic if the receiver is unknown.
|
||||
//
|
||||
@ -1078,7 +1153,7 @@ func (val Value) LengthInt() int {
|
||||
// compatibility with callers that were relying on LengthInt rather
|
||||
// than calling Length. Instead of panicking when a set contains an
|
||||
// unknown value, LengthInt returns the largest possible length.
|
||||
return val.v.(set.Set).Length()
|
||||
return val.v.(set.Set[interface{}]).Length()
|
||||
|
||||
case val.ty.IsMapType():
|
||||
return len(val.v.(map[string]interface{}))
|
||||
@ -1164,7 +1239,7 @@ func (val Value) Not() Value {
|
||||
|
||||
if shortCircuit := mustTypeCheck(Bool, Bool, val); shortCircuit != nil {
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Bool)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
return BoolVal(!val.v.(bool))
|
||||
@ -1180,8 +1255,14 @@ func (val Value) And(other Value) Value {
|
||||
}
|
||||
|
||||
if shortCircuit := mustTypeCheck(Bool, Bool, val, other); shortCircuit != nil {
|
||||
// If either value is known to be exactly False then it doesn't
|
||||
// matter what the other value is, because the final result must
|
||||
// either be False or an error.
|
||||
if val == False || other == False {
|
||||
return False
|
||||
}
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Bool)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
return BoolVal(val.v.(bool) && other.v.(bool))
|
||||
@ -1197,8 +1278,14 @@ func (val Value) Or(other Value) Value {
|
||||
}
|
||||
|
||||
if shortCircuit := mustTypeCheck(Bool, Bool, val, other); shortCircuit != nil {
|
||||
// If either value is known to be exactly True then it doesn't
|
||||
// matter what the other value is, because the final result must
|
||||
// either be True or an error.
|
||||
if val == True || other == True {
|
||||
return True
|
||||
}
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Bool)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
return BoolVal(val.v.(bool) || other.v.(bool))
|
||||
@ -1214,8 +1301,30 @@ func (val Value) LessThan(other Value) Value {
|
||||
}
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Bool, val, other); shortCircuit != nil {
|
||||
// We might be able to return a known answer even with unknown inputs.
|
||||
// FIXME: This is more conservative than it needs to be, because it
|
||||
// treats all bounds as exclusive bounds.
|
||||
valRng := val.Range()
|
||||
otherRng := other.Range()
|
||||
if valRng.TypeConstraint() == Number && other.Range().TypeConstraint() == Number {
|
||||
valMax, _ := valRng.NumberUpperBound()
|
||||
otherMin, _ := otherRng.NumberLowerBound()
|
||||
if valMax.IsKnown() && otherMin.IsKnown() {
|
||||
if r := valMax.LessThan(otherMin); r.True() {
|
||||
return True
|
||||
}
|
||||
}
|
||||
valMin, _ := valRng.NumberLowerBound()
|
||||
otherMax, _ := otherRng.NumberUpperBound()
|
||||
if valMin.IsKnown() && otherMax.IsKnown() {
|
||||
if r := valMin.GreaterThan(otherMax); r.True() {
|
||||
return False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Bool)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
return BoolVal(val.v.(*big.Float).Cmp(other.v.(*big.Float)) < 0)
|
||||
@ -1231,8 +1340,30 @@ func (val Value) GreaterThan(other Value) Value {
|
||||
}
|
||||
|
||||
if shortCircuit := mustTypeCheck(Number, Bool, val, other); shortCircuit != nil {
|
||||
// We might be able to return a known answer even with unknown inputs.
|
||||
// FIXME: This is more conservative than it needs to be, because it
|
||||
// treats all bounds as exclusive bounds.
|
||||
valRng := val.Range()
|
||||
otherRng := other.Range()
|
||||
if valRng.TypeConstraint() == Number && other.Range().TypeConstraint() == Number {
|
||||
valMin, _ := valRng.NumberLowerBound()
|
||||
otherMax, _ := otherRng.NumberUpperBound()
|
||||
if valMin.IsKnown() && otherMax.IsKnown() {
|
||||
if r := valMin.GreaterThan(otherMax); r.True() {
|
||||
return True
|
||||
}
|
||||
}
|
||||
valMax, _ := valRng.NumberUpperBound()
|
||||
otherMin, _ := otherRng.NumberLowerBound()
|
||||
if valMax.IsKnown() && otherMin.IsKnown() {
|
||||
if r := valMax.LessThan(otherMin); r.True() {
|
||||
return False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shortCircuit = forceShortCircuitType(shortCircuit, Bool)
|
||||
return *shortCircuit
|
||||
return (*shortCircuit).RefineNotNull()
|
||||
}
|
||||
|
||||
return BoolVal(val.v.(*big.Float).Cmp(other.v.(*big.Float)) > 0)
|
||||
|
Reference in New Issue
Block a user