this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/core/path: package for Selector to Feature conversion

The reodering of label types results in slightly nicer presentation
for type strings and results in faster code.

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I1f208d70c0f208df7e7f0f490c612d87bd4c2cc0
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/542924
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Paul Jolly <paul@myitcv.io>

+224 -22
+11 -19
cue/path.go
··· 37 37 const ( 38 38 // StringLabel represents a regular non-definition field. 39 39 StringLabel SelectorType = 1 << iota 40 + // IndexLabel represents a numeric index into an array. 41 + IndexLabel 42 + // DefinitionLabel represents a definition. 43 + DefinitionLabel 40 44 // HiddenLabel represents a hidden non-definition field. 41 45 HiddenLabel 42 - // DefinitionLabel represents a definition. 43 - DefinitionLabel 44 46 // HiddenDefinitionLabel represents a hidden definition. 45 47 HiddenDefinitionLabel 46 - // IndexLabel represents a numeric index into an array. 47 - IndexLabel 48 48 49 49 // OptionalConstraint represents an optional constraint (?). 50 50 OptionalConstraint 51 - 52 51 // PatternConstraint represents a selector of fields in a struct 53 52 // or array that match a constraint. 54 53 PatternConstraint ··· 69 68 var selectorTypeStrings = [...]string{ 70 69 "InvalidSelectorType", 71 70 "StringLabel", 72 - "HiddenLabel", 71 + "IndexLabel", 73 72 "DefinitionLabel", 73 + "HiddenLabel", 74 74 "HiddenDefinitionLabel", 75 - "IndexLabel", 76 75 "OptionalConstraint", 77 76 "PatternConstraint", 78 77 } ··· 560 559 func (s anySelector) String() string { return "[_]" } 561 560 func (s anySelector) optional() bool { return true } 562 561 func (s anySelector) labelType() SelectorType { 563 - var l SelectorType 564 - switch adt.Feature(s) { 565 - case adt.AnyString: 566 - l = StringLabel 567 - case adt.AnyIndex: 568 - l = IndexLabel 569 - case adt.AnyDefinition: 570 - l = DefinitionLabel 571 - case adt.AnyHidden: 572 - l = HiddenLabel 573 - } 574 - return l 562 + // FeatureTypes are numbered sequentially. SelectorType is a bitmap. As they 563 + // are defined in the same order, we can go from FeatureType to SelectorType 564 + // by left shifting. As valid FeatureTypes starts at 1, we need to end with 565 + // a final right shift. 566 + return SelectorType((1 << adt.Feature(s).Typ()) >> 1) 575 567 } 576 568 func (s anySelector) constraintType() SelectorType { return PatternConstraint } 577 569
+1 -1
cue/path_test.go
··· 288 288 if got, want := (StringLabel | OptionalConstraint).String(), "StringLabel|OptionalConstraint"; got != want { 289 289 t.Errorf("unexpected SelectorType.String result; got %q want %q", got, want) 290 290 } 291 - if got, want := SelectorType(255).String(), "StringLabel|HiddenLabel|DefinitionLabel|HiddenDefinitionLabel|IndexLabel|OptionalConstraint|PatternConstraint"; got != want { 291 + if got, want := SelectorType(255).String(), "StringLabel|IndexLabel|DefinitionLabel|HiddenLabel|HiddenDefinitionLabel|OptionalConstraint|PatternConstraint"; got != want { 292 292 t.Errorf("unexpected SelectorType.String result; got %q want %q", got, want) 293 293 } 294 294 }
+34 -2
internal/core/adt/feature.go
··· 68 68 x := f.safeIndex() 69 69 switch f.Typ() { 70 70 case IntLabel: 71 + if f == AnyIndex { 72 + return "_" 73 + } 71 74 return strconv.Itoa(int(x)) 72 75 case StringLabel: 73 76 s := index.IndexToString(x) 74 77 if ast.IsValidIdent(s) && !internal.IsDefOrHidden(s) { 75 78 return s 79 + } 80 + if f == AnyString { 81 + return "_" 76 82 } 77 83 return literal.String.Quote(s) 78 84 default: ··· 153 159 switch { 154 160 case strings.HasPrefix(s, "_#"): 155 161 t = HiddenDefinitionLabel 156 - s = fmt.Sprintf("%s\x00%s", s, pkgpath) 162 + s = HiddenKey(s, pkgpath) 157 163 case strings.HasPrefix(s, "#"): 158 164 t = DefinitionLabel 159 165 case strings.HasPrefix(s, "_"): 160 - s = fmt.Sprintf("%s\x00%s", s, pkgpath) 166 + s = HiddenKey(s, pkgpath) 161 167 t = HiddenLabel 162 168 } 163 169 i := r.StringToIndex(s) 164 170 f, err := MakeLabel(nil, i, t) 165 171 if err != nil { 166 172 panic("out of free string slots") 173 + } 174 + return f 175 + } 176 + 177 + // HiddenKey constructs the uniquely identifying string for a hidden fields and 178 + // its package. 179 + func HiddenKey(s, pkgPath string) string { 180 + // TODO: Consider just using space instead of \x00. 181 + return fmt.Sprintf("%s\x00%s", s, pkgPath) 182 + } 183 + 184 + // MakeNamedLabel creates a feature for the given name and feature type. 185 + func MakeNamedLabel(r StringIndexer, t FeatureType, s string) Feature { 186 + i := r.StringToIndex(s) 187 + f, err := MakeLabel(nil, i, t) 188 + if err != nil { 189 + panic("out of free string slots") 190 + } 191 + return f 192 + } 193 + 194 + // MakeIntLabel creates an integer label. 195 + func MakeIntLabel(t FeatureType, i int64) Feature { 196 + f, err := MakeLabel(nil, i, t) 197 + if err != nil { 198 + panic("index out of range") 167 199 } 168 200 return f 169 201 }
+78
internal/core/path/selector.go
··· 1 + // Copyright 2022 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 + 15 + // Package path provides utilities for converting cue.Selectors and cue.Paths to 16 + // internal equivalents. 17 + package path 18 + 19 + import ( 20 + "math/bits" 21 + 22 + "cuelang.org/go/cue" 23 + "cuelang.org/go/internal/core/adt" 24 + "cuelang.org/go/internal/core/runtime" 25 + ) 26 + 27 + // ToFeatureType converts a SelectorType constant to a FeatureType. It assumes a single label bit is set. 28 + func ToFeatureType(t cue.SelectorType) adt.FeatureType { 29 + t = t.LabelType() 30 + return adt.FeatureType(bits.Len16(uint16(t))) 31 + } 32 + 33 + // MakeFeature converts a cue.Selector to an adt.Feature for a given runtime. 34 + func MakeFeature(r *runtime.Runtime, s cue.Selector) adt.Feature { 35 + constraintType := s.ConstraintType() 36 + labelType := s.LabelType() 37 + 38 + if constraintType == cue.PatternConstraint { 39 + switch labelType { 40 + case cue.StringLabel: 41 + return adt.AnyString 42 + case cue.IndexLabel: 43 + return adt.AnyIndex 44 + 45 + // These are not really a thing at the moment: 46 + case cue.DefinitionLabel: 47 + return adt.AnyDefinition 48 + case cue.HiddenLabel: 49 + return adt.AnyHidden // TODO: fix 50 + case cue.HiddenDefinitionLabel: 51 + return adt.AnyHidden // TODO: fix 52 + default: 53 + panic("unreachable") 54 + } 55 + } 56 + 57 + switch labelType { 58 + case cue.StringLabel: 59 + return adt.MakeStringLabel(r, s.Unquoted()) 60 + 61 + case cue.IndexLabel: 62 + return adt.MakeIntLabel(adt.IntLabel, int64(s.Index())) 63 + 64 + case cue.DefinitionLabel: 65 + return adt.MakeNamedLabel(r, adt.DefinitionLabel, s.String()) 66 + 67 + case cue.HiddenLabel: 68 + str := adt.HiddenKey(s.String(), s.PkgPath()) 69 + return adt.MakeNamedLabel(r, adt.HiddenLabel, str) 70 + 71 + case cue.HiddenDefinitionLabel: 72 + str := adt.HiddenKey(s.String(), s.PkgPath()) 73 + return adt.MakeNamedLabel(r, adt.HiddenDefinitionLabel, str) 74 + 75 + default: 76 + return adt.InvalidLabel 77 + } 78 + }
+100
internal/core/path/selector_test.go
··· 1 + // Copyright 2022 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 + 15 + package path 16 + 17 + import ( 18 + "testing" 19 + 20 + "cuelang.org/go/cue" 21 + "cuelang.org/go/internal/core/adt" 22 + "cuelang.org/go/internal/core/runtime" 23 + ) 24 + 25 + // TestToFeatureType also tests that SelectorType and FeatureType are in sync. 26 + func TestToFeatureType(t *testing.T) { 27 + testCases := []struct { 28 + s cue.SelectorType 29 + f adt.FeatureType 30 + }{{ 31 + cue.InvalidSelectorType, 32 + adt.InvalidLabelType, 33 + }, { 34 + cue.StringLabel, 35 + adt.StringLabel, 36 + }, { 37 + cue.IndexLabel, 38 + adt.IntLabel, 39 + }, { 40 + cue.DefinitionLabel, 41 + adt.DefinitionLabel, 42 + }, { 43 + cue.HiddenLabel, 44 + adt.HiddenLabel, 45 + }, { 46 + cue.HiddenDefinitionLabel, 47 + adt.HiddenDefinitionLabel, 48 + }, { 49 + cue.StringLabel | cue.OptionalConstraint, 50 + adt.StringLabel, 51 + }, { 52 + cue.OptionalConstraint, 53 + adt.InvalidLabelType, 54 + }} 55 + for _, tc := range testCases { 56 + t.Run(tc.s.String(), func(t *testing.T) { 57 + if got := ToFeatureType(tc.s); got != tc.f { 58 + t.Errorf("got %v, want %v", got, tc.f) 59 + } 60 + }) 61 + } 62 + } 63 + 64 + func TestMakeFeature(t *testing.T) { 65 + testCases := []struct { 66 + sel cue.Selector 67 + str string 68 + }{{ 69 + sel: cue.Str("s-t"), 70 + str: `"s-t"`, 71 + }, { 72 + // Optional should be disregarded, as it is not part of a Feature. 73 + sel: cue.Str("s-t").Optional(), 74 + str: `"s-t"`, 75 + }, { 76 + sel: cue.Index(5), 77 + str: "5", 78 + }, { 79 + sel: cue.Def("#Foo"), 80 + str: "#Foo", 81 + }, { 82 + sel: cue.Hid("_foo", "pkg"), 83 + str: "_foo", 84 + }, { 85 + sel: cue.Hid("_#foo", "pkg"), 86 + str: "_#foo", 87 + }, { 88 + sel: cue.AnyString, 89 + str: `_`, 90 + }} 91 + for _, tc := range testCases { 92 + r := runtime.New() 93 + t.Run(tc.sel.String(), func(t *testing.T) { 94 + got := MakeFeature(r, tc.sel).SelectorString(r) 95 + if got != tc.str { 96 + t.Errorf("got %v, want %v", got, tc.str) 97 + } 98 + }) 99 + } 100 + }