add prune and remove unused packages
This commit is contained in:
220
vendor/golang.org/x/tools/go/internal/cgo/cgo.go
generated
vendored
220
vendor/golang.org/x/tools/go/internal/cgo/cgo.go
generated
vendored
@@ -1,220 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cgo
|
||||
|
||||
// This file handles cgo preprocessing of files containing `import "C"`.
|
||||
//
|
||||
// DESIGN
|
||||
//
|
||||
// The approach taken is to run the cgo processor on the package's
|
||||
// CgoFiles and parse the output, faking the filenames of the
|
||||
// resulting ASTs so that the synthetic file containing the C types is
|
||||
// called "C" (e.g. "~/go/src/net/C") and the preprocessed files
|
||||
// have their original names (e.g. "~/go/src/net/cgo_unix.go"),
|
||||
// not the names of the actual temporary files.
|
||||
//
|
||||
// The advantage of this approach is its fidelity to 'go build'. The
|
||||
// downside is that the token.Position.Offset for each AST node is
|
||||
// incorrect, being an offset within the temporary file. Line numbers
|
||||
// should still be correct because of the //line comments.
|
||||
//
|
||||
// The logic of this file is mostly plundered from the 'go build'
|
||||
// tool, which also invokes the cgo preprocessor.
|
||||
//
|
||||
//
|
||||
// REJECTED ALTERNATIVE
|
||||
//
|
||||
// An alternative approach that we explored is to extend go/types'
|
||||
// Importer mechanism to provide the identity of the importing package
|
||||
// so that each time `import "C"` appears it resolves to a different
|
||||
// synthetic package containing just the objects needed in that case.
|
||||
// The loader would invoke cgo but parse only the cgo_types.go file
|
||||
// defining the package-level objects, discarding the other files
|
||||
// resulting from preprocessing.
|
||||
//
|
||||
// The benefit of this approach would have been that source-level
|
||||
// syntax information would correspond exactly to the original cgo
|
||||
// file, with no preprocessing involved, making source tools like
|
||||
// godoc, guru, and eg happy. However, the approach was rejected
|
||||
// due to the additional complexity it would impose on go/types. (It
|
||||
// made for a beautiful demo, though.)
|
||||
//
|
||||
// cgo files, despite their *.go extension, are not legal Go source
|
||||
// files per the specification since they may refer to unexported
|
||||
// members of package "C" such as C.int. Also, a function such as
|
||||
// C.getpwent has in effect two types, one matching its C type and one
|
||||
// which additionally returns (errno C.int). The cgo preprocessor
|
||||
// uses name mangling to distinguish these two functions in the
|
||||
// processed code, but go/types would need to duplicate this logic in
|
||||
// its handling of function calls, analogous to the treatment of map
|
||||
// lookups in which y=m[k] and y,ok=m[k] are both legal.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProcessFiles invokes the cgo preprocessor on bp.CgoFiles, parses
|
||||
// the output and returns the resulting ASTs.
|
||||
//
|
||||
func ProcessFiles(bp *build.Package, fset *token.FileSet, DisplayPath func(path string) string, mode parser.Mode) ([]*ast.File, error) {
|
||||
tmpdir, err := ioutil.TempDir("", strings.Replace(bp.ImportPath, "/", "_", -1)+"_C")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
pkgdir := bp.Dir
|
||||
if DisplayPath != nil {
|
||||
pkgdir = DisplayPath(pkgdir)
|
||||
}
|
||||
|
||||
cgoFiles, cgoDisplayFiles, err := Run(bp, pkgdir, tmpdir, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var files []*ast.File
|
||||
for i := range cgoFiles {
|
||||
rd, err := os.Open(cgoFiles[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
display := filepath.Join(bp.Dir, cgoDisplayFiles[i])
|
||||
f, err := parser.ParseFile(fset, display, rd, mode)
|
||||
rd.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, f)
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
var cgoRe = regexp.MustCompile(`[/\\:]`)
|
||||
|
||||
// Run invokes the cgo preprocessor on bp.CgoFiles and returns two
|
||||
// lists of files: the resulting processed files (in temporary
|
||||
// directory tmpdir) and the corresponding names of the unprocessed files.
|
||||
//
|
||||
// Run is adapted from (*builder).cgo in
|
||||
// $GOROOT/src/cmd/go/build.go, but these features are unsupported:
|
||||
// Objective C, CGOPKGPATH, CGO_FLAGS.
|
||||
//
|
||||
// If useabs is set to true, absolute paths of the bp.CgoFiles will be passed in
|
||||
// to the cgo preprocessor. This in turn will set the // line comments
|
||||
// referring to those files to use absolute paths. This is needed for
|
||||
// go/packages using the legacy go list support so it is able to find
|
||||
// the original files.
|
||||
func Run(bp *build.Package, pkgdir, tmpdir string, useabs bool) (files, displayFiles []string, err error) {
|
||||
cgoCPPFLAGS, _, _, _ := cflags(bp, true)
|
||||
_, cgoexeCFLAGS, _, _ := cflags(bp, false)
|
||||
|
||||
if len(bp.CgoPkgConfig) > 0 {
|
||||
pcCFLAGS, err := pkgConfigFlags(bp)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
|
||||
}
|
||||
|
||||
// Allows including _cgo_export.h from .[ch] files in the package.
|
||||
cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", tmpdir)
|
||||
|
||||
// _cgo_gotypes.go (displayed "C") contains the type definitions.
|
||||
files = append(files, filepath.Join(tmpdir, "_cgo_gotypes.go"))
|
||||
displayFiles = append(displayFiles, "C")
|
||||
for _, fn := range bp.CgoFiles {
|
||||
// "foo.cgo1.go" (displayed "foo.go") is the processed Go source.
|
||||
f := cgoRe.ReplaceAllString(fn[:len(fn)-len("go")], "_")
|
||||
files = append(files, filepath.Join(tmpdir, f+"cgo1.go"))
|
||||
displayFiles = append(displayFiles, fn)
|
||||
}
|
||||
|
||||
var cgoflags []string
|
||||
if bp.Goroot && bp.ImportPath == "runtime/cgo" {
|
||||
cgoflags = append(cgoflags, "-import_runtime_cgo=false")
|
||||
}
|
||||
if bp.Goroot && bp.ImportPath == "runtime/race" || bp.ImportPath == "runtime/cgo" {
|
||||
cgoflags = append(cgoflags, "-import_syscall=false")
|
||||
}
|
||||
|
||||
var cgoFiles []string = bp.CgoFiles
|
||||
if useabs {
|
||||
cgoFiles = make([]string, len(bp.CgoFiles))
|
||||
for i := range cgoFiles {
|
||||
cgoFiles[i] = filepath.Join(pkgdir, bp.CgoFiles[i])
|
||||
}
|
||||
}
|
||||
|
||||
args := stringList(
|
||||
"go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--",
|
||||
cgoCPPFLAGS, cgoexeCFLAGS, cgoFiles,
|
||||
)
|
||||
if false {
|
||||
log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir)
|
||||
}
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Dir = pkgdir
|
||||
cmd.Stdout = os.Stderr
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, nil, fmt.Errorf("cgo failed: %s: %s", args, err)
|
||||
}
|
||||
|
||||
return files, displayFiles, nil
|
||||
}
|
||||
|
||||
// -- unmodified from 'go build' ---------------------------------------
|
||||
|
||||
// Return the flags to use when invoking the C or C++ compilers, or cgo.
|
||||
func cflags(p *build.Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
|
||||
var defaults string
|
||||
if def {
|
||||
defaults = "-g -O2"
|
||||
}
|
||||
|
||||
cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
|
||||
cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
|
||||
cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
|
||||
ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
|
||||
return
|
||||
}
|
||||
|
||||
// envList returns the value of the given environment variable broken
|
||||
// into fields, using the default value when the variable is empty.
|
||||
func envList(key, def string) []string {
|
||||
v := os.Getenv(key)
|
||||
if v == "" {
|
||||
v = def
|
||||
}
|
||||
return strings.Fields(v)
|
||||
}
|
||||
|
||||
// stringList's arguments should be a sequence of string or []string values.
|
||||
// stringList flattens them into a single []string.
|
||||
func stringList(args ...interface{}) []string {
|
||||
var x []string
|
||||
for _, arg := range args {
|
||||
switch arg := arg.(type) {
|
||||
case []string:
|
||||
x = append(x, arg...)
|
||||
case string:
|
||||
x = append(x, arg)
|
||||
default:
|
||||
panic("stringList: invalid argument")
|
||||
}
|
||||
}
|
||||
return x
|
||||
}
|
39
vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go
generated
vendored
39
vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go
generated
vendored
@@ -1,39 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cgo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// pkgConfig runs pkg-config with the specified arguments and returns the flags it prints.
|
||||
func pkgConfig(mode string, pkgs []string) (flags []string, err error) {
|
||||
cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err)
|
||||
if len(out) > 0 {
|
||||
s = fmt.Sprintf("%s: %s", s, out)
|
||||
}
|
||||
return nil, errors.New(s)
|
||||
}
|
||||
if len(out) > 0 {
|
||||
flags = strings.Fields(string(out))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// pkgConfigFlags calls pkg-config if needed and returns the cflags
|
||||
// needed to build the package.
|
||||
func pkgConfigFlags(p *build.Package) (cflags []string, err error) {
|
||||
if len(p.CgoPkgConfig) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return pkgConfig("--cflags", p.CgoPkgConfig)
|
||||
}
|
151
vendor/golang.org/x/tools/go/internal/gccgoimporter/ar.go
generated
vendored
151
vendor/golang.org/x/tools/go/internal/gccgoimporter/ar.go
generated
vendored
@@ -1,151 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"debug/elf"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Magic strings for different archive file formats.
|
||||
const (
|
||||
armag = "!<arch>\n"
|
||||
armagt = "!<thin>\n"
|
||||
armagb = "<bigaf>\n"
|
||||
)
|
||||
|
||||
// Offsets and sizes for fields in a standard archive header.
|
||||
const (
|
||||
arNameOff = 0
|
||||
arNameSize = 16
|
||||
arDateOff = arNameOff + arNameSize
|
||||
arDateSize = 12
|
||||
arUIDOff = arDateOff + arDateSize
|
||||
arUIDSize = 6
|
||||
arGIDOff = arUIDOff + arUIDSize
|
||||
arGIDSize = 6
|
||||
arModeOff = arGIDOff + arGIDSize
|
||||
arModeSize = 8
|
||||
arSizeOff = arModeOff + arModeSize
|
||||
arSizeSize = 10
|
||||
arFmagOff = arSizeOff + arSizeSize
|
||||
arFmagSize = 2
|
||||
|
||||
arHdrSize = arFmagOff + arFmagSize
|
||||
)
|
||||
|
||||
// The contents of the fmag field of a standard archive header.
|
||||
const arfmag = "`\n"
|
||||
|
||||
// arExportData takes an archive file and returns a ReadSeeker for the
|
||||
// export data in that file. This assumes that there is only one
|
||||
// object in the archive containing export data, which is not quite
|
||||
// what gccgo does; gccgo concatenates together all the export data
|
||||
// for all the objects in the file. In practice that case does not arise.
|
||||
func arExportData(archive io.ReadSeeker) (io.ReadSeeker, error) {
|
||||
if _, err := archive.Seek(0, io.SeekStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var buf [len(armag)]byte
|
||||
if _, err := archive.Read(buf[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch string(buf[:]) {
|
||||
case armag:
|
||||
return standardArExportData(archive)
|
||||
case armagt:
|
||||
return nil, errors.New("unsupported thin archive")
|
||||
case armagb:
|
||||
return nil, errors.New("unsupported AIX big archive")
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized archive file format %q", buf[:])
|
||||
}
|
||||
}
|
||||
|
||||
// standardArExportData returns export data form a standard archive.
|
||||
func standardArExportData(archive io.ReadSeeker) (io.ReadSeeker, error) {
|
||||
off := int64(len(armag))
|
||||
for {
|
||||
var hdrBuf [arHdrSize]byte
|
||||
if _, err := archive.Read(hdrBuf[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
off += arHdrSize
|
||||
|
||||
if bytes.Compare(hdrBuf[arFmagOff:arFmagOff+arFmagSize], []byte(arfmag)) != 0 {
|
||||
return nil, fmt.Errorf("archive header format header (%q)", hdrBuf[:])
|
||||
}
|
||||
|
||||
size, err := strconv.ParseInt(strings.TrimSpace(string(hdrBuf[arSizeOff:arSizeOff+arSizeSize])), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing size in archive header (%q): %v", hdrBuf[:], err)
|
||||
}
|
||||
|
||||
fn := hdrBuf[arNameOff : arNameOff+arNameSize]
|
||||
if fn[0] == '/' && (fn[1] == ' ' || fn[1] == '/' || bytes.Compare(fn[:8], []byte("/SYM64/ ")) == 0) {
|
||||
// Archive symbol table or extended name table,
|
||||
// which we don't care about.
|
||||
} else {
|
||||
archiveAt := readerAtFromSeeker(archive)
|
||||
ret, err := elfFromAr(io.NewSectionReader(archiveAt, off, size))
|
||||
if ret != nil || err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
|
||||
if size&1 != 0 {
|
||||
size++
|
||||
}
|
||||
off += size
|
||||
if _, err := archive.Seek(off, io.SeekStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// elfFromAr tries to get export data from an archive member as an ELF file.
|
||||
// If there is no export data, this returns nil, nil.
|
||||
func elfFromAr(member *io.SectionReader) (io.ReadSeeker, error) {
|
||||
ef, err := elf.NewFile(member)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sec := ef.Section(".go_export")
|
||||
if sec == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return sec.Open(), nil
|
||||
}
|
||||
|
||||
// readerAtFromSeeker turns an io.ReadSeeker into an io.ReaderAt.
|
||||
// This is only safe because there won't be any concurrent seeks
|
||||
// while this code is executing.
|
||||
func readerAtFromSeeker(rs io.ReadSeeker) io.ReaderAt {
|
||||
if ret, ok := rs.(io.ReaderAt); ok {
|
||||
return ret
|
||||
}
|
||||
return seekerReadAt{rs}
|
||||
}
|
||||
|
||||
type seekerReadAt struct {
|
||||
seeker io.ReadSeeker
|
||||
}
|
||||
|
||||
func (sra seekerReadAt) ReadAt(p []byte, off int64) (int, error) {
|
||||
if _, err := sra.seeker.Seek(off, io.SeekStart); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sra.seeker.Read(p)
|
||||
}
|
32
vendor/golang.org/x/tools/go/internal/gccgoimporter/backdoor.go
generated
vendored
32
vendor/golang.org/x/tools/go/internal/gccgoimporter/backdoor.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file opens a back door to the parser for golang.org/x/tools/go/gccgoexportdata.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Parse reads and parses gccgo export data from in and constructs a
|
||||
// Package, inserting it into the imports map.
|
||||
func Parse(in io.Reader, imports map[string]*types.Package, path string) (_ *types.Package, err error) {
|
||||
var p parser
|
||||
p.init(path, in, imports)
|
||||
defer func() {
|
||||
switch x := recover().(type) {
|
||||
case nil:
|
||||
// success
|
||||
case importError:
|
||||
err = x
|
||||
default:
|
||||
panic(x) // resume unexpected panic
|
||||
}
|
||||
}()
|
||||
pkg := p.parsePackage()
|
||||
imports[path] = pkg
|
||||
return pkg, err
|
||||
}
|
100
vendor/golang.org/x/tools/go/internal/gccgoimporter/gccgoinstallation.go
generated
vendored
100
vendor/golang.org/x/tools/go/internal/gccgoimporter/gccgoinstallation.go
generated
vendored
@@ -1,100 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"go/types"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Information about a specific installation of gccgo.
|
||||
type GccgoInstallation struct {
|
||||
// Version of gcc (e.g. 4.8.0).
|
||||
GccVersion string
|
||||
|
||||
// Target triple (e.g. x86_64-unknown-linux-gnu).
|
||||
TargetTriple string
|
||||
|
||||
// Built-in library paths used by this installation.
|
||||
LibPaths []string
|
||||
}
|
||||
|
||||
// Ask the driver at the given path for information for this GccgoInstallation.
|
||||
// The given arguments are passed directly to the call of the driver.
|
||||
func (inst *GccgoInstallation) InitFromDriver(gccgoPath string, args ...string) (err error) {
|
||||
argv := append([]string{"-###", "-S", "-x", "go", "-"}, args...)
|
||||
cmd := exec.Command(gccgoPath, argv...)
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
switch {
|
||||
case strings.HasPrefix(line, "Target: "):
|
||||
inst.TargetTriple = line[8:]
|
||||
|
||||
case line[0] == ' ':
|
||||
args := strings.Fields(line)
|
||||
for _, arg := range args[1:] {
|
||||
if strings.HasPrefix(arg, "-L") {
|
||||
inst.LibPaths = append(inst.LibPaths, arg[2:])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
argv = append([]string{"-dumpversion"}, args...)
|
||||
stdout, err := exec.Command(gccgoPath, argv...).Output()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
inst.GccVersion = strings.TrimSpace(string(stdout))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Return the list of export search paths for this GccgoInstallation.
|
||||
func (inst *GccgoInstallation) SearchPaths() (paths []string) {
|
||||
for _, lpath := range inst.LibPaths {
|
||||
spath := filepath.Join(lpath, "go", inst.GccVersion)
|
||||
fi, err := os.Stat(spath)
|
||||
if err != nil || !fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
paths = append(paths, spath)
|
||||
|
||||
spath = filepath.Join(spath, inst.TargetTriple)
|
||||
fi, err = os.Stat(spath)
|
||||
if err != nil || !fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
paths = append(paths, spath)
|
||||
}
|
||||
|
||||
paths = append(paths, inst.LibPaths...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Return an importer that searches incpaths followed by the gcc installation's
|
||||
// built-in search paths and the current directory.
|
||||
func (inst *GccgoInstallation) GetImporter(incpaths []string, initmap map[*types.Package]InitData) Importer {
|
||||
return GetImporter(append(append(incpaths, inst.SearchPaths()...), "."), initmap)
|
||||
}
|
191
vendor/golang.org/x/tools/go/internal/gccgoimporter/gccgoinstallation_test.go
generated
vendored
191
vendor/golang.org/x/tools/go/internal/gccgoimporter/gccgoinstallation_test.go
generated
vendored
@@ -1,191 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var importablePackages = [...]string{
|
||||
"archive/tar",
|
||||
"archive/zip",
|
||||
"bufio",
|
||||
"bytes",
|
||||
"compress/bzip2",
|
||||
"compress/flate",
|
||||
"compress/gzip",
|
||||
"compress/lzw",
|
||||
"compress/zlib",
|
||||
"container/heap",
|
||||
"container/list",
|
||||
"container/ring",
|
||||
"crypto/aes",
|
||||
"crypto/cipher",
|
||||
"crypto/des",
|
||||
"crypto/dsa",
|
||||
"crypto/ecdsa",
|
||||
"crypto/elliptic",
|
||||
"crypto",
|
||||
"crypto/hmac",
|
||||
"crypto/md5",
|
||||
"crypto/rand",
|
||||
"crypto/rc4",
|
||||
"crypto/rsa",
|
||||
"crypto/sha1",
|
||||
"crypto/sha256",
|
||||
"crypto/sha512",
|
||||
"crypto/subtle",
|
||||
"crypto/tls",
|
||||
"crypto/x509",
|
||||
"crypto/x509/pkix",
|
||||
"database/sql/driver",
|
||||
"database/sql",
|
||||
"debug/dwarf",
|
||||
"debug/elf",
|
||||
"debug/gosym",
|
||||
"debug/macho",
|
||||
"debug/pe",
|
||||
"encoding/ascii85",
|
||||
"encoding/asn1",
|
||||
"encoding/base32",
|
||||
"encoding/base64",
|
||||
"encoding/binary",
|
||||
"encoding/csv",
|
||||
"encoding/gob",
|
||||
"encoding",
|
||||
"encoding/hex",
|
||||
"encoding/json",
|
||||
"encoding/pem",
|
||||
"encoding/xml",
|
||||
"errors",
|
||||
"expvar",
|
||||
"flag",
|
||||
"fmt",
|
||||
"go/ast",
|
||||
"go/build",
|
||||
"go/doc",
|
||||
"go/format",
|
||||
"go/parser",
|
||||
"go/printer",
|
||||
"go/scanner",
|
||||
"go/token",
|
||||
"hash/adler32",
|
||||
"hash/crc32",
|
||||
"hash/crc64",
|
||||
"hash/fnv",
|
||||
"hash",
|
||||
"html",
|
||||
"html/template",
|
||||
"image/color",
|
||||
"image/color/palette",
|
||||
"image/draw",
|
||||
"image/gif",
|
||||
"image",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"index/suffixarray",
|
||||
"io",
|
||||
"io/ioutil",
|
||||
"log",
|
||||
"log/syslog",
|
||||
"math/big",
|
||||
"math/cmplx",
|
||||
"math",
|
||||
"math/rand",
|
||||
"mime",
|
||||
"mime/multipart",
|
||||
"net",
|
||||
"net/http/cgi",
|
||||
"net/http/cookiejar",
|
||||
"net/http/fcgi",
|
||||
"net/http",
|
||||
"net/http/httptest",
|
||||
"net/http/httputil",
|
||||
"net/http/pprof",
|
||||
"net/mail",
|
||||
"net/rpc",
|
||||
"net/rpc/jsonrpc",
|
||||
"net/smtp",
|
||||
"net/textproto",
|
||||
"net/url",
|
||||
"os/exec",
|
||||
"os",
|
||||
"os/signal",
|
||||
"os/user",
|
||||
"path/filepath",
|
||||
"path",
|
||||
"reflect",
|
||||
"regexp",
|
||||
"regexp/syntax",
|
||||
"runtime/debug",
|
||||
"runtime",
|
||||
"runtime/pprof",
|
||||
"sort",
|
||||
"strconv",
|
||||
"strings",
|
||||
"sync/atomic",
|
||||
"sync",
|
||||
"syscall",
|
||||
"testing",
|
||||
"testing/iotest",
|
||||
"testing/quick",
|
||||
"text/scanner",
|
||||
"text/tabwriter",
|
||||
"text/template",
|
||||
"text/template/parse",
|
||||
"time",
|
||||
"unicode",
|
||||
"unicode/utf16",
|
||||
"unicode/utf8",
|
||||
}
|
||||
|
||||
func TestInstallationImporter(t *testing.T) {
|
||||
// This test relies on gccgo being around, which it most likely will be if we
|
||||
// were compiled with gccgo.
|
||||
if runtime.Compiler != "gccgo" {
|
||||
t.Skip("This test needs gccgo")
|
||||
}
|
||||
|
||||
var inst GccgoInstallation
|
||||
err := inst.InitFromDriver("gccgo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
imp := inst.GetImporter(nil, nil)
|
||||
|
||||
// Ensure we don't regress the number of packages we can parse. First import
|
||||
// all packages into the same map and then each individually.
|
||||
pkgMap := make(map[string]*types.Package)
|
||||
for _, pkg := range importablePackages {
|
||||
_, err = imp(pkgMap, pkg, ".", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range importablePackages {
|
||||
_, err = imp(make(map[string]*types.Package), pkg, ".", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test for certain specific entities in the imported data.
|
||||
for _, test := range [...]importerTest{
|
||||
{pkgpath: "io", name: "Reader", want: "type Reader interface{Read(p []uint8) (n int, err error)}"},
|
||||
{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
|
||||
{pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
|
||||
{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
|
||||
{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
|
||||
{pkgpath: "unsafe", name: "Pointer", want: "type Pointer unsafe.Pointer"},
|
||||
} {
|
||||
runImporterTest(t, imp, nil, &test)
|
||||
}
|
||||
}
|
249
vendor/golang.org/x/tools/go/internal/gccgoimporter/importer.go
generated
vendored
249
vendor/golang.org/x/tools/go/internal/gccgoimporter/importer.go
generated
vendored
@@ -1,249 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment and the import path, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter.
|
||||
|
||||
// Package gccgoimporter implements Import for gccgo-generated object files.
|
||||
package gccgoimporter // import "golang.org/x/tools/go/internal/gccgoimporter"
|
||||
|
||||
import (
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A PackageInit describes an imported package that needs initialization.
|
||||
type PackageInit struct {
|
||||
Name string // short package name
|
||||
InitFunc string // name of init function
|
||||
Priority int // priority of init function, see InitData.Priority
|
||||
}
|
||||
|
||||
// The gccgo-specific init data for a package.
|
||||
type InitData struct {
|
||||
// Initialization priority of this package relative to other packages.
|
||||
// This is based on the maximum depth of the package's dependency graph;
|
||||
// it is guaranteed to be greater than that of its dependencies.
|
||||
Priority int
|
||||
|
||||
// The list of packages which this package depends on to be initialized,
|
||||
// including itself if needed. This is the subset of the transitive closure of
|
||||
// the package's dependencies that need initialization.
|
||||
Inits []PackageInit
|
||||
}
|
||||
|
||||
// Locate the file from which to read export data.
|
||||
// This is intended to replicate the logic in gofrontend.
|
||||
func findExportFile(searchpaths []string, pkgpath string) (string, error) {
|
||||
for _, spath := range searchpaths {
|
||||
pkgfullpath := filepath.Join(spath, pkgpath)
|
||||
pkgdir, name := filepath.Split(pkgfullpath)
|
||||
|
||||
for _, filepath := range [...]string{
|
||||
pkgfullpath,
|
||||
pkgfullpath + ".gox",
|
||||
pkgdir + "lib" + name + ".so",
|
||||
pkgdir + "lib" + name + ".a",
|
||||
pkgfullpath + ".o",
|
||||
} {
|
||||
fi, err := os.Stat(filepath)
|
||||
if err == nil && !fi.IsDir() {
|
||||
return filepath, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("%s: could not find export data (tried %s)", pkgpath, strings.Join(searchpaths, ":"))
|
||||
}
|
||||
|
||||
const (
|
||||
gccgov1Magic = "v1;\n"
|
||||
gccgov2Magic = "v2;\n"
|
||||
goimporterMagic = "\n$$ "
|
||||
archiveMagic = "!<ar"
|
||||
)
|
||||
|
||||
// Opens the export data file at the given path. If this is an ELF file,
|
||||
// searches for and opens the .go_export section. If this is an archive,
|
||||
// reads the export data from the first member, which is assumed to be an ELF file.
|
||||
// This is intended to replicate the logic in gofrontend.
|
||||
func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err error) {
|
||||
f, err := os.Open(fpath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
closer = f
|
||||
defer func() {
|
||||
if err != nil && closer != nil {
|
||||
f.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
var magic [4]byte
|
||||
_, err = f.ReadAt(magic[:], 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var elfreader io.ReaderAt
|
||||
switch string(magic[:]) {
|
||||
case gccgov1Magic, gccgov2Magic, goimporterMagic:
|
||||
// Raw export data.
|
||||
reader = f
|
||||
return
|
||||
|
||||
case archiveMagic:
|
||||
reader, err = arExportData(f)
|
||||
return
|
||||
|
||||
default:
|
||||
elfreader = f
|
||||
}
|
||||
|
||||
ef, err := elf.NewFile(elfreader)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sec := ef.Section(".go_export")
|
||||
if sec == nil {
|
||||
err = fmt.Errorf("%s: .go_export section not found", fpath)
|
||||
return
|
||||
}
|
||||
|
||||
reader = sec.Open()
|
||||
return
|
||||
}
|
||||
|
||||
// An Importer resolves import paths to Packages. The imports map records
|
||||
// packages already known, indexed by package path.
|
||||
// An importer must determine the canonical package path and check imports
|
||||
// to see if it is already present in the map. If so, the Importer can return
|
||||
// the map entry. Otherwise, the importer must load the package data for the
|
||||
// given path into a new *Package, record it in imports map, and return the
|
||||
// package.
|
||||
type Importer func(imports map[string]*types.Package, path, srcDir string, lookup func(string) (io.ReadCloser, error)) (*types.Package, error)
|
||||
|
||||
func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Importer {
|
||||
return func(imports map[string]*types.Package, pkgpath, srcDir string, lookup func(string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
|
||||
// TODO(gri): Use srcDir.
|
||||
// Or not. It's possible that srcDir will fade in importance as
|
||||
// the go command and other tools provide a translation table
|
||||
// for relative imports (like ./foo or vendored imports).
|
||||
if pkgpath == "unsafe" {
|
||||
return types.Unsafe, nil
|
||||
}
|
||||
|
||||
var reader io.ReadSeeker
|
||||
var fpath string
|
||||
var rc io.ReadCloser
|
||||
if lookup != nil {
|
||||
if p := imports[pkgpath]; p != nil && p.Complete() {
|
||||
return p, nil
|
||||
}
|
||||
rc, err = lookup(pkgpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if rc != nil {
|
||||
defer rc.Close()
|
||||
rs, ok := rc.(io.ReadSeeker)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("gccgo importer requires lookup to return an io.ReadSeeker, have %T", rc)
|
||||
}
|
||||
reader = rs
|
||||
fpath = "<lookup " + pkgpath + ">"
|
||||
// Take name from Name method (like on os.File) if present.
|
||||
if n, ok := rc.(interface{ Name() string }); ok {
|
||||
fpath = n.Name()
|
||||
}
|
||||
} else {
|
||||
fpath, err = findExportFile(searchpaths, pkgpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r, closer, err := openExportFile(fpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if closer != nil {
|
||||
defer closer.Close()
|
||||
}
|
||||
reader = r
|
||||
}
|
||||
|
||||
var magics string
|
||||
magics, err = readMagic(reader)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if magics == archiveMagic {
|
||||
reader, err = arExportData(reader)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
magics, err = readMagic(reader)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch magics {
|
||||
case gccgov1Magic, gccgov2Magic:
|
||||
var p parser
|
||||
p.init(fpath, reader, imports)
|
||||
pkg = p.parsePackage()
|
||||
if initmap != nil {
|
||||
initmap[pkg] = p.initdata
|
||||
}
|
||||
|
||||
// Excluded for now: Standard gccgo doesn't support this import format currently.
|
||||
// case goimporterMagic:
|
||||
// var data []byte
|
||||
// data, err = ioutil.ReadAll(reader)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// var n int
|
||||
// n, pkg, err = importer.ImportData(imports, data)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// if initmap != nil {
|
||||
// suffixreader := bytes.NewReader(data[n:])
|
||||
// var p parser
|
||||
// p.init(fpath, suffixreader, nil)
|
||||
// p.parseInitData()
|
||||
// initmap[pkg] = p.initdata
|
||||
// }
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("unrecognized magic string: %q", magics)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// readMagic reads the four bytes at the start of a ReadSeeker and
|
||||
// returns them as a string.
|
||||
func readMagic(reader io.ReadSeeker) (string, error) {
|
||||
var magic [4]byte
|
||||
if _, err := reader.Read(magic[:]); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := reader.Seek(0, io.SeekStart); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(magic[:]), nil
|
||||
}
|
182
vendor/golang.org/x/tools/go/internal/gccgoimporter/importer_test.go
generated
vendored
182
vendor/golang.org/x/tools/go/internal/gccgoimporter/importer_test.go
generated
vendored
@@ -1,182 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter without
|
||||
// the import of "testenv".
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type importerTest struct {
|
||||
pkgpath, name, want, wantval string
|
||||
wantinits []string
|
||||
}
|
||||
|
||||
func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]InitData, test *importerTest) {
|
||||
pkg, err := imp(make(map[string]*types.Package), test.pkgpath, ".", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if test.name != "" {
|
||||
obj := pkg.Scope().Lookup(test.name)
|
||||
if obj == nil {
|
||||
t.Errorf("%s: object not found", test.name)
|
||||
return
|
||||
}
|
||||
|
||||
got := types.ObjectString(obj, types.RelativeTo(pkg))
|
||||
if got != test.want {
|
||||
t.Errorf("%s: got %q; want %q", test.name, got, test.want)
|
||||
}
|
||||
|
||||
if test.wantval != "" {
|
||||
gotval := obj.(*types.Const).Val().String()
|
||||
if gotval != test.wantval {
|
||||
t.Errorf("%s: got val %q; want val %q", test.name, gotval, test.wantval)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(test.wantinits) > 0 {
|
||||
initdata := initmap[pkg]
|
||||
found := false
|
||||
// Check that the package's own init function has the package's priority
|
||||
for _, pkginit := range initdata.Inits {
|
||||
if pkginit.InitFunc == test.wantinits[0] {
|
||||
if initdata.Priority != pkginit.Priority {
|
||||
t.Errorf("%s: got self priority %d; want %d", test.pkgpath, pkginit.Priority, initdata.Priority)
|
||||
}
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("%s: could not find expected function %q", test.pkgpath, test.wantinits[0])
|
||||
}
|
||||
|
||||
// Each init function in the list other than the first one is a
|
||||
// dependency of the function immediately before it. Check that
|
||||
// the init functions appear in descending priority order.
|
||||
priority := initdata.Priority
|
||||
for _, wantdepinit := range test.wantinits[1:] {
|
||||
found = false
|
||||
for _, pkginit := range initdata.Inits {
|
||||
if pkginit.InitFunc == wantdepinit {
|
||||
if priority <= pkginit.Priority {
|
||||
t.Errorf("%s: got dep priority %d; want less than %d", test.pkgpath, pkginit.Priority, priority)
|
||||
}
|
||||
found = true
|
||||
priority = pkginit.Priority
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("%s: could not find expected function %q", test.pkgpath, wantdepinit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var importerTests = [...]importerTest{
|
||||
{pkgpath: "pointer", name: "Int8Ptr", want: "type Int8Ptr *int8"},
|
||||
{pkgpath: "complexnums", name: "NN", want: "const NN untyped complex", wantval: "(-1 + -1i)"},
|
||||
{pkgpath: "complexnums", name: "NP", want: "const NP untyped complex", wantval: "(-1 + 1i)"},
|
||||
{pkgpath: "complexnums", name: "PN", want: "const PN untyped complex", wantval: "(1 + -1i)"},
|
||||
{pkgpath: "complexnums", name: "PP", want: "const PP untyped complex", wantval: "(1 + 1i)"},
|
||||
{pkgpath: "conversions", name: "Bits", want: "const Bits Units", wantval: `"bits"`},
|
||||
{pkgpath: "time", name: "Duration", want: "type Duration int64"},
|
||||
{pkgpath: "time", name: "Nanosecond", want: "const Nanosecond Duration", wantval: "1"},
|
||||
{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
|
||||
{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
|
||||
{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
|
||||
{pkgpath: "importsar", name: "Hello", want: "var Hello string"},
|
||||
{pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
|
||||
{pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
|
||||
{pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
|
||||
{pkgpath: "issue27856", name: "M", want: "type M struct{E F}"},
|
||||
}
|
||||
|
||||
func TestGoxImporter(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
initmap := make(map[*types.Package]InitData)
|
||||
imp := GetImporter([]string{"testdata"}, initmap)
|
||||
|
||||
for _, test := range importerTests {
|
||||
runImporterTest(t, imp, initmap, &test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestObjImporter(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
// This test relies on gccgo being around, which it most likely will be if we
|
||||
// were compiled with gccgo.
|
||||
if runtime.Compiler != "gccgo" {
|
||||
t.Skip("This test needs gccgo")
|
||||
}
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
initmap := make(map[*types.Package]InitData)
|
||||
imp := GetImporter([]string{tmpdir}, initmap)
|
||||
|
||||
artmpdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
arinitmap := make(map[*types.Package]InitData)
|
||||
arimp := GetImporter([]string{artmpdir}, arinitmap)
|
||||
|
||||
for _, test := range importerTests {
|
||||
gofile := filepath.Join("testdata", test.pkgpath+".go")
|
||||
ofile := filepath.Join(tmpdir, test.pkgpath+".o")
|
||||
afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a")
|
||||
|
||||
cmd := exec.Command("gccgo", "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatalf("gccgo %s failed: %s", gofile, err)
|
||||
}
|
||||
|
||||
runImporterTest(t, imp, initmap, &test)
|
||||
|
||||
cmd = exec.Command("ar", "cr", afile, ofile)
|
||||
out, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatalf("ar cr %s %s failed: %s", afile, ofile, err)
|
||||
}
|
||||
|
||||
runImporterTest(t, arimp, arinitmap, &test)
|
||||
|
||||
if err = os.Remove(ofile); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = os.Remove(afile); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = os.Remove(tmpdir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
21
vendor/golang.org/x/tools/go/internal/gccgoimporter/newInterface10.go
generated
vendored
21
vendor/golang.org/x/tools/go/internal/gccgoimporter/newInterface10.go
generated
vendored
@@ -1,21 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.11
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
|
||||
named := make([]*types.Named, len(embeddeds))
|
||||
for i, e := range embeddeds {
|
||||
var ok bool
|
||||
named[i], ok = e.(*types.Named)
|
||||
if !ok {
|
||||
panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
|
||||
}
|
||||
}
|
||||
return types.NewInterface(methods, named)
|
||||
}
|
13
vendor/golang.org/x/tools/go/internal/gccgoimporter/newInterface11.go
generated
vendored
13
vendor/golang.org/x/tools/go/internal/gccgoimporter/newInterface11.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.11
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
|
||||
return types.NewInterfaceType(methods, embeddeds)
|
||||
}
|
997
vendor/golang.org/x/tools/go/internal/gccgoimporter/parser.go
generated
vendored
997
vendor/golang.org/x/tools/go/internal/gccgoimporter/parser.go
generated
vendored
@@ -1,997 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter, with
|
||||
// a small modification in parseInterface to support older Go versions.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
type parser struct {
|
||||
scanner scanner.Scanner
|
||||
version string // format version
|
||||
tok rune // current token
|
||||
lit string // literal string; only valid for Ident, Int, String tokens
|
||||
pkgpath string // package path of imported package
|
||||
pkgname string // name of imported package
|
||||
pkg *types.Package // reference to imported package
|
||||
imports map[string]*types.Package // package path -> package object
|
||||
typeList []types.Type // type number -> type
|
||||
initdata InitData // package init priority data
|
||||
}
|
||||
|
||||
func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
|
||||
p.scanner.Init(src)
|
||||
p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
|
||||
p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
|
||||
p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
|
||||
p.scanner.Filename = filename // for good error messages
|
||||
p.next()
|
||||
p.imports = imports
|
||||
p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
|
||||
}
|
||||
|
||||
type importError struct {
|
||||
pos scanner.Position
|
||||
err error
|
||||
}
|
||||
|
||||
func (e importError) Error() string {
|
||||
return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
|
||||
}
|
||||
|
||||
func (p *parser) error(err interface{}) {
|
||||
if s, ok := err.(string); ok {
|
||||
err = errors.New(s)
|
||||
}
|
||||
// panic with a runtime.Error if err is not an error
|
||||
panic(importError{p.scanner.Pos(), err.(error)})
|
||||
}
|
||||
|
||||
func (p *parser) errorf(format string, args ...interface{}) {
|
||||
p.error(fmt.Errorf(format, args...))
|
||||
}
|
||||
|
||||
func (p *parser) expect(tok rune) string {
|
||||
lit := p.lit
|
||||
if p.tok != tok {
|
||||
p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
|
||||
}
|
||||
p.next()
|
||||
return lit
|
||||
}
|
||||
|
||||
func (p *parser) expectKeyword(keyword string) {
|
||||
lit := p.expect(scanner.Ident)
|
||||
if lit != keyword {
|
||||
p.errorf("expected keyword %s, got %q", keyword, lit)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseString() string {
|
||||
str, err := strconv.Unquote(p.expect(scanner.String))
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// unquotedString = { unquotedStringChar } .
|
||||
// unquotedStringChar = <neither a whitespace nor a ';' char> .
|
||||
func (p *parser) parseUnquotedString() string {
|
||||
if p.tok == scanner.EOF {
|
||||
p.error("unexpected EOF")
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(p.scanner.TokenText())
|
||||
// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
|
||||
// we need to let it be consumed by p.next().
|
||||
for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
|
||||
buf.WriteRune(ch)
|
||||
p.scanner.Next()
|
||||
}
|
||||
p.next()
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (p *parser) next() {
|
||||
p.tok = p.scanner.Scan()
|
||||
switch p.tok {
|
||||
case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
|
||||
p.lit = p.scanner.TokenText()
|
||||
default:
|
||||
p.lit = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseQualifiedName() (path, name string) {
|
||||
return p.parseQualifiedNameStr(p.parseString())
|
||||
}
|
||||
|
||||
func (p *parser) parseUnquotedQualifiedName() (path, name string) {
|
||||
return p.parseQualifiedNameStr(p.parseUnquotedString())
|
||||
}
|
||||
|
||||
// qualifiedName = [ ["."] unquotedString "." ] unquotedString .
|
||||
//
|
||||
// The above production uses greedy matching.
|
||||
func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
|
||||
parts := strings.Split(unquotedName, ".")
|
||||
if parts[0] == "" {
|
||||
parts = parts[1:]
|
||||
}
|
||||
|
||||
switch len(parts) {
|
||||
case 0:
|
||||
p.errorf("malformed qualified name: %q", unquotedName)
|
||||
case 1:
|
||||
// unqualified name
|
||||
pkgpath = p.pkgpath
|
||||
name = parts[0]
|
||||
default:
|
||||
// qualified name, which may contain periods
|
||||
pkgpath = strings.Join(parts[0:len(parts)-1], ".")
|
||||
name = parts[len(parts)-1]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getPkg returns the package for a given path. If the package is
|
||||
// not found but we have a package name, create the package and
|
||||
// add it to the p.imports map.
|
||||
//
|
||||
func (p *parser) getPkg(pkgpath, name string) *types.Package {
|
||||
// package unsafe is not in the imports map - handle explicitly
|
||||
if pkgpath == "unsafe" {
|
||||
return types.Unsafe
|
||||
}
|
||||
pkg := p.imports[pkgpath]
|
||||
if pkg == nil && name != "" {
|
||||
pkg = types.NewPackage(pkgpath, name)
|
||||
p.imports[pkgpath] = pkg
|
||||
}
|
||||
return pkg
|
||||
}
|
||||
|
||||
// parseExportedName is like parseQualifiedName, but
|
||||
// the package path is resolved to an imported *types.Package.
|
||||
//
|
||||
// ExportedName = string [string] .
|
||||
func (p *parser) parseExportedName() (pkg *types.Package, name string) {
|
||||
path, name := p.parseQualifiedName()
|
||||
var pkgname string
|
||||
if p.tok == scanner.String {
|
||||
pkgname = p.parseString()
|
||||
}
|
||||
pkg = p.getPkg(path, pkgname)
|
||||
if pkg == nil {
|
||||
p.errorf("package %s (path = %q) not found", name, path)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Name = QualifiedName | "?" .
|
||||
func (p *parser) parseName() string {
|
||||
if p.tok == '?' {
|
||||
// Anonymous.
|
||||
p.next()
|
||||
return ""
|
||||
}
|
||||
// The package path is redundant for us. Don't try to parse it.
|
||||
_, name := p.parseUnquotedQualifiedName()
|
||||
return name
|
||||
}
|
||||
|
||||
func deref(typ types.Type) types.Type {
|
||||
if p, _ := typ.(*types.Pointer); p != nil {
|
||||
typ = p.Elem()
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
// Field = Name Type [string] .
|
||||
func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
|
||||
name := p.parseName()
|
||||
typ := p.parseType(pkg)
|
||||
anon := false
|
||||
if name == "" {
|
||||
anon = true
|
||||
switch typ := deref(typ).(type) {
|
||||
case *types.Basic:
|
||||
name = typ.Name()
|
||||
case *types.Named:
|
||||
name = typ.Obj().Name()
|
||||
default:
|
||||
p.error("anonymous field expected")
|
||||
}
|
||||
}
|
||||
field = types.NewField(token.NoPos, pkg, name, typ, anon)
|
||||
if p.tok == scanner.String {
|
||||
tag = p.parseString()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Param = Name ["..."] Type .
|
||||
func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
|
||||
name := p.parseName()
|
||||
if p.tok == '<' && p.scanner.Peek() == 'e' {
|
||||
// EscInfo = "<esc:" int ">" . (optional and ignored)
|
||||
p.next()
|
||||
p.expectKeyword("esc")
|
||||
p.expect(':')
|
||||
p.expect(scanner.Int)
|
||||
p.expect('>')
|
||||
}
|
||||
if p.tok == '.' {
|
||||
p.next()
|
||||
p.expect('.')
|
||||
p.expect('.')
|
||||
isVariadic = true
|
||||
}
|
||||
typ := p.parseType(pkg)
|
||||
if isVariadic {
|
||||
typ = types.NewSlice(typ)
|
||||
}
|
||||
param = types.NewParam(token.NoPos, pkg, name, typ)
|
||||
return
|
||||
}
|
||||
|
||||
// Var = Name Type .
|
||||
func (p *parser) parseVar(pkg *types.Package) *types.Var {
|
||||
name := p.parseName()
|
||||
return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
|
||||
}
|
||||
|
||||
// Conversion = "convert" "(" Type "," ConstValue ")" .
|
||||
func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
|
||||
p.expectKeyword("convert")
|
||||
p.expect('(')
|
||||
typ = p.parseType(pkg)
|
||||
p.expect(',')
|
||||
val, _ = p.parseConstValue(pkg)
|
||||
p.expect(')')
|
||||
return
|
||||
}
|
||||
|
||||
// ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
|
||||
// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
|
||||
func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
|
||||
switch p.tok {
|
||||
case scanner.String:
|
||||
str := p.parseString()
|
||||
val = constant.MakeString(str)
|
||||
typ = types.Typ[types.UntypedString]
|
||||
return
|
||||
|
||||
case scanner.Ident:
|
||||
b := false
|
||||
switch p.lit {
|
||||
case "false":
|
||||
case "true":
|
||||
b = true
|
||||
|
||||
case "convert":
|
||||
return p.parseConversion(pkg)
|
||||
|
||||
default:
|
||||
p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
||||
}
|
||||
|
||||
p.next()
|
||||
val = constant.MakeBool(b)
|
||||
typ = types.Typ[types.UntypedBool]
|
||||
return
|
||||
}
|
||||
|
||||
sign := ""
|
||||
if p.tok == '-' {
|
||||
p.next()
|
||||
sign = "-"
|
||||
}
|
||||
|
||||
switch p.tok {
|
||||
case scanner.Int:
|
||||
val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
|
||||
if val == nil {
|
||||
p.error("could not parse integer literal")
|
||||
}
|
||||
|
||||
p.next()
|
||||
if p.tok == '\'' {
|
||||
p.next()
|
||||
typ = types.Typ[types.UntypedRune]
|
||||
} else {
|
||||
typ = types.Typ[types.UntypedInt]
|
||||
}
|
||||
|
||||
case scanner.Float:
|
||||
re := sign + p.lit
|
||||
p.next()
|
||||
|
||||
var im string
|
||||
switch p.tok {
|
||||
case '+':
|
||||
p.next()
|
||||
im = p.expect(scanner.Float)
|
||||
|
||||
case '-':
|
||||
p.next()
|
||||
im = "-" + p.expect(scanner.Float)
|
||||
|
||||
case scanner.Ident:
|
||||
// re is in fact the imaginary component. Expect "i" below.
|
||||
im = re
|
||||
re = "0"
|
||||
|
||||
default:
|
||||
val = constant.MakeFromLiteral(re, token.FLOAT, 0)
|
||||
if val == nil {
|
||||
p.error("could not parse float literal")
|
||||
}
|
||||
typ = types.Typ[types.UntypedFloat]
|
||||
return
|
||||
}
|
||||
|
||||
p.expectKeyword("i")
|
||||
reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
|
||||
if reval == nil {
|
||||
p.error("could not parse real component of complex literal")
|
||||
}
|
||||
imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
|
||||
if imval == nil {
|
||||
p.error("could not parse imag component of complex literal")
|
||||
}
|
||||
val = constant.BinaryOp(reval, token.ADD, imval)
|
||||
typ = types.Typ[types.UntypedComplex]
|
||||
|
||||
default:
|
||||
p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Const = Name [Type] "=" ConstValue .
|
||||
func (p *parser) parseConst(pkg *types.Package) *types.Const {
|
||||
name := p.parseName()
|
||||
var typ types.Type
|
||||
if p.tok == '<' {
|
||||
typ = p.parseType(pkg)
|
||||
}
|
||||
p.expect('=')
|
||||
val, vtyp := p.parseConstValue(pkg)
|
||||
if typ == nil {
|
||||
typ = vtyp
|
||||
}
|
||||
return types.NewConst(token.NoPos, pkg, name, typ, val)
|
||||
}
|
||||
|
||||
// reserved is a singleton type used to fill type map slots that have
|
||||
// been reserved (i.e., for which a type number has been parsed) but
|
||||
// which don't have their actual type yet. When the type map is updated,
|
||||
// the actual type must replace a reserved entry (or we have an internal
|
||||
// error). Used for self-verification only - not required for correctness.
|
||||
var reserved = new(struct{ types.Type })
|
||||
|
||||
// reserve reserves the type map entry n for future use.
|
||||
func (p *parser) reserve(n int) {
|
||||
if n != len(p.typeList) {
|
||||
p.errorf("invalid type number %d (out of sync)", n)
|
||||
}
|
||||
p.typeList = append(p.typeList, reserved)
|
||||
}
|
||||
|
||||
// update sets the type map entries for the given type numbers nlist to t.
|
||||
func (p *parser) update(t types.Type, nlist []int) {
|
||||
for _, n := range nlist {
|
||||
if p.typeList[n] != reserved {
|
||||
p.errorf("typeMap[%d] not reserved", n)
|
||||
}
|
||||
p.typeList[n] = t
|
||||
}
|
||||
}
|
||||
|
||||
// NamedType = TypeName [ "=" ] Type { Method } .
|
||||
// TypeName = ExportedName .
|
||||
// Method = "func" "(" Param ")" Name ParamList ResultList ";" .
|
||||
func (p *parser) parseNamedType(nlist []int) types.Type {
|
||||
pkg, name := p.parseExportedName()
|
||||
scope := pkg.Scope()
|
||||
obj := scope.Lookup(name)
|
||||
if obj != nil && obj.Type() == nil {
|
||||
p.errorf("%v has nil type", obj)
|
||||
}
|
||||
|
||||
// type alias
|
||||
if p.tok == '=' {
|
||||
p.next()
|
||||
if obj != nil {
|
||||
// use the previously imported (canonical) type
|
||||
t := obj.Type()
|
||||
p.update(t, nlist)
|
||||
p.parseType(pkg) // discard
|
||||
return t
|
||||
}
|
||||
t := p.parseType(pkg, nlist...)
|
||||
obj = types.NewTypeName(token.NoPos, pkg, name, t)
|
||||
scope.Insert(obj)
|
||||
return t
|
||||
}
|
||||
|
||||
// defined type
|
||||
if obj == nil {
|
||||
// A named type may be referred to before the underlying type
|
||||
// is known - set it up.
|
||||
tname := types.NewTypeName(token.NoPos, pkg, name, nil)
|
||||
types.NewNamed(tname, nil, nil)
|
||||
scope.Insert(tname)
|
||||
obj = tname
|
||||
}
|
||||
|
||||
// use the previously imported (canonical), or newly created type
|
||||
t := obj.Type()
|
||||
p.update(t, nlist)
|
||||
|
||||
nt, ok := t.(*types.Named)
|
||||
if !ok {
|
||||
// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
|
||||
pt := p.parseType(pkg)
|
||||
if pt != t {
|
||||
p.error("unexpected underlying type for non-named TypeName")
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
underlying := p.parseType(pkg)
|
||||
if nt.Underlying() == nil {
|
||||
nt.SetUnderlying(underlying.Underlying())
|
||||
}
|
||||
|
||||
// collect associated methods
|
||||
for p.tok == scanner.Ident {
|
||||
p.expectKeyword("func")
|
||||
p.expect('(')
|
||||
receiver, _ := p.parseParam(pkg)
|
||||
p.expect(')')
|
||||
name := p.parseName()
|
||||
params, isVariadic := p.parseParamList(pkg)
|
||||
results := p.parseResultList(pkg)
|
||||
p.expect(';')
|
||||
|
||||
sig := types.NewSignature(receiver, params, results, isVariadic)
|
||||
nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
|
||||
}
|
||||
|
||||
return nt
|
||||
}
|
||||
|
||||
func (p *parser) parseInt64() int64 {
|
||||
lit := p.expect(scanner.Int)
|
||||
n, err := strconv.ParseInt(lit, 10, 64)
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) parseInt() int {
|
||||
lit := p.expect(scanner.Int)
|
||||
n, err := strconv.ParseInt(lit, 10, 0 /* int */)
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
}
|
||||
return int(n)
|
||||
}
|
||||
|
||||
// ArrayOrSliceType = "[" [ int ] "]" Type .
|
||||
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expect('[')
|
||||
if p.tok == ']' {
|
||||
p.next()
|
||||
|
||||
t := new(types.Slice)
|
||||
p.update(t, nlist)
|
||||
|
||||
*t = *types.NewSlice(p.parseType(pkg))
|
||||
return t
|
||||
}
|
||||
|
||||
t := new(types.Array)
|
||||
p.update(t, nlist)
|
||||
|
||||
len := p.parseInt64()
|
||||
p.expect(']')
|
||||
|
||||
*t = *types.NewArray(p.parseType(pkg), len)
|
||||
return t
|
||||
}
|
||||
|
||||
// MapType = "map" "[" Type "]" Type .
|
||||
func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("map")
|
||||
|
||||
t := new(types.Map)
|
||||
p.update(t, nlist)
|
||||
|
||||
p.expect('[')
|
||||
key := p.parseType(pkg)
|
||||
p.expect(']')
|
||||
elem := p.parseType(pkg)
|
||||
|
||||
*t = *types.NewMap(key, elem)
|
||||
return t
|
||||
}
|
||||
|
||||
// ChanType = "chan" ["<-" | "-<"] Type .
|
||||
func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("chan")
|
||||
|
||||
t := new(types.Chan)
|
||||
p.update(t, nlist)
|
||||
|
||||
dir := types.SendRecv
|
||||
switch p.tok {
|
||||
case '-':
|
||||
p.next()
|
||||
p.expect('<')
|
||||
dir = types.SendOnly
|
||||
|
||||
case '<':
|
||||
// don't consume '<' if it belongs to Type
|
||||
if p.scanner.Peek() == '-' {
|
||||
p.next()
|
||||
p.expect('-')
|
||||
dir = types.RecvOnly
|
||||
}
|
||||
}
|
||||
|
||||
*t = *types.NewChan(dir, p.parseType(pkg))
|
||||
return t
|
||||
}
|
||||
|
||||
// StructType = "struct" "{" { Field } "}" .
|
||||
func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("struct")
|
||||
|
||||
t := new(types.Struct)
|
||||
p.update(t, nlist)
|
||||
|
||||
var fields []*types.Var
|
||||
var tags []string
|
||||
|
||||
p.expect('{')
|
||||
for p.tok != '}' && p.tok != scanner.EOF {
|
||||
field, tag := p.parseField(pkg)
|
||||
p.expect(';')
|
||||
fields = append(fields, field)
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
p.expect('}')
|
||||
|
||||
*t = *types.NewStruct(fields, tags)
|
||||
return t
|
||||
}
|
||||
|
||||
// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
|
||||
func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
|
||||
var list []*types.Var
|
||||
isVariadic := false
|
||||
|
||||
p.expect('(')
|
||||
for p.tok != ')' && p.tok != scanner.EOF {
|
||||
if len(list) > 0 {
|
||||
p.expect(',')
|
||||
}
|
||||
par, variadic := p.parseParam(pkg)
|
||||
list = append(list, par)
|
||||
if variadic {
|
||||
if isVariadic {
|
||||
p.error("... not on final argument")
|
||||
}
|
||||
isVariadic = true
|
||||
}
|
||||
}
|
||||
p.expect(')')
|
||||
|
||||
return types.NewTuple(list...), isVariadic
|
||||
}
|
||||
|
||||
// ResultList = Type | ParamList .
|
||||
func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
|
||||
switch p.tok {
|
||||
case '<':
|
||||
return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
|
||||
|
||||
case '(':
|
||||
params, _ := p.parseParamList(pkg)
|
||||
return params
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// FunctionType = ParamList ResultList .
|
||||
func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
|
||||
t := new(types.Signature)
|
||||
p.update(t, nlist)
|
||||
|
||||
params, isVariadic := p.parseParamList(pkg)
|
||||
results := p.parseResultList(pkg)
|
||||
|
||||
*t = *types.NewSignature(nil, params, results, isVariadic)
|
||||
return t
|
||||
}
|
||||
|
||||
// Func = Name FunctionType .
|
||||
func (p *parser) parseFunc(pkg *types.Package) *types.Func {
|
||||
name := p.parseName()
|
||||
if strings.ContainsRune(name, '$') {
|
||||
// This is a Type$equal or Type$hash function, which we don't want to parse,
|
||||
// except for the types.
|
||||
p.discardDirectiveWhileParsingTypes(pkg)
|
||||
return nil
|
||||
}
|
||||
return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
|
||||
}
|
||||
|
||||
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
|
||||
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("interface")
|
||||
|
||||
t := new(types.Interface)
|
||||
p.update(t, nlist)
|
||||
|
||||
var methods []*types.Func
|
||||
var embeddeds []types.Type
|
||||
|
||||
p.expect('{')
|
||||
for p.tok != '}' && p.tok != scanner.EOF {
|
||||
if p.tok == '?' {
|
||||
p.next()
|
||||
embeddeds = append(embeddeds, p.parseType(pkg))
|
||||
} else {
|
||||
method := p.parseFunc(pkg)
|
||||
methods = append(methods, method)
|
||||
}
|
||||
p.expect(';')
|
||||
}
|
||||
p.expect('}')
|
||||
|
||||
*t = *newInterface(methods, embeddeds)
|
||||
return t
|
||||
}
|
||||
|
||||
// PointerType = "*" ("any" | Type) .
|
||||
func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expect('*')
|
||||
if p.tok == scanner.Ident {
|
||||
p.expectKeyword("any")
|
||||
t := types.Typ[types.UnsafePointer]
|
||||
p.update(t, nlist)
|
||||
return t
|
||||
}
|
||||
|
||||
t := new(types.Pointer)
|
||||
p.update(t, nlist)
|
||||
|
||||
*t = *types.NewPointer(p.parseType(pkg))
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
|
||||
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
|
||||
switch p.tok {
|
||||
case scanner.String:
|
||||
return p.parseNamedType(nlist)
|
||||
|
||||
case scanner.Ident:
|
||||
switch p.lit {
|
||||
case "map":
|
||||
return p.parseMapType(pkg, nlist)
|
||||
|
||||
case "chan":
|
||||
return p.parseChanType(pkg, nlist)
|
||||
|
||||
case "struct":
|
||||
return p.parseStructType(pkg, nlist)
|
||||
|
||||
case "interface":
|
||||
return p.parseInterfaceType(pkg, nlist)
|
||||
}
|
||||
|
||||
case '*':
|
||||
return p.parsePointerType(pkg, nlist)
|
||||
|
||||
case '[':
|
||||
return p.parseArrayOrSliceType(pkg, nlist)
|
||||
|
||||
case '(':
|
||||
return p.parseFunctionType(pkg, nlist)
|
||||
}
|
||||
|
||||
p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
// From gofrontend/go/export.h
|
||||
// Note that these values are negative in the gofrontend and have been made positive
|
||||
// in the gccgoimporter.
|
||||
gccgoBuiltinINT8 = 1
|
||||
gccgoBuiltinINT16 = 2
|
||||
gccgoBuiltinINT32 = 3
|
||||
gccgoBuiltinINT64 = 4
|
||||
gccgoBuiltinUINT8 = 5
|
||||
gccgoBuiltinUINT16 = 6
|
||||
gccgoBuiltinUINT32 = 7
|
||||
gccgoBuiltinUINT64 = 8
|
||||
gccgoBuiltinFLOAT32 = 9
|
||||
gccgoBuiltinFLOAT64 = 10
|
||||
gccgoBuiltinINT = 11
|
||||
gccgoBuiltinUINT = 12
|
||||
gccgoBuiltinUINTPTR = 13
|
||||
gccgoBuiltinBOOL = 15
|
||||
gccgoBuiltinSTRING = 16
|
||||
gccgoBuiltinCOMPLEX64 = 17
|
||||
gccgoBuiltinCOMPLEX128 = 18
|
||||
gccgoBuiltinERROR = 19
|
||||
gccgoBuiltinBYTE = 20
|
||||
gccgoBuiltinRUNE = 21
|
||||
)
|
||||
|
||||
func lookupBuiltinType(typ int) types.Type {
|
||||
return [...]types.Type{
|
||||
gccgoBuiltinINT8: types.Typ[types.Int8],
|
||||
gccgoBuiltinINT16: types.Typ[types.Int16],
|
||||
gccgoBuiltinINT32: types.Typ[types.Int32],
|
||||
gccgoBuiltinINT64: types.Typ[types.Int64],
|
||||
gccgoBuiltinUINT8: types.Typ[types.Uint8],
|
||||
gccgoBuiltinUINT16: types.Typ[types.Uint16],
|
||||
gccgoBuiltinUINT32: types.Typ[types.Uint32],
|
||||
gccgoBuiltinUINT64: types.Typ[types.Uint64],
|
||||
gccgoBuiltinFLOAT32: types.Typ[types.Float32],
|
||||
gccgoBuiltinFLOAT64: types.Typ[types.Float64],
|
||||
gccgoBuiltinINT: types.Typ[types.Int],
|
||||
gccgoBuiltinUINT: types.Typ[types.Uint],
|
||||
gccgoBuiltinUINTPTR: types.Typ[types.Uintptr],
|
||||
gccgoBuiltinBOOL: types.Typ[types.Bool],
|
||||
gccgoBuiltinSTRING: types.Typ[types.String],
|
||||
gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64],
|
||||
gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
|
||||
gccgoBuiltinERROR: types.Universe.Lookup("error").Type(),
|
||||
gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(),
|
||||
gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(),
|
||||
}[typ]
|
||||
}
|
||||
|
||||
// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
|
||||
//
|
||||
// parseType updates the type map to t for all type numbers n.
|
||||
//
|
||||
func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
|
||||
p.expect('<')
|
||||
p.expectKeyword("type")
|
||||
|
||||
switch p.tok {
|
||||
case scanner.Int:
|
||||
n1 := p.parseInt()
|
||||
if p.tok == '>' {
|
||||
t = p.typeList[n1]
|
||||
if t == reserved {
|
||||
p.errorf("invalid type cycle, type %d not yet defined", n1)
|
||||
}
|
||||
p.update(t, n)
|
||||
} else {
|
||||
p.reserve(n1)
|
||||
t = p.parseTypeSpec(pkg, append(n, n1))
|
||||
}
|
||||
|
||||
case '-':
|
||||
p.next()
|
||||
n1 := p.parseInt()
|
||||
t = lookupBuiltinType(n1)
|
||||
p.update(t, n)
|
||||
|
||||
default:
|
||||
p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
||||
}
|
||||
|
||||
p.expect('>')
|
||||
return
|
||||
}
|
||||
|
||||
// PackageInit = unquotedString unquotedString int .
|
||||
func (p *parser) parsePackageInit() PackageInit {
|
||||
name := p.parseUnquotedString()
|
||||
initfunc := p.parseUnquotedString()
|
||||
priority := -1
|
||||
if p.version == "v1" {
|
||||
priority = p.parseInt()
|
||||
}
|
||||
return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
|
||||
}
|
||||
|
||||
// Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
|
||||
func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
|
||||
for {
|
||||
switch p.tok {
|
||||
case ';':
|
||||
return
|
||||
case '<':
|
||||
p.parseType(pkg)
|
||||
case scanner.EOF:
|
||||
p.error("unexpected EOF")
|
||||
default:
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the package if we have parsed both the package path and package name.
|
||||
func (p *parser) maybeCreatePackage() {
|
||||
if p.pkgname != "" && p.pkgpath != "" {
|
||||
p.pkg = p.getPkg(p.pkgpath, p.pkgname)
|
||||
}
|
||||
}
|
||||
|
||||
// InitDataDirective = ( "v1" | "v2" ) ";" |
|
||||
// "priority" int ";" |
|
||||
// "init" { PackageInit } ";" |
|
||||
// "checksum" unquotedString ";" .
|
||||
func (p *parser) parseInitDataDirective() {
|
||||
if p.tok != scanner.Ident {
|
||||
// unexpected token kind; panic
|
||||
p.expect(scanner.Ident)
|
||||
}
|
||||
|
||||
switch p.lit {
|
||||
case "v1", "v2":
|
||||
p.version = p.lit
|
||||
p.next()
|
||||
p.expect(';')
|
||||
|
||||
case "priority":
|
||||
p.next()
|
||||
p.initdata.Priority = p.parseInt()
|
||||
p.expect(';')
|
||||
|
||||
case "init":
|
||||
p.next()
|
||||
for p.tok != ';' && p.tok != scanner.EOF {
|
||||
p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
|
||||
}
|
||||
p.expect(';')
|
||||
|
||||
case "init_graph":
|
||||
p.next()
|
||||
// The graph data is thrown away for now.
|
||||
for p.tok != ';' && p.tok != scanner.EOF {
|
||||
p.parseInt64()
|
||||
p.parseInt64()
|
||||
}
|
||||
p.expect(';')
|
||||
|
||||
case "checksum":
|
||||
// Don't let the scanner try to parse the checksum as a number.
|
||||
defer func(mode uint) {
|
||||
p.scanner.Mode = mode
|
||||
}(p.scanner.Mode)
|
||||
p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
|
||||
p.next()
|
||||
p.parseUnquotedString()
|
||||
p.expect(';')
|
||||
|
||||
default:
|
||||
p.errorf("unexpected identifier: %q", p.lit)
|
||||
}
|
||||
}
|
||||
|
||||
// Directive = InitDataDirective |
|
||||
// "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
|
||||
// "pkgpath" unquotedString ";" |
|
||||
// "prefix" unquotedString ";" |
|
||||
// "import" unquotedString unquotedString string ";" |
|
||||
// "func" Func ";" |
|
||||
// "type" Type ";" |
|
||||
// "var" Var ";" |
|
||||
// "const" Const ";" .
|
||||
func (p *parser) parseDirective() {
|
||||
if p.tok != scanner.Ident {
|
||||
// unexpected token kind; panic
|
||||
p.expect(scanner.Ident)
|
||||
}
|
||||
|
||||
switch p.lit {
|
||||
case "v1", "v2", "priority", "init", "init_graph", "checksum":
|
||||
p.parseInitDataDirective()
|
||||
|
||||
case "package":
|
||||
p.next()
|
||||
p.pkgname = p.parseUnquotedString()
|
||||
p.maybeCreatePackage()
|
||||
if p.version == "v2" && p.tok != ';' {
|
||||
p.parseUnquotedString()
|
||||
p.parseUnquotedString()
|
||||
}
|
||||
p.expect(';')
|
||||
|
||||
case "pkgpath":
|
||||
p.next()
|
||||
p.pkgpath = p.parseUnquotedString()
|
||||
p.maybeCreatePackage()
|
||||
p.expect(';')
|
||||
|
||||
case "prefix":
|
||||
p.next()
|
||||
p.pkgpath = p.parseUnquotedString()
|
||||
p.expect(';')
|
||||
|
||||
case "import":
|
||||
p.next()
|
||||
pkgname := p.parseUnquotedString()
|
||||
pkgpath := p.parseUnquotedString()
|
||||
p.getPkg(pkgpath, pkgname)
|
||||
p.parseString()
|
||||
p.expect(';')
|
||||
|
||||
case "func":
|
||||
p.next()
|
||||
fun := p.parseFunc(p.pkg)
|
||||
if fun != nil {
|
||||
p.pkg.Scope().Insert(fun)
|
||||
}
|
||||
p.expect(';')
|
||||
|
||||
case "type":
|
||||
p.next()
|
||||
p.parseType(p.pkg)
|
||||
p.expect(';')
|
||||
|
||||
case "var":
|
||||
p.next()
|
||||
v := p.parseVar(p.pkg)
|
||||
p.pkg.Scope().Insert(v)
|
||||
p.expect(';')
|
||||
|
||||
case "const":
|
||||
p.next()
|
||||
c := p.parseConst(p.pkg)
|
||||
p.pkg.Scope().Insert(c)
|
||||
p.expect(';')
|
||||
|
||||
default:
|
||||
p.errorf("unexpected identifier: %q", p.lit)
|
||||
}
|
||||
}
|
||||
|
||||
// Package = { Directive } .
|
||||
func (p *parser) parsePackage() *types.Package {
|
||||
for p.tok != scanner.EOF {
|
||||
p.parseDirective()
|
||||
}
|
||||
for _, typ := range p.typeList {
|
||||
if it, ok := typ.(*types.Interface); ok {
|
||||
it.Complete()
|
||||
}
|
||||
}
|
||||
p.pkg.MarkComplete()
|
||||
return p.pkg
|
||||
}
|
80
vendor/golang.org/x/tools/go/internal/gccgoimporter/parser_test.go
generated
vendored
80
vendor/golang.org/x/tools/go/internal/gccgoimporter/parser_test.go
generated
vendored
@@ -1,80 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Except for this comment, this file is a verbatim copy of the file
|
||||
// with the same name in $GOROOT/src/go/internal/gccgoimporter.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/types"
|
||||
"strings"
|
||||
"testing"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
var typeParserTests = []struct {
|
||||
id, typ, want, underlying, methods string
|
||||
}{
|
||||
{id: "foo", typ: "<type -1>", want: "int8"},
|
||||
{id: "foo", typ: "<type 1 *<type -19>>", want: "*error"},
|
||||
{id: "foo", typ: "<type 1 *any>", want: "unsafe.Pointer"},
|
||||
{id: "foo", typ: "<type 1 \"Bar\" <type 2 *<type 1>>>", want: "foo.Bar", underlying: "*foo.Bar"},
|
||||
{id: "foo", typ: "<type 1 \"bar.Foo\" \"bar\" <type -1> func (? <type 1>) M (); >", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"},
|
||||
{id: "foo", typ: "<type 1 \".bar.foo\" \"bar\" <type -1>>", want: "bar.foo", underlying: "int8"},
|
||||
{id: "foo", typ: "<type 1 []<type -1>>", want: "[]int8"},
|
||||
{id: "foo", typ: "<type 1 [42]<type -1>>", want: "[42]int8"},
|
||||
{id: "foo", typ: "<type 1 map [<type -1>] <type -2>>", want: "map[int8]int16"},
|
||||
{id: "foo", typ: "<type 1 chan <type -1>>", want: "chan int8"},
|
||||
{id: "foo", typ: "<type 1 chan <- <type -1>>", want: "<-chan int8"},
|
||||
{id: "foo", typ: "<type 1 chan -< <type -1>>", want: "chan<- int8"},
|
||||
{id: "foo", typ: "<type 1 struct { I8 <type -1>; I16 <type -2> \"i16\"; }>", want: "struct{I8 int8; I16 int16 \"i16\"}"},
|
||||
{id: "foo", typ: "<type 1 interface { Foo (a <type -1>, b <type -2>) <type -1>; Bar (? <type -2>, ? ...<type -1>) (? <type -2>, ? <type -1>); Baz (); }>", want: "interface{Bar(int16, ...int8) (int16, int8); Baz(); Foo(a int8, b int16) int8}"},
|
||||
{id: "foo", typ: "<type 1 (? <type -1>) <type -2>>", want: "func(int8) int16"},
|
||||
}
|
||||
|
||||
func TestTypeParser(t *testing.T) {
|
||||
for _, test := range typeParserTests {
|
||||
var p parser
|
||||
p.init("test.gox", strings.NewReader(test.typ), make(map[string]*types.Package))
|
||||
p.pkgname = test.id
|
||||
p.pkgpath = test.id
|
||||
p.maybeCreatePackage()
|
||||
typ := p.parseType(p.pkg)
|
||||
|
||||
if p.tok != scanner.EOF {
|
||||
t.Errorf("expected full parse, stopped at %q", p.lit)
|
||||
}
|
||||
|
||||
// interfaces must be explicitly completed
|
||||
if ityp, _ := typ.(*types.Interface); ityp != nil {
|
||||
ityp.Complete()
|
||||
}
|
||||
|
||||
got := typ.String()
|
||||
if got != test.want {
|
||||
t.Errorf("got type %q, expected %q", got, test.want)
|
||||
}
|
||||
|
||||
if test.underlying != "" {
|
||||
underlying := typ.Underlying().String()
|
||||
if underlying != test.underlying {
|
||||
t.Errorf("got underlying type %q, expected %q", underlying, test.underlying)
|
||||
}
|
||||
}
|
||||
|
||||
if test.methods != "" {
|
||||
nt := typ.(*types.Named)
|
||||
var buf bytes.Buffer
|
||||
for i := 0; i != nt.NumMethods(); i++ {
|
||||
buf.WriteString(nt.Method(i).String())
|
||||
}
|
||||
methods := buf.String()
|
||||
if methods != test.methods {
|
||||
t.Errorf("got methods %q, expected %q", methods, test.methods)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
65
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/aliases.go
generated
vendored
65
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/aliases.go
generated
vendored
@@ -1,65 +0,0 @@
|
||||
package aliases
|
||||
|
||||
type (
|
||||
T0 [10]int
|
||||
T1 []byte
|
||||
T2 struct {
|
||||
x int
|
||||
}
|
||||
T3 interface {
|
||||
m() T2
|
||||
}
|
||||
T4 func(int, T0) chan T2
|
||||
)
|
||||
|
||||
// basic aliases
|
||||
type (
|
||||
Ai = int
|
||||
A0 = T0
|
||||
A1 = T1
|
||||
A2 = T2
|
||||
A3 = T3
|
||||
A4 = T4
|
||||
|
||||
A10 = [10]int
|
||||
A11 = []byte
|
||||
A12 = struct {
|
||||
x int
|
||||
}
|
||||
A13 = interface {
|
||||
m() A2
|
||||
}
|
||||
A14 = func(int, A0) chan A2
|
||||
)
|
||||
|
||||
// alias receiver types
|
||||
func (T0) m1() {}
|
||||
func (A0) m2() {}
|
||||
|
||||
// alias receiver types (long type declaration chains)
|
||||
type (
|
||||
V0 = V1
|
||||
V1 = (V2)
|
||||
V2 = (V3)
|
||||
V3 = T0
|
||||
)
|
||||
|
||||
func (V1) n() {}
|
||||
|
||||
// cycles
|
||||
type C0 struct {
|
||||
f1 C1
|
||||
f2 C2
|
||||
}
|
||||
|
||||
type (
|
||||
C1 *C0
|
||||
C2 = C1
|
||||
)
|
||||
|
||||
type (
|
||||
C5 struct {
|
||||
f *C6
|
||||
}
|
||||
C6 = C5
|
||||
)
|
33
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/aliases.gox
generated
vendored
33
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/aliases.gox
generated
vendored
@@ -1,33 +0,0 @@
|
||||
v2;
|
||||
package aliases;
|
||||
prefix go;
|
||||
package aliases go.aliases go.aliases;
|
||||
type <type 1 "A0" = <type 2 "T0" <type 3 [10 ] <type -11>>
|
||||
func (? <esc:0x1> <type 2>) .go.aliases.m1 ();
|
||||
func (? <esc:0x1> <type 1>) .go.aliases.m2 ();
|
||||
func (? <esc:0x1> <type 4 "V1" = <type 5 "V2" = <type 6 "V3" = <type 2>>>>) .go.aliases.n ();
|
||||
>>;
|
||||
type <type 7 "A1" = <type 8 "T1" <type 9 [] <type -20>>>>;
|
||||
type <type 10 "A10" = <type 11 [10 ] <type -11>>>;
|
||||
type <type 12 "A11" = <type 13 [] <type -20>>>;
|
||||
type <type 14 "A12" = <type 15 struct { .go.aliases.x <type -11>; }>>;
|
||||
type <type 16 "A13" = <type 17 interface { .go.aliases.m () <type 18 "A2" = <type 19 "T2" <type 20 struct { .go.aliases.x <type -11>; }>>>; }>>;
|
||||
type <type 21 "A14" = <type 22 (? <type -11>, ? <type 1>) <type 23 chan <type 18>>>>;
|
||||
type <type 18>;
|
||||
type <type 24 "A3" = <type 25 "T3" <type 26 interface { .go.aliases.m () <type 19>; }>>>;
|
||||
type <type 27 "A4" = <type 28 "T4" <type 29 (? <type -11>, ? <type 2>) <type 30 chan <type 19>>>>>;
|
||||
type <type 31 "Ai" = <type -11>>;
|
||||
type <type 32 "C0" <type 33 struct { .go.aliases.f1 <type 34 "C1" <type 35 *<type 32>>>; .go.aliases.f2 <type 36 "C2" = <type 34>>; }>>;
|
||||
type <type 34>;
|
||||
type <type 36>;
|
||||
type <type 37 "C5" <type 38 struct { .go.aliases.f <type 39 *<type 40 "C6" = <type 37>>>; }>>;
|
||||
type <type 40>;
|
||||
type <type 2>;
|
||||
type <type 8>;
|
||||
type <type 19>;
|
||||
type <type 25>;
|
||||
type <type 28>;
|
||||
type <type 41 "V0" = <type 4>>;
|
||||
type <type 4>;
|
||||
type <type 5>;
|
||||
type <type 6>;
|
6
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/complexnums.go
generated
vendored
6
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/complexnums.go
generated
vendored
@@ -1,6 +0,0 @@
|
||||
package complexnums
|
||||
|
||||
const NN = -1 - 1i
|
||||
const NP = -1 + 1i
|
||||
const PN = 1 - 1i
|
||||
const PP = 1 + 1i
|
8
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/complexnums.gox
generated
vendored
8
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/complexnums.gox
generated
vendored
@@ -1,8 +0,0 @@
|
||||
v1;
|
||||
package complexnums;
|
||||
pkgpath complexnums;
|
||||
priority 1;
|
||||
const NN = -0.1E1-0.1E1i ;
|
||||
const NP = -0.1E1+0.1E1i ;
|
||||
const PN = 0.1E1-0.1E1i ;
|
||||
const PP = 0.1E1+0.1E1i ;
|
5
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/conversions.go
generated
vendored
5
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/conversions.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
package conversions
|
||||
|
||||
type Units string
|
||||
|
||||
const Bits = Units("bits")
|
6
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/conversions.gox
generated
vendored
6
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/conversions.gox
generated
vendored
@@ -1,6 +0,0 @@
|
||||
v2;
|
||||
package conversions;
|
||||
prefix go;
|
||||
package conversions go.conversions go.conversions;
|
||||
const Bits <type 1 "Units" <type -16>> = convert(<type 1>, "bits");
|
||||
type <type 1>;
|
13
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/escapeinfo.go
generated
vendored
13
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/escapeinfo.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
// Test case for escape info in export data. To compile and extract .gox file:
|
||||
// gccgo -fgo-optimize-allocs -c escapeinfo.go
|
||||
// objcopy -j .go_export escapeinfo.o escapeinfo.gox
|
||||
|
||||
package escapeinfo
|
||||
|
||||
type T struct{ data []byte }
|
||||
|
||||
func NewT(data []byte) *T {
|
||||
return &T{data}
|
||||
}
|
||||
|
||||
func (*T) Read(p []byte) {}
|
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/escapeinfo.gox
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/escapeinfo.gox
generated
vendored
Binary file not shown.
5
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/imports.go
generated
vendored
5
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/imports.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
package imports
|
||||
|
||||
import "fmt"
|
||||
|
||||
var Hello = fmt.Sprintf("Hello, world")
|
7
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/imports.gox
generated
vendored
7
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/imports.gox
generated
vendored
@@ -1,7 +0,0 @@
|
||||
v1;
|
||||
package imports;
|
||||
pkgpath imports;
|
||||
priority 7;
|
||||
import fmt fmt "fmt";
|
||||
init imports imports..import 7 math math..import 1 runtime runtime..import 1 strconv strconv..import 2 io io..import 3 reflect reflect..import 3 syscall syscall..import 3 time time..import 4 os os..import 5 fmt fmt..import 6;
|
||||
var Hello <type -16>;
|
9
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/issue27856.go
generated
vendored
9
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/issue27856.go
generated
vendored
@@ -1,9 +0,0 @@
|
||||
package lib
|
||||
|
||||
type M struct {
|
||||
E E
|
||||
}
|
||||
type F struct {
|
||||
_ *M
|
||||
}
|
||||
type E = F
|
9
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/issue27856.gox
generated
vendored
9
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/issue27856.gox
generated
vendored
@@ -1,9 +0,0 @@
|
||||
v2;
|
||||
package main;
|
||||
pkgpath main;
|
||||
import runtime runtime "runtime";
|
||||
init runtime runtime..import sys runtime_internal_sys..import;
|
||||
init_graph 0 1;
|
||||
type <type 1 "E" = <type 2 "F" <type 3 struct { .main._ <type 4 *<type 5 "M" <type 6 struct { E <type 1>; }>>>; }>>>;
|
||||
type <type 2>;
|
||||
type <type 5>;
|
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/libimportsar.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/libimportsar.a
generated
vendored
Binary file not shown.
3
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/pointer.go
generated
vendored
3
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/pointer.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
package pointer
|
||||
|
||||
type Int8Ptr *int8
|
4
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/pointer.gox
generated
vendored
4
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/pointer.gox
generated
vendored
@@ -1,4 +0,0 @@
|
||||
v1;
|
||||
package pointer;
|
||||
pkgpath pointer;
|
||||
type <type 1 "Int8Ptr" <type 2 *<type -1>>>;
|
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/time.gox
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/time.gox
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/unicode.gox
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata/unicode.gox
generated
vendored
Binary file not shown.
44
vendor/golang.org/x/tools/go/internal/gccgoimporter/testenv_test.go
generated
vendored
44
vendor/golang.org/x/tools/go/internal/gccgoimporter/testenv_test.go
generated
vendored
@@ -1,44 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file contains testing utilities copied from $GOROOT/src/internal/testenv/testenv.go.
|
||||
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// HasGoBuild reports whether the current system can build programs with ``go build''
|
||||
// and then run them with os.StartProcess or exec.Command.
|
||||
func HasGoBuild() bool {
|
||||
switch runtime.GOOS {
|
||||
case "android", "nacl":
|
||||
return false
|
||||
case "darwin":
|
||||
if strings.HasPrefix(runtime.GOARCH, "arm") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MustHaveGoBuild checks that the current system can build programs with ``go build''
|
||||
// and then run them with os.StartProcess or exec.Command.
|
||||
// If not, MustHaveGoBuild calls t.Skip with an explanation.
|
||||
func MustHaveGoBuild(t *testing.T) {
|
||||
if !HasGoBuild() {
|
||||
t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
}
|
||||
|
||||
var testenv = struct {
|
||||
HasGoBuild func() bool
|
||||
MustHaveGoBuild func(*testing.T)
|
||||
}{
|
||||
HasGoBuild: HasGoBuild,
|
||||
MustHaveGoBuild: MustHaveGoBuild,
|
||||
}
|
852
vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
generated
vendored
852
vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
generated
vendored
@@ -1,852 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Binary package export.
|
||||
// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go;
|
||||
// see that file for specification of the format.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// If debugFormat is set, each integer and string value is preceded by a marker
|
||||
// and position information in the encoding. This mechanism permits an importer
|
||||
// to recognize immediately when it is out of sync. The importer recognizes this
|
||||
// mode automatically (i.e., it can import export data produced with debugging
|
||||
// support even if debugFormat is not set at the time of import). This mode will
|
||||
// lead to massively larger export data (by a factor of 2 to 3) and should only
|
||||
// be enabled during development and debugging.
|
||||
//
|
||||
// NOTE: This flag is the first flag to enable if importing dies because of
|
||||
// (suspected) format errors, and whenever a change is made to the format.
|
||||
const debugFormat = false // default: false
|
||||
|
||||
// If trace is set, debugging output is printed to std out.
|
||||
const trace = false // default: false
|
||||
|
||||
// Current export format version. Increase with each format change.
|
||||
// Note: The latest binary (non-indexed) export format is at version 6.
|
||||
// This exporter is still at level 4, but it doesn't matter since
|
||||
// the binary importer can handle older versions just fine.
|
||||
// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE
|
||||
// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMEMTED HERE
|
||||
// 4: type name objects support type aliases, uses aliasTag
|
||||
// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
|
||||
// 2: removed unused bool in ODCL export (compiler only)
|
||||
// 1: header format change (more regular), export package for _ struct fields
|
||||
// 0: Go1.7 encoding
|
||||
const exportVersion = 4
|
||||
|
||||
// trackAllTypes enables cycle tracking for all types, not just named
|
||||
// types. The existing compiler invariants assume that unnamed types
|
||||
// that are not completely set up are not used, or else there are spurious
|
||||
// errors.
|
||||
// If disabled, only named types are tracked, possibly leading to slightly
|
||||
// less efficient encoding in rare cases. It also prevents the export of
|
||||
// some corner-case type declarations (but those are not handled correctly
|
||||
// with with the textual export format either).
|
||||
// TODO(gri) enable and remove once issues caused by it are fixed
|
||||
const trackAllTypes = false
|
||||
|
||||
type exporter struct {
|
||||
fset *token.FileSet
|
||||
out bytes.Buffer
|
||||
|
||||
// object -> index maps, indexed in order of serialization
|
||||
strIndex map[string]int
|
||||
pkgIndex map[*types.Package]int
|
||||
typIndex map[types.Type]int
|
||||
|
||||
// position encoding
|
||||
posInfoFormat bool
|
||||
prevFile string
|
||||
prevLine int
|
||||
|
||||
// debugging support
|
||||
written int // bytes written
|
||||
indent int // for trace
|
||||
}
|
||||
|
||||
// internalError represents an error generated inside this package.
|
||||
type internalError string
|
||||
|
||||
func (e internalError) Error() string { return "gcimporter: " + string(e) }
|
||||
|
||||
func internalErrorf(format string, args ...interface{}) error {
|
||||
return internalError(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
// BExportData returns binary export data for pkg.
|
||||
// If no file set is provided, position info will be missing.
|
||||
func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
if ierr, ok := e.(internalError); ok {
|
||||
err = ierr
|
||||
return
|
||||
}
|
||||
// Not an internal error; panic again.
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
|
||||
p := exporter{
|
||||
fset: fset,
|
||||
strIndex: map[string]int{"": 0}, // empty string is mapped to 0
|
||||
pkgIndex: make(map[*types.Package]int),
|
||||
typIndex: make(map[types.Type]int),
|
||||
posInfoFormat: true, // TODO(gri) might become a flag, eventually
|
||||
}
|
||||
|
||||
// write version info
|
||||
// The version string must start with "version %d" where %d is the version
|
||||
// number. Additional debugging information may follow after a blank; that
|
||||
// text is ignored by the importer.
|
||||
p.rawStringln(fmt.Sprintf("version %d", exportVersion))
|
||||
var debug string
|
||||
if debugFormat {
|
||||
debug = "debug"
|
||||
}
|
||||
p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
|
||||
p.bool(trackAllTypes)
|
||||
p.bool(p.posInfoFormat)
|
||||
|
||||
// --- generic export data ---
|
||||
|
||||
// populate type map with predeclared "known" types
|
||||
for index, typ := range predeclared {
|
||||
p.typIndex[typ] = index
|
||||
}
|
||||
if len(p.typIndex) != len(predeclared) {
|
||||
return nil, internalError("duplicate entries in type map?")
|
||||
}
|
||||
|
||||
// write package data
|
||||
p.pkg(pkg, true)
|
||||
if trace {
|
||||
p.tracef("\n")
|
||||
}
|
||||
|
||||
// write objects
|
||||
objcount := 0
|
||||
scope := pkg.Scope()
|
||||
for _, name := range scope.Names() {
|
||||
if !ast.IsExported(name) {
|
||||
continue
|
||||
}
|
||||
if trace {
|
||||
p.tracef("\n")
|
||||
}
|
||||
p.obj(scope.Lookup(name))
|
||||
objcount++
|
||||
}
|
||||
|
||||
// indicate end of list
|
||||
if trace {
|
||||
p.tracef("\n")
|
||||
}
|
||||
p.tag(endTag)
|
||||
|
||||
// for self-verification only (redundant)
|
||||
p.int(objcount)
|
||||
|
||||
if trace {
|
||||
p.tracef("\n")
|
||||
}
|
||||
|
||||
// --- end of export data ---
|
||||
|
||||
return p.out.Bytes(), nil
|
||||
}
|
||||
|
||||
func (p *exporter) pkg(pkg *types.Package, emptypath bool) {
|
||||
if pkg == nil {
|
||||
panic(internalError("unexpected nil pkg"))
|
||||
}
|
||||
|
||||
// if we saw the package before, write its index (>= 0)
|
||||
if i, ok := p.pkgIndex[pkg]; ok {
|
||||
p.index('P', i)
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, remember the package, write the package tag (< 0) and package data
|
||||
if trace {
|
||||
p.tracef("P%d = { ", len(p.pkgIndex))
|
||||
defer p.tracef("} ")
|
||||
}
|
||||
p.pkgIndex[pkg] = len(p.pkgIndex)
|
||||
|
||||
p.tag(packageTag)
|
||||
p.string(pkg.Name())
|
||||
if emptypath {
|
||||
p.string("")
|
||||
} else {
|
||||
p.string(pkg.Path())
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) obj(obj types.Object) {
|
||||
switch obj := obj.(type) {
|
||||
case *types.Const:
|
||||
p.tag(constTag)
|
||||
p.pos(obj)
|
||||
p.qualifiedName(obj)
|
||||
p.typ(obj.Type())
|
||||
p.value(obj.Val())
|
||||
|
||||
case *types.TypeName:
|
||||
if obj.IsAlias() {
|
||||
p.tag(aliasTag)
|
||||
p.pos(obj)
|
||||
p.qualifiedName(obj)
|
||||
} else {
|
||||
p.tag(typeTag)
|
||||
}
|
||||
p.typ(obj.Type())
|
||||
|
||||
case *types.Var:
|
||||
p.tag(varTag)
|
||||
p.pos(obj)
|
||||
p.qualifiedName(obj)
|
||||
p.typ(obj.Type())
|
||||
|
||||
case *types.Func:
|
||||
p.tag(funcTag)
|
||||
p.pos(obj)
|
||||
p.qualifiedName(obj)
|
||||
sig := obj.Type().(*types.Signature)
|
||||
p.paramList(sig.Params(), sig.Variadic())
|
||||
p.paramList(sig.Results(), false)
|
||||
|
||||
default:
|
||||
panic(internalErrorf("unexpected object %v (%T)", obj, obj))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) pos(obj types.Object) {
|
||||
if !p.posInfoFormat {
|
||||
return
|
||||
}
|
||||
|
||||
file, line := p.fileLine(obj)
|
||||
if file == p.prevFile {
|
||||
// common case: write line delta
|
||||
// delta == 0 means different file or no line change
|
||||
delta := line - p.prevLine
|
||||
p.int(delta)
|
||||
if delta == 0 {
|
||||
p.int(-1) // -1 means no file change
|
||||
}
|
||||
} else {
|
||||
// different file
|
||||
p.int(0)
|
||||
// Encode filename as length of common prefix with previous
|
||||
// filename, followed by (possibly empty) suffix. Filenames
|
||||
// frequently share path prefixes, so this can save a lot
|
||||
// of space and make export data size less dependent on file
|
||||
// path length. The suffix is unlikely to be empty because
|
||||
// file names tend to end in ".go".
|
||||
n := commonPrefixLen(p.prevFile, file)
|
||||
p.int(n) // n >= 0
|
||||
p.string(file[n:]) // write suffix only
|
||||
p.prevFile = file
|
||||
p.int(line)
|
||||
}
|
||||
p.prevLine = line
|
||||
}
|
||||
|
||||
func (p *exporter) fileLine(obj types.Object) (file string, line int) {
|
||||
if p.fset != nil {
|
||||
pos := p.fset.Position(obj.Pos())
|
||||
file = pos.Filename
|
||||
line = pos.Line
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func commonPrefixLen(a, b string) int {
|
||||
if len(a) > len(b) {
|
||||
a, b = b, a
|
||||
}
|
||||
// len(a) <= len(b)
|
||||
i := 0
|
||||
for i < len(a) && a[i] == b[i] {
|
||||
i++
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (p *exporter) qualifiedName(obj types.Object) {
|
||||
p.string(obj.Name())
|
||||
p.pkg(obj.Pkg(), false)
|
||||
}
|
||||
|
||||
func (p *exporter) typ(t types.Type) {
|
||||
if t == nil {
|
||||
panic(internalError("nil type"))
|
||||
}
|
||||
|
||||
// Possible optimization: Anonymous pointer types *T where
|
||||
// T is a named type are common. We could canonicalize all
|
||||
// such types *T to a single type PT = *T. This would lead
|
||||
// to at most one *T entry in typIndex, and all future *T's
|
||||
// would be encoded as the respective index directly. Would
|
||||
// save 1 byte (pointerTag) per *T and reduce the typIndex
|
||||
// size (at the cost of a canonicalization map). We can do
|
||||
// this later, without encoding format change.
|
||||
|
||||
// if we saw the type before, write its index (>= 0)
|
||||
if i, ok := p.typIndex[t]; ok {
|
||||
p.index('T', i)
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, remember the type, write the type tag (< 0) and type data
|
||||
if trackAllTypes {
|
||||
if trace {
|
||||
p.tracef("T%d = {>\n", len(p.typIndex))
|
||||
defer p.tracef("<\n} ")
|
||||
}
|
||||
p.typIndex[t] = len(p.typIndex)
|
||||
}
|
||||
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
if !trackAllTypes {
|
||||
// if we don't track all types, track named types now
|
||||
p.typIndex[t] = len(p.typIndex)
|
||||
}
|
||||
|
||||
p.tag(namedTag)
|
||||
p.pos(t.Obj())
|
||||
p.qualifiedName(t.Obj())
|
||||
p.typ(t.Underlying())
|
||||
if !types.IsInterface(t) {
|
||||
p.assocMethods(t)
|
||||
}
|
||||
|
||||
case *types.Array:
|
||||
p.tag(arrayTag)
|
||||
p.int64(t.Len())
|
||||
p.typ(t.Elem())
|
||||
|
||||
case *types.Slice:
|
||||
p.tag(sliceTag)
|
||||
p.typ(t.Elem())
|
||||
|
||||
case *dddSlice:
|
||||
p.tag(dddTag)
|
||||
p.typ(t.elem)
|
||||
|
||||
case *types.Struct:
|
||||
p.tag(structTag)
|
||||
p.fieldList(t)
|
||||
|
||||
case *types.Pointer:
|
||||
p.tag(pointerTag)
|
||||
p.typ(t.Elem())
|
||||
|
||||
case *types.Signature:
|
||||
p.tag(signatureTag)
|
||||
p.paramList(t.Params(), t.Variadic())
|
||||
p.paramList(t.Results(), false)
|
||||
|
||||
case *types.Interface:
|
||||
p.tag(interfaceTag)
|
||||
p.iface(t)
|
||||
|
||||
case *types.Map:
|
||||
p.tag(mapTag)
|
||||
p.typ(t.Key())
|
||||
p.typ(t.Elem())
|
||||
|
||||
case *types.Chan:
|
||||
p.tag(chanTag)
|
||||
p.int(int(3 - t.Dir())) // hack
|
||||
p.typ(t.Elem())
|
||||
|
||||
default:
|
||||
panic(internalErrorf("unexpected type %T: %s", t, t))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) assocMethods(named *types.Named) {
|
||||
// Sort methods (for determinism).
|
||||
var methods []*types.Func
|
||||
for i := 0; i < named.NumMethods(); i++ {
|
||||
methods = append(methods, named.Method(i))
|
||||
}
|
||||
sort.Sort(methodsByName(methods))
|
||||
|
||||
p.int(len(methods))
|
||||
|
||||
if trace && methods != nil {
|
||||
p.tracef("associated methods {>\n")
|
||||
}
|
||||
|
||||
for i, m := range methods {
|
||||
if trace && i > 0 {
|
||||
p.tracef("\n")
|
||||
}
|
||||
|
||||
p.pos(m)
|
||||
name := m.Name()
|
||||
p.string(name)
|
||||
if !exported(name) {
|
||||
p.pkg(m.Pkg(), false)
|
||||
}
|
||||
|
||||
sig := m.Type().(*types.Signature)
|
||||
p.paramList(types.NewTuple(sig.Recv()), false)
|
||||
p.paramList(sig.Params(), sig.Variadic())
|
||||
p.paramList(sig.Results(), false)
|
||||
p.int(0) // dummy value for go:nointerface pragma - ignored by importer
|
||||
}
|
||||
|
||||
if trace && methods != nil {
|
||||
p.tracef("<\n} ")
|
||||
}
|
||||
}
|
||||
|
||||
type methodsByName []*types.Func
|
||||
|
||||
func (x methodsByName) Len() int { return len(x) }
|
||||
func (x methodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() }
|
||||
|
||||
func (p *exporter) fieldList(t *types.Struct) {
|
||||
if trace && t.NumFields() > 0 {
|
||||
p.tracef("fields {>\n")
|
||||
defer p.tracef("<\n} ")
|
||||
}
|
||||
|
||||
p.int(t.NumFields())
|
||||
for i := 0; i < t.NumFields(); i++ {
|
||||
if trace && i > 0 {
|
||||
p.tracef("\n")
|
||||
}
|
||||
p.field(t.Field(i))
|
||||
p.string(t.Tag(i))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) field(f *types.Var) {
|
||||
if !f.IsField() {
|
||||
panic(internalError("field expected"))
|
||||
}
|
||||
|
||||
p.pos(f)
|
||||
p.fieldName(f)
|
||||
p.typ(f.Type())
|
||||
}
|
||||
|
||||
func (p *exporter) iface(t *types.Interface) {
|
||||
// TODO(gri): enable importer to load embedded interfaces,
|
||||
// then emit Embeddeds and ExplicitMethods separately here.
|
||||
p.int(0)
|
||||
|
||||
n := t.NumMethods()
|
||||
if trace && n > 0 {
|
||||
p.tracef("methods {>\n")
|
||||
defer p.tracef("<\n} ")
|
||||
}
|
||||
p.int(n)
|
||||
for i := 0; i < n; i++ {
|
||||
if trace && i > 0 {
|
||||
p.tracef("\n")
|
||||
}
|
||||
p.method(t.Method(i))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) method(m *types.Func) {
|
||||
sig := m.Type().(*types.Signature)
|
||||
if sig.Recv() == nil {
|
||||
panic(internalError("method expected"))
|
||||
}
|
||||
|
||||
p.pos(m)
|
||||
p.string(m.Name())
|
||||
if m.Name() != "_" && !ast.IsExported(m.Name()) {
|
||||
p.pkg(m.Pkg(), false)
|
||||
}
|
||||
|
||||
// interface method; no need to encode receiver.
|
||||
p.paramList(sig.Params(), sig.Variadic())
|
||||
p.paramList(sig.Results(), false)
|
||||
}
|
||||
|
||||
func (p *exporter) fieldName(f *types.Var) {
|
||||
name := f.Name()
|
||||
|
||||
if f.Anonymous() {
|
||||
// anonymous field - we distinguish between 3 cases:
|
||||
// 1) field name matches base type name and is exported
|
||||
// 2) field name matches base type name and is not exported
|
||||
// 3) field name doesn't match base type name (alias name)
|
||||
bname := basetypeName(f.Type())
|
||||
if name == bname {
|
||||
if ast.IsExported(name) {
|
||||
name = "" // 1) we don't need to know the field name or package
|
||||
} else {
|
||||
name = "?" // 2) use unexported name "?" to force package export
|
||||
}
|
||||
} else {
|
||||
// 3) indicate alias and export name as is
|
||||
// (this requires an extra "@" but this is a rare case)
|
||||
p.string("@")
|
||||
}
|
||||
}
|
||||
|
||||
p.string(name)
|
||||
if name != "" && !ast.IsExported(name) {
|
||||
p.pkg(f.Pkg(), false)
|
||||
}
|
||||
}
|
||||
|
||||
func basetypeName(typ types.Type) string {
|
||||
switch typ := deref(typ).(type) {
|
||||
case *types.Basic:
|
||||
return typ.Name()
|
||||
case *types.Named:
|
||||
return typ.Obj().Name()
|
||||
default:
|
||||
return "" // unnamed type
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) paramList(params *types.Tuple, variadic bool) {
|
||||
// use negative length to indicate unnamed parameters
|
||||
// (look at the first parameter only since either all
|
||||
// names are present or all are absent)
|
||||
n := params.Len()
|
||||
if n > 0 && params.At(0).Name() == "" {
|
||||
n = -n
|
||||
}
|
||||
p.int(n)
|
||||
for i := 0; i < params.Len(); i++ {
|
||||
q := params.At(i)
|
||||
t := q.Type()
|
||||
if variadic && i == params.Len()-1 {
|
||||
t = &dddSlice{t.(*types.Slice).Elem()}
|
||||
}
|
||||
p.typ(t)
|
||||
if n > 0 {
|
||||
name := q.Name()
|
||||
p.string(name)
|
||||
if name != "_" {
|
||||
p.pkg(q.Pkg(), false)
|
||||
}
|
||||
}
|
||||
p.string("") // no compiler-specific info
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) value(x constant.Value) {
|
||||
if trace {
|
||||
p.tracef("= ")
|
||||
}
|
||||
|
||||
switch x.Kind() {
|
||||
case constant.Bool:
|
||||
tag := falseTag
|
||||
if constant.BoolVal(x) {
|
||||
tag = trueTag
|
||||
}
|
||||
p.tag(tag)
|
||||
|
||||
case constant.Int:
|
||||
if v, exact := constant.Int64Val(x); exact {
|
||||
// common case: x fits into an int64 - use compact encoding
|
||||
p.tag(int64Tag)
|
||||
p.int64(v)
|
||||
return
|
||||
}
|
||||
// uncommon case: large x - use float encoding
|
||||
// (powers of 2 will be encoded efficiently with exponent)
|
||||
p.tag(floatTag)
|
||||
p.float(constant.ToFloat(x))
|
||||
|
||||
case constant.Float:
|
||||
p.tag(floatTag)
|
||||
p.float(x)
|
||||
|
||||
case constant.Complex:
|
||||
p.tag(complexTag)
|
||||
p.float(constant.Real(x))
|
||||
p.float(constant.Imag(x))
|
||||
|
||||
case constant.String:
|
||||
p.tag(stringTag)
|
||||
p.string(constant.StringVal(x))
|
||||
|
||||
case constant.Unknown:
|
||||
// package contains type errors
|
||||
p.tag(unknownTag)
|
||||
|
||||
default:
|
||||
panic(internalErrorf("unexpected value %v (%T)", x, x))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *exporter) float(x constant.Value) {
|
||||
if x.Kind() != constant.Float {
|
||||
panic(internalErrorf("unexpected constant %v, want float", x))
|
||||
}
|
||||
// extract sign (there is no -0)
|
||||
sign := constant.Sign(x)
|
||||
if sign == 0 {
|
||||
// x == 0
|
||||
p.int(0)
|
||||
return
|
||||
}
|
||||
// x != 0
|
||||
|
||||
var f big.Float
|
||||
if v, exact := constant.Float64Val(x); exact {
|
||||
// float64
|
||||
f.SetFloat64(v)
|
||||
} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
|
||||
// TODO(gri): add big.Rat accessor to constant.Value.
|
||||
r := valueToRat(num)
|
||||
f.SetRat(r.Quo(r, valueToRat(denom)))
|
||||
} else {
|
||||
// Value too large to represent as a fraction => inaccessible.
|
||||
// TODO(gri): add big.Float accessor to constant.Value.
|
||||
f.SetFloat64(math.MaxFloat64) // FIXME
|
||||
}
|
||||
|
||||
// extract exponent such that 0.5 <= m < 1.0
|
||||
var m big.Float
|
||||
exp := f.MantExp(&m)
|
||||
|
||||
// extract mantissa as *big.Int
|
||||
// - set exponent large enough so mant satisfies mant.IsInt()
|
||||
// - get *big.Int from mant
|
||||
m.SetMantExp(&m, int(m.MinPrec()))
|
||||
mant, acc := m.Int(nil)
|
||||
if acc != big.Exact {
|
||||
panic(internalError("internal error"))
|
||||
}
|
||||
|
||||
p.int(sign)
|
||||
p.int(exp)
|
||||
p.string(string(mant.Bytes()))
|
||||
}
|
||||
|
||||
func valueToRat(x constant.Value) *big.Rat {
|
||||
// Convert little-endian to big-endian.
|
||||
// I can't believe this is necessary.
|
||||
bytes := constant.Bytes(x)
|
||||
for i := 0; i < len(bytes)/2; i++ {
|
||||
bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
|
||||
}
|
||||
return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
|
||||
}
|
||||
|
||||
func (p *exporter) bool(b bool) bool {
|
||||
if trace {
|
||||
p.tracef("[")
|
||||
defer p.tracef("= %v] ", b)
|
||||
}
|
||||
|
||||
x := 0
|
||||
if b {
|
||||
x = 1
|
||||
}
|
||||
p.int(x)
|
||||
return b
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Low-level encoders
|
||||
|
||||
func (p *exporter) index(marker byte, index int) {
|
||||
if index < 0 {
|
||||
panic(internalError("invalid index < 0"))
|
||||
}
|
||||
if debugFormat {
|
||||
p.marker('t')
|
||||
}
|
||||
if trace {
|
||||
p.tracef("%c%d ", marker, index)
|
||||
}
|
||||
p.rawInt64(int64(index))
|
||||
}
|
||||
|
||||
func (p *exporter) tag(tag int) {
|
||||
if tag >= 0 {
|
||||
panic(internalError("invalid tag >= 0"))
|
||||
}
|
||||
if debugFormat {
|
||||
p.marker('t')
|
||||
}
|
||||
if trace {
|
||||
p.tracef("%s ", tagString[-tag])
|
||||
}
|
||||
p.rawInt64(int64(tag))
|
||||
}
|
||||
|
||||
func (p *exporter) int(x int) {
|
||||
p.int64(int64(x))
|
||||
}
|
||||
|
||||
func (p *exporter) int64(x int64) {
|
||||
if debugFormat {
|
||||
p.marker('i')
|
||||
}
|
||||
if trace {
|
||||
p.tracef("%d ", x)
|
||||
}
|
||||
p.rawInt64(x)
|
||||
}
|
||||
|
||||
func (p *exporter) string(s string) {
|
||||
if debugFormat {
|
||||
p.marker('s')
|
||||
}
|
||||
if trace {
|
||||
p.tracef("%q ", s)
|
||||
}
|
||||
// if we saw the string before, write its index (>= 0)
|
||||
// (the empty string is mapped to 0)
|
||||
if i, ok := p.strIndex[s]; ok {
|
||||
p.rawInt64(int64(i))
|
||||
return
|
||||
}
|
||||
// otherwise, remember string and write its negative length and bytes
|
||||
p.strIndex[s] = len(p.strIndex)
|
||||
p.rawInt64(-int64(len(s)))
|
||||
for i := 0; i < len(s); i++ {
|
||||
p.rawByte(s[i])
|
||||
}
|
||||
}
|
||||
|
||||
// marker emits a marker byte and position information which makes
|
||||
// it easy for a reader to detect if it is "out of sync". Used for
|
||||
// debugFormat format only.
|
||||
func (p *exporter) marker(m byte) {
|
||||
p.rawByte(m)
|
||||
// Enable this for help tracking down the location
|
||||
// of an incorrect marker when running in debugFormat.
|
||||
if false && trace {
|
||||
p.tracef("#%d ", p.written)
|
||||
}
|
||||
p.rawInt64(int64(p.written))
|
||||
}
|
||||
|
||||
// rawInt64 should only be used by low-level encoders.
|
||||
func (p *exporter) rawInt64(x int64) {
|
||||
var tmp [binary.MaxVarintLen64]byte
|
||||
n := binary.PutVarint(tmp[:], x)
|
||||
for i := 0; i < n; i++ {
|
||||
p.rawByte(tmp[i])
|
||||
}
|
||||
}
|
||||
|
||||
// rawStringln should only be used to emit the initial version string.
|
||||
func (p *exporter) rawStringln(s string) {
|
||||
for i := 0; i < len(s); i++ {
|
||||
p.rawByte(s[i])
|
||||
}
|
||||
p.rawByte('\n')
|
||||
}
|
||||
|
||||
// rawByte is the bottleneck interface to write to p.out.
|
||||
// rawByte escapes b as follows (any encoding does that
|
||||
// hides '$'):
|
||||
//
|
||||
// '$' => '|' 'S'
|
||||
// '|' => '|' '|'
|
||||
//
|
||||
// Necessary so other tools can find the end of the
|
||||
// export data by searching for "$$".
|
||||
// rawByte should only be used by low-level encoders.
|
||||
func (p *exporter) rawByte(b byte) {
|
||||
switch b {
|
||||
case '$':
|
||||
// write '$' as '|' 'S'
|
||||
b = 'S'
|
||||
fallthrough
|
||||
case '|':
|
||||
// write '|' as '|' '|'
|
||||
p.out.WriteByte('|')
|
||||
p.written++
|
||||
}
|
||||
p.out.WriteByte(b)
|
||||
p.written++
|
||||
}
|
||||
|
||||
// tracef is like fmt.Printf but it rewrites the format string
|
||||
// to take care of indentation.
|
||||
func (p *exporter) tracef(format string, args ...interface{}) {
|
||||
if strings.ContainsAny(format, "<>\n") {
|
||||
var buf bytes.Buffer
|
||||
for i := 0; i < len(format); i++ {
|
||||
// no need to deal with runes
|
||||
ch := format[i]
|
||||
switch ch {
|
||||
case '>':
|
||||
p.indent++
|
||||
continue
|
||||
case '<':
|
||||
p.indent--
|
||||
continue
|
||||
}
|
||||
buf.WriteByte(ch)
|
||||
if ch == '\n' {
|
||||
for j := p.indent; j > 0; j-- {
|
||||
buf.WriteString(". ")
|
||||
}
|
||||
}
|
||||
}
|
||||
format = buf.String()
|
||||
}
|
||||
fmt.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Debugging support.
|
||||
// (tagString is only used when tracing is enabled)
|
||||
var tagString = [...]string{
|
||||
// Packages
|
||||
-packageTag: "package",
|
||||
|
||||
// Types
|
||||
-namedTag: "named type",
|
||||
-arrayTag: "array",
|
||||
-sliceTag: "slice",
|
||||
-dddTag: "ddd",
|
||||
-structTag: "struct",
|
||||
-pointerTag: "pointer",
|
||||
-signatureTag: "signature",
|
||||
-interfaceTag: "interface",
|
||||
-mapTag: "map",
|
||||
-chanTag: "chan",
|
||||
|
||||
// Values
|
||||
-falseTag: "false",
|
||||
-trueTag: "true",
|
||||
-int64Tag: "int64",
|
||||
-floatTag: "float",
|
||||
-fractionTag: "fraction",
|
||||
-complexTag: "complex",
|
||||
-stringTag: "string",
|
||||
-unknownTag: "unknown",
|
||||
|
||||
// Type aliases
|
||||
-aliasTag: "alias",
|
||||
}
|
414
vendor/golang.org/x/tools/go/internal/gcimporter/bexport_test.go
generated
vendored
414
vendor/golang.org/x/tools/go/internal/gcimporter/bexport_test.go
generated
vendored
@@ -1,414 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gcimporter_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/constant"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/buildutil"
|
||||
"golang.org/x/tools/go/internal/gcimporter"
|
||||
"golang.org/x/tools/go/loader"
|
||||
)
|
||||
|
||||
func TestBExportData_stdlib(t *testing.T) {
|
||||
if runtime.Compiler == "gccgo" {
|
||||
t.Skip("gccgo standard library is inaccessible")
|
||||
}
|
||||
if runtime.GOOS == "android" {
|
||||
t.Skipf("incomplete std lib on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
// Load, parse and type-check the program.
|
||||
ctxt := build.Default // copy
|
||||
ctxt.GOPATH = "" // disable GOPATH
|
||||
conf := loader.Config{
|
||||
Build: &ctxt,
|
||||
AllowErrors: true,
|
||||
}
|
||||
for _, path := range buildutil.AllPackages(conf.Build) {
|
||||
conf.Import(path)
|
||||
}
|
||||
|
||||
// Create a package containing type and value errors to ensure
|
||||
// they are properly encoded/decoded.
|
||||
f, err := conf.ParseFile("haserrors/haserrors.go", `package haserrors
|
||||
const UnknownValue = "" + 0
|
||||
type UnknownType undefined
|
||||
`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conf.CreateFromFiles("haserrors", f)
|
||||
|
||||
prog, err := conf.Load()
|
||||
if err != nil {
|
||||
t.Fatalf("Load failed: %v", err)
|
||||
}
|
||||
|
||||
numPkgs := len(prog.AllPackages)
|
||||
if want := 248; numPkgs < want {
|
||||
t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
|
||||
}
|
||||
|
||||
for pkg, info := range prog.AllPackages {
|
||||
if info.Files == nil {
|
||||
continue // empty directory
|
||||
}
|
||||
exportdata, err := gcimporter.BExportData(conf.Fset, pkg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
imports := make(map[string]*types.Package)
|
||||
fset2 := token.NewFileSet()
|
||||
n, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg.Path())
|
||||
if err != nil {
|
||||
t.Errorf("BImportData(%s): %v", pkg.Path(), err)
|
||||
continue
|
||||
}
|
||||
if n != len(exportdata) {
|
||||
t.Errorf("BImportData(%s) decoded %d bytes, want %d",
|
||||
pkg.Path(), n, len(exportdata))
|
||||
}
|
||||
|
||||
// Compare the packages' corresponding members.
|
||||
for _, name := range pkg.Scope().Names() {
|
||||
if !ast.IsExported(name) {
|
||||
continue
|
||||
}
|
||||
obj1 := pkg.Scope().Lookup(name)
|
||||
obj2 := pkg2.Scope().Lookup(name)
|
||||
if obj2 == nil {
|
||||
t.Errorf("%s.%s not found, want %s", pkg.Path(), name, obj1)
|
||||
continue
|
||||
}
|
||||
|
||||
fl1 := fileLine(conf.Fset, obj1)
|
||||
fl2 := fileLine(fset2, obj2)
|
||||
if fl1 != fl2 {
|
||||
t.Errorf("%s.%s: got posn %s, want %s",
|
||||
pkg.Path(), name, fl2, fl1)
|
||||
}
|
||||
|
||||
if err := equalObj(obj1, obj2); err != nil {
|
||||
t.Errorf("%s.%s: %s\ngot: %s\nwant: %s",
|
||||
pkg.Path(), name, err, obj2, obj1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fileLine(fset *token.FileSet, obj types.Object) string {
|
||||
posn := fset.Position(obj.Pos())
|
||||
return fmt.Sprintf("%s:%d", posn.Filename, posn.Line)
|
||||
}
|
||||
|
||||
// equalObj reports how x and y differ. They are assumed to belong to
|
||||
// different universes so cannot be compared directly.
|
||||
func equalObj(x, y types.Object) error {
|
||||
if reflect.TypeOf(x) != reflect.TypeOf(y) {
|
||||
return fmt.Errorf("%T vs %T", x, y)
|
||||
}
|
||||
xt := x.Type()
|
||||
yt := y.Type()
|
||||
switch x.(type) {
|
||||
case *types.Var, *types.Func:
|
||||
// ok
|
||||
case *types.Const:
|
||||
xval := x.(*types.Const).Val()
|
||||
yval := y.(*types.Const).Val()
|
||||
// Use string comparison for floating-point values since rounding is permitted.
|
||||
if constant.Compare(xval, token.NEQ, yval) &&
|
||||
!(xval.Kind() == constant.Float && xval.String() == yval.String()) {
|
||||
return fmt.Errorf("unequal constants %s vs %s", xval, yval)
|
||||
}
|
||||
case *types.TypeName:
|
||||
xt = xt.Underlying()
|
||||
yt = yt.Underlying()
|
||||
default:
|
||||
return fmt.Errorf("unexpected %T", x)
|
||||
}
|
||||
return equalType(xt, yt)
|
||||
}
|
||||
|
||||
func equalType(x, y types.Type) error {
|
||||
if reflect.TypeOf(x) != reflect.TypeOf(y) {
|
||||
return fmt.Errorf("unequal kinds: %T vs %T", x, y)
|
||||
}
|
||||
switch x := x.(type) {
|
||||
case *types.Interface:
|
||||
y := y.(*types.Interface)
|
||||
// TODO(gri): enable separate emission of Embedded interfaces
|
||||
// and ExplicitMethods then use this logic.
|
||||
// if x.NumEmbeddeds() != y.NumEmbeddeds() {
|
||||
// return fmt.Errorf("unequal number of embedded interfaces: %d vs %d",
|
||||
// x.NumEmbeddeds(), y.NumEmbeddeds())
|
||||
// }
|
||||
// for i := 0; i < x.NumEmbeddeds(); i++ {
|
||||
// xi := x.Embedded(i)
|
||||
// yi := y.Embedded(i)
|
||||
// if xi.String() != yi.String() {
|
||||
// return fmt.Errorf("mismatched %th embedded interface: %s vs %s",
|
||||
// i, xi, yi)
|
||||
// }
|
||||
// }
|
||||
// if x.NumExplicitMethods() != y.NumExplicitMethods() {
|
||||
// return fmt.Errorf("unequal methods: %d vs %d",
|
||||
// x.NumExplicitMethods(), y.NumExplicitMethods())
|
||||
// }
|
||||
// for i := 0; i < x.NumExplicitMethods(); i++ {
|
||||
// xm := x.ExplicitMethod(i)
|
||||
// ym := y.ExplicitMethod(i)
|
||||
// if xm.Name() != ym.Name() {
|
||||
// return fmt.Errorf("mismatched %th method: %s vs %s", i, xm, ym)
|
||||
// }
|
||||
// if err := equalType(xm.Type(), ym.Type()); err != nil {
|
||||
// return fmt.Errorf("mismatched %s method: %s", xm.Name(), err)
|
||||
// }
|
||||
// }
|
||||
if x.NumMethods() != y.NumMethods() {
|
||||
return fmt.Errorf("unequal methods: %d vs %d",
|
||||
x.NumMethods(), y.NumMethods())
|
||||
}
|
||||
for i := 0; i < x.NumMethods(); i++ {
|
||||
xm := x.Method(i)
|
||||
ym := y.Method(i)
|
||||
if xm.Name() != ym.Name() {
|
||||
return fmt.Errorf("mismatched %dth method: %s vs %s", i, xm, ym)
|
||||
}
|
||||
if err := equalType(xm.Type(), ym.Type()); err != nil {
|
||||
return fmt.Errorf("mismatched %s method: %s", xm.Name(), err)
|
||||
}
|
||||
}
|
||||
case *types.Array:
|
||||
y := y.(*types.Array)
|
||||
if x.Len() != y.Len() {
|
||||
return fmt.Errorf("unequal array lengths: %d vs %d", x.Len(), y.Len())
|
||||
}
|
||||
if err := equalType(x.Elem(), y.Elem()); err != nil {
|
||||
return fmt.Errorf("array elements: %s", err)
|
||||
}
|
||||
case *types.Basic:
|
||||
y := y.(*types.Basic)
|
||||
if x.Kind() != y.Kind() {
|
||||
return fmt.Errorf("unequal basic types: %s vs %s", x, y)
|
||||
}
|
||||
case *types.Chan:
|
||||
y := y.(*types.Chan)
|
||||
if x.Dir() != y.Dir() {
|
||||
return fmt.Errorf("unequal channel directions: %d vs %d", x.Dir(), y.Dir())
|
||||
}
|
||||
if err := equalType(x.Elem(), y.Elem()); err != nil {
|
||||
return fmt.Errorf("channel elements: %s", err)
|
||||
}
|
||||
case *types.Map:
|
||||
y := y.(*types.Map)
|
||||
if err := equalType(x.Key(), y.Key()); err != nil {
|
||||
return fmt.Errorf("map keys: %s", err)
|
||||
}
|
||||
if err := equalType(x.Elem(), y.Elem()); err != nil {
|
||||
return fmt.Errorf("map values: %s", err)
|
||||
}
|
||||
case *types.Named:
|
||||
y := y.(*types.Named)
|
||||
if x.String() != y.String() {
|
||||
return fmt.Errorf("unequal named types: %s vs %s", x, y)
|
||||
}
|
||||
case *types.Pointer:
|
||||
y := y.(*types.Pointer)
|
||||
if err := equalType(x.Elem(), y.Elem()); err != nil {
|
||||
return fmt.Errorf("pointer elements: %s", err)
|
||||
}
|
||||
case *types.Signature:
|
||||
y := y.(*types.Signature)
|
||||
if err := equalType(x.Params(), y.Params()); err != nil {
|
||||
return fmt.Errorf("parameters: %s", err)
|
||||
}
|
||||
if err := equalType(x.Results(), y.Results()); err != nil {
|
||||
return fmt.Errorf("results: %s", err)
|
||||
}
|
||||
if x.Variadic() != y.Variadic() {
|
||||
return fmt.Errorf("unequal varidicity: %t vs %t",
|
||||
x.Variadic(), y.Variadic())
|
||||
}
|
||||
if (x.Recv() != nil) != (y.Recv() != nil) {
|
||||
return fmt.Errorf("unequal receivers: %s vs %s", x.Recv(), y.Recv())
|
||||
}
|
||||
if x.Recv() != nil {
|
||||
// TODO(adonovan): fix: this assertion fires for interface methods.
|
||||
// The type of the receiver of an interface method is a named type
|
||||
// if the Package was loaded from export data, or an unnamed (interface)
|
||||
// type if the Package was produced by type-checking ASTs.
|
||||
// if err := equalType(x.Recv().Type(), y.Recv().Type()); err != nil {
|
||||
// return fmt.Errorf("receiver: %s", err)
|
||||
// }
|
||||
}
|
||||
case *types.Slice:
|
||||
y := y.(*types.Slice)
|
||||
if err := equalType(x.Elem(), y.Elem()); err != nil {
|
||||
return fmt.Errorf("slice elements: %s", err)
|
||||
}
|
||||
case *types.Struct:
|
||||
y := y.(*types.Struct)
|
||||
if x.NumFields() != y.NumFields() {
|
||||
return fmt.Errorf("unequal struct fields: %d vs %d",
|
||||
x.NumFields(), y.NumFields())
|
||||
}
|
||||
for i := 0; i < x.NumFields(); i++ {
|
||||
xf := x.Field(i)
|
||||
yf := y.Field(i)
|
||||
if xf.Name() != yf.Name() {
|
||||
return fmt.Errorf("mismatched fields: %s vs %s", xf, yf)
|
||||
}
|
||||
if err := equalType(xf.Type(), yf.Type()); err != nil {
|
||||
return fmt.Errorf("struct field %s: %s", xf.Name(), err)
|
||||
}
|
||||
if x.Tag(i) != y.Tag(i) {
|
||||
return fmt.Errorf("struct field %s has unequal tags: %q vs %q",
|
||||
xf.Name(), x.Tag(i), y.Tag(i))
|
||||
}
|
||||
}
|
||||
case *types.Tuple:
|
||||
y := y.(*types.Tuple)
|
||||
if x.Len() != y.Len() {
|
||||
return fmt.Errorf("unequal tuple lengths: %d vs %d", x.Len(), y.Len())
|
||||
}
|
||||
for i := 0; i < x.Len(); i++ {
|
||||
if err := equalType(x.At(i).Type(), y.At(i).Type()); err != nil {
|
||||
return fmt.Errorf("tuple element %d: %s", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestVeryLongFile tests the position of an import object declared in
|
||||
// a very long input file. Line numbers greater than maxlines are
|
||||
// reported as line 1, not garbage or token.NoPos.
|
||||
func TestVeryLongFile(t *testing.T) {
|
||||
// parse and typecheck
|
||||
longFile := "package foo" + strings.Repeat("\n", 123456) + "var X int"
|
||||
fset1 := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset1, "foo.go", longFile, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var conf types.Config
|
||||
pkg, err := conf.Check("foo", fset1, []*ast.File{f}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// export
|
||||
exportdata, err := gcimporter.BExportData(fset1, pkg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// import
|
||||
imports := make(map[string]*types.Package)
|
||||
fset2 := token.NewFileSet()
|
||||
_, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg.Path())
|
||||
if err != nil {
|
||||
t.Fatalf("BImportData(%s): %v", pkg.Path(), err)
|
||||
}
|
||||
|
||||
// compare
|
||||
posn1 := fset1.Position(pkg.Scope().Lookup("X").Pos())
|
||||
posn2 := fset2.Position(pkg2.Scope().Lookup("X").Pos())
|
||||
if want := "foo.go:1:1"; posn2.String() != want {
|
||||
t.Errorf("X position = %s, want %s (orig was %s)",
|
||||
posn2, want, posn1)
|
||||
}
|
||||
}
|
||||
|
||||
const src = `
|
||||
package p
|
||||
|
||||
type (
|
||||
T0 = int32
|
||||
T1 = struct{}
|
||||
T2 = struct{ T1 }
|
||||
Invalid = foo // foo is undeclared
|
||||
)
|
||||
`
|
||||
|
||||
func checkPkg(t *testing.T, pkg *types.Package, label string) {
|
||||
T1 := types.NewStruct(nil, nil)
|
||||
T2 := types.NewStruct([]*types.Var{types.NewField(0, pkg, "T1", T1, true)}, nil)
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
typ types.Type
|
||||
}{
|
||||
{"T0", types.Typ[types.Int32]},
|
||||
{"T1", T1},
|
||||
{"T2", T2},
|
||||
{"Invalid", types.Typ[types.Invalid]},
|
||||
} {
|
||||
obj := pkg.Scope().Lookup(test.name)
|
||||
if obj == nil {
|
||||
t.Errorf("%s: %s not found", label, test.name)
|
||||
continue
|
||||
}
|
||||
tname, _ := obj.(*types.TypeName)
|
||||
if tname == nil {
|
||||
t.Errorf("%s: %v not a type name", label, obj)
|
||||
continue
|
||||
}
|
||||
if !tname.IsAlias() {
|
||||
t.Errorf("%s: %v: not marked as alias", label, tname)
|
||||
continue
|
||||
}
|
||||
if got := tname.Type(); !types.Identical(got, test.typ) {
|
||||
t.Errorf("%s: %v: got %v; want %v", label, tname, got, test.typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeAliases(t *testing.T) {
|
||||
// parse and typecheck
|
||||
fset1 := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset1, "p.go", src, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var conf types.Config
|
||||
pkg1, err := conf.Check("p", fset1, []*ast.File{f}, nil)
|
||||
if err == nil {
|
||||
// foo in undeclared in src; we should see an error
|
||||
t.Fatal("invalid source type-checked without error")
|
||||
}
|
||||
if pkg1 == nil {
|
||||
// despite incorrect src we should see a (partially) type-checked package
|
||||
t.Fatal("nil package returned")
|
||||
}
|
||||
checkPkg(t, pkg1, "export")
|
||||
|
||||
// export
|
||||
exportdata, err := gcimporter.BExportData(fset1, pkg1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// import
|
||||
imports := make(map[string]*types.Package)
|
||||
fset2 := token.NewFileSet()
|
||||
_, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg1.Path())
|
||||
if err != nil {
|
||||
t.Fatalf("BImportData(%s): %v", pkg1.Path(), err)
|
||||
}
|
||||
checkPkg(t, pkg2, "import")
|
||||
}
|
1028
vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
generated
vendored
1028
vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
generated
vendored
File diff suppressed because it is too large
Load Diff
93
vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
generated
vendored
93
vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
generated
vendored
@@ -1,93 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
|
||||
|
||||
// This file implements FindExportData.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
|
||||
// See $GOROOT/include/ar.h.
|
||||
hdr := make([]byte, 16+12+6+6+8+10+2)
|
||||
_, err = io.ReadFull(r, hdr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// leave for debugging
|
||||
if false {
|
||||
fmt.Printf("header: %s", hdr)
|
||||
}
|
||||
s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
|
||||
size, err = strconv.Atoi(s)
|
||||
if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
|
||||
err = fmt.Errorf("invalid archive header")
|
||||
return
|
||||
}
|
||||
name = strings.TrimSpace(string(hdr[:16]))
|
||||
return
|
||||
}
|
||||
|
||||
// FindExportData positions the reader r at the beginning of the
|
||||
// export data section of an underlying GC-created object/archive
|
||||
// file by reading from it. The reader must be positioned at the
|
||||
// start of the file before calling this function. The hdr result
|
||||
// is the string before the export data, either "$$" or "$$B".
|
||||
//
|
||||
func FindExportData(r *bufio.Reader) (hdr string, err error) {
|
||||
// Read first line to make sure this is an object file.
|
||||
line, err := r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can't find export data (%v)", err)
|
||||
return
|
||||
}
|
||||
|
||||
if string(line) == "!<arch>\n" {
|
||||
// Archive file. Scan to __.PKGDEF.
|
||||
var name string
|
||||
if name, _, err = readGopackHeader(r); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// First entry should be __.PKGDEF.
|
||||
if name != "__.PKGDEF" {
|
||||
err = fmt.Errorf("go archive is missing __.PKGDEF")
|
||||
return
|
||||
}
|
||||
|
||||
// Read first line of __.PKGDEF data, so that line
|
||||
// is once again the first line of the input.
|
||||
if line, err = r.ReadSlice('\n'); err != nil {
|
||||
err = fmt.Errorf("can't find export data (%v)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Now at __.PKGDEF in archive or still at beginning of file.
|
||||
// Either way, line should begin with "go object ".
|
||||
if !strings.HasPrefix(string(line), "go object ") {
|
||||
err = fmt.Errorf("not a Go object file")
|
||||
return
|
||||
}
|
||||
|
||||
// Skip over object header to export data.
|
||||
// Begins after first line starting with $$.
|
||||
for line[0] != '$' {
|
||||
if line, err = r.ReadSlice('\n'); err != nil {
|
||||
err = fmt.Errorf("can't find export data (%v)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
hdr = string(line)
|
||||
|
||||
return
|
||||
}
|
1078
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
generated
vendored
1078
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
generated
vendored
File diff suppressed because it is too large
Load Diff
129
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter11_test.go
generated
vendored
129
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter11_test.go
generated
vendored
@@ -1,129 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.11
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var importedObjectTests = []struct {
|
||||
name string
|
||||
want string
|
||||
}{
|
||||
// non-interfaces
|
||||
{"crypto.Hash", "type Hash uint"},
|
||||
{"go/ast.ObjKind", "type ObjKind int"},
|
||||
{"go/types.Qualifier", "type Qualifier func(*Package) string"},
|
||||
{"go/types.Comparable", "func Comparable(T Type) bool"},
|
||||
{"math.Pi", "const Pi untyped float"},
|
||||
{"math.Sin", "func Sin(x float64) float64"},
|
||||
{"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"},
|
||||
{"go/internal/gcimporter.BImportData", "func BImportData(fset *go/token.FileSet, imports map[string]*go/types.Package, data []byte, path string) (_ int, pkg *go/types.Package, err error)"},
|
||||
|
||||
// interfaces
|
||||
{"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"},
|
||||
{"crypto.Decrypter", "type Decrypter interface{Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error); Public() PublicKey}"},
|
||||
{"encoding.BinaryMarshaler", "type BinaryMarshaler interface{MarshalBinary() (data []byte, err error)}"},
|
||||
{"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"},
|
||||
{"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"},
|
||||
{"go/ast.Node", "type Node interface{End() go/token.Pos; Pos() go/token.Pos}"},
|
||||
{"go/types.Type", "type Type interface{String() string; Underlying() Type}"},
|
||||
}
|
||||
|
||||
func TestImportedTypes(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
for _, test := range importedObjectTests {
|
||||
s := strings.Split(test.name, ".")
|
||||
if len(s) != 2 {
|
||||
t.Fatal("inconsistent test data")
|
||||
}
|
||||
importPath := s[0]
|
||||
objName := s[1]
|
||||
|
||||
pkg, err := Import(make(map[string]*types.Package), importPath, ".", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
obj := pkg.Scope().Lookup(objName)
|
||||
if obj == nil {
|
||||
t.Errorf("%s: object not found", test.name)
|
||||
continue
|
||||
}
|
||||
|
||||
got := types.ObjectString(obj, types.RelativeTo(pkg))
|
||||
if got != test.want {
|
||||
t.Errorf("%s: got %q; want %q", test.name, got, test.want)
|
||||
}
|
||||
|
||||
if named, _ := obj.Type().(*types.Named); named != nil {
|
||||
verifyInterfaceMethodRecvs(t, named, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// verifyInterfaceMethodRecvs verifies that method receiver types
|
||||
// are named if the methods belong to a named interface type.
|
||||
func verifyInterfaceMethodRecvs(t *testing.T, named *types.Named, level int) {
|
||||
// avoid endless recursion in case of an embedding bug that lead to a cycle
|
||||
if level > 10 {
|
||||
t.Errorf("%s: embeds itself", named)
|
||||
return
|
||||
}
|
||||
|
||||
iface, _ := named.Underlying().(*types.Interface)
|
||||
if iface == nil {
|
||||
return // not an interface
|
||||
}
|
||||
|
||||
// check explicitly declared methods
|
||||
for i := 0; i < iface.NumExplicitMethods(); i++ {
|
||||
m := iface.ExplicitMethod(i)
|
||||
recv := m.Type().(*types.Signature).Recv()
|
||||
if recv == nil {
|
||||
t.Errorf("%s: missing receiver type", m)
|
||||
continue
|
||||
}
|
||||
if recv.Type() != named {
|
||||
t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named)
|
||||
}
|
||||
}
|
||||
|
||||
// check embedded interfaces (if they are named, too)
|
||||
for i := 0; i < iface.NumEmbeddeds(); i++ {
|
||||
// embedding of interfaces cannot have cycles; recursion will terminate
|
||||
if etype, _ := iface.EmbeddedType(i).(*types.Named); etype != nil {
|
||||
verifyInterfaceMethodRecvs(t, etype, level+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestIssue25301(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
// On windows, we have to set the -D option for the compiler to avoid having a drive
|
||||
// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("avoid dealing with relative paths/drive letters on windows")
|
||||
}
|
||||
|
||||
compileAndImportPkg(t, "issue25301")
|
||||
}
|
517
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter_test.go
generated
vendored
517
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter_test.go
generated
vendored
@@ -1,517 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is a copy of $GOROOT/src/go/internal/gcimporter/gcimporter_test.go,
|
||||
// adjusted to make it build with code from (std lib) internal/testenv copied.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// The following three functions (Builder, HasGoBuild, MustHaveGoBuild) were
|
||||
// copied from $GOROOT/src/internal/testenv since that package is not available
|
||||
// in x/tools.
|
||||
|
||||
// Builder reports the name of the builder running this test
|
||||
// (for example, "linux-amd64" or "windows-386-gce").
|
||||
// If the test is not running on the build infrastructure,
|
||||
// Builder returns the empty string.
|
||||
func Builder() string {
|
||||
return os.Getenv("GO_BUILDER_NAME")
|
||||
}
|
||||
|
||||
// HasGoBuild reports whether the current system can build programs with ``go build''
|
||||
// and then run them with os.StartProcess or exec.Command.
|
||||
func HasGoBuild() bool {
|
||||
switch runtime.GOOS {
|
||||
case "android", "nacl":
|
||||
return false
|
||||
case "darwin":
|
||||
if strings.HasPrefix(runtime.GOARCH, "arm") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MustHaveGoBuild checks that the current system can build programs with ``go build''
|
||||
// and then run them with os.StartProcess or exec.Command.
|
||||
// If not, MustHaveGoBuild calls t.Skip with an explanation.
|
||||
func MustHaveGoBuild(t *testing.T) {
|
||||
if !HasGoBuild() {
|
||||
t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// skipSpecialPlatforms causes the test to be skipped for platforms where
|
||||
// builders (build.golang.org) don't have access to compiled packages for
|
||||
// import.
|
||||
func skipSpecialPlatforms(t *testing.T) {
|
||||
switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform {
|
||||
case "nacl-amd64p32",
|
||||
"nacl-386",
|
||||
"nacl-arm",
|
||||
"darwin-arm",
|
||||
"darwin-arm64":
|
||||
t.Skipf("no compiled packages available for import on %s", platform)
|
||||
}
|
||||
}
|
||||
|
||||
// compile runs the compiler on filename, with dirname as the working directory,
|
||||
// and writes the output file to outdirname.
|
||||
func compile(t *testing.T, dirname, filename, outdirname string) string {
|
||||
/* testenv. */ MustHaveGoBuild(t)
|
||||
// filename must end with ".go"
|
||||
if !strings.HasSuffix(filename, ".go") {
|
||||
t.Fatalf("filename doesn't end in .go: %s", filename)
|
||||
}
|
||||
basename := filepath.Base(filename)
|
||||
outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o")
|
||||
cmd := exec.Command("go", "tool", "compile", "-o", outname, filename)
|
||||
cmd.Dir = dirname
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatalf("go tool compile %s failed: %s", filename, err)
|
||||
}
|
||||
return outname
|
||||
}
|
||||
|
||||
func testPath(t *testing.T, path, srcDir string) *types.Package {
|
||||
t0 := time.Now()
|
||||
pkg, err := Import(make(map[string]*types.Package), path, srcDir, nil)
|
||||
if err != nil {
|
||||
t.Errorf("testPath(%s): %s", path, err)
|
||||
return nil
|
||||
}
|
||||
t.Logf("testPath(%s): %v", path, time.Since(t0))
|
||||
return pkg
|
||||
}
|
||||
|
||||
const maxTime = 30 * time.Second
|
||||
|
||||
func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) {
|
||||
dirname := filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir)
|
||||
list, err := ioutil.ReadDir(dirname)
|
||||
if err != nil {
|
||||
t.Fatalf("testDir(%s): %s", dirname, err)
|
||||
}
|
||||
for _, f := range list {
|
||||
if time.Now().After(endTime) {
|
||||
t.Log("testing time used up")
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case !f.IsDir():
|
||||
// try extensions
|
||||
for _, ext := range pkgExts {
|
||||
if strings.HasSuffix(f.Name(), ext) {
|
||||
name := f.Name()[0 : len(f.Name())-len(ext)] // remove extension
|
||||
if testPath(t, filepath.Join(dir, name), dir) != nil {
|
||||
nimports++
|
||||
}
|
||||
}
|
||||
}
|
||||
case f.IsDir():
|
||||
nimports += testDir(t, filepath.Join(dir, f.Name()), endTime)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func mktmpdir(t *testing.T) string {
|
||||
tmpdir, err := ioutil.TempDir("", "gcimporter_test")
|
||||
if err != nil {
|
||||
t.Fatal("mktmpdir:", err)
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(tmpdir, "testdata"), 0700); err != nil {
|
||||
os.RemoveAll(tmpdir)
|
||||
t.Fatal("mktmpdir:", err)
|
||||
}
|
||||
return tmpdir
|
||||
}
|
||||
|
||||
const testfile = "exports.go"
|
||||
|
||||
func TestImportTestdata(t *testing.T) {
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
tmpdir := mktmpdir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
compile(t, "testdata", testfile, filepath.Join(tmpdir, "testdata"))
|
||||
|
||||
// filename should end with ".go"
|
||||
filename := testfile[:len(testfile)-3]
|
||||
if pkg := testPath(t, "./testdata/"+filename, tmpdir); pkg != nil {
|
||||
// The package's Imports list must include all packages
|
||||
// explicitly imported by testfile, plus all packages
|
||||
// referenced indirectly via exported objects in testfile.
|
||||
// With the textual export format (when run against Go1.6),
|
||||
// the list may also include additional packages that are
|
||||
// not strictly required for import processing alone (they
|
||||
// are exported to err "on the safe side").
|
||||
// For now, we just test the presence of a few packages
|
||||
// that we know are there for sure.
|
||||
got := fmt.Sprint(pkg.Imports())
|
||||
for _, want := range []string{"go/ast", "go/token"} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf(`Package("exports").Imports() = %s, does not contain %s`, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionHandling(t *testing.T) {
|
||||
skipSpecialPlatforms(t) // we really only need to exclude nacl platforms, but this is fine
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
const dir = "./testdata/versions"
|
||||
list, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpdir := mktmpdir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
corruptdir := filepath.Join(tmpdir, "testdata", "versions")
|
||||
if err := os.Mkdir(corruptdir, 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, f := range list {
|
||||
name := f.Name()
|
||||
if !strings.HasSuffix(name, ".a") {
|
||||
continue // not a package file
|
||||
}
|
||||
if strings.Contains(name, "corrupted") {
|
||||
continue // don't process a leftover corrupted file
|
||||
}
|
||||
pkgpath := "./" + name[:len(name)-2]
|
||||
|
||||
if testing.Verbose() {
|
||||
t.Logf("importing %s", name)
|
||||
}
|
||||
|
||||
// test that export data can be imported
|
||||
_, err := Import(make(map[string]*types.Package), pkgpath, dir, nil)
|
||||
if err != nil {
|
||||
// ok to fail if it fails with a newer version error for select files
|
||||
if strings.Contains(err.Error(), "newer version") {
|
||||
switch name {
|
||||
case "test_go1.11_999b.a", "test_go1.11_999i.a":
|
||||
continue
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
t.Errorf("import %q failed: %v", pkgpath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// create file with corrupted export data
|
||||
// 1) read file
|
||||
data, err := ioutil.ReadFile(filepath.Join(dir, name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// 2) find export data
|
||||
i := bytes.Index(data, []byte("\n$$B\n")) + 5
|
||||
j := bytes.Index(data[i:], []byte("\n$$\n")) + i
|
||||
if i < 0 || j < 0 || i > j {
|
||||
t.Fatalf("export data section not found (i = %d, j = %d)", i, j)
|
||||
}
|
||||
// 3) corrupt the data (increment every 7th byte)
|
||||
for k := j - 13; k >= i; k -= 7 {
|
||||
data[k]++
|
||||
}
|
||||
// 4) write the file
|
||||
pkgpath += "_corrupted"
|
||||
filename := filepath.Join(corruptdir, pkgpath) + ".a"
|
||||
ioutil.WriteFile(filename, data, 0666)
|
||||
|
||||
// test that importing the corrupted file results in an error
|
||||
_, err = Import(make(map[string]*types.Package), pkgpath, corruptdir, nil)
|
||||
if err == nil {
|
||||
t.Errorf("import corrupted %q succeeded", pkgpath)
|
||||
} else if msg := err.Error(); !strings.Contains(msg, "version skew") {
|
||||
t.Errorf("import %q error incorrect (%s)", pkgpath, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportStdLib(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
dt := maxTime
|
||||
if testing.Short() && /* testenv. */ Builder() == "" {
|
||||
dt = 10 * time.Millisecond
|
||||
}
|
||||
nimports := testDir(t, "", time.Now().Add(dt)) // installed packages
|
||||
t.Logf("tested %d imports", nimports)
|
||||
}
|
||||
|
||||
func TestIssue5815(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
pkg := importPkg(t, "strings", ".")
|
||||
|
||||
scope := pkg.Scope()
|
||||
for _, name := range scope.Names() {
|
||||
obj := scope.Lookup(name)
|
||||
if obj.Pkg() == nil {
|
||||
t.Errorf("no pkg for %s", obj)
|
||||
}
|
||||
if tname, _ := obj.(*types.TypeName); tname != nil {
|
||||
named := tname.Type().(*types.Named)
|
||||
for i := 0; i < named.NumMethods(); i++ {
|
||||
m := named.Method(i)
|
||||
if m.Pkg() == nil {
|
||||
t.Errorf("no pkg for %s", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Smoke test to ensure that imported methods get the correct package.
|
||||
func TestCorrectMethodPackage(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
imports := make(map[string]*types.Package)
|
||||
_, err := Import(imports, "net/http", ".", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mutex := imports["sync"].Scope().Lookup("Mutex").(*types.TypeName).Type()
|
||||
mset := types.NewMethodSet(types.NewPointer(mutex)) // methods of *sync.Mutex
|
||||
sel := mset.Lookup(nil, "Lock")
|
||||
lock := sel.Obj().(*types.Func)
|
||||
if got, want := lock.Pkg().Path(), "sync"; got != want {
|
||||
t.Errorf("got package path %q; want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue13566(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
// On windows, we have to set the -D option for the compiler to avoid having a drive
|
||||
// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("avoid dealing with relative paths/drive letters on windows")
|
||||
}
|
||||
|
||||
tmpdir := mktmpdir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
testoutdir := filepath.Join(tmpdir, "testdata")
|
||||
|
||||
// b.go needs to be compiled from the output directory so that the compiler can
|
||||
// find the compiled package a. We pass the full path to compile() so that we
|
||||
// don't have to copy the file to that directory.
|
||||
bpath, err := filepath.Abs(filepath.Join("testdata", "b.go"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
compile(t, "testdata", "a.go", testoutdir)
|
||||
compile(t, testoutdir, bpath, testoutdir)
|
||||
|
||||
// import must succeed (test for issue at hand)
|
||||
pkg := importPkg(t, "./testdata/b", tmpdir)
|
||||
|
||||
// make sure all indirectly imported packages have names
|
||||
for _, imp := range pkg.Imports() {
|
||||
if imp.Name() == "" {
|
||||
t.Errorf("no name for %s package", imp.Path())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue13898(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
// import go/internal/gcimporter which imports go/types partially
|
||||
imports := make(map[string]*types.Package)
|
||||
_, err := Import(imports, "go/internal/gcimporter", ".", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// look for go/types package
|
||||
var goTypesPkg *types.Package
|
||||
for path, pkg := range imports {
|
||||
if path == "go/types" {
|
||||
goTypesPkg = pkg
|
||||
break
|
||||
}
|
||||
}
|
||||
if goTypesPkg == nil {
|
||||
t.Fatal("go/types not found")
|
||||
}
|
||||
|
||||
// look for go/types.Object type
|
||||
obj := lookupObj(t, goTypesPkg.Scope(), "Object")
|
||||
typ, ok := obj.Type().(*types.Named)
|
||||
if !ok {
|
||||
t.Fatalf("go/types.Object type is %v; wanted named type", typ)
|
||||
}
|
||||
|
||||
// lookup go/types.Object.Pkg method
|
||||
m, index, indirect := types.LookupFieldOrMethod(typ, false, nil, "Pkg")
|
||||
if m == nil {
|
||||
t.Fatalf("go/types.Object.Pkg not found (index = %v, indirect = %v)", index, indirect)
|
||||
}
|
||||
|
||||
// the method must belong to go/types
|
||||
if m.Pkg().Path() != "go/types" {
|
||||
t.Fatalf("found %v; want go/types", m.Pkg())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue15517(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
// On windows, we have to set the -D option for the compiler to avoid having a drive
|
||||
// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("avoid dealing with relative paths/drive letters on windows")
|
||||
}
|
||||
|
||||
tmpdir := mktmpdir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
compile(t, "testdata", "p.go", filepath.Join(tmpdir, "testdata"))
|
||||
|
||||
// Multiple imports of p must succeed without redeclaration errors.
|
||||
// We use an import path that's not cleaned up so that the eventual
|
||||
// file path for the package is different from the package path; this
|
||||
// will expose the error if it is present.
|
||||
//
|
||||
// (Issue: Both the textual and the binary importer used the file path
|
||||
// of the package to be imported as key into the shared packages map.
|
||||
// However, the binary importer then used the package path to identify
|
||||
// the imported package to mark it as complete; effectively marking the
|
||||
// wrong package as complete. By using an "unclean" package path, the
|
||||
// file and package path are different, exposing the problem if present.
|
||||
// The same issue occurs with vendoring.)
|
||||
imports := make(map[string]*types.Package)
|
||||
for i := 0; i < 3; i++ {
|
||||
if _, err := Import(imports, "./././testdata/p", tmpdir, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue15920(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
// On windows, we have to set the -D option for the compiler to avoid having a drive
|
||||
// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("avoid dealing with relative paths/drive letters on windows")
|
||||
}
|
||||
|
||||
compileAndImportPkg(t, "issue15920")
|
||||
}
|
||||
|
||||
func TestIssue20046(t *testing.T) {
|
||||
skipSpecialPlatforms(t)
|
||||
|
||||
// This package only handles gc export data.
|
||||
if runtime.Compiler != "gc" {
|
||||
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
|
||||
}
|
||||
|
||||
// On windows, we have to set the -D option for the compiler to avoid having a drive
|
||||
// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("avoid dealing with relative paths/drive letters on windows")
|
||||
}
|
||||
|
||||
// "./issue20046".V.M must exist
|
||||
pkg := compileAndImportPkg(t, "issue20046")
|
||||
obj := lookupObj(t, pkg.Scope(), "V")
|
||||
if m, index, indirect := types.LookupFieldOrMethod(obj.Type(), false, nil, "M"); m == nil {
|
||||
t.Fatalf("V.M not found (index = %v, indirect = %v)", index, indirect)
|
||||
}
|
||||
}
|
||||
|
||||
func importPkg(t *testing.T, path, srcDir string) *types.Package {
|
||||
pkg, err := Import(make(map[string]*types.Package), path, srcDir, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return pkg
|
||||
}
|
||||
|
||||
func compileAndImportPkg(t *testing.T, name string) *types.Package {
|
||||
tmpdir := mktmpdir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
compile(t, "testdata", name+".go", filepath.Join(tmpdir, "testdata"))
|
||||
return importPkg(t, "./testdata/"+name, tmpdir)
|
||||
}
|
||||
|
||||
func lookupObj(t *testing.T, scope *types.Scope, name string) types.Object {
|
||||
if obj := scope.Lookup(name); obj != nil {
|
||||
return obj
|
||||
}
|
||||
t.Fatalf("%s not found", name)
|
||||
return nil
|
||||
}
|
598
vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
generated
vendored
598
vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
generated
vendored
@@ -1,598 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Indexed package import.
|
||||
// See cmd/compile/internal/gc/iexport.go for the export data format.
|
||||
|
||||
// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"io"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type intReader struct {
|
||||
*bytes.Reader
|
||||
path string
|
||||
}
|
||||
|
||||
func (r *intReader) int64() int64 {
|
||||
i, err := binary.ReadVarint(r.Reader)
|
||||
if err != nil {
|
||||
errorf("import %q: read varint error: %v", r.path, err)
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (r *intReader) uint64() uint64 {
|
||||
i, err := binary.ReadUvarint(r.Reader)
|
||||
if err != nil {
|
||||
errorf("import %q: read varint error: %v", r.path, err)
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
const predeclReserved = 32
|
||||
|
||||
type itag uint64
|
||||
|
||||
const (
|
||||
// Types
|
||||
definedType itag = iota
|
||||
pointerType
|
||||
sliceType
|
||||
arrayType
|
||||
chanType
|
||||
mapType
|
||||
signatureType
|
||||
structType
|
||||
interfaceType
|
||||
)
|
||||
|
||||
// IImportData imports a package from the serialized package data
|
||||
// and returns the number of bytes consumed and a reference to the package.
|
||||
// If the export data version is not recognized or the format is otherwise
|
||||
// compromised, an error is returned.
|
||||
func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
|
||||
const currentVersion = 0
|
||||
version := -1
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
if version > currentVersion {
|
||||
err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
|
||||
} else {
|
||||
err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
r := &intReader{bytes.NewReader(data), path}
|
||||
|
||||
version = int(r.uint64())
|
||||
switch version {
|
||||
case currentVersion:
|
||||
default:
|
||||
errorf("unknown iexport format version %d", version)
|
||||
}
|
||||
|
||||
sLen := int64(r.uint64())
|
||||
dLen := int64(r.uint64())
|
||||
|
||||
whence, _ := r.Seek(0, io.SeekCurrent)
|
||||
stringData := data[whence : whence+sLen]
|
||||
declData := data[whence+sLen : whence+sLen+dLen]
|
||||
r.Seek(sLen+dLen, io.SeekCurrent)
|
||||
|
||||
p := iimporter{
|
||||
ipath: path,
|
||||
|
||||
stringData: stringData,
|
||||
stringCache: make(map[uint64]string),
|
||||
pkgCache: make(map[uint64]*types.Package),
|
||||
|
||||
declData: declData,
|
||||
pkgIndex: make(map[*types.Package]map[string]uint64),
|
||||
typCache: make(map[uint64]types.Type),
|
||||
|
||||
fake: fakeFileSet{
|
||||
fset: fset,
|
||||
files: make(map[string]*token.File),
|
||||
},
|
||||
}
|
||||
|
||||
for i, pt := range predeclared {
|
||||
p.typCache[uint64(i)] = pt
|
||||
}
|
||||
|
||||
pkgList := make([]*types.Package, r.uint64())
|
||||
for i := range pkgList {
|
||||
pkgPathOff := r.uint64()
|
||||
pkgPath := p.stringAt(pkgPathOff)
|
||||
pkgName := p.stringAt(r.uint64())
|
||||
_ = r.uint64() // package height; unused by go/types
|
||||
|
||||
if pkgPath == "" {
|
||||
pkgPath = path
|
||||
}
|
||||
pkg := imports[pkgPath]
|
||||
if pkg == nil {
|
||||
pkg = types.NewPackage(pkgPath, pkgName)
|
||||
imports[pkgPath] = pkg
|
||||
} else if pkg.Name() != pkgName {
|
||||
errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
|
||||
}
|
||||
|
||||
p.pkgCache[pkgPathOff] = pkg
|
||||
|
||||
nameIndex := make(map[string]uint64)
|
||||
for nSyms := r.uint64(); nSyms > 0; nSyms-- {
|
||||
name := p.stringAt(r.uint64())
|
||||
nameIndex[name] = r.uint64()
|
||||
}
|
||||
|
||||
p.pkgIndex[pkg] = nameIndex
|
||||
pkgList[i] = pkg
|
||||
}
|
||||
|
||||
localpkg := pkgList[0]
|
||||
|
||||
names := make([]string, 0, len(p.pkgIndex[localpkg]))
|
||||
for name := range p.pkgIndex[localpkg] {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
for _, name := range names {
|
||||
p.doDecl(localpkg, name)
|
||||
}
|
||||
|
||||
for _, typ := range p.interfaceList {
|
||||
typ.Complete()
|
||||
}
|
||||
|
||||
// record all referenced packages as imports
|
||||
list := append(([]*types.Package)(nil), pkgList[1:]...)
|
||||
sort.Sort(byPath(list))
|
||||
localpkg.SetImports(list)
|
||||
|
||||
// package was imported completely and without errors
|
||||
localpkg.MarkComplete()
|
||||
|
||||
consumed, _ := r.Seek(0, io.SeekCurrent)
|
||||
return int(consumed), localpkg, nil
|
||||
}
|
||||
|
||||
type iimporter struct {
|
||||
ipath string
|
||||
|
||||
stringData []byte
|
||||
stringCache map[uint64]string
|
||||
pkgCache map[uint64]*types.Package
|
||||
|
||||
declData []byte
|
||||
pkgIndex map[*types.Package]map[string]uint64
|
||||
typCache map[uint64]types.Type
|
||||
|
||||
fake fakeFileSet
|
||||
interfaceList []*types.Interface
|
||||
}
|
||||
|
||||
func (p *iimporter) doDecl(pkg *types.Package, name string) {
|
||||
// See if we've already imported this declaration.
|
||||
if obj := pkg.Scope().Lookup(name); obj != nil {
|
||||
return
|
||||
}
|
||||
|
||||
off, ok := p.pkgIndex[pkg][name]
|
||||
if !ok {
|
||||
errorf("%v.%v not in index", pkg, name)
|
||||
}
|
||||
|
||||
r := &importReader{p: p, currPkg: pkg}
|
||||
r.declReader.Reset(p.declData[off:])
|
||||
|
||||
r.obj(name)
|
||||
}
|
||||
|
||||
func (p *iimporter) stringAt(off uint64) string {
|
||||
if s, ok := p.stringCache[off]; ok {
|
||||
return s
|
||||
}
|
||||
|
||||
slen, n := binary.Uvarint(p.stringData[off:])
|
||||
if n <= 0 {
|
||||
errorf("varint failed")
|
||||
}
|
||||
spos := off + uint64(n)
|
||||
s := string(p.stringData[spos : spos+slen])
|
||||
p.stringCache[off] = s
|
||||
return s
|
||||
}
|
||||
|
||||
func (p *iimporter) pkgAt(off uint64) *types.Package {
|
||||
if pkg, ok := p.pkgCache[off]; ok {
|
||||
return pkg
|
||||
}
|
||||
path := p.stringAt(off)
|
||||
errorf("missing package %q in %q", path, p.ipath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
|
||||
if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
|
||||
return t
|
||||
}
|
||||
|
||||
if off < predeclReserved {
|
||||
errorf("predeclared type missing from cache: %v", off)
|
||||
}
|
||||
|
||||
r := &importReader{p: p}
|
||||
r.declReader.Reset(p.declData[off-predeclReserved:])
|
||||
t := r.doType(base)
|
||||
|
||||
if base == nil || !isInterface(t) {
|
||||
p.typCache[off] = t
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
type importReader struct {
|
||||
p *iimporter
|
||||
declReader bytes.Reader
|
||||
currPkg *types.Package
|
||||
prevFile string
|
||||
prevLine int64
|
||||
}
|
||||
|
||||
func (r *importReader) obj(name string) {
|
||||
tag := r.byte()
|
||||
pos := r.pos()
|
||||
|
||||
switch tag {
|
||||
case 'A':
|
||||
typ := r.typ()
|
||||
|
||||
r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
|
||||
|
||||
case 'C':
|
||||
typ, val := r.value()
|
||||
|
||||
r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
|
||||
|
||||
case 'F':
|
||||
sig := r.signature(nil)
|
||||
|
||||
r.declare(types.NewFunc(pos, r.currPkg, name, sig))
|
||||
|
||||
case 'T':
|
||||
// Types can be recursive. We need to setup a stub
|
||||
// declaration before recursing.
|
||||
obj := types.NewTypeName(pos, r.currPkg, name, nil)
|
||||
named := types.NewNamed(obj, nil, nil)
|
||||
r.declare(obj)
|
||||
|
||||
underlying := r.p.typAt(r.uint64(), named).Underlying()
|
||||
named.SetUnderlying(underlying)
|
||||
|
||||
if !isInterface(underlying) {
|
||||
for n := r.uint64(); n > 0; n-- {
|
||||
mpos := r.pos()
|
||||
mname := r.ident()
|
||||
recv := r.param()
|
||||
msig := r.signature(recv)
|
||||
|
||||
named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
|
||||
}
|
||||
}
|
||||
|
||||
case 'V':
|
||||
typ := r.typ()
|
||||
|
||||
r.declare(types.NewVar(pos, r.currPkg, name, typ))
|
||||
|
||||
default:
|
||||
errorf("unexpected tag: %v", tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *importReader) declare(obj types.Object) {
|
||||
obj.Pkg().Scope().Insert(obj)
|
||||
}
|
||||
|
||||
func (r *importReader) value() (typ types.Type, val constant.Value) {
|
||||
typ = r.typ()
|
||||
|
||||
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
|
||||
case types.IsBoolean:
|
||||
val = constant.MakeBool(r.bool())
|
||||
|
||||
case types.IsString:
|
||||
val = constant.MakeString(r.string())
|
||||
|
||||
case types.IsInteger:
|
||||
val = r.mpint(b)
|
||||
|
||||
case types.IsFloat:
|
||||
val = r.mpfloat(b)
|
||||
|
||||
case types.IsComplex:
|
||||
re := r.mpfloat(b)
|
||||
im := r.mpfloat(b)
|
||||
val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
|
||||
|
||||
default:
|
||||
errorf("unexpected type %v", typ) // panics
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func intSize(b *types.Basic) (signed bool, maxBytes uint) {
|
||||
if (b.Info() & types.IsUntyped) != 0 {
|
||||
return true, 64
|
||||
}
|
||||
|
||||
switch b.Kind() {
|
||||
case types.Float32, types.Complex64:
|
||||
return true, 3
|
||||
case types.Float64, types.Complex128:
|
||||
return true, 7
|
||||
}
|
||||
|
||||
signed = (b.Info() & types.IsUnsigned) == 0
|
||||
switch b.Kind() {
|
||||
case types.Int8, types.Uint8:
|
||||
maxBytes = 1
|
||||
case types.Int16, types.Uint16:
|
||||
maxBytes = 2
|
||||
case types.Int32, types.Uint32:
|
||||
maxBytes = 4
|
||||
default:
|
||||
maxBytes = 8
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *importReader) mpint(b *types.Basic) constant.Value {
|
||||
signed, maxBytes := intSize(b)
|
||||
|
||||
maxSmall := 256 - maxBytes
|
||||
if signed {
|
||||
maxSmall = 256 - 2*maxBytes
|
||||
}
|
||||
if maxBytes == 1 {
|
||||
maxSmall = 256
|
||||
}
|
||||
|
||||
n, _ := r.declReader.ReadByte()
|
||||
if uint(n) < maxSmall {
|
||||
v := int64(n)
|
||||
if signed {
|
||||
v >>= 1
|
||||
if n&1 != 0 {
|
||||
v = ^v
|
||||
}
|
||||
}
|
||||
return constant.MakeInt64(v)
|
||||
}
|
||||
|
||||
v := -n
|
||||
if signed {
|
||||
v = -(n &^ 1) >> 1
|
||||
}
|
||||
if v < 1 || uint(v) > maxBytes {
|
||||
errorf("weird decoding: %v, %v => %v", n, signed, v)
|
||||
}
|
||||
|
||||
buf := make([]byte, v)
|
||||
io.ReadFull(&r.declReader, buf)
|
||||
|
||||
// convert to little endian
|
||||
// TODO(gri) go/constant should have a more direct conversion function
|
||||
// (e.g., once it supports a big.Float based implementation)
|
||||
for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
|
||||
buf[i], buf[j] = buf[j], buf[i]
|
||||
}
|
||||
|
||||
x := constant.MakeFromBytes(buf)
|
||||
if signed && n&1 != 0 {
|
||||
x = constant.UnaryOp(token.SUB, x, 0)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func (r *importReader) mpfloat(b *types.Basic) constant.Value {
|
||||
x := r.mpint(b)
|
||||
if constant.Sign(x) == 0 {
|
||||
return x
|
||||
}
|
||||
|
||||
exp := r.int64()
|
||||
switch {
|
||||
case exp > 0:
|
||||
x = constant.Shift(x, token.SHL, uint(exp))
|
||||
case exp < 0:
|
||||
d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
|
||||
x = constant.BinaryOp(x, token.QUO, d)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func (r *importReader) ident() string {
|
||||
return r.string()
|
||||
}
|
||||
|
||||
func (r *importReader) qualifiedIdent() (*types.Package, string) {
|
||||
name := r.string()
|
||||
pkg := r.pkg()
|
||||
return pkg, name
|
||||
}
|
||||
|
||||
func (r *importReader) pos() token.Pos {
|
||||
delta := r.int64()
|
||||
if delta != deltaNewFile {
|
||||
r.prevLine += delta
|
||||
} else if l := r.int64(); l == -1 {
|
||||
r.prevLine += deltaNewFile
|
||||
} else {
|
||||
r.prevFile = r.string()
|
||||
r.prevLine = l
|
||||
}
|
||||
|
||||
if r.prevFile == "" && r.prevLine == 0 {
|
||||
return token.NoPos
|
||||
}
|
||||
|
||||
return r.p.fake.pos(r.prevFile, int(r.prevLine))
|
||||
}
|
||||
|
||||
func (r *importReader) typ() types.Type {
|
||||
return r.p.typAt(r.uint64(), nil)
|
||||
}
|
||||
|
||||
func isInterface(t types.Type) bool {
|
||||
_, ok := t.(*types.Interface)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
|
||||
func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
|
||||
|
||||
func (r *importReader) doType(base *types.Named) types.Type {
|
||||
switch k := r.kind(); k {
|
||||
default:
|
||||
errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
|
||||
return nil
|
||||
|
||||
case definedType:
|
||||
pkg, name := r.qualifiedIdent()
|
||||
r.p.doDecl(pkg, name)
|
||||
return pkg.Scope().Lookup(name).(*types.TypeName).Type()
|
||||
case pointerType:
|
||||
return types.NewPointer(r.typ())
|
||||
case sliceType:
|
||||
return types.NewSlice(r.typ())
|
||||
case arrayType:
|
||||
n := r.uint64()
|
||||
return types.NewArray(r.typ(), int64(n))
|
||||
case chanType:
|
||||
dir := chanDir(int(r.uint64()))
|
||||
return types.NewChan(dir, r.typ())
|
||||
case mapType:
|
||||
return types.NewMap(r.typ(), r.typ())
|
||||
case signatureType:
|
||||
r.currPkg = r.pkg()
|
||||
return r.signature(nil)
|
||||
|
||||
case structType:
|
||||
r.currPkg = r.pkg()
|
||||
|
||||
fields := make([]*types.Var, r.uint64())
|
||||
tags := make([]string, len(fields))
|
||||
for i := range fields {
|
||||
fpos := r.pos()
|
||||
fname := r.ident()
|
||||
ftyp := r.typ()
|
||||
emb := r.bool()
|
||||
tag := r.string()
|
||||
|
||||
fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
|
||||
tags[i] = tag
|
||||
}
|
||||
return types.NewStruct(fields, tags)
|
||||
|
||||
case interfaceType:
|
||||
r.currPkg = r.pkg()
|
||||
|
||||
embeddeds := make([]types.Type, r.uint64())
|
||||
for i := range embeddeds {
|
||||
_ = r.pos()
|
||||
embeddeds[i] = r.typ()
|
||||
}
|
||||
|
||||
methods := make([]*types.Func, r.uint64())
|
||||
for i := range methods {
|
||||
mpos := r.pos()
|
||||
mname := r.ident()
|
||||
|
||||
// TODO(mdempsky): Matches bimport.go, but I
|
||||
// don't agree with this.
|
||||
var recv *types.Var
|
||||
if base != nil {
|
||||
recv = types.NewVar(token.NoPos, r.currPkg, "", base)
|
||||
}
|
||||
|
||||
msig := r.signature(recv)
|
||||
methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
|
||||
}
|
||||
|
||||
typ := newInterface(methods, embeddeds)
|
||||
r.p.interfaceList = append(r.p.interfaceList, typ)
|
||||
return typ
|
||||
}
|
||||
}
|
||||
|
||||
func (r *importReader) kind() itag {
|
||||
return itag(r.uint64())
|
||||
}
|
||||
|
||||
func (r *importReader) signature(recv *types.Var) *types.Signature {
|
||||
params := r.paramList()
|
||||
results := r.paramList()
|
||||
variadic := params.Len() > 0 && r.bool()
|
||||
return types.NewSignature(recv, params, results, variadic)
|
||||
}
|
||||
|
||||
func (r *importReader) paramList() *types.Tuple {
|
||||
xs := make([]*types.Var, r.uint64())
|
||||
for i := range xs {
|
||||
xs[i] = r.param()
|
||||
}
|
||||
return types.NewTuple(xs...)
|
||||
}
|
||||
|
||||
func (r *importReader) param() *types.Var {
|
||||
pos := r.pos()
|
||||
name := r.ident()
|
||||
typ := r.typ()
|
||||
return types.NewParam(pos, r.currPkg, name, typ)
|
||||
}
|
||||
|
||||
func (r *importReader) bool() bool {
|
||||
return r.uint64() != 0
|
||||
}
|
||||
|
||||
func (r *importReader) int64() int64 {
|
||||
n, err := binary.ReadVarint(&r.declReader)
|
||||
if err != nil {
|
||||
errorf("readVarint: %v", err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *importReader) uint64() uint64 {
|
||||
n, err := binary.ReadUvarint(&r.declReader)
|
||||
if err != nil {
|
||||
errorf("readUvarint: %v", err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (r *importReader) byte() byte {
|
||||
x, err := r.declReader.ReadByte()
|
||||
if err != nil {
|
||||
errorf("declReader.ReadByte: %v", err)
|
||||
}
|
||||
return x
|
||||
}
|
21
vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go
generated
vendored
21
vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go
generated
vendored
@@ -1,21 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.11
|
||||
|
||||
package gcimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
|
||||
named := make([]*types.Named, len(embeddeds))
|
||||
for i, e := range embeddeds {
|
||||
var ok bool
|
||||
named[i], ok = e.(*types.Named)
|
||||
if !ok {
|
||||
panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
|
||||
}
|
||||
}
|
||||
return types.NewInterface(methods, named)
|
||||
}
|
13
vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go
generated
vendored
13
vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.11
|
||||
|
||||
package gcimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
|
||||
return types.NewInterfaceType(methods, embeddeds)
|
||||
}
|
14
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/a.go
generated
vendored
14
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/a.go
generated
vendored
@@ -1,14 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Input for TestIssue13566
|
||||
|
||||
package a
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type A struct {
|
||||
a *A
|
||||
json json.RawMessage
|
||||
}
|
11
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/b.go
generated
vendored
11
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/b.go
generated
vendored
@@ -1,11 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Input for TestIssue13566
|
||||
|
||||
package b
|
||||
|
||||
import "./a"
|
||||
|
||||
type A a.A
|
89
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/exports.go
generated
vendored
89
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/exports.go
generated
vendored
@@ -1,89 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is used to generate an object file which
|
||||
// serves as test file for gcimporter_test.go.
|
||||
|
||||
package exports
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
)
|
||||
|
||||
// Issue 3682: Correctly read dotted identifiers from export data.
|
||||
const init1 = 0
|
||||
|
||||
func init() {}
|
||||
|
||||
const (
|
||||
C0 int = 0
|
||||
C1 = 3.14159265
|
||||
C2 = 2.718281828i
|
||||
C3 = -123.456e-789
|
||||
C4 = +123.456E+789
|
||||
C5 = 1234i
|
||||
C6 = "foo\n"
|
||||
C7 = `bar\n`
|
||||
)
|
||||
|
||||
type (
|
||||
T1 int
|
||||
T2 [10]int
|
||||
T3 []int
|
||||
T4 *int
|
||||
T5 chan int
|
||||
T6a chan<- int
|
||||
T6b chan (<-chan int)
|
||||
T6c chan<- (chan int)
|
||||
T7 <-chan *ast.File
|
||||
T8 struct{}
|
||||
T9 struct {
|
||||
a int
|
||||
b, c float32
|
||||
d []string `go:"tag"`
|
||||
}
|
||||
T10 struct {
|
||||
T8
|
||||
T9
|
||||
_ *T10
|
||||
}
|
||||
T11 map[int]string
|
||||
T12 interface{}
|
||||
T13 interface {
|
||||
m1()
|
||||
m2(int) float32
|
||||
}
|
||||
T14 interface {
|
||||
T12
|
||||
T13
|
||||
m3(x ...struct{}) []T9
|
||||
}
|
||||
T15 func()
|
||||
T16 func(int)
|
||||
T17 func(x int)
|
||||
T18 func() float32
|
||||
T19 func() (x float32)
|
||||
T20 func(...interface{})
|
||||
T21 struct{ next *T21 }
|
||||
T22 struct{ link *T23 }
|
||||
T23 struct{ link *T22 }
|
||||
T24 *T24
|
||||
T25 *T26
|
||||
T26 *T27
|
||||
T27 *T25
|
||||
T28 func(T28) T28
|
||||
)
|
||||
|
||||
var (
|
||||
V0 int
|
||||
V1 = -991.0
|
||||
)
|
||||
|
||||
func F1() {}
|
||||
func F2(x int) {}
|
||||
func F3() int { return 0 }
|
||||
func F4() float32 { return 0 }
|
||||
func F5(a, b, c int, u, v, w struct{ x, y T1 }, more ...interface{}) (p, q, r chan<- T10)
|
||||
|
||||
func (p *T1) M1()
|
11
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/issue15920.go
generated
vendored
11
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/issue15920.go
generated
vendored
@@ -1,11 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
// The underlying type of Error is the underlying type of error.
|
||||
// Make sure we can import this again without problems.
|
||||
type Error error
|
||||
|
||||
func F() Error { return nil }
|
9
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/issue20046.go
generated
vendored
9
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/issue20046.go
generated
vendored
@@ -1,9 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
var V interface {
|
||||
M()
|
||||
}
|
17
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/issue25301.go
generated
vendored
17
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/issue25301.go
generated
vendored
@@ -1,17 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package issue25301
|
||||
|
||||
type (
|
||||
A = interface {
|
||||
M()
|
||||
}
|
||||
T interface {
|
||||
A
|
||||
}
|
||||
S struct{}
|
||||
)
|
||||
|
||||
func (S) M() { println("m") }
|
13
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/p.go
generated
vendored
13
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/p.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Input for TestIssue15517
|
||||
|
||||
package p
|
||||
|
||||
const C = 0
|
||||
|
||||
var V int
|
||||
|
||||
func F() {}
|
30
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test.go
generated
vendored
30
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is a copy of $GOROOT/src/go/internal/gcimporter/testdata/versions.test.go.
|
||||
|
||||
// To create a test case for a new export format version,
|
||||
// build this package with the latest compiler and store
|
||||
// the resulting .a file appropriately named in the versions
|
||||
// directory. The VersionHandling test will pick it up.
|
||||
//
|
||||
// In the testdata/versions:
|
||||
//
|
||||
// go build -o test_go1.$X_$Y.a test.go
|
||||
//
|
||||
// with $X = Go version and $Y = export format version
|
||||
// (add 'b' or 'i' to distinguish between binary and
|
||||
// indexed format starting with 1.11 as long as both
|
||||
// formats are supported).
|
||||
//
|
||||
// Make sure this source is extended such that it exercises
|
||||
// whatever export format change has taken place.
|
||||
|
||||
package test
|
||||
|
||||
// Any release before and including Go 1.7 didn't encode
|
||||
// the package for a blank struct field.
|
||||
type BlankField struct {
|
||||
_ int
|
||||
}
|
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_0i.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_0i.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_6b.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_6b.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_999b.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_999b.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_999i.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.11_999i.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.7_0.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.7_0.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.7_1.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.7_1.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.8_4.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.8_4.a
generated
vendored
Binary file not shown.
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.8_5.a
generated
vendored
BIN
vendor/golang.org/x/tools/go/internal/gcimporter/testdata/versions/test_go1.8_5.a
generated
vendored
Binary file not shown.
Reference in New Issue
Block a user