src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

bimport.go (2027B)


      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 }