blob: a58947a8426ee0065d3e0d2626cfdee6f075274e [file] [log] [blame]
Marcel van Lohuizencea55b22020-12-18 12:09:05 +01001// Copyright 2020 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package adt
16
17// MatchAndInsert finds matching optional parts for a given Arc and adds its
18// conjuncts. Bulk fields are only applied if no fields match, and additional
19// constraints are only added if neither regular nor bulk fields match.
20func (o *StructInfo) MatchAndInsert(c *OpContext, arc *Vertex) {
21 env := o.Env
22
Marcel van Lohuizen826bd7b2021-01-16 17:26:00 +010023 closeInfo := o.CloseInfo
24 closeInfo.IsClosed = false
25
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010026 // Match normal fields
27 matched := false
28outer:
29 for _, f := range o.Fields {
30 if f.Label == arc.Label {
31 for _, e := range f.Optional {
Marcel van Lohuizen826bd7b2021-01-16 17:26:00 +010032 arc.AddConjunct(MakeConjunct(env, e, closeInfo))
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010033 }
34 matched = true
35 break outer
36 }
37 }
38
Marcel van Lohuizen957003c2021-04-08 10:26:31 +020039 f := arc.Label
40 if !f.IsRegular() {
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010041 return
42 }
Marcel van Lohuizen957003c2021-04-08 10:26:31 +020043 if int64(f.Index()) == MaxIndex {
44 f = 0
45 }
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010046
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +010047 var label Value
Marcel van Lohuizen957003c2021-04-08 10:26:31 +020048 if o.types&HasComplexPattern != 0 && f.IsString() {
49 label = f.ToValue(c)
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +010050 }
51
Marcel van Lohuizen08e814f2021-01-19 13:43:59 +010052 if len(o.Bulk) > 0 {
53 bulkEnv := *env
Marcel van Lohuizen957003c2021-04-08 10:26:31 +020054 bulkEnv.DynamicLabel = f
Marcel van Lohuizen08e814f2021-01-19 13:43:59 +010055 bulkEnv.Deref = nil
56 bulkEnv.Cycles = nil
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010057
Marcel van Lohuizen08e814f2021-01-19 13:43:59 +010058 // match bulk optional fields / pattern properties
59 for _, b := range o.Bulk {
60 // if matched && f.additional {
61 // continue
62 // }
Marcel van Lohuizen957003c2021-04-08 10:26:31 +020063 if matchBulk(c, env, b, f, label) {
Marcel van Lohuizen08e814f2021-01-19 13:43:59 +010064 matched = true
65 info := closeInfo.SpawnSpan(b.Value, ConstraintSpan)
66 arc.AddConjunct(MakeConjunct(&bulkEnv, b, info))
67 }
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010068 }
69 }
Marcel van Lohuizen08e814f2021-01-19 13:43:59 +010070
71 if matched || len(o.Additional) == 0 {
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010072 return
73 }
74
75 addEnv := *env
76 addEnv.Deref = nil
77 addEnv.Cycles = nil
78
79 // match others
80 for _, x := range o.Additional {
Marcel van Lohuizen08e814f2021-01-19 13:43:59 +010081 info := closeInfo
82 if _, ok := x.(*Top); !ok {
83 info = info.SpawnSpan(x, ConstraintSpan)
84 }
85 arc.AddConjunct(MakeConjunct(&addEnv, x, info))
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010086 }
87}
88
Marcel van Lohuizen1f9300d2021-03-20 19:18:27 +010089// matchBulk reports whether feature f matches the filter of x. It evaluation of
90// the filter is erroneous, it returns false and the error will be set in c.
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +010091func matchBulk(c *OpContext, env *Environment, x *BulkOptionalField, f Feature, label Value) bool {
92 v := env.evalCached(c, x.Filter)
Marcel van Lohuizencea55b22020-12-18 12:09:05 +010093
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +010094 // Fast-track certain cases.
95 switch x := v.(type) {
Marcel van Lohuizen1f9300d2021-03-20 19:18:27 +010096 case *Bottom:
97 if c.errs == nil {
98 c.AddBottom(x)
99 }
100 return false
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100101 case *Top:
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100102 return true
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100103
104 case *BasicType:
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100105 return x.K&StringKind != 0
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100106
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100107 case *BoundValue:
108 switch x.Kind() {
109 case StringKind:
110 if label == nil {
Marcel van Lohuizenc505c192021-04-07 09:40:57 +0200111 return false
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100112 }
113 str := label.(*String).Str
114 return x.validateStr(c, str)
115
116 case IntKind:
117 return x.validateInt(c, int64(f.Index()))
118 }
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100119 }
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100120
Marcel van Lohuizenc505c192021-04-07 09:40:57 +0200121 if label == nil {
122 return false
123 }
124
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100125 n := Vertex{}
126 m := MakeRootConjunct(env, v)
127 n.AddConjunct(m)
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100128 n.AddConjunct(MakeRootConjunct(m.Env, label))
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100129
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100130 c.inConstraint++
131 n.Finalize(c)
132 c.inConstraint--
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100133
Marcel van Lohuizen48d255a2021-02-04 16:56:14 +0100134 b, _ := n.BaseValue.(*Bottom)
Marcel van Lohuizencea55b22020-12-18 12:09:05 +0100135 return b == nil
136}