support.mx raw

   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 = []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