Source file src/go/internal/gcimporter/support.go

     1  // Copyright 2015 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  // This file implements support functionality for ureader.go.
     6  
     7  package gcimporter
     8  
     9  import (
    10  	"fmt"
    11  	"go/token"
    12  	"internal/pkgbits"
    13  	"sync"
    14  )
    15  
    16  func assert(b bool) {
    17  	if !b {
    18  		panic("assertion failed")
    19  	}
    20  }
    21  
    22  func errorf(format string, args ...any) {
    23  	panic(fmt.Sprintf(format, args...))
    24  }
    25  
    26  // Synthesize a token.Pos
    27  type fakeFileSet struct {
    28  	fset  *token.FileSet
    29  	files map[string]*fileInfo
    30  }
    31  
    32  type fileInfo struct {
    33  	file     *token.File
    34  	lastline int
    35  }
    36  
    37  const maxlines = 64 * 1024
    38  
    39  func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
    40  	// TODO(mdempsky): Make use of column.
    41  
    42  	// Since we don't know the set of needed file positions, we reserve
    43  	// maxlines positions per file. We delay calling token.File.SetLines until
    44  	// all positions have been calculated (by way of fakeFileSet.setLines), so
    45  	// that we can avoid setting unnecessary lines. See also golang/go#46586.
    46  	f := s.files[file]
    47  	if f == nil {
    48  		f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
    49  		s.files[file] = f
    50  	}
    51  
    52  	if line > maxlines {
    53  		line = 1
    54  	}
    55  	if line > f.lastline {
    56  		f.lastline = line
    57  	}
    58  
    59  	// Return a fake position assuming that f.file consists only of newlines.
    60  	return token.Pos(f.file.Base() + line - 1)
    61  }
    62  
    63  func (s *fakeFileSet) setLines() {
    64  	fakeLinesOnce.Do(func() {
    65  		fakeLines = make([]int, maxlines)
    66  		for i := range fakeLines {
    67  			fakeLines[i] = i
    68  		}
    69  	})
    70  	for _, f := range s.files {
    71  		f.file.SetLines(fakeLines[:f.lastline])
    72  	}
    73  }
    74  
    75  var (
    76  	fakeLines     []int
    77  	fakeLinesOnce sync.Once
    78  )
    79  
    80  // See cmd/compile/internal/noder.derivedInfo.
    81  type derivedInfo struct {
    82  	idx    pkgbits.Index
    83  	needed bool
    84  }
    85  
    86  // See cmd/compile/internal/noder.typeInfo.
    87  type typeInfo struct {
    88  	idx     pkgbits.Index
    89  	derived bool
    90  }
    91  
    92  // See cmd/compile/internal/types.SplitVargenSuffix.
    93  func splitVargenSuffix(name string) (base, suffix string) {
    94  	i := len(name)
    95  	for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
    96  		i--
    97  	}
    98  	const dot = "ยท"
    99  	if i >= len(dot) && name[i-len(dot):i] == dot {
   100  		i -= len(dot)
   101  		return name[:i], name[i:]
   102  	}
   103  	return name, ""
   104  }
   105  

View as plain text