@@ -187,6 +187,10 @@ type snapshot struct {
187
187
// active packages. Running type checking batches in parallel after an
188
188
// invalidation can cause redundant calculation of this shared state.
189
189
typeCheckMu sync.Mutex
190
+
191
+ // options holds the user configuration at the time this snapshot was
192
+ // created.
193
+ options * source.Options
190
194
}
191
195
192
196
var globalSnapshotID uint64
@@ -275,12 +279,39 @@ func (s *snapshot) View() source.View {
275
279
return s .view
276
280
}
277
281
278
- func (s * snapshot ) FileKind (h source.FileHandle ) source.FileKind {
279
- return s .view .FileKind (h )
282
+ func (s * snapshot ) FileKind (fh source.FileHandle ) source.FileKind {
283
+ // The kind of an unsaved buffer comes from the
284
+ // TextDocumentItem.LanguageID field in the didChange event,
285
+ // not from the file name. They may differ.
286
+ if o , ok := fh .(* Overlay ); ok {
287
+ if o .kind != source .UnknownKind {
288
+ return o .kind
289
+ }
290
+ }
291
+
292
+ fext := filepath .Ext (fh .URI ().Filename ())
293
+ switch fext {
294
+ case ".go" :
295
+ return source .Go
296
+ case ".mod" :
297
+ return source .Mod
298
+ case ".sum" :
299
+ return source .Sum
300
+ case ".work" :
301
+ return source .Work
302
+ }
303
+ exts := s .options .TemplateExtensions
304
+ for _ , ext := range exts {
305
+ if fext == ext || fext == "." + ext {
306
+ return source .Tmpl
307
+ }
308
+ }
309
+ // and now what? This should never happen, but it does for cgo before go1.15
310
+ return source .Go
280
311
}
281
312
282
313
func (s * snapshot ) Options () * source.Options {
283
- return s .view . Options () // temporarily return view options.
314
+ return s .options // temporarily return view options.
284
315
}
285
316
286
317
func (s * snapshot ) BackgroundContext () context.Context {
@@ -306,7 +337,7 @@ func (s *snapshot) Templates() map[span.URI]source.FileHandle {
306
337
307
338
tmpls := map [span.URI ]source.FileHandle {}
308
339
s .files .Range (func (k span.URI , fh source.FileHandle ) {
309
- if s .view . FileKind (fh ) == source .Tmpl {
340
+ if s .FileKind (fh ) == source .Tmpl {
310
341
tmpls [k ] = fh
311
342
}
312
343
})
@@ -354,8 +385,7 @@ func (s *snapshot) workspaceMode() workspaceMode {
354
385
return mode
355
386
}
356
387
mode |= moduleMode
357
- options := s .view .Options ()
358
- if options .TempModfile {
388
+ if s .options .TempModfile {
359
389
mode |= tempModfile
360
390
}
361
391
return mode
@@ -368,9 +398,6 @@ func (s *snapshot) workspaceMode() workspaceMode {
368
398
// multiple modules in on config, so buildOverlay needs to filter overlays by
369
399
// module.
370
400
func (s * snapshot ) config (ctx context.Context , inv * gocommand.Invocation ) * packages.Config {
371
- s .view .optionsMu .Lock ()
372
- verboseOutput := s .view .options .VerboseOutput
373
- s .view .optionsMu .Unlock ()
374
401
375
402
cfg := & packages.Config {
376
403
Context : ctx ,
@@ -393,7 +420,7 @@ func (s *snapshot) config(ctx context.Context, inv *gocommand.Invocation) *packa
393
420
panic ("go/packages must not be used to parse files" )
394
421
},
395
422
Logf : func (format string , args ... interface {}) {
396
- if verboseOutput {
423
+ if s . options . VerboseOutput {
397
424
event .Log (ctx , fmt .Sprintf (format , args ... ))
398
425
}
399
426
},
@@ -475,18 +502,16 @@ func (s *snapshot) RunGoCommands(ctx context.Context, allowNetwork bool, wd stri
475
502
// it used only after call to tempModFile. Clarify that it is only
476
503
// non-nil on success.
477
504
func (s * snapshot ) goCommandInvocation (ctx context.Context , flags source.InvocationFlags , inv * gocommand.Invocation ) (tmpURI span.URI , updatedInv * gocommand.Invocation , cleanup func (), err error ) {
478
- s .view .optionsMu .Lock ()
479
- allowModfileModificationOption := s .view .options .AllowModfileModifications
480
- allowNetworkOption := s .view .options .AllowImplicitNetworkAccess
505
+ allowModfileModificationOption := s .options .AllowModfileModifications
506
+ allowNetworkOption := s .options .AllowImplicitNetworkAccess
481
507
482
508
// TODO(rfindley): this is very hard to follow, and may not even be doing the
483
509
// right thing: should inv.Env really trample view.options? Do we ever invoke
484
510
// this with a non-empty inv.Env?
485
511
//
486
512
// We should refactor to make it clearer that the correct env is being used.
487
- inv .Env = append (append (append (os .Environ (), s .view .options .EnvSlice ()... ), inv .Env ... ), "GO111MODULE=" + s .view .GO111MODULE ())
488
- inv .BuildFlags = append ([]string {}, s .view .options .BuildFlags ... )
489
- s .view .optionsMu .Unlock ()
513
+ inv .Env = append (append (append (os .Environ (), s .options .EnvSlice ()... ), inv .Env ... ), "GO111MODULE=" + s .view .GO111MODULE ())
514
+ inv .BuildFlags = append ([]string {}, s .options .BuildFlags ... )
490
515
cleanup = func () {} // fallback
491
516
492
517
// All logic below is for module mode.
@@ -993,8 +1018,7 @@ func (s *snapshot) workspaceDirs(ctx context.Context) []string {
993
1018
// Code) that do not send notifications for individual files in a directory
994
1019
// when the entire directory is deleted.
995
1020
func (s * snapshot ) watchSubdirs () bool {
996
- opts := s .view .Options ()
997
- switch p := opts .SubdirWatchPatterns ; p {
1021
+ switch p := s .options .SubdirWatchPatterns ; p {
998
1022
case source .SubdirWatchPatternsOn :
999
1023
return true
1000
1024
case source .SubdirWatchPatternsOff :
@@ -1007,7 +1031,7 @@ func (s *snapshot) watchSubdirs() bool {
1007
1031
// requirements that client names do not change. We should update the VS
1008
1032
// Code extension to set a default value of "subdirWatchPatterns" to "on",
1009
1033
// so that this workaround is only temporary.
1010
- if opts . ClientInfo != nil && opts .ClientInfo .Name == "Visual Studio Code" {
1034
+ if s . options . ClientInfo != nil && s . options .ClientInfo .Name == "Visual Studio Code" {
1011
1035
return true
1012
1036
}
1013
1037
return false
@@ -1505,7 +1529,7 @@ func (s *snapshot) reloadOrphanedOpenFiles(ctx context.Context) error {
1505
1529
var files []* Overlay
1506
1530
for _ , o := range open {
1507
1531
uri := o .URI ()
1508
- if s .IsBuiltin (uri ) || s .view . FileKind (o ) != source .Go {
1532
+ if s .IsBuiltin (uri ) || s .FileKind (o ) != source .Go {
1509
1533
continue
1510
1534
}
1511
1535
if len (meta .ids [uri ]) == 0 {
@@ -1606,7 +1630,7 @@ func (s *snapshot) OrphanedFileDiagnostics(ctx context.Context) (map[span.URI]*s
1606
1630
searchOverlays:
1607
1631
for _ , o := range s .overlays () {
1608
1632
uri := o .URI ()
1609
- if s .IsBuiltin (uri ) || s .view . FileKind (o ) != source .Go {
1633
+ if s .IsBuiltin (uri ) || s .FileKind (o ) != source .Go {
1610
1634
continue
1611
1635
}
1612
1636
md , err := s .MetadataForFile (ctx , uri )
@@ -1805,7 +1829,7 @@ func inVendor(uri span.URI) bool {
1805
1829
return found && strings .Contains (after , "/" )
1806
1830
}
1807
1831
1808
- func (s * snapshot ) clone (ctx , bgCtx context.Context , changes map [span.URI ]source.FileHandle , forceReloadMetadata bool ) (* snapshot , func ()) {
1832
+ func (s * snapshot ) clone (ctx , bgCtx context.Context , changes map [span.URI ]source.FileHandle , newOptions * source. Options , forceReloadMetadata bool ) (* snapshot , func ()) {
1809
1833
ctx , done := event .Start (ctx , "cache.snapshot.clone" )
1810
1834
defer done ()
1811
1835
@@ -1838,6 +1862,11 @@ func (s *snapshot) clone(ctx, bgCtx context.Context, changes map[span.URI]source
1838
1862
workspaceModFilesErr : s .workspaceModFilesErr ,
1839
1863
importGraph : s .importGraph ,
1840
1864
pkgIndex : s .pkgIndex ,
1865
+ options : s .options ,
1866
+ }
1867
+
1868
+ if newOptions != nil {
1869
+ result .options = newOptions
1841
1870
}
1842
1871
1843
1872
// Create a lease on the new snapshot.
0 commit comments