this repo has no description
0
fork

Configure Feed

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

at master 96 lines 2.9 kB view raw
1// 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 export 16 17import ( 18 "crypto/md5" 19 "fmt" 20 "io" 21 "strconv" 22 23 "cuelang.org/go/cue/ast" 24 "cuelang.org/go/cue/token" 25 "cuelang.org/go/internal/core/adt" 26) 27 28func (e *exporter) stringLabel(f adt.Feature) ast.Label { 29 x := f.Index() 30 switch f.Typ() { 31 case adt.IntLabel: 32 return ast.NewLit(token.INT, strconv.Itoa(x)) 33 34 case adt.DefinitionLabel, adt.HiddenLabel, adt.HiddenDefinitionLabel: 35 s := e.identString(f) 36 return ast.NewIdent(s) 37 38 default: 39 return ast.NewStringLabel(e.ctx.IndexToString(int64(x))) 40 } 41} 42 43// identString converts the given Feature f to an identifier string. 44// 45// Hidden field mangling: 46// 47// If f is a hidden field that comes from an expanded package, it will mangle 48// the name by expending it with the MD5 hash of the package name. This is to 49// avoid collisions of the hidden identifiers when namespaces are merged. 50// It uses the MD5 hash to allow hidden fields from the same package to 51// still match across inlining and unifications. 52// 53// TODO: Alternatives approaches to consider: 54// 1. Rewrite to unique hidden field names. This means, though, that hidden 55// fields may not match across unifications. That may be okay. 56// 2. Force inline hidden fields from such packages, or translate them to let 57// expressions when necessary. This should generally preserve semantics 58// quite well. 59// 3. Allow addressing hidden fields across packages, for instance by allowing 60// `_(hiddenField, pkg: "import/path")`. This kind of defeats the purpose 61// of hidden fields, though. 62// 63// Option 2 seems the best long-term solution. It should be possible to 64// piggyback on the self containment algorithm for this: basically, whenever 65// we see a hidden reference of an inlined package, we treat it as an 66// external reference itself. 67// 68// For now, as this only can occur when the InlineImports feature is used, 69// we use this simpler approach. 70func (e *exporter) identString(f adt.Feature) string { 71 s := f.IdentString(e.ctx) 72 73 if !f.IsHidden() || !e.cfg.InlineImports { 74 return s 75 } 76 77 pkg := f.PkgID(e.ctx) 78 if pkg == "" || pkg == "_" || pkg == e.pkgID { 79 return s 80 } 81 82 if e.pkgHash == nil { 83 e.pkgHash = map[string]string{} 84 } 85 id, ok := e.pkgHash[pkg] 86 if !ok { 87 h := md5.New() 88 io.WriteString(h, pkg) 89 b := h.Sum(nil) 90 id = fmt.Sprintf("_%8X", b[:4]) 91 e.pkgHash[pkg] = id 92 } 93 s += id 94 95 return s 96}