Skip to content

Commit a7eda13

Browse files
committed
cue: remove all support for quoted identifiers
Note that QuoteIdent has now been removed alltogether. Affected packages: - cue/scanner - cue/parser - cue/ast - tools/fix - faulty spec reference Fixes #1475 Signed-off-by: Marcel van Lohuizen <mpvl@golang.org> Change-Id: Ide35cb383bc303955eef516928a7e1e5d0602fc7 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/531206 Unity-Result: CUEcueckoo <cueckoo@cuelang.org> TryBot-Result: CUEcueckoo <cueckoo@cuelang.org> Reviewed-by: Paul Jolly <paul@myitcv.io>
1 parent 6bc922c commit a7eda13

File tree

8 files changed

+3
-196
lines changed

8 files changed

+3
-196
lines changed

cue/ast/ident.go

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -68,38 +68,6 @@ func IsValidIdent(ident string) bool {
6868
return true
6969
}
7070

71-
// QuoteIdent quotes an identifier, if needed, and reports
72-
// an error if the identifier is invalid.
73-
//
74-
// Deprecated: quoted identifiers are deprecated. Use aliases.
75-
func QuoteIdent(ident string) (string, error) {
76-
if ident != "" && ident[0] == '`' {
77-
if _, err := strconv.Unquote(ident); err != nil {
78-
return "", errors.Newf(token.NoPos, "invalid quoted identifier %q", ident)
79-
}
80-
return ident, nil
81-
}
82-
83-
// TODO: consider quoting keywords
84-
// switch ident {
85-
// case "for", "in", "if", "let", "true", "false", "null":
86-
// goto escape
87-
// }
88-
89-
for _, r := range ident {
90-
if isLetter(r) || isDigit(r) || r == '_' || r == '$' {
91-
continue
92-
}
93-
if r == '-' {
94-
return "`" + ident + "`", nil
95-
}
96-
return "", errors.Newf(token.NoPos, "invalid character '%s' in identifier", string(r))
97-
}
98-
99-
_, err := parseIdent(token.NoPos, ident)
100-
return ident, err
101-
}
102-
10371
// ParseIdent unquotes a possibly quoted identifier and validates
10472
// if the result is valid.
10573
//

cue/parser/parser.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,6 @@ func (p *parser) next() {
388388
p.comments.add(comment)
389389
}
390390
}
391-
392-
if p.tok == token.IDENT && p.lit[0] == '`' {
393-
p.assertV0(p.pos, 0, 13, "quoted identifiers")
394-
}
395391
}
396392

397393
// assertV0 indicates the last version at which a certain feature was

cue/scanner/scanner.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -296,32 +296,6 @@ func isExtendedIdent(r rune) bool {
296296
return strings.IndexRune("-_#$%. ", r) >= 0
297297
}
298298

299-
func (s *Scanner) scanQuotedIdentifier() string {
300-
offs := s.offset - 1 // quote already consumed
301-
hasInvalid := false
302-
for ; ; s.next() {
303-
switch {
304-
default:
305-
if !hasInvalid {
306-
s.errf(s.offset, "invalid character '%s' in identifier", string(s.ch))
307-
hasInvalid = true
308-
}
309-
continue
310-
311-
case isLetter(s.ch) || isDigit(s.ch) || isExtendedIdent(s.ch):
312-
continue
313-
314-
case s.ch == '`':
315-
s.next()
316-
return string(s.src[offs:s.offset])
317-
318-
case s.ch == '\n':
319-
s.errf(s.offset, "quoted identifier not terminated")
320-
return string(s.src[offs:s.offset])
321-
}
322-
}
323-
}
324-
325299
func digitVal(ch rune) int {
326300
switch {
327301
case '0' <= ch && ch <= '9':
@@ -821,10 +795,6 @@ scanAgain:
821795
lit = "_" + s.scanFieldIdentifier()
822796
}
823797
insertEOL = true
824-
case '`':
825-
tok = token.IDENT
826-
lit = s.scanQuotedIdentifier()
827-
insertEOL = true
828798

829799
case '\n':
830800
// we only reach here if s.insertComma was

cue/scanner/scanner_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ var testTokens = [...]elt{
8585
{token.IDENT, "#_foobar", literal},
8686
{token.IDENT, "_#foobar", literal},
8787
{token.IDENT, "__#foobar", literal},
88-
{token.IDENT, "`foobar`", literal},
8988
{token.IDENT, "a۰۱۸", literal},
9089
{token.IDENT, "foo६४", literal},
9190
{token.IDENT, "bar9876", literal},
@@ -739,14 +738,13 @@ var errorTests = []struct {
739738
lit string
740739
err string
741740
}{
741+
{"`", token.ILLEGAL, 0, "", "illegal character U+0060 '`'"},
742+
742743
{"\a", token.ILLEGAL, 0, "", "illegal character U+0007"},
743744
{`^`, token.ILLEGAL, 0, "", "illegal character U+005E '^'"},
744745
{`…`, token.ILLEGAL, 0, "", "illegal character U+2026 '…'"},
745746
{`_|`, token.ILLEGAL, 0, "", "illegal token '_|'; expected '_'"},
746747

747-
{"`foo=bar`", token.IDENT, 4, "`foo=bar`", "invalid character '=' in identifier"},
748-
{"`foo\nbar`", token.IDENT, 4, "`foo", "quoted identifier not terminated"},
749-
750748
{`@`, token.ATTRIBUTE, 1, `@`, "invalid attribute: expected '('"},
751749
{`@foo`, token.ATTRIBUTE, 4, `@foo`, "invalid attribute: expected '('"},
752750
{`@foo(`, token.ATTRIBUTE, 5, `@foo(`, "attribute missing ')'"},
@@ -784,6 +782,7 @@ var errorTests = []struct {
784782
{`"\U00000000"`, token.STRING, 0, `"\U00000000"`, ""},
785783
{`"\Uffffffff"`, token.STRING, 2, `"\Uffffffff"`, "escape sequence is invalid Unicode code point"},
786784
{`'`, token.STRING, 0, `'`, "string literal not terminated"},
785+
{`"`, token.STRING, 0, `"`, "string literal not terminated"},
787786
{`""`, token.STRING, 0, `""`, ""},
788787
{`"abc`, token.STRING, 0, `"abc`, "string literal not terminated"},
789788
{`""abc`, token.STRING, 0, `""`, ""},

cue/testdata/resolve/003_resolution_of_quoted_identifiers.txtar

Lines changed: 0 additions & 7 deletions
This file was deleted.

doc/ref/spec.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,6 @@ These examples all represent the same string:
484484
```
485485
"日本語" // UTF-8 input text
486486
'日本語' // UTF-8 input text as byte sequence
487-
`日本語` // UTF-8 input text as a raw literal
488487
"\u65e5\u672c\u8a9e" // the explicit Unicode code points
489488
"\U000065e5\U0000672c\U00008a9e" // the explicit Unicode code points
490489
'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e' // the explicit UTF-8 bytes

tools/fix/fix.go

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
package fix
2121

2222
import (
23-
"fmt"
2423
"strings"
2524

2625
"cuelang.org/go/cue/ast"
@@ -122,95 +121,6 @@ func File(f *ast.File, o ...Option) *ast.File {
122121
return true
123122
}, nil)
124123

125-
// Referred nodes and used identifiers.
126-
referred := map[ast.Node]string{}
127-
used := map[string]bool{}
128-
replacement := map[ast.Node]string{}
129-
130-
ast.Walk(f, func(n ast.Node) bool {
131-
if i, ok := n.(*ast.Ident); ok {
132-
str, err := ast.ParseIdent(i)
133-
if err != nil {
134-
return false
135-
}
136-
referred[i.Node] = str
137-
used[str] = true
138-
}
139-
return true
140-
}, nil)
141-
142-
num := 0
143-
newIdent := func() string {
144-
for num++; ; num++ {
145-
str := fmt.Sprintf("X%d", num)
146-
if !used[str] {
147-
used[str] = true
148-
return str
149-
}
150-
}
151-
}
152-
153-
// Rewrite quoted identifier fields that are referenced.
154-
f = astutil.Apply(f, func(c astutil.Cursor) bool {
155-
n := c.Node()
156-
switch x := n.(type) {
157-
case *ast.Field:
158-
m, ok := referred[x.Value]
159-
if !ok {
160-
break
161-
}
162-
163-
if b, ok := x.Label.(*ast.Ident); ok {
164-
str, err := ast.ParseIdent(b)
165-
var expr ast.Expr = b
166-
167-
switch {
168-
case token.Lookup(str) != token.IDENT:
169-
// quote keywords
170-
expr = ast.NewString(b.Name)
171-
172-
case err != nil || str != m || str == b.Name:
173-
return true
174-
175-
case ast.IsValidIdent(str):
176-
x.Label = astutil.CopyMeta(ast.NewIdent(str), x.Label).(ast.Label)
177-
return true
178-
}
179-
180-
ident := newIdent()
181-
replacement[x.Value] = ident
182-
expr = &ast.Alias{Ident: ast.NewIdent(ident), Expr: expr}
183-
ast.SetRelPos(x.Label, token.NoRelPos)
184-
x.Label = astutil.CopyMeta(expr, x.Label).(ast.Label)
185-
}
186-
}
187-
return true
188-
}, nil).(*ast.File)
189-
190-
// Replace quoted references with their alias identifier.
191-
astutil.Apply(f, func(c astutil.Cursor) bool {
192-
n := c.Node()
193-
switch x := n.(type) {
194-
case *ast.Ident:
195-
if r, ok := replacement[x.Node]; ok {
196-
c.Replace(astutil.CopyMeta(ast.NewIdent(r), n))
197-
break
198-
}
199-
str, err := ast.ParseIdent(x)
200-
if err != nil || str == x.Name {
201-
break
202-
}
203-
// Either the identifier is valid, in which can be replaced simply
204-
// as here, or it is a complicated identifier and the original
205-
// destination must have been quoted, in which case it is handled
206-
// above.
207-
if ast.IsValidIdent(str) && token.Lookup(str) == token.IDENT {
208-
c.Replace(astutil.CopyMeta(ast.NewIdent(str), n))
209-
}
210-
}
211-
return true
212-
}, nil)
213-
214124
// TODO: we are probably reintroducing slices. Disable for now.
215125
//
216126
// Rewrite slice expression.

tools/fix/fix_test.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,6 @@ a: __div(1, 2)
4242
b: __mod(3, 5)
4343
c: __quo(2, 9)
4444
d: __rem(1.0, 1.0) // pass on illegal values.
45-
`,
46-
}, {
47-
name: "referenced quoted fields",
48-
in: `package foo
49-
50-
a: {
51-
fiz: 4
52-
faz: ` + "`fiz`" + `
53-
54-
// biz
55-
` + "`biz`" + `: 5 // biz
56-
buz: ` + "`biz`" + `
57-
in: 3
58-
ref: ` + "`in`" + ` & x
59-
}
60-
`,
61-
out: `package foo
62-
63-
a: {
64-
fiz: 4
65-
faz: fiz
66-
67-
// biz
68-
biz: 5 // biz
69-
buz: biz
70-
X1="in": 3
71-
ref: X1 & x
72-
}
7345
`,
7446
}, {
7547
in: `

0 commit comments

Comments
 (0)