/
constraints.go
67 lines (51 loc) · 1.62 KB
/
constraints.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package core
import (
"errors"
"github.com/inoxlang/inox/internal/parse"
"github.com/inoxlang/inox/internal/utils"
cmap "github.com/orcaman/concurrent-map/v2"
)
// A ConstraintId represents an id that is used to retrieve the constraints on a Value.
type ConstraintId uint64
const (
CONSTRAINTS_KEY = "_constraints_"
)
var (
constraintMap = cmap.NewWithCustomShardingFunction[ConstraintId, Pattern](
func(key ConstraintId) uint32 {
return uint32(key % 16)
},
)
nextConstraintId = ConstraintId(1)
ErrConstraintViolation = errors.New("constraint violation")
)
func (id ConstraintId) HasConstraint() bool {
return id > 0
}
func GetConstraint(constraintId ConstraintId) (Pattern, bool) {
return constraintMap.Get(constraintId)
}
func initializeConstraintMetaproperty(v *Object, block *parse.InitializationBlock) {
id := nextConstraintId
nextConstraintId++
patt := &ObjectPattern{
complexPropertyPatterns: []*ComplexPropertyConstraint{},
inexact: true,
}
for _, stmt := range block.Statements {
var props []string
parse.Walk(stmt, func(node, parent, scopeNode parse.Node, ancestorChain []parse.Node, after bool) (parse.TraversalAction, error) {
if membExpr, ok := node.(*parse.MemberExpression); ok && utils.Implements[*parse.SelfExpression](membExpr.Left) {
props = append(props, membExpr.PropertyName.Name)
}
return parse.ContinueTraversal, nil
}, nil)
patt.complexPropertyPatterns = append(patt.complexPropertyPatterns, &ComplexPropertyConstraint{
Properties: props,
Expr: stmt,
})
}
constraintMap.Set(id, patt)
v.ensureAdditionalFields()
v.constraintId = id
}