gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

tokeninternal.go (1475B)


      1 // Copyright 2023 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // package tokeninternal provides access to some internal features of the token
      6 // package.
      7 package tokeninternal
      8 
      9 import (
     10 	"go/token"
     11 	"sync"
     12 	"unsafe"
     13 )
     14 
     15 // GetLines returns the table of line-start offsets from a token.File.
     16 func GetLines(file *token.File) []int {
     17 	// token.File has a Lines method on Go 1.21 and later.
     18 	if file, ok := (interface{})(file).(interface{ Lines() []int }); ok {
     19 		return file.Lines()
     20 	}
     21 
     22 	// This declaration must match that of token.File.
     23 	// This creates a risk of dependency skew.
     24 	// For now we check that the size of the two
     25 	// declarations is the same, on the (fragile) assumption
     26 	// that future changes would add fields.
     27 	type tokenFile119 struct {
     28 		_     string
     29 		_     int
     30 		_     int
     31 		mu    sync.Mutex // we're not complete monsters
     32 		lines []int
     33 		_     []struct{}
     34 	}
     35 	type tokenFile118 struct {
     36 		_ *token.FileSet // deleted in go1.19
     37 		tokenFile119
     38 	}
     39 
     40 	type uP = unsafe.Pointer
     41 	switch unsafe.Sizeof(*file) {
     42 	case unsafe.Sizeof(tokenFile118{}):
     43 		var ptr *tokenFile118
     44 		*(*uP)(uP(&ptr)) = uP(file)
     45 		ptr.mu.Lock()
     46 		defer ptr.mu.Unlock()
     47 		return ptr.lines
     48 
     49 	case unsafe.Sizeof(tokenFile119{}):
     50 		var ptr *tokenFile119
     51 		*(*uP)(uP(&ptr)) = uP(file)
     52 		ptr.mu.Lock()
     53 		defer ptr.mu.Unlock()
     54 		return ptr.lines
     55 
     56 	default:
     57 		panic("unexpected token.File size")
     58 	}
     59 }