all: implement hidden identifiers scoped per-package
This has been part of the spec for a long time, but never implemented.
Note that all files with the same package name within a module
belong to the same package. A hidden identifier is thus uniqued by
module+name.
Closes #65
Fixes #503
Change-Id: I6d97ca1dbcf4ccc5730fde2cf8193c8e667787ad
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7361
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/core/adt/feature.go b/internal/core/adt/feature.go
index 6ee3b6a..0356e02 100644
--- a/internal/core/adt/feature.go
+++ b/internal/core/adt/feature.go
@@ -15,6 +15,7 @@
package adt
import (
+ "fmt"
"strconv"
"strings"
@@ -68,10 +69,36 @@
}
return literal.String.Quote(s)
default:
- return index.IndexToString(int64(x))
+ return f.IdentString(index)
}
}
+// IdentString reports the identifier of f. The result is undefined if f
+// is not an identifier label.
+func (f Feature) IdentString(index StringIndexer) string {
+ s := index.IndexToString(int64(f.Index()))
+ if f.IsHidden() {
+ if p := strings.IndexByte(s, '\x00'); p >= 0 {
+ s = s[:p]
+ }
+ }
+ return s
+}
+
+// PkgID returns the package identifier, composed of the module and package
+// name, associated with this identifier. It will return "" if this is not
+// a hidden label.
+func (f Feature) PkgID(index StringIndexer) string {
+ if !f.IsHidden() {
+ return ""
+ }
+ s := index.IndexToString(int64(f.Index()))
+ if p := strings.IndexByte(s, '\x00'); p >= 0 {
+ return s[p+1:]
+ }
+ return s
+}
+
// StringValue reports the string value of f, which must be a string label.
func (f Feature) StringValue(index StringIndexer) string {
if !f.IsString() {
@@ -113,17 +140,19 @@
}
// MakeIdentLabel creates a label for the given identifier.
-func MakeIdentLabel(r StringIndexer, s string) Feature {
- i := r.StringToIndex(s)
+func MakeIdentLabel(r StringIndexer, s, pkgpath string) Feature {
t := StringLabel
switch {
case strings.HasPrefix(s, "_#"):
t = HiddenDefinitionLabel
+ s = fmt.Sprintf("%s\x00%s", s, pkgpath)
case strings.HasPrefix(s, "#"):
t = DefinitionLabel
case strings.HasPrefix(s, "_"):
+ s = fmt.Sprintf("%s\x00%s", s, pkgpath)
t = HiddenLabel
}
+ i := r.StringToIndex(s)
f, err := MakeLabel(nil, i, t)
if err != nil {
panic("out of free string slots")