this repo has no description
0
fork

Configure Feed

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

cue/load: replace readimports with cueimports.Read

Pretty much the same code inherited from Go.
The way cue/load used it already matched the cueimports.Read API.

While here, fileProcessor.add only needs to use cue/parser to read
a CUE file's package clause and imported package paths,
so there is no need to parse comments at all.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: I67c5349dd691b282a8c4c1fbd3dd5daaf7f10163
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1194965
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>

+3 -459
+1 -1
cue/load/loader_common.go
··· 211 211 return false 212 212 } 213 213 214 - pf, perr := parser.ParseFile(fullPath, data, parser.ImportsOnly, parser.ParseComments) 214 + pf, perr := parser.ParseFile(fullPath, data, parser.ImportsOnly) 215 215 if perr != nil { 216 216 badFile(errors.Promote(perr, "add failed")) 217 217 return true
+2 -1
cue/load/match.go
··· 21 21 "cuelang.org/go/cue/build" 22 22 "cuelang.org/go/cue/errors" 23 23 "cuelang.org/go/cue/token" 24 + "cuelang.org/go/internal/cueimports" 24 25 ) 25 26 26 27 // A match represents the result of matching a single package pattern. ··· 74 75 return false, nil, err 75 76 } 76 77 77 - data, err = readImports(f, false, nil) 78 + data, err = cueimports.Read(f) 78 79 f.Close() 79 80 if err != nil { 80 81 return false, nil,
-247
cue/load/read.go
··· 1 - // Copyright 2018 The 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 load 16 - 17 - import ( 18 - "bufio" 19 - "io" 20 - "unicode/utf8" 21 - 22 - "cuelang.org/go/cue/errors" 23 - "cuelang.org/go/cue/token" 24 - ) 25 - 26 - type importReader struct { 27 - b *bufio.Reader 28 - buf []byte 29 - peek byte 30 - err errors.Error 31 - eof bool 32 - nerr int 33 - } 34 - 35 - func isIdent(c byte) bool { 36 - return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf 37 - } 38 - 39 - var ( 40 - errSyntax = errors.Newf(token.NoPos, "syntax error") // TODO: remove 41 - errNUL = errors.Newf(token.NoPos, "unexpected NUL in input") 42 - ) 43 - 44 - // syntaxError records a syntax error, but only if an I/O error has not already been recorded. 45 - func (r *importReader) syntaxError() { 46 - if r.err == nil { 47 - r.err = errSyntax 48 - } 49 - } 50 - 51 - // readByte reads the next byte from the input, saves it in buf, and returns it. 52 - // If an error occurs, readByte records the error in r.err and returns 0. 53 - func (r *importReader) readByte() byte { 54 - c, err := r.b.ReadByte() 55 - if err == nil { 56 - r.buf = append(r.buf, c) 57 - if c == 0 { 58 - err = errNUL 59 - } 60 - } 61 - if err != nil { 62 - if err == io.EOF { 63 - r.eof = true 64 - } else if r.err == nil { 65 - r.err = errors.Wrapf(err, token.NoPos, "readByte") 66 - } 67 - c = 0 68 - } 69 - return c 70 - } 71 - 72 - // peekByte returns the next byte from the input reader but does not advance beyond it. 73 - // If skipSpace is set, peekByte skips leading spaces and comments. 74 - func (r *importReader) peekByte(skipSpace bool) byte { 75 - if r.err != nil { 76 - if r.nerr++; r.nerr > 10000 { 77 - panic("go/build: import reader looping") 78 - } 79 - return 0 80 - } 81 - 82 - // Use r.peek as first input byte. 83 - // Don't just return r.peek here: it might have been left by peekByte(false) 84 - // and this might be peekByte(true). 85 - c := r.peek 86 - if c == 0 { 87 - c = r.readByte() 88 - } 89 - for r.err == nil && !r.eof { 90 - if skipSpace { 91 - // For the purposes of this reader, semicolons are never necessary to 92 - // understand the input and are treated as spaces. 93 - switch c { 94 - case ' ', '\f', '\t', '\r', '\n', ';': 95 - c = r.readByte() 96 - continue 97 - 98 - case '/': 99 - c = r.readByte() 100 - if c == '/' { 101 - for c != '\n' && r.err == nil && !r.eof { 102 - c = r.readByte() 103 - } 104 - } else if c == '*' { 105 - var c1 byte 106 - for (c != '*' || c1 != '/') && r.err == nil { 107 - if r.eof { 108 - r.syntaxError() 109 - } 110 - c, c1 = c1, r.readByte() 111 - } 112 - } else { 113 - r.syntaxError() 114 - } 115 - c = r.readByte() 116 - continue 117 - } 118 - } 119 - break 120 - } 121 - r.peek = c 122 - return r.peek 123 - } 124 - 125 - // nextByte is like peekByte but advances beyond the returned byte. 126 - func (r *importReader) nextByte(skipSpace bool) byte { 127 - c := r.peekByte(skipSpace) 128 - r.peek = 0 129 - return c 130 - } 131 - 132 - // readKeyword reads the given keyword from the input. 133 - // If the keyword is not present, readKeyword records a syntax error. 134 - func (r *importReader) readKeyword(kw string) { 135 - r.peekByte(true) 136 - for i := 0; i < len(kw); i++ { 137 - if r.nextByte(false) != kw[i] { 138 - r.syntaxError() 139 - return 140 - } 141 - } 142 - if isIdent(r.peekByte(false)) { 143 - r.syntaxError() 144 - } 145 - } 146 - 147 - // readIdent reads an identifier from the input. 148 - // If an identifier is not present, readIdent records a syntax error. 149 - func (r *importReader) readIdent() { 150 - c := r.peekByte(true) 151 - if !isIdent(c) { 152 - r.syntaxError() 153 - return 154 - } 155 - for isIdent(r.peekByte(false)) { 156 - r.peek = 0 157 - } 158 - } 159 - 160 - // readString reads a quoted string literal from the input. 161 - // If an identifier is not present, readString records a syntax error. 162 - func (r *importReader) readString(save *[]string) { 163 - switch r.nextByte(true) { 164 - case '`': 165 - start := len(r.buf) - 1 166 - for r.err == nil { 167 - if r.nextByte(false) == '`' { 168 - if save != nil { 169 - *save = append(*save, string(r.buf[start:])) 170 - } 171 - break 172 - } 173 - if r.eof { 174 - r.syntaxError() 175 - } 176 - } 177 - case '"': 178 - start := len(r.buf) - 1 179 - for r.err == nil { 180 - c := r.nextByte(false) 181 - if c == '"' { 182 - if save != nil { 183 - *save = append(*save, string(r.buf[start:])) 184 - } 185 - break 186 - } 187 - if r.eof || c == '\n' { 188 - r.syntaxError() 189 - } 190 - if c == '\\' { 191 - r.nextByte(false) 192 - } 193 - } 194 - default: 195 - r.syntaxError() 196 - } 197 - } 198 - 199 - // readImport reads an import clause - optional identifier followed by quoted string - 200 - // from the input. 201 - func (r *importReader) readImport(imports *[]string) { 202 - c := r.peekByte(true) 203 - if c == '.' { 204 - r.peek = 0 205 - } else if isIdent(c) { 206 - r.readIdent() 207 - } 208 - r.readString(imports) 209 - } 210 - 211 - // readImports is like io.ReadAll, except that it expects a CUE file as 212 - // input and stops reading the input once the imports have completed. 213 - func readImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, errors.Error) { 214 - r := &importReader{b: bufio.NewReader(f)} 215 - 216 - r.readKeyword("package") 217 - r.readIdent() 218 - for r.peekByte(true) == 'i' { 219 - r.readKeyword("import") 220 - if r.peekByte(true) == '(' { 221 - r.nextByte(false) 222 - for r.peekByte(true) != ')' && r.err == nil { 223 - r.readImport(imports) 224 - } 225 - r.nextByte(false) 226 - } else { 227 - r.readImport(imports) 228 - } 229 - } 230 - 231 - // If we stopped successfully before EOF, we read a byte that told us we were done. 232 - // Return all but that last byte, which would cause a syntax error if we let it through. 233 - if r.err == nil && !r.eof { 234 - return r.buf[:len(r.buf)-1], nil 235 - } 236 - 237 - // If we stopped for a syntax error, consume the whole file so that 238 - // we are sure we don't change the errors that go/parser returns. 239 - if r.err == errSyntax && !reportSyntaxError { 240 - r.err = nil 241 - for r.err == nil && !r.eof { 242 - r.readByte() 243 - } 244 - } 245 - 246 - return r.buf, r.err 247 - }
-210
cue/load/read_test.go
··· 1 - // Copyright 2018 The 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 load 16 - 17 - import ( 18 - "io" 19 - "strings" 20 - "testing" 21 - 22 - "cuelang.org/go/cue/errors" 23 - ) 24 - 25 - const quote = "`" 26 - 27 - type readTest struct { 28 - // Test input contains ℙ where readImports should stop. 29 - in string 30 - err string 31 - } 32 - 33 - var readImportsTests = []readTest{ 34 - { 35 - `package p`, 36 - "", 37 - }, 38 - { 39 - `package p; import "x"`, 40 - "", 41 - }, 42 - { 43 - `package p; import . "x"`, 44 - "", 45 - }, 46 - { 47 - `package p; import "x";ℙvar x = 1`, 48 - "", 49 - }, 50 - { 51 - `package p 52 - 53 - // comment 54 - 55 - import "x" 56 - import _ "x" 57 - import a "x" 58 - 59 - import ( 60 - "x" 61 - _ "x" 62 - a "x" // comment 63 - ` + quote + `x` + quote + ` 64 - _ ` + quote + `x` + quote + ` 65 - a ` + quote + `x` + quote + ` 66 - ) 67 - import ( 68 - ) 69 - import () 70 - import()import()import() 71 - import();import();import() 72 - 73 - ℙvar x = 1 74 - `, 75 - "", 76 - }, 77 - } 78 - 79 - func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, errors.Error)) { 80 - for i, tt := range tests { 81 - var in, testOut string 82 - j := strings.Index(tt.in, "ℙ") 83 - if j < 0 { 84 - in = tt.in 85 - testOut = tt.in 86 - } else { 87 - in = tt.in[:j] + tt.in[j+len("ℙ"):] 88 - testOut = tt.in[:j] 89 - } 90 - r := strings.NewReader(in) 91 - buf, err := read(r) 92 - if err != nil { 93 - if tt.err == "" { 94 - t.Errorf("#%d: err=%q, expected success (%q)", i, err, string(buf)) 95 - continue 96 - } 97 - if !strings.Contains(err.Error(), tt.err) { 98 - t.Errorf("#%d: err=%q, expected %q", i, err, tt.err) 99 - continue 100 - } 101 - continue 102 - } 103 - if tt.err != "" { 104 - t.Errorf("#%d: success, expected %q", i, tt.err) 105 - continue 106 - } 107 - 108 - out := string(buf) 109 - if out != testOut { 110 - t.Errorf("#%d: wrong output:\nhave %q\nwant %q\n", i, out, testOut) 111 - } 112 - } 113 - } 114 - 115 - func TestReadImports(t *testing.T) { 116 - testRead(t, readImportsTests, func(r io.Reader) ([]byte, errors.Error) { 117 - return readImports(r, true, nil) 118 - }) 119 - } 120 - 121 - var readFailuresTests = []readTest{ 122 - { 123 - `package`, 124 - "syntax error", 125 - }, 126 - { 127 - "package p\n\x00\nimport `math`\n", 128 - "unexpected NUL in input", 129 - }, 130 - { 131 - `package p; import`, 132 - "syntax error", 133 - }, 134 - { 135 - `package p; import "`, 136 - "syntax error", 137 - }, 138 - { 139 - "package p; import ` \n\n", 140 - "syntax error", 141 - }, 142 - { 143 - `package p; import "x`, 144 - "syntax error", 145 - }, 146 - { 147 - `package p; import _`, 148 - "syntax error", 149 - }, 150 - { 151 - `package p; import _ "`, 152 - "syntax error", 153 - }, 154 - { 155 - `package p; import _ "x`, 156 - "syntax error", 157 - }, 158 - { 159 - `package p; import .`, 160 - "syntax error", 161 - }, 162 - { 163 - `package p; import . "`, 164 - "syntax error", 165 - }, 166 - { 167 - `package p; import . "x`, 168 - "syntax error", 169 - }, 170 - { 171 - `package p; import (`, 172 - "syntax error", 173 - }, 174 - { 175 - `package p; import ("`, 176 - "syntax error", 177 - }, 178 - { 179 - `package p; import ("x`, 180 - "syntax error", 181 - }, 182 - { 183 - `package p; import ("x"`, 184 - "syntax error", 185 - }, 186 - } 187 - 188 - func TestReadFailures(t *testing.T) { 189 - // Errors should be reported (true arg to readImports). 190 - testRead(t, readFailuresTests, func(r io.Reader) ([]byte, errors.Error) { 191 - return readImports(r, true, nil) 192 - }) 193 - } 194 - 195 - func TestReadFailuresIgnored(t *testing.T) { 196 - // Syntax errors should not be reported (false arg to readImports). 197 - // Instead, entire file should be the output and no error. 198 - // Convert tests not to return syntax errors. 199 - tests := make([]readTest, len(readFailuresTests)) 200 - copy(tests, readFailuresTests) 201 - for i := range tests { 202 - tt := &tests[i] 203 - if !strings.Contains(tt.err, "NUL") { 204 - tt.err = "" 205 - } 206 - } 207 - testRead(t, tests, func(r io.Reader) ([]byte, errors.Error) { 208 - return readImports(r, false, nil) 209 - }) 210 - }