Source file src/go/types/self_test.go

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package types_test
     6  
     7  import (
     8  	"go/ast"
     9  	"go/importer"
    10  	"go/parser"
    11  	"go/token"
    12  	"internal/testenv"
    13  	"path"
    14  	"path/filepath"
    15  	"testing"
    16  	"time"
    17  
    18  	. "go/types"
    19  )
    20  
    21  func TestSelf(t *testing.T) {
    22  	testenv.MustHaveGoBuild(t) // The Go command is needed for the importer to determine the locations of stdlib .a files.
    23  
    24  	fset := token.NewFileSet()
    25  	files, err := pkgFiles(fset, ".")
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	conf := Config{Importer: importer.Default()}
    31  	_, err = conf.Check("go/types", fset, files, nil)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  }
    36  
    37  func BenchmarkCheck(b *testing.B) {
    38  	testenv.MustHaveGoBuild(b) // The Go command is needed for the importer to determine the locations of stdlib .a files.
    39  
    40  	for _, p := range []string{
    41  		"net/http",
    42  		"go/parser",
    43  		"go/constant",
    44  		"runtime",
    45  		filepath.Join("go", "internal", "gcimporter"),
    46  	} {
    47  		b.Run(path.Base(p), func(b *testing.B) {
    48  			path := filepath.Join("..", "..", p)
    49  			for _, ignoreFuncBodies := range []bool{false, true} {
    50  				name := "funcbodies"
    51  				if ignoreFuncBodies {
    52  					name = "nofuncbodies"
    53  				}
    54  				b.Run(name, func(b *testing.B) {
    55  					b.Run("info", func(b *testing.B) {
    56  						runbench(b, path, ignoreFuncBodies, true)
    57  					})
    58  					b.Run("noinfo", func(b *testing.B) {
    59  						runbench(b, path, ignoreFuncBodies, false)
    60  					})
    61  				})
    62  			}
    63  		})
    64  	}
    65  }
    66  
    67  func runbench(b *testing.B, path string, ignoreFuncBodies, writeInfo bool) {
    68  	fset := token.NewFileSet()
    69  	files, err := pkgFiles(fset, path)
    70  	if err != nil {
    71  		b.Fatal(err)
    72  	}
    73  	// determine line count
    74  	lines := 0
    75  	fset.Iterate(func(f *token.File) bool {
    76  		lines += f.LineCount()
    77  		return true
    78  	})
    79  
    80  	b.ResetTimer()
    81  	start := time.Now()
    82  	for i := 0; i < b.N; i++ {
    83  		conf := Config{
    84  			IgnoreFuncBodies: ignoreFuncBodies,
    85  			Importer:         importer.Default(),
    86  		}
    87  		var info *Info
    88  		if writeInfo {
    89  			info = &Info{
    90  				Types:      make(map[ast.Expr]TypeAndValue),
    91  				Defs:       make(map[*ast.Ident]Object),
    92  				Uses:       make(map[*ast.Ident]Object),
    93  				Implicits:  make(map[ast.Node]Object),
    94  				Selections: make(map[*ast.SelectorExpr]*Selection),
    95  				Scopes:     make(map[ast.Node]*Scope),
    96  			}
    97  		}
    98  		if _, err := conf.Check(path, fset, files, info); err != nil {
    99  			b.Fatal(err)
   100  		}
   101  	}
   102  	b.StopTimer()
   103  	b.ReportMetric(float64(lines)*float64(b.N)/time.Since(start).Seconds(), "lines/s")
   104  }
   105  
   106  func pkgFiles(fset *token.FileSet, path string) ([]*ast.File, error) {
   107  	filenames, err := pkgFilenames(path, true) // from stdlib_test.go
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  
   112  	var files []*ast.File
   113  	for _, filename := range filenames {
   114  		file, err := parser.ParseFile(fset, filename, nil, 0)
   115  		if err != nil {
   116  			return nil, err
   117  		}
   118  		files = append(files, file)
   119  	}
   120  
   121  	return files, nil
   122  }
   123  

View as plain text