// Copyright 2023 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.
// package tokeninternal provides access to some internal features of the token// package.
package tokeninternalimport ()// GetLines returns the table of line-start offsets from a token.File.func ( *token.File) []int {// token.File has a Lines method on Go 1.21 and later.if , := (interface{})().(interface{ () []int }); {return .() }// This declaration must match that of token.File. // This creates a risk of dependency skew. // For now we check that the size of the two // declarations is the same, on the (fragile) assumption // that future changes would add fields.typestruct {stringintintsync.Mutex// we're not complete monsters []int []struct{} }ifunsafe.Sizeof(*) != unsafe.Sizeof({}) {panic("unexpected token.File size") }var *type = unsafe.Pointer *(*)((&)) = () ..Lock()defer ..Unlock()return .}// AddExistingFiles adds the specified files to the FileSet if they// are not already present. It panics if any pair of files in the// resulting FileSet would overlap.func ( *token.FileSet, []*token.File) {// Punch through the FileSet encapsulation.typestruct {// This type remained essentially consistent from go1.16 to go1.21.sync.RWMutexint []*token.File *token.File// changed to atomic.Pointer[token.File] in go1.19 }// If the size of token.FileSet changes, this will fail to compile.const = int64(unsafe.Sizeof({})) - int64(unsafe.Sizeof(token.FileSet{}))var [- * ]inttype = unsafe.Pointervar * *(*)((&)) = () ..Lock()defer ..Unlock()// Merge and sort. := append(., ...)sort.Slice(, func(, int) bool {return [].Base() < [].Base() })// Reject overlapping files. // Discard adjacent identical files. := [:0]for , := range {if > 0 { := [-1]if == {continue }if .Base()+.Size()+1 > .Base() {panic(fmt.Sprintf("file %s (%d-%d) overlaps with file %s (%d-%d)", .Name(), .Base(), .Base()+.Size(), .Name(), .Base(), .Base()+.Size())) } } = append(, ) } = . = // Advance FileSet.Base().iflen() > 0 { := [len()-1] := .Base() + .Size() + 1if . < { . = } }}// FileSetFor returns a new FileSet containing a sequence of new Files with// the same base, size, and line as the input files, for use in APIs that// require a FileSet.//// Precondition: the input files must be non-overlapping, and sorted in order// of their Base.func ( ...*token.File) *token.FileSet { := token.NewFileSet()for , := range { := .AddFile(.Name(), .Base(), .Size()) := GetLines() .SetLines() }return}// CloneFileSet creates a new FileSet holding all files in fset. It does not// create copies of the token.Files in fset: they are added to the resulting// FileSet unmodified.func ( *token.FileSet) *token.FileSet {var []*token.File .Iterate(func( *token.File) bool { = append(, )returntrue }) := token.NewFileSet()AddExistingFiles(, )return}
The pages are generated with Goldsv0.7.6. (GOOS=linux GOARCH=amd64)