this repo has no description
0
fork

Configure Feed

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

cue/internal: Make ToFile optionally preserve StructLits

internal.ToFile when passed a StructLit, would previously take its
elements, and return them in a File.

This can be problematic, because File.Pos and File.End only inspect the
Pos and End of its first and last elements. This means that if the
StructLit had explicit braces but no elements, it would go from having a
known range in its source, to having no range at all. This breaks
completions for embedded json files.

Change-Id: Ibe505be80207def55b366eca8a213a87f3f4270b
Signed-off-by: Matthew Sackman <matthew@cue.works>
Reviewed-on: https://cue.gerrithub.io/c/cue-lang/cue/+/1231227
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>

+35 -18
+1 -1
cmd/cue/cmd/eval.go
··· 168 168 } 169 169 } 170 170 171 - f := internal.ToFile(v.Syntax(syn...)) 171 + f := internal.ToFile(v.Syntax(syn...), false) 172 172 f.Filename = id 173 173 err := e.EncodeFile(f) 174 174 if err != nil {
+11 -5
cmd/cue/cmd/integration/workspace/embedded_test.go
··· 283 283 cows: bool 284 284 } 285 285 286 - glob: {"data/d1.json": s} @embed(glob=data/d*.json) 286 + glob: {"data/d1.json": s, "data/d3.json": s} @embed(glob=data/d*.json) 287 287 -- b.cue -- 288 288 package a 289 289 ··· 319 319 "cows": false 320 320 }, 321 321 "fieldCount": -1 322 + } 323 + -- data/d3.json -- 324 + { 322 325 } 323 326 ` 324 327 ··· 422 425 rootURI := env.Sandbox.Workdir.RootURI() 423 426 424 427 env.OpenFile("data/file.json") 428 + env.OpenFile("data/d3.json") 425 429 env.Await( 426 430 env.DoneWithOpen(), 427 - LogMatching(protocol.Debug, 1, false, `Package dirs=\[%v/data\] importPath=mod\.example/x/data@v0:_.+ Created`, rootURI), 428 - LogMatching(protocol.Debug, 1, false, `Package dirs=\[%v/data\] importPath=mod\.example/x/data@v0:_.+ Reloaded`, rootURI), 431 + LogMatching(protocol.Debug, 2, false, `Package dirs=\[%v/data\] importPath=mod\.example/x/data@v0:_.+ Created`, rootURI), 432 + LogMatching(protocol.Debug, 2, false, `Package dirs=\[%v/data\] importPath=mod\.example/x/data@v0:_.+ Reloaded`, rootURI), 429 433 NoLogMatching(protocol.Debug, `Package dirs=\[%v/data\] importPath=mod\.example/x@v0:a Created`, rootURI), 430 434 ) 431 435 ··· 438 442 testCases := map[position][]string{ 439 443 fln("data/file.json", 3, 1, `"`): {`"sheep"`, `"cows"`, `"horses"`}, 440 444 fln("data/file.json", 6, 1, `"`): {`"field"`, `"fieldCount"`}, 445 + fln("data/d3.json", 2, 1, `}`): {`"field"`, `"fieldCount"`}, 441 446 } 442 447 443 448 for p, expectedLabels := range testCases { ··· 455 460 qt.Assert(t, qt.ContentEquals(gotLabels, expectedLabels)) 456 461 } 457 462 458 - // Calling Hover should have caused package x:a to be loaded 459 - // because that's the package which embeds the json files. 463 + // Calling Completion should have caused package x:a to be 464 + // loaded because that's the package which embeds the json 465 + // files. 460 466 env.Await( 461 467 LogMatching(protocol.Debug, 1, false, `Package dirs=\[%v\] importPath=mod\.example/x@v0:a Created`, rootURI), 462 468 )
+1 -1
encoding/openapi/decode_test.go
··· 80 80 if inFile == nil { 81 81 var inExpr ast.Expr 82 82 inExpr, err = json.Extract(f.Name, f.Data) 83 - inFile = internal.ToFile(inExpr) 83 + inFile = internal.ToFile(inExpr, false) 84 84 } 85 85 case ".yaml": 86 86 if inFile == nil {
+3 -3
internal/encoding/encoder.go
··· 93 93 if err != nil { 94 94 return nil, err 95 95 } 96 - return internal.ToFile(expr), nil 96 + return internal.ToFile(expr, false), nil 97 97 } 98 98 case build.ProtobufJSON: 99 99 e.interpret = func(v cue.Value) (*ast.File, error) { 100 - f := internal.ToFile(v.Syntax()) 100 + f := internal.ToFile(v.Syntax(), false) 101 101 return f, jsonpb.NewEncoder(v).RewriteFile(f) 102 102 } 103 103 default: ··· 147 147 148 148 // Casting an ast.Expr to an ast.File ensures that it always ends 149 149 // with a newline. 150 - f := internal.ToFile(n) 150 + f := internal.ToFile(n, false) 151 151 if e.cfg.PkgName != "" && f.PackageName() == "" { 152 152 pkg := &ast.Package{ 153 153 PackagePos: token.NoPos.WithRel(token.NewSection),
+1 -1
internal/encoding/encoding.go
··· 113 113 if i.file != nil { 114 114 return i.file 115 115 } 116 - return internal.ToFile(i.expr) 116 + return internal.ToFile(i.expr, false) 117 117 } 118 118 119 119 func (i *Decoder) Err() error {
+1 -1
internal/encoding/yaml/decode_test.go
··· 791 791 if node == nil { 792 792 return "" 793 793 } 794 - b, _ := format.Node(internal.ToFile(node)) 794 + b, _ := format.Node(internal.ToFile(node, false)) 795 795 return strings.TrimSpace(string(b)) 796 796 } 797 797
+16 -5
internal/internal.go
··· 240 240 // ToFile converts an expression to a file. 241 241 // 242 242 // Adjusts the spacing of x when needed. 243 - func ToFile(n ast.Node) *ast.File { 243 + // 244 + // If preserveStructLit is true and n is a [*ast.StructLit], then n 245 + // will be embedded within the returned [*ast.File] rather than only 246 + // its elements being included in the returned File. This ensures that 247 + // position information of the StructLit's braces is not lost. 248 + func ToFile(n ast.Node, preserveStructLit bool) *ast.File { 244 249 if n == nil { 245 250 return nil 246 251 } 247 252 switch n := n.(type) { 248 253 case *ast.StructLit: 249 - f := &ast.File{Decls: n.Elts} 250 - // Ensure that the comments attached to the struct literal are not lost. 251 - ast.SetComments(f, ast.Comments(n)) 252 - return f 254 + if preserveStructLit { 255 + ast.SetRelPos(n, token.NoSpace) 256 + return &ast.File{Decls: []ast.Decl{&ast.EmbedDecl{Expr: n}}} 257 + 258 + } else { 259 + f := &ast.File{Decls: n.Elts} 260 + // Ensure that the comments attached to the struct literal are not lost. 261 + ast.SetComments(f, ast.Comments(n)) 262 + return f 263 + } 253 264 case ast.Expr: 254 265 ast.SetRelPos(n, token.NoSpace) 255 266 return &ast.File{Decls: []ast.Decl{&ast.EmbedDecl{Expr: n}}}
+1 -1
internal/lsp/fscache/fs_cache.go
··· 122 122 case build.JSON: 123 123 var expr ast.Expr 124 124 expr, err = parser.ParseExpr(filename, content) 125 - syntax = internal.ToFile(expr) 125 + syntax = internal.ToFile(expr, true) 126 126 if syntax == nil { 127 127 syntax = &ast.File{} 128 128 }