2016-03-01 22:57:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright 2011 The Go Authors. All rights reserved.  
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Use of this source code is governed by a BSD-style  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// license that can be found in the LICENSE file.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Binary api computes the exported API of a set of Go packages.  
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  main  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bufio" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"flag" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"go/ast" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"go/build" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"go/parser" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"go/token" 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"go/types" 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-15 12:14:06 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									exec  "internal/execabs" 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"log" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 13:12:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"regexp" 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-08 13:44:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"sort" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-19 18:18:09 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  goCmd ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  exeSuffix  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  runtime . GOOS  ==  "windows"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										exeSuffix  =  ".exe" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  :=  filepath . Join ( runtime . GOROOT ( ) ,  "bin" ,  "go" + exeSuffix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  :=  os . Stat ( path ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "go" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Flags  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
									
										
										
										
											2013-05-06 17:25:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									checkFile   =  flag . String ( "c" ,  "" ,  "optional comma-separated filename(s) to check API against" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-04 11:35:17 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									allowNew    =  flag . Bool ( "allow_new" ,  true ,  "allow API additions" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									exceptFile  =  flag . String ( "except" ,  "" ,  "optional filename of packages that are allowed to change without triggering a failure in the tool" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nextFile    =  flag . String ( "next" ,  "" ,  "optional filename of tentative upcoming API features for the next release. This file can be lazily maintained. It only affects the delta warnings from the -c file printed on success." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									verbose     =  flag . Bool ( "v" ,  false ,  "verbose debugging" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									forceCtx    =  flag . String ( "contexts" ,  "" ,  "optional comma-separated list of <goos>-<goarch>[-cgo] to override default contexts." ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 13:45:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// contexts are the default contexts which are scanned, unless  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// overridden by the -contexts flag.  
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  contexts  =  [ ] * build . Context {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "linux" ,  GOARCH :  "386" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "linux" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "linux" ,  GOARCH :  "amd64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "linux" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-21 21:47:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "linux" ,  GOARCH :  "arm" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-04 15:21:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "linux" ,  GOARCH :  "arm" } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "darwin" ,  GOARCH :  "amd64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "darwin" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "windows" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "windows" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-21 21:47:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "freebsd" ,  GOARCH :  "386" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-01 18:42:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "freebsd" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-21 21:47:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "freebsd" ,  GOARCH :  "amd64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "freebsd" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "freebsd" ,  GOARCH :  "arm" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "freebsd" ,  GOARCH :  "arm" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "386" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "amd64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "arm" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "arm" } , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-20 14:39:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "arm64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "netbsd" ,  GOARCH :  "arm64" } , 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-21 21:47:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ GOOS :  "openbsd" ,  GOARCH :  "386" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "openbsd" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "openbsd" ,  GOARCH :  "amd64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ GOOS :  "openbsd" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  contextName ( c  * build . Context )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  c . GOOS  +  "-"  +  c . GOARCH 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  c . CgoEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-14 10:19:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s  +=  "-cgo" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  c . Dir  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  +=  fmt . Sprintf ( " [%s]" ,  c . Dir ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 13:45:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseContext ( c  string )  * build . Context  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parts  :=  strings . Split ( c ,  "-" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( parts )  <  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Fatalf ( "bad context: %q" ,  c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bc  :=  & build . Context { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GOOS :    parts [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GOARCH :  parts [ 1 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( parts )  ==  3  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  parts [ 2 ]  ==  "cgo"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bc . CgoEnabled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Fatalf ( "bad context: %q" ,  c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  bc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  setContexts ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									contexts  =  [ ] * build . Context { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  c  :=  range  strings . Split ( * forceCtx ,  "," )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contexts  =  append ( contexts ,  parseContext ( c ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-15 11:08:37 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  internalPkg  =  regexp . MustCompile ( ` (^|/)internal($|/) ` )  
						 
					
						
							
								
									
										
										
										
											2014-07-21 12:06:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  main ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									flag . Parse ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-15 11:08:37 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! strings . Contains ( runtime . Version ( ) ,  "weekly" )  &&  ! strings . Contains ( runtime . Version ( ) ,  "devel" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-08 13:44:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  * nextFile  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Printf ( "Go version is %q, ignoring -next %s\n" ,  runtime . Version ( ) ,  * nextFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* nextFile  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 13:45:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  * forceCtx  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setContexts ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  c  :=  range  contexts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . Compiler  =  build . Default . Compiler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									walkers  :=  make ( [ ] * Walker ,  len ( contexts ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  context  :=  range  contexts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i ,  context  :=  i ,  context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											walkers [ i ]  =  NewWalker ( context ,  filepath . Join ( build . Default . GOROOT ,  "src" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									wg . Wait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  featureCtx  =  make ( map [ string ] map [ string ] bool )  // feature -> context name -> true 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  w  :=  range  walkers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pkgNames  :=  w . stdPackages 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  flag . NArg ( )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pkgNames  =  flag . Args ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  name  :=  range  pkgNames  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pkg ,  err  :=  w . Import ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  nogo  :=  err . ( * build . NoGoError ) ;  nogo  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-22 22:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Fatalf ( "Import(%q): %v" ,  name ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . export ( pkg ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ctxName  :=  contextName ( w . context ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  f  :=  range  w . Features ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  featureCtx [ f ]  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												featureCtx [ f ]  =  make ( map [ string ] bool ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											featureCtx [ f ] [ ctxName ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  features  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  f ,  cmap  :=  range  featureCtx  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( cmap )  ==  len ( contexts )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											features  =  append ( features ,  f ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-05 15:49:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										comma  :=  strings . Index ( f ,  "," ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  cname  :=  range  cmap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f2  :=  fmt . Sprintf ( "%s (%s)%s" ,  f [ : comma ] ,  cname ,  f [ comma : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											features  =  append ( features ,  f2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fail  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  fail  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Exit ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bw  :=  bufio . NewWriter ( os . Stdout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  bw . Flush ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  * checkFile  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-19 22:20:46 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sort . Strings ( features ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  f  :=  range  features  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fmt . Fprintln ( bw ,  f ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-05-06 17:25:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  required  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  file  :=  range  strings . Split ( * checkFile ,  "," )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										required  =  append ( required ,  fileFeatures ( file ) ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									optional  :=  fileFeatures ( * nextFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									exception  :=  fileFeatures ( * exceptFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 16:44:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fail  =  ! compareAPI ( bw ,  features ,  required ,  optional ,  exception ,  * allowNew ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// export emits the exported package features.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  export ( pkg  * types . Package )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  * verbose  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Println ( pkg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pop  :=  w . pushScope ( "pkg "  +  pkg . Path ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . current  =  pkg 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scope  :=  pkg . Scope ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  name  :=  range  scope . Names ( )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												all: clean up code with token.IsExported
A handful of packages were reimplementing IsExported, so use
token.IsExported instead. This caused the deps test to fail for net/rpc.
However, net/rpc deals with Go types, and go/token is light and fairly
low-level in terms of Go tooling packages, so that's okay.
While at it, replace all uses of ast.IsExported with token.IsExported.
This is more consistent, and also means that the import graphs are
leaner. A couple of files no longer need to import go/ast, for example.
We can't get rid of cmd/compile/internal/types.IsExported, as the
compiler can only depend on go/token as of Go 1.4. However, gc used
different implementations in a couple of places, so consolidate the use
of types.IsExported there.
Finally, we can't get rid of the copied IsExported implementation in
encoding/gob, as go/token depends on it as part of a test. That test
can't be an external test either, so there's no easy way to break the
import cycle.
Overall, this removes about forty lines of unnecessary code.
Change-Id: I86a475b7614261e6a7b0b153d5ca02b9f64a7b2d
Reviewed-on: https://go-review.googlesource.com/c/go/+/172037
Run-TryBot: Daniel Martà <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2019-04-15 23:10:50 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  token . IsExported ( name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . emitObj ( scope . Lookup ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 13:12:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  set ( items  [ ] string )  map [ string ] bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  make ( map [ string ] bool ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  items  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s [ v ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  spaceParensRx  =  regexp . MustCompile ( `  \(\S+?\) ` )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  featureWithoutContext ( f  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! strings . Contains ( f ,  "(" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  spaceParensRx . ReplaceAllString ( f ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 22:44:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// portRemoved reports whether the given port-specific API feature is  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// okay to no longer exist because its port was removed.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  portRemoved ( feature  string )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  strings . Contains ( feature ,  "(darwin-386)" )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strings . Contains ( feature ,  "(darwin-386-cgo)" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-08 04:27:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  compareAPI ( w  io . Writer ,  features ,  required ,  optional ,  exception  [ ] string ,  allowAdd  bool )  ( ok  bool )  {  
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ok  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 13:12:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									optionalSet  :=  set ( optional ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									exceptionSet  :=  set ( exception ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									featureSet  :=  set ( features ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( features ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( required ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-04 11:35:17 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									take  :=  func ( sl  * [ ] string )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  ( * sl ) [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* sl  =  ( * sl ) [ 1 : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  len ( required )  >  0  ||  len ( features )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 13:12:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  len ( features )  ==  0  ||  ( len ( required )  >  0  &&  required [ 0 ]  <  features [ 0 ] ) : 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-04 11:35:17 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											feature  :=  take ( & required ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  exceptionSet [ feature ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-14 09:43:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// An "unfortunate" case: the feature was once 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// included in the API (e.g. go1.txt), but was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// subsequently removed. These are already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// acknowledged by being in the file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// "api/except.txt". No need to print them out 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// here. 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 22:44:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  portRemoved ( feature )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// okay. 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 13:12:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  featureSet [ featureWithoutContext ( feature ) ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// okay. 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-04 11:35:17 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Fprintf ( w ,  "-%s\n" ,  feature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ok  =  false  // broke compatibility 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-04 11:35:17 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 13:12:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  len ( required )  ==  0  ||  ( len ( features )  >  0  &&  required [ 0 ]  >  features [ 0 ] ) : 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											newFeature  :=  take ( & features ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  optionalSet [ newFeature ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Known added feature to the upcoming release. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Delete it from the map so we can detect any upcoming features 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// which were never seen.  (so we can clean up the nextFile) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												delete ( optionalSet ,  newFeature ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Fprintf ( w ,  "+%s\n" ,  newFeature ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-08 04:27:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! allowAdd  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ok  =  false  // we're in lock-down mode for next release 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											take ( & required ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											take ( & features ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-27 15:39:56 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// In next file, but not in API. 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  missing  [ ] string 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  feature  :=  range  optionalSet  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										missing  =  append ( missing ,  feature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( missing ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  feature  :=  range  missing  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fmt . Fprintf ( w ,  "±%s\n" ,  feature ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 09:49:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// aliasReplacer applies type aliases to earlier API files,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to avoid misleading negative results.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This makes all the references to os.FileInfo in go1.txt  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// be read as if they said fs.FileInfo, since os.FileInfo is now an alias.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If there are many of these, we could do a more general solution,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but for now the replacer is fine.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  aliasReplacer  =  strings . NewReplacer (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os.FileInfo" ,  "fs.FileInfo" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os.FileMode" ,  "fs.FileMode" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os.PathError" ,  "fs.PathError" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  fileFeatures ( filename  string )  [ ] string  {  
						 
					
						
							
								
									
										
										
										
											2012-10-30 11:23:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  filename  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 14:17:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bs ,  err  :=  os . ReadFile ( filename ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Fatalf ( "Error reading file %s: %v" ,  filename ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 09:49:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s  :=  string ( bs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  =  aliasReplacer . Replace ( s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lines  :=  strings . Split ( s ,  "\n" ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 14:04:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  nonblank  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  line  :=  range  lines  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										line  =  strings . TrimSpace ( line ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  line  !=  ""  &&  ! strings . HasPrefix ( line ,  "#" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nonblank  =  append ( nonblank ,  line ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-08 13:44:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 14:04:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nonblank 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-13 09:59:46 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  fset  =  token . NewFileSet ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  Walker  struct  {  
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									context      * build . Context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									root         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scope        [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current      * types . Package 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									features     map [ string ] bool               // set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									imported     map [ string ] * types . Package     // packages already imported 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stdPackages  [ ] string                      // names, omitting "unsafe", internal, and vendored packages 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									importMap    map [ string ] map [ string ] string  // importer dir -> import path -> canonical path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									importDir    map [ string ] string             // canonical import path -> dir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NewWalker ( context  * build . Context ,  root  string )  * Walker  {  
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  :=  & Walker { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										context :   context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										root :      root , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										features :  map [ string ] bool { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										imported :  map [ string ] * types . Package { "unsafe" :  types . Unsafe } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . loadImports ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  w 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  Features ( )  ( fs  [ ] string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  f  :=  range  w . features  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fs  =  append ( fs ,  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( fs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  parsedFileCache  =  make ( map [ string ] * ast . File )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  parseFile ( dir ,  file  string )  ( * ast . File ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									filename  :=  filepath . Join ( dir ,  file ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 16:24:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  f  :=  parsedFileCache [ filename ] ;  f  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  f ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 16:24:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									f ,  err  :=  parser . ParseFile ( fset ,  filename ,  nil ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-19 13:50:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parsedFileCache [ filename ]  =  f 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 16:24:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  f ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-19 13:50:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-04 16:46:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Disable before debugging non-obvious errors from the type-checker.  
						 
					
						
							
								
									
										
										
										
											2014-09-15 16:40:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  usePkgCache  =  true  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pkgCache  =  map [ string ] * types . Package { }  // map tagKey to package 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pkgTags   =  map [ string ] [ ] string { }        // map import dir to list of relevant tags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// tagKey returns the tag-based key to use in the pkgCache.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It is a comma-separated string; the first part is dir, the rest tags.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The satisfied tags are derived from context but only those that  
						 
					
						
							
								
									
										
										
										
											2018-10-04 16:46:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// matter (the ones listed in the tags argument plus GOOS and GOARCH) are used.  
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The tags list, which came from go/build's Package.AllTags,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is known to be sorted.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  tagKey ( dir  string ,  context  * build . Context ,  tags  [ ] string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctags  :=  map [ string ] bool { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										context . GOOS :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										context . GOARCH :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  context . CgoEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctags [ "cgo" ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  tag  :=  range  context . BuildTags  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctags [ tag ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO: ReleaseTags (need to load default) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									key  :=  dir 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-04 16:46:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// explicit on GOOS and GOARCH as global cache will use "all" cached packages for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// an indirect imported package. See https://github.com/golang/go/issues/21181 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// for more detail. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tags  =  append ( tags ,  context . GOOS ,  context . GOARCH ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( tags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  tag  :=  range  tags  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ctags [ tag ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											key  +=  ","  +  tag 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-04 16:46:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ctags [ tag ]  =  false 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  listImports  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stdPackages  [ ] string                      // names, omitting "unsafe", internal, and vendored packages 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									importDir    map [ string ] string             // canonical import path → directory 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									importMap    map [ string ] map [ string ] string  // import path → canonical import path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  listCache  sync . Map  // map[string]listImports, keyed by contextName  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 11:32:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// listSem is a semaphore restricting concurrent invocations of 'go list'.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  listSem  =  make ( chan  semToken ,  runtime . GOMAXPROCS ( 0 ) )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  semToken  struct { }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// loadImports populates w with information about the packages in the standard  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// library and the packages they themselves import in w's build context.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The source import path and expanded import path are identical except for vendored packages.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// For example, on return:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	w.importMap["math"] = "math"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	w.importDir["math"] = "<goroot>/src/math"  
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	w.importMap["golang.org/x/net/route"] = "vendor/golang.org/x/net/route"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	w.importDir["vendor/golang.org/x/net/route"] = "<goroot>/src/vendor/golang.org/x/net/route"  
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Since the set of packages that exist depends on context, the result of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// loadImports also depends on context. However, to improve test running time  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the configuration for each environment is cached across runs.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  loadImports ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . context  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  // test-only Walker; does not use the import map 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									name  :=  contextName ( w . context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									imports ,  ok  :=  listCache . Load ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 11:32:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										listSem  <-  semToken { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  func ( )  {  <- listSem  } ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cmd  :=  exec . Command ( goCmd ( ) ,  "list" ,  "-e" ,  "-deps" ,  "-json" ,  "std" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cmd . Env  =  listEnv ( w . context ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-14 10:19:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  w . context . Dir  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cmd . Dir  =  w . context . Dir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										out ,  err  :=  cmd . CombinedOutput ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Fatalf ( "loading imports: %v\n%s" ,  err ,  out ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  stdPackages  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										importMap  :=  make ( map [ string ] map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										importDir  :=  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dec  :=  json . NewDecoder ( bytes . NewReader ( out ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  pkg  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ImportPath ,  Dir  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ImportMap        map [ string ] string 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-14 10:19:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Standard         bool 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  dec . Decode ( & pkg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  io . EOF  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Fatalf ( "go list: invalid output: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// - Package "unsafe" contains special signatures requiring 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//   extra care when printing them - ignore since it is not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//   going to change w/o a language change. 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-14 10:19:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// - Internal and vendored packages do not contribute to our 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//   API surface. (If we are running within the "std" module, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//   vendored dependencies appear as themselves instead of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//   their "vendor/" standard-library copies.) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// - 'go list std' does not include commands, which cannot be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//   imported anyway. 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-14 10:19:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ip  :=  pkg . ImportPath ;  pkg . Standard  &&  ip  !=  "unsafe"  &&  ! strings . HasPrefix ( ip ,  "vendor/" )  &&  ! internalPkg . MatchString ( ip )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												stdPackages  =  append ( stdPackages ,  ip ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											importDir [ pkg . ImportPath ]  =  pkg . Dir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( pkg . ImportMap )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												importMap [ pkg . Dir ]  =  make ( map [ string ] string ,  len ( pkg . ImportMap ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  k ,  v  :=  range  pkg . ImportMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												importMap [ pkg . Dir ] [ k ]  =  v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sort . Strings ( stdPackages ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										imports  =  listImports { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											stdPackages :  stdPackages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											importMap :    importMap , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											importDir :    importDir , 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										imports ,  _  =  listCache . LoadOrStore ( name ,  imports ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									li  :=  imports . ( listImports ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . stdPackages  =  li . stdPackages 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . importDir  =  li . importDir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . importMap  =  li . importMap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// listEnv returns the process environment to use when invoking 'go list' for  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the given context.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  listEnv ( c  * build . Context )  [ ] string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  c  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  os . Environ ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									environ  :=  append ( os . Environ ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"GOOS=" + c . GOOS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"GOARCH=" + c . GOARCH ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  c . CgoEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										environ  =  append ( environ ,  "CGO_ENABLED=1" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										environ  =  append ( environ ,  "CGO_ENABLED=0" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-16 07:29:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  environ 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Importing is a sentinel taking the place in Walker.imported  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// for a package that is in the process of being imported.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  importing  types . Package  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-10 17:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  Import ( name  string )  ( * types . Package ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  w . ImportFrom ( name ,  "" ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  ImportFrom ( fromPath ,  fromDir  string ,  mode  types . ImportMode )  ( * types . Package ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									name  :=  fromPath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  canonical ,  ok  :=  w . importMap [ fromDir ] [ fromPath ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										name  =  canonical 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-10 17:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pkg  :=  w . imported [ name ] 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  pkg  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  pkg  ==  & importing  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Fatalf ( "cycle importing package %q" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-10 17:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  pkg ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . imported [ name ]  =  & importing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Determine package files. 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 16:52:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dir  :=  w . importDir [ name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  dir  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dir  =  filepath . Join ( w . root ,  filepath . FromSlash ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  fi ,  err  :=  os . Stat ( dir ) ;  err  !=  nil  ||  ! fi . IsDir ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 15:15:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Panicf ( "no source in tree for import %q (from import %s in %s): %v" ,  name ,  fromPath ,  fromDir ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									context  :=  w . context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  context  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										context  =  & build . Default 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Look in cache. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If we've already done an import with the same set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// of relevant tags, reuse the result. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  key  string 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-15 16:40:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  usePkgCache  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  tags ,  ok  :=  pkgTags [ dir ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											key  =  tagKey ( dir ,  context ,  tags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  pkg  :=  pkgCache [ key ] ;  pkg  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . imported [ name ]  =  pkg 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-10 17:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  pkg ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-15 16:40:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									info ,  err  :=  context . ImportDir ( dir ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  nogo  :=  err . ( * build . NoGoError ) ;  nogo  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-23 00:22:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										log . Fatalf ( "pkg %q, dir %q: ScanDir: %v" ,  name ,  dir ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save tags list first time we see a directory. 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-15 16:40:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  usePkgCache  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  ok  :=  pkgTags [ dir ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pkgTags [ dir ]  =  info . AllTags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											key  =  tagKey ( dir ,  context ,  info . AllTags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									filenames  :=  append ( append ( [ ] string { } ,  info . GoFiles ... ) ,  info . CgoFiles ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parse package files. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  files  [ ] * ast . File 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  file  :=  range  filenames  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f ,  err  :=  w . parseFile ( dir ,  file ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Fatalf ( "error parsing package %s: %s" ,  name ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										files  =  append ( files ,  f ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Type-check package files. 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 13:26:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  sizes  types . Sizes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . context  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sizes  =  types . SizesFor ( w . context . Compiler ,  w . context . GOARCH ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									conf  :=  types . Config { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IgnoreFuncBodies :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FakeImportC :       true , 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-10 17:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Importer :          w , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 13:26:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Sizes :             sizes , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pkg ,  err  =  conf . Check ( name ,  fset ,  files ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctxt  :=  "<no context>" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . context  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ctxt  =  fmt . Sprintf ( "%s-%s" ,  w . context . GOOS ,  w . context . GOARCH ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Fatalf ( "error typechecking package %s: %s (%s)" ,  name ,  err ,  ctxt ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-09-15 16:40:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  usePkgCache  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pkgCache [ key ]  =  pkg 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-09 18:44:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . imported [ name ]  =  pkg 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-10 17:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  pkg ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// pushScope enters a new scope (walking a package, type, node, etc)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and returns a function that will leave the scope (with sanity checking  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// for mismatched pushes & pops)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  pushScope ( name  string )  ( popFunc  func ( ) )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . scope  =  append ( w . scope ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( w . scope )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Fatalf ( "attempt to leave scope %q with empty scope list" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . scope [ len ( w . scope ) - 1 ]  !=  name  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Fatalf ( "attempt to leave scope %q, but scope is currently %#v" ,  name ,  w . scope ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . scope  =  w . scope [ : len ( w . scope ) - 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  sortedMethodNames ( typ  * types . Interface )  [ ] string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  :=  typ . NumMethods ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list  :=  make ( [ ] string ,  n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  range  list  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										list [ i ]  =  typ . Method ( i ) . Name ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * Walker )  writeType ( buf  * bytes . Buffer ,  typ  types . Type )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  typ  :=  typ . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Basic : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  typ . Name ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  typ . Kind ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UnsafePointer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "unsafe.Pointer" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedBool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "ideal-bool" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedInt : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "ideal-int" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedRune : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// "ideal-char" for compatibility with old tool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// TODO(gri) change to "ideal-rune" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "ideal-char" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedFloat : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "ideal-float" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedComplex : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "ideal-complex" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedString : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  "ideal-string" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  types . UntypedNil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											panic ( "should never see untyped nil type" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  s  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  "byte" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s  =  "uint8" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  "rune" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s  =  "int32" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Array : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fmt . Fprintf ( buf ,  "[%d]" ,  typ . Len ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ . Elem ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Slice : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( "[]" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ . Elem ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Struct : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( "struct" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Pointer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteByte ( '*' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ . Elem ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Tuple : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "should never see a tuple type" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Signature : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( "func" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeSignature ( buf ,  typ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Interface : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( "interface{" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  typ . NumMethods ( )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteByte ( ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteString ( strings . Join ( sortedMethodNames ( typ ) ,  ", " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteByte ( ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( "}" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Map : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( "map[" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ . Key ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteByte ( ']' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ . Elem ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Chan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  s  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  typ . Dir ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  types . SendOnly : 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											s  =  "chan<- " 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  types . RecvOnly : 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											s  =  "<-chan " 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  types . SendRecv : 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											s  =  "chan " 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											panic ( "unreachable" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										buf . WriteString ( s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ . Elem ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  * types . Named : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj  :=  typ . Obj ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pkg  :=  obj . Pkg ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  pkg  !=  nil  &&  pkg  !=  w . current  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteString ( pkg . Name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteByte ( '.' ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										buf . WriteString ( typ . Obj ( ) . Name ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( fmt . Sprintf ( "unknown type %T" ,  typ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  writeSignature ( buf  * bytes . Buffer ,  sig  * types . Signature )  {  
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . writeParams ( buf ,  sig . Params ( ) ,  sig . Variadic ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  res  :=  sig . Results ( ) ;  res . Len ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// nothing to do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteByte ( ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeType ( buf ,  res . At ( 0 ) . Type ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteByte ( ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeParams ( buf ,  res ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  writeParams ( buf  * bytes . Buffer ,  t  * types . Tuple ,  variadic  bool )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf . WriteByte ( '(' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  n  :=  0 ,  t . Len ( ) ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  i  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteString ( ", " ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										typ  :=  t . At ( i ) . Type ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  variadic  &&  i + 1  ==  n  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteString ( "..." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											typ  =  typ . ( * types . Slice ) . Elem ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . writeType ( buf ,  typ ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									buf . WriteByte ( ')' ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  typeString ( typ  types . Type )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buf  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . writeType ( & buf ,  typ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  buf . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  signatureString ( sig  * types . Signature )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buf  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . writeSignature ( & buf ,  sig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  buf . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitObj ( obj  types . Object )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  obj  :=  obj . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Const : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitf ( "const %s %s" ,  obj . Name ( ) ,  w . typeString ( obj . Type ( ) ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												go/constant: switch to floating-point representation when fractions become too large
Use two internal representations for Float values (similar to what is done
for Int values). Transparently switch to a big.Float representation when
big.Rat values become unwieldy. This is almost never needed for real-world
programs but it is trivial to create test cases that cannot be handled with
rational arithmetic alone.
As a consequence, the go/constant API semantics changes slightly: Until now,
a value could always be represented in its "smallest" form (e.g., float values
that happened to be integers would be represented as integers). Now, constant
Kind depends on how the value was created, rather than its actual value. (The
reason why we cannot automatically "normalize" values to their smallest form
anymore is because floating-point numbers are not exact in general; and thus
normalization is often not possible in the first place, or would throw away
precision when it is not desired.) This has repercussions as to how constant
Values are used go/types and required corresponding adjustments.
Details of the changes:
go/constant package:
- use big.Rat and big.Float values to represent floating-point values
  (internal change)
- changed semantic of Value.Kind accordingly
- String now returns a short, human-readable form of a value
  (this leads to better error messages in go/types)
- added ToInt, ToFloat, and ToComplex conversion functions
- added ExactString to obtain an exact string form of a value
go/types:
- adjusted and simplified implementation of representableConst
- adjusted various places where Value.Kind was expected to be "smallest"
  by calling the respective ToInt/Float/Complex conversion functions
- enabled 5 disabled tests in stdlib_test.go that now work
api checker:
- print all constant values in a short human-readable form (floats are
  printed in floating-point form), but also print an exact form if it
  is different from the short form
- adjusted test golden file and go.1.1.text reference file
Fixes #11327.
Change-Id: I492b704aae5b0238e5b7cee13e18ffce61193587
Reviewed-on: https://go-review.googlesource.com/17360
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-02 17:41:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										x  :=  obj . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										short  :=  x . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										exact  :=  x . ExactString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  short  ==  exact  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . emitf ( "const %s = %s" ,  obj . Name ( ) ,  short ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . emitf ( "const %s = %s  // %s" ,  obj . Name ( ) ,  short ,  exact ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  * types . Var : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitf ( "var %s %s" ,  obj . Name ( ) ,  w . typeString ( obj . Type ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . TypeName : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitType ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Func : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitFunc ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "unknown object: "  +  obj . String ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitType ( obj  * types . TypeName )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									name  :=  obj . Name ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									typ  :=  obj . Type ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 09:49:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  obj . IsAlias ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitf ( "type %s = %s" ,  name ,  w . typeString ( typ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  typ  :=  typ . Underlying ( ) . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Struct : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitStructType ( name ,  typ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * types . Interface : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitIfaceType ( name ,  typ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  // methods are handled by emitIfaceType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitf ( "type %s %s" ,  name ,  w . typeString ( typ . Underlying ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// emit methods with value receiver 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  methodNames  map [ string ] bool 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vset  :=  types . NewMethodSet ( typ ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  n  :=  0 ,  vset . Len ( ) ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m  :=  vset . At ( i ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  m . Obj ( ) . Exported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . emitMethod ( m ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  methodNames  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												methodNames  =  make ( map [ string ] bool ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											methodNames [ m . Obj ( ) . Name ( ) ]  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// emit methods with pointer receiver; exclude 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// methods that we have emitted already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// (the method set of *T includes the methods of T) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pset  :=  types . NewMethodSet ( types . NewPointer ( typ ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  n  :=  0 ,  pset . Len ( ) ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m  :=  pset . At ( i ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  m . Obj ( ) . Exported ( )  &&  ! methodNames [ m . Obj ( ) . Name ( ) ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . emitMethod ( m ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitStructType ( name  string ,  typ  * types . Struct )  {  
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									typeStruct  :=  fmt . Sprintf ( "type %s struct" ,  name ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . emitf ( typeStruct ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  w . pushScope ( typeStruct ) ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  typ . NumFields ( ) ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f  :=  typ . Field ( i ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! f . Exported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										typ  :=  f . Type ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  f . Anonymous ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . emitf ( "embedded %s" ,  w . typeString ( typ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . emitf ( "%s %s" ,  f . Name ( ) ,  w . typeString ( typ ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitIfaceType ( name  string ,  typ  * types . Interface )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pop  :=  w . pushScope ( "type "  +  name  +  " interface" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  methodNames  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									complete  :=  true 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mset  :=  types . NewMethodSet ( typ ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  n  :=  0 ,  mset . Len ( ) ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m  :=  mset . At ( i ) . Obj ( ) . ( * types . Func ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! m . Exported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											complete  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										methodNames  =  append ( methodNames ,  m . Name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitf ( "%s%s" ,  m . Name ( ) ,  w . signatureString ( m . Type ( ) . ( * types . Signature ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-18 15:57:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! complete  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// The method set has unexported methods, so all the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// implementations are provided by the same package, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// so the method set can be extended. Instead of recording 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the full set of names (below), record only that there were 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// unexported methods. (If the interface shrinks, we will notice 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// because a method signature emitted during the last loop 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-18 15:57:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// will disappear.) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . emitf ( "unexported methods" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-18 15:57:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									pop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-18 15:57:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! complete  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( methodNames )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . emitf ( "type %s interface {}" ,  name ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sort . Strings ( methodNames ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . emitf ( "type %s interface { %s }" ,  name ,  strings . Join ( methodNames ,  ", " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitFunc ( f  * types . Func )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sig  :=  f . Type ( ) . ( * types . Signature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sig . Recv ( )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "method considered a regular function: "  +  f . String ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . emitf ( "func %s%s" ,  f . Name ( ) ,  w . signatureString ( sig ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitMethod ( m  * types . Selection )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sig  :=  m . Type ( ) . ( * types . Signature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									recv  :=  sig . Recv ( ) . Type ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-02 13:17:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// report exported methods with unexported receiver base type 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  true  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										base  :=  recv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  p ,  _  :=  recv . ( * types . Pointer ) ;  p  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											base  =  p . Elem ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-07 11:04:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  obj  :=  base . ( * types . Named ) . Obj ( ) ;  ! obj . Exported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Fatalf ( "exported method with unexported receiver base type: %s" ,  m ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . emitf ( "method (%s) %s%s" ,  w . typeString ( recv ) ,  m . Obj ( ) . Name ( ) ,  w . signatureString ( sig ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * Walker )  emitf ( format  string ,  args  ... interface { } )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f  :=  strings . Join ( w . scope ,  ", " )  +  ", "  +  fmt . Sprintf ( format ,  args ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  strings . Contains ( f ,  "\n" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "feature contains newlines: "  +  f ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-28 16:45:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  _ ,  dup  :=  w . features [ f ] ;  dup  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "duplicate feature inserted: "  +  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . features [ f ]  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:10:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  * verbose  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Printf ( "feature: %s" ,  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}