bimport.go 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 contains the remaining vestiges of
   6  // $GOROOT/src/go/internal/gcimporter/bimport.go.
   7  
   8  package gcimporter
   9  
  10  import (
  11  	"fmt"
  12  	"go/token"
  13  	"go/types"
  14  	"sync"
  15  )
  16  
  17  func errorf(format string, args ...any) {
  18  	panic(fmt.Sprintf(format, args...))
  19  }
  20  
  21  const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
  22  
  23  // Synthesize a token.Pos
  24  type fakeFileSet struct {
  25  	fset  *token.FileSet
  26  	files map[string]*fileInfo
  27  }
  28  
  29  type fileInfo struct {
  30  	file     *token.File
  31  	lastline int
  32  }
  33  
  34  const maxlines = 64 * 1024
  35  
  36  func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
  37  	_ = column // TODO(mdempsky): Make use of column.
  38  
  39  	// Since we don't know the set of needed file positions, we reserve maxlines
  40  	// positions per file. We delay calling token.File.SetLines until all
  41  	// positions have been calculated (by way of fakeFileSet.setLines), so that
  42  	// we can avoid setting unnecessary lines. See also golang/go#46586.
  43  	f := s.files[file]
  44  	if f == nil {
  45  		f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
  46  		s.files[file] = f
  47  	}
  48  	if line > maxlines {
  49  		line = 1
  50  	}
  51  	if line > f.lastline {
  52  		f.lastline = line
  53  	}
  54  
  55  	// Return a fake position assuming that f.file consists only of newlines.
  56  	return token.Pos(f.file.Base() + line - 1)
  57  }
  58  
  59  func (s *fakeFileSet) setLines() {
  60  	fakeLinesOnce.Do(func() {
  61  		fakeLines = make([]int, maxlines)
  62  		for i := range fakeLines {
  63  			fakeLines[i] = i
  64  		}
  65  	})
  66  	for _, f := range s.files {
  67  		f.file.SetLines(fakeLines[:f.lastline])
  68  	}
  69  }
  70  
  71  var (
  72  	fakeLines     []int
  73  	fakeLinesOnce sync.Once
  74  )
  75  
  76  func chanDir(d int) types.ChanDir {
  77  	// tag values must match the constants in cmd/compile/internal/gc/go.go
  78  	switch d {
  79  	case 1 /* Crecv */ :
  80  		return types.RecvOnly
  81  	case 2 /* Csend */ :
  82  		return types.SendOnly
  83  	case 3 /* Cboth */ :
  84  		return types.SendRecv
  85  	default:
  86  		errorf("unexpected channel dir %d", d)
  87  		return 0
  88  	}
  89  }
  90