2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// Copyright 2011 The Go Authors.  All rights reserved. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Use of this source code is governed by a BSD-style 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// license that can be found in the LICENSE file. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-31 10:38:07 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Api computes the exported API of a set of Go packages. 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// BUG(bradfitz): Note that this tool is only currently suitable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// for use on the Go standard library, not arbitrary packages. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Once the Go AST has type information, this tool will be more 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// reliable without hard-coded hacks throughout. 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								package  main 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"bufio" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"bytes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"flag" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"go/ast" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"go/build" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"go/doc" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"go/parser" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"go/printer" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"go/token" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"io/ioutil" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"log" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"os/exec" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"sort" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"strings" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Flags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// TODO(bradfitz): once Go 1.1 comes out, allow the -c flag to take a comma-separated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// list of files, rather than just one. 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									checkFile  =  flag . String ( "c" ,  "" ,  "optional filename to check API against" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									allowNew   =  flag . Bool ( "allow_new" ,  true ,  "allow API additions" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									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" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 13:45:53 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									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" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ GOOS :  "darwin" ,  GOARCH :  "386" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ GOOS :  "darwin" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ GOOS :  "darwin" ,  GOARCH :  "amd64" ,  CgoEnabled :  true } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ GOOS :  "darwin" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ GOOS :  "windows" ,  GOARCH :  "amd64" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ GOOS :  "windows" ,  GOARCH :  "386" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  contextName ( c  * build . Context )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									s  :=  c . GOOS  +  "-"  +  c . GOARCH 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  c . CgoEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  s  +  "-cgo" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									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 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  main ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									flag . Parse ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 13:45:53 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  * forceCtx  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										setContexts ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  c  :=  range  contexts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c . Compiler  =  build . Default . Compiler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									var  pkgs  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  flag . NArg ( )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pkgs  =  flag . Args ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										stds ,  err  :=  exec . Command ( "go" ,  "list" ,  "std" ) . Output ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pkgs  =  strings . Fields ( string ( stds ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									var  featureCtx  =  make ( map [ string ] map [ string ] bool )  // feature -> context name -> true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  context  :=  range  contexts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w  :=  NewWalker ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . context  =  context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  pkg  :=  range  pkgs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											w . wantedPkg [ pkg ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  pkg  :=  range  pkgs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  strings . HasPrefix ( pkg ,  "cmd/" )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												strings . HasPrefix ( pkg ,  "exp/" )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												strings . HasPrefix ( pkg ,  "old/" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.
This is basically a complete replacement of what used to be here.
build.Tree is gone.
build.DirInfo is expanded and now called build.Package.
build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.
build.ScanDir is now build.ImportDir.
build.FindTree+build.ScanDir is now build.Import.
The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.
The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)
This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.
R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043
											 
										 
										
											2012-03-01 12:12:09 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  fi ,  err  :=  os . Stat ( filepath . Join ( w . root ,  pkg ) ) ;  err  !=  nil  ||  ! fi . IsDir ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												log . Fatalf ( "no source in tree for package %q" ,  pkg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											w . WalkPackage ( pkg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ctxName  :=  contextName ( context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										comma  :=  strings . Index ( f ,  "," ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										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-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									sort . Strings ( features ) 
							 
						 
					
						
							
								
									
										
										
										
											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  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  f  :=  range  features  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											fmt . Fprintf ( bw ,  "%s\n" ,  f ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 18:41:20 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  required  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  filename  :=  range  [ ] string { * checkFile }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										required  =  append ( required ,  fileFeatures ( filename ) ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sort . Strings ( required ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  optional  =  make ( map [ string ] bool )  // feature => true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  * nextFile  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  feature  :=  range  fileFeatures ( * nextFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											optional [ feature ]  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08: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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  len ( features )  ==  0  ||  required [ 0 ]  <  features [ 0 ] : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											fmt . Fprintf ( bw ,  "-%s\n" ,  take ( & required ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											fail  =  true  // broke compatibility 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  len ( required )  ==  0  ||  required [ 0 ]  >  features [ 0 ] : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											newFeature  :=  take ( & features ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  optional [ newFeature ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// 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) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												delete ( optional ,  newFeature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												fmt . Fprintf ( bw ,  "+%s\n" ,  newFeature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ! * allowNew  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													fail  =  true  // we're in lock-down mode for next release 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  missing  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  feature  :=  range  optional  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										missing  =  append ( missing ,  feature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sort . Strings ( missing ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  feature  :=  range  missing  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										fmt . Fprintf ( bw ,  "(in next file, but not in API) -%s\n" ,  feature ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  fileFeatures ( filename  string )  [ ] string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bs ,  err  :=  ioutil . ReadFile ( filename ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										log . Fatalf ( "Error reading file %s: %v" ,  filename ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  strings . Split ( strings . TrimSpace ( string ( bs ) ) ,  "\n" ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// pkgSymbol represents a symbol in a package 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  pkgSymbol  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pkg     string  // "net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									symbol  string  // "RoundTripper" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								type  Walker  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									context          * build . Context 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.
This is basically a complete replacement of what used to be here.
build.Tree is gone.
build.DirInfo is expanded and now called build.Package.
build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.
build.ScanDir is now build.ImportDir.
build.FindTree+build.ScanDir is now build.Import.
The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.
The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)
This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.
R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043
											 
										 
										
											2012-03-01 12:12:09 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									root             string 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									fset             * token . FileSet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									scope            [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									features         map [ string ] bool  // set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									lastConstType    string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									curPackageName   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									curPackage       * ast . Package 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									prevConstType    map [ pkgSymbol ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									constDep         map [ string ] string  // key's const identifier has type of future value const identifier 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									packageState     map [ string ] loadState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									interfaces       map [ pkgSymbol ] * ast . InterfaceType 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									functionTypes    map [ pkgSymbol ] string  // symbol => return type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									selectorFullPkg  map [ string ] string     // "http" => "net/http", updated by imports 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									wantedPkg        map [ string ] bool       // packages requested on the command line 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  NewWalker ( )  * Walker  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & Walker { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										fset :             token . NewFileSet ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										features :         make ( map [ string ] bool ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										packageState :     make ( map [ string ] loadState ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										interfaces :       make ( map [ pkgSymbol ] * ast . InterfaceType ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										functionTypes :    make ( map [ pkgSymbol ] string ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										selectorFullPkg :  make ( map [ string ] string ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										wantedPkg :        make ( map [ string ] bool ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										prevConstType :    make ( map [ pkgSymbol ] string ) , 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.
This is basically a complete replacement of what used to be here.
build.Tree is gone.
build.DirInfo is expanded and now called build.Package.
build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.
build.ScanDir is now build.ImportDir.
build.FindTree+build.ScanDir is now build.Import.
The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.
The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)
This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.
R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043
											 
										 
										
											2012-03-01 12:12:09 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										root :             filepath . Join ( build . Default . GOROOT ,  "src/pkg" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// loadState is the state of a package's parsing. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  loadState  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									notLoaded  loadState  =  iota 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									loading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									loaded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// hardCodedConstantType is a hack until the type checker is sufficient for our needs. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Rather than litter the code with unnecessary type annotations, we'll hard-code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// the cases we can't handle yet. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  hardCodedConstantType ( name  string )  ( typ  string ,  ok  bool )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  w . scope [ 0 ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  "pkg syscall" : 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										switch  name  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  "darwinAMD64" : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 20:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  "bool" ,  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  "" ,  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  Features ( )  ( fs  [ ] string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  f  :=  range  w . features  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										fs  =  append ( fs ,  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sort . Strings ( fs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// fileDeps returns the imports in a file. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  fileDeps ( f  * ast . File )  ( pkgs  [ ] string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  is  :=  range  f . Imports  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										fpkg ,  err  :=  strconv . Unquote ( is . Path . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Fatalf ( "error unquoting import string %q: %v" ,  is . Path . Value ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  fpkg  !=  "C"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pkgs  =  append ( pkgs ,  fpkg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// WalkPackage walks all files in package `name'. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// WalkPackage does nothing if the package has already been loaded. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  WalkPackage ( name  string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  w . packageState [ name ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  loading : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										log . Fatalf ( "import cycle loading package %q?" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  loaded : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w . packageState [ name ]  =  loading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . packageState [ name ]  =  loaded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.
This is basically a complete replacement of what used to be here.
build.Tree is gone.
build.DirInfo is expanded and now called build.Package.
build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.
build.ScanDir is now build.ImportDir.
build.FindTree+build.ScanDir is now build.Import.
The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.
The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)
This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.
R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043
											 
										 
										
											2012-03-01 12:12:09 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dir  :=  filepath . Join ( w . root ,  filepath . FromSlash ( name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.
This is basically a complete replacement of what used to be here.
build.Tree is gone.
build.DirInfo is expanded and now called build.Package.
build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.
build.ScanDir is now build.ImportDir.
build.FindTree+build.ScanDir is now build.Import.
The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.
The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)
This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.
R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043
											 
										 
										
											2012-03-01 12:12:09 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ctxt  :=  w . context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ctxt  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ctxt  =  & build . Default 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.
This is basically a complete replacement of what used to be here.
build.Tree is gone.
build.DirInfo is expanded and now called build.Package.
build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.
build.ScanDir is now build.ImportDir.
build.FindTree+build.ScanDir is now build.Import.
The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.
The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)
This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.
R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043
											 
										 
										
											2012-03-01 12:12:09 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									info ,  err  :=  ctxt . ImportDir ( dir ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-07 18:13:11 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  strings . Contains ( err . Error ( ) ,  "no Go source files" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										log . Fatalf ( "pkg %q, dir %q: ScanDir: %v" ,  name ,  dir ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									apkg  :=  & ast . Package { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Files :  make ( map [ string ] * ast . File ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									files  :=  append ( append ( [ ] string { } ,  info . GoFiles ... ) ,  info . CgoFiles ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  file  :=  range  files  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										f ,  err  :=  parser . ParseFile ( w . fset ,  filepath . Join ( dir ,  file ) ,  nil ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Fatalf ( "error parsing package %s, file %s: %v" ,  name ,  file ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										apkg . Files [ file ]  =  f 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  dep  :=  range  fileDeps ( f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											w . WalkPackage ( dep ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-17 11:20:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  * verbose  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										log . Printf ( "package %s" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pop  :=  w . pushScope ( "pkg "  +  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  pop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									w . curPackageName  =  name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w . curPackage  =  apkg 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									w . constDep  =  map [ string ] string { } 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  afile  :=  range  apkg . Files  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . recordTypes ( afile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Register all function declarations first. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  afile  :=  range  apkg . Files  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  di  :=  range  afile . Decls  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  d ,  ok  :=  di . ( * ast . FuncDecl ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												w . peekFuncDecl ( d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  afile  :=  range  apkg . Files  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . walkFile ( afile ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									w . resolveConstantDeps ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Now that we're done walking types, vars and consts 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// in the *ast.Package, use go/doc to do the rest 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// (functions and methods). This is done here because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// go/doc is destructive.  We can't use the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// *ast.Package after this. 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-31 09:48:10 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dpkg  :=  doc . New ( apkg ,  name ,  doc . AllMethods ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  t  :=  range  dpkg . Types  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Move funcs up to the top-level, not hiding in the Types. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										dpkg . Funcs  =  append ( dpkg . Funcs ,  t . Funcs ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  m  :=  range  t . Methods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											w . walkFuncDecl ( m . Decl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  f  :=  range  dpkg . Funcs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . walkFuncDecl ( f . Decl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 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 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  recordTypes ( file  * ast . File )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  di  :=  range  file . Decls  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  d  :=  di . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  * ast . GenDecl : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											switch  d . Tok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  token . TYPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												for  _ ,  sp  :=  range  d . Specs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ts  :=  sp . ( * ast . TypeSpec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													name  :=  ts . Name . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ast . IsExported ( name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  it ,  ok  :=  ts . Type . ( * ast . InterfaceType ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															w . noteInterface ( name ,  it ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkFile ( file  * ast . File )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Not entering a scope here; file boundaries aren't interesting. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  di  :=  range  file . Decls  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  d  :=  di . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  * ast . GenDecl : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											switch  d . Tok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  token . IMPORT : 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												for  _ ,  sp  :=  range  d . Specs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													is  :=  sp . ( * ast . ImportSpec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													fpath ,  err  :=  strconv . Unquote ( is . Path . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														log . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													name  :=  path . Base ( fpath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  is . Name  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														name  =  is . Name . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													w . selectorFullPkg [ name ]  =  fpath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											case  token . CONST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												for  _ ,  sp  :=  range  d . Specs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													w . walkConst ( sp . ( * ast . ValueSpec ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  token . TYPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												for  _ ,  sp  :=  range  d . Specs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													w . walkTypeSpec ( sp . ( * ast . TypeSpec ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  token . VAR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												for  _ ,  sp  :=  range  d . Specs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													w . walkVar ( sp . ( * ast . ValueSpec ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "unknown token type %d in GenDecl" ,  d . Tok ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  * ast . FuncDecl : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Ignore. Handled in subsequent pass, by go/doc. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Printf ( "unhandled %T, %#v\n" ,  di ,  di ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printer . Fprint ( os . Stderr ,  w . fset ,  di ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											os . Stderr . Write ( [ ] byte ( "\n" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  constType  =  map [ token . Token ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . INT :     "ideal-int" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . FLOAT :   "ideal-float" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . STRING :  "ideal-string" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . CHAR :    "ideal-char" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . IMAG :    "ideal-imag" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  varType  =  map [ token . Token ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . INT :     "int" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . FLOAT :   "float64" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . STRING :  "string" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . CHAR :    "rune" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									token . IMAG :    "complex128" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  errTODO  =  errors . New ( "TODO" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  constValueType ( vi  interface { } )  ( string ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  v  :=  vi . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . BasicLit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										litType ,  ok  :=  constType [ v . Kind ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  fmt . Errorf ( "unknown basic literal kind %#v" ,  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  litType ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . UnaryExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . constValueType ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . SelectorExpr : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										lhs  :=  w . nodeString ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										rhs  :=  w . nodeString ( v . Sel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pkg ,  ok  :=  w . selectorFullPkg [ lhs ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  fmt . Errorf ( "unknown constant reference; unknown package in expression %s.%s" ,  lhs ,  rhs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  t ,  ok  :=  w . prevConstType [ pkgSymbol { pkg ,  rhs } ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  t ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  fmt . Errorf ( "unknown constant reference to %s.%s" ,  lhs ,  rhs ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . Ident : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  v . Name  ==  "iota"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "ideal-int" ,  nil  // hack. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  v . Name  ==  "false"  ||  v . Name  ==  "true"  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 20:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  "bool" ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  v . Name  ==  "intSize"  &&  w . curPackageName  ==  "strconv"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Hack. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "ideal-int" ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  t ,  ok  :=  w . prevConstType [ pkgSymbol { w . curPackageName ,  v . Name } ] ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return  t ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  constDepPrefix  +  v . Name ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . BinaryExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										left ,  err  :=  w . constValueType ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										right ,  err  :=  w . constValueType ( v . Y ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  left  !=  right  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											// TODO(bradfitz): encode the real rules here, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// rather than this mess. 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											if  left  ==  "ideal-int"  &&  right  ==  "ideal-float"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  "ideal-float" ,  nil  // math.Log2E 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  left  ==  "ideal-char"  &&  right  ==  "ideal-int"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  "ideal-int" ,  nil  // math/big.MaxBase 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  left  ==  "ideal-int"  &&  right  ==  "ideal-char"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  "ideal-int" ,  nil  // text/scanner.GoWhitespace 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  left  ==  "ideal-int"  &&  right  ==  "Duration"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// Hack, for package time. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  "Duration" ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  left  ==  "ideal-int"  &&  ! strings . HasPrefix ( right ,  "ideal-" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  right ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  right  ==  "ideal-int"  &&  ! strings . HasPrefix ( left ,  "ideal-" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  left ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  strings . HasPrefix ( left ,  constDepPrefix )  &&  strings . HasPrefix ( right ,  constDepPrefix )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// Just pick one. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// e.g. text/scanner GoTokens const-dependency:ScanIdents, const-dependency:ScanFloats 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  left ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  fmt . Errorf ( "in BinaryExpr, unhandled type mismatch; left=%q, right=%q" ,  left ,  right ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  left ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . CallExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Not a call, but a type conversion. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . nodeString ( v . Fun ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . ParenExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . constValueType ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  "" ,  fmt . Errorf ( "unknown const value type %T" ,  vi ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  varValueType ( vi  interface { } )  ( string ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  v  :=  vi . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . BasicLit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										litType ,  ok  :=  varType [ v . Kind ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  fmt . Errorf ( "unknown basic literal kind %#v" ,  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  litType ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . CompositeLit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . nodeString ( v . Type ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . FuncLit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . nodeString ( w . namelessType ( v . Type ) ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . UnaryExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  v . Op  ==  token . AND  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											typ ,  err  :=  w . varValueType ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "*"  +  typ ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  fmt . Errorf ( "unknown unary expr: %#v" ,  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . SelectorExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  errTODO 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . Ident : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										node ,  _ ,  ok  :=  w . resolveName ( v . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  fmt . Errorf ( "unresolved identifier: %q" ,  v . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . varValueType ( node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . BinaryExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										left ,  err  :=  w . varValueType ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										right ,  err  :=  w . varValueType ( v . Y ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  left  !=  right  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  fmt . Errorf ( "in BinaryExpr, unhandled type mismatch; left=%q, right=%q" ,  left ,  right ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  left ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . ParenExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  w . varValueType ( v . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . CallExpr : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										var  funSym  pkgSymbol 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  selnode ,  ok  :=  v . Fun . ( * ast . SelectorExpr ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// assume it is not a method. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pkg ,  ok  :=  w . selectorFullPkg [ w . nodeString ( selnode . X ) ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  "" ,  fmt . Errorf ( "not a package: %s" ,  w . nodeString ( selnode . X ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											funSym  =  pkgSymbol { pkg ,  selnode . Sel . Name } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  retType ,  ok  :=  w . functionTypes [ funSym ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ast . IsExported ( retType )  &&  pkg  !=  w . curPackageName  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													// otherpkg.F returning an exported type from otherpkg. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  pkg  +  "."  +  retType ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  retType ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											funSym  =  pkgSymbol { w . curPackageName ,  w . nodeString ( v . Fun ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  retType ,  ok  :=  w . functionTypes [ funSym ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  retType ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// maybe a function call; maybe a conversion.  Need to lookup type. 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-11 17:55:15 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// TODO(bradfitz): this is a hack, but arguably most of this tool is, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// until the Go AST has type information. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										nodeStr  :=  w . nodeString ( v . Fun ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  nodeStr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  "string" ,  "[]byte" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nodeStr ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  fmt . Errorf ( "not a known function %q" ,  nodeStr ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  fmt . Errorf ( "unknown const value type %T" ,  vi ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									panic ( "unreachable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// resolveName finds a top-level node named name and returns the node 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// v and its type t, if known. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  resolveName ( name  string )  ( v  interface { } ,  t  interface { } ,  ok  bool )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  file  :=  range  w . curPackage . Files  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  di  :=  range  file . Decls  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											switch  d  :=  di . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  * ast . GenDecl : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												switch  d . Tok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  token . VAR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													for  _ ,  sp  :=  range  d . Specs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														vs  :=  sp . ( * ast . ValueSpec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														for  i ,  vname  :=  range  vs . Names  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															if  vname . Name  ==  name  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																if  len ( vs . Values )  >  i  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																	return  vs . Values [ i ] ,  vs . Type ,  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																return  nil ,  vs . Type ,  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil ,  nil ,  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// constDepPrefix is a magic prefix that is used by constValueType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// and walkConst to signal that a type isn't known yet. These are 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// resolved at the end of walking of a package's files. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  constDepPrefix  =  "const-dependency:" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkConst ( vs  * ast . ValueSpec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  ident  :=  range  vs . Names  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										litType  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  vs . Type  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											litType  =  w . nodeString ( vs . Type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											litType  =  w . lastConstType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  vs . Values  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  len ( vs . Values )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													log . Fatalf ( "const %q, values: %#v" ,  ident . Name ,  vs . Values ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												litType ,  err  =  w . constValueType ( vs . Values [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  t ,  ok  :=  w . hardCodedConstantType ( ident . Name ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														litType  =  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														err  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														log . Fatalf ( "unknown kind in const %q (%T): %v" ,  ident . Name ,  vs . Values [ 0 ] ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  strings . HasPrefix ( litType ,  constDepPrefix )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dep  :=  litType [ len ( constDepPrefix ) : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											w . constDep [ ident . Name ]  =  dep 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  litType  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Fatalf ( "unknown kind in const %q" ,  ident . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . lastConstType  =  litType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-10 10:05:26 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										w . prevConstType [ pkgSymbol { w . curPackageName ,  ident . Name } ]  =  litType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ast . IsExported ( ident . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											w . emitFeature ( fmt . Sprintf ( "const %s %s" ,  ident ,  litType ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  resolveConstantDeps ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  findConstType  func ( string )  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									findConstType  =  func ( ident  string )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  dep ,  ok  :=  w . constDep [ ident ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  findConstType ( dep ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  t ,  ok  :=  w . prevConstType [ pkgSymbol { w . curPackageName ,  ident } ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ident  :=  range  w . constDep  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ast . IsExported ( ident )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										t  :=  findConstType ( ident ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  t  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Fatalf ( "failed to resolve constant %q" ,  ident ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "const %s %s" ,  ident ,  t ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkVar ( vs  * ast . ValueSpec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i ,  ident  :=  range  vs . Names  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ast . IsExported ( ident . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										typ  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  vs . Type  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											typ  =  w . nodeString ( vs . Type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  len ( vs . Values )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "no values for var %q" ,  ident . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  len ( vs . Values )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "more than 1 values in ValueSpec not handled, var %q" ,  ident . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											typ ,  err  =  w . varValueType ( vs . Values [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "unknown type of variable %q, type %T, error = %v\ncode: %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ident . Name ,  vs . Values [ i ] ,  err ,  w . nodeString ( vs . Values [ i ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "var %s %s" ,  ident ,  typ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  nodeString ( node  interface { } )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  node  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  b  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									printer . Fprint ( & b ,  w . fset ,  node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  b . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  nodeDebug ( node  interface { } )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  node  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  b  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast . Fprint ( & b ,  w . fset ,  node ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  b . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  noteInterface ( name  string ,  it  * ast . InterfaceType )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w . interfaces [ pkgSymbol { w . curPackageName ,  name } ]  =  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkTypeSpec ( ts  * ast . TypeSpec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									name  :=  ts . Name . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ast . IsExported ( name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  t  :=  ts . Type . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . StructType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . walkStructType ( name ,  t ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  * ast . InterfaceType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . walkInterfaceType ( name ,  t ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "type %s %s" ,  name ,  w . nodeString ( ts . Type ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkStructType ( name  string ,  t  * ast . StructType )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									typeStruct  :=  fmt . Sprintf ( "type %s struct" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w . emitFeature ( typeStruct ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pop  :=  w . pushScope ( typeStruct ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  pop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  f  :=  range  t . Fields . List  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										typ  :=  f . Type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  name  :=  range  f . Names  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ast . IsExported ( name . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												w . emitFeature ( fmt . Sprintf ( "%s %s" ,  name ,  w . nodeString ( w . namelessType ( typ ) ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  f . Names  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											switch  v  :=  typ . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  * ast . Ident : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ast . IsExported ( v . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													w . emitFeature ( fmt . Sprintf ( "embedded %s" ,  v . Name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  * ast . StarExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												switch  vv  :=  v . X . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  * ast . Ident : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ast . IsExported ( vv . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														w . emitFeature ( fmt . Sprintf ( "embedded *%s" ,  vv . Name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  * ast . SelectorExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													w . emitFeature ( fmt . Sprintf ( "embedded %s" ,  w . nodeString ( typ ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												default : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-14 12:37:57 +11:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													log . Fatalf ( "unable to handle embedded starexpr before %T" ,  typ ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  * ast . SelectorExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												w . emitFeature ( fmt . Sprintf ( "embedded %s" ,  w . nodeString ( typ ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "unable to handle embedded %T" ,  typ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// method is a method of an interface. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  method  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									name  string  // "Read" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sig   string  // "([]byte) (int, error)", from funcSigString 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// interfaceMethods returns the expanded list of methods for an interface. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// pkg is the complete package name ("net/http") 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// iname is the interface name. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  interfaceMethods ( pkg ,  iname  string )  ( methods  [ ] method )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									t ,  ok  :=  w . interfaces [ pkgSymbol { pkg ,  iname } ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										log . Fatalf ( "failed to find interface %s.%s" ,  pkg ,  iname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  f  :=  range  t . Methods . List  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										typ  :=  f . Type 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										switch  tv  :=  typ . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  * ast . FuncType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  _ ,  mname  :=  range  f . Names  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ast . IsExported ( mname . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ft  :=  typ . ( * ast . FuncType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													methods  =  append ( methods ,  method { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														name :  mname . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														sig :   w . funcSigString ( ft ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  * ast . Ident : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											embedded  :=  typ . ( * ast . Ident ) . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  embedded  ==  "error"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												methods  =  append ( methods ,  method { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													name :  "Error" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													sig :   "() string" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ! ast . IsExported ( embedded )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "unexported embedded interface %q in exported interface %s.%s; confused" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													embedded ,  pkg ,  iname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											methods  =  append ( methods ,  w . interfaceMethods ( pkg ,  embedded ) ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  * ast . SelectorExpr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											lhs  :=  w . nodeString ( tv . X ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											rhs  :=  w . nodeString ( tv . Sel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											fpkg ,  ok  :=  w . selectorFullPkg [ lhs ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												log . Fatalf ( "can't resolve selector %q in interface %s.%s" ,  lhs ,  pkg ,  iname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											methods  =  append ( methods ,  w . interfaceMethods ( fpkg ,  rhs ) ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											log . Fatalf ( "unknown type %T in interface field" ,  typ ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkInterfaceType ( name  string ,  t  * ast . InterfaceType )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									methNames  :=  [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pop  :=  w . pushScope ( "type "  +  name  +  " interface" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  m  :=  range  w . interfaceMethods ( w . curPackageName ,  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										methNames  =  append ( methNames ,  m . name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "%s%s" ,  m . name ,  m . sig ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									pop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									sort . Strings ( methNames ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( methNames )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "type %s interface {}" ,  name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "type %s interface { %s }" ,  name ,  strings . Join ( methNames ,  ", " ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 07:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  peekFuncDecl ( f  * ast . FuncDecl )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  f . Recv  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Record return type for later use. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  f . Type . Results  !=  nil  &&  len ( f . Type . Results . List )  ==  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										retType  :=  w . nodeString ( w . namelessType ( f . Type . Results . List [ 0 ] . Type ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . functionTypes [ pkgSymbol { w . curPackageName ,  f . Name . Name } ]  =  retType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  walkFuncDecl ( f  * ast . FuncDecl )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ast . IsExported ( f . Name . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  f . Recv  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Method. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										recvType  :=  w . nodeString ( f . Recv . List [ 0 ] . Type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										keep  :=  ast . IsExported ( recvType )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( strings . HasPrefix ( recvType ,  "*" )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast . IsExported ( recvType [ 1 : ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! keep  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										w . emitFeature ( fmt . Sprintf ( "method (%s) %s%s" ,  recvType ,  f . Name . Name ,  w . funcSigString ( f . Type ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Else, a function 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w . emitFeature ( fmt . Sprintf ( "func %s%s" ,  f . Name . Name ,  w . funcSigString ( f . Type ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  funcSigString ( ft  * ast . FuncType )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  b  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									b . WriteByte ( '(' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ft . Params  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  i ,  f  :=  range  ft . Params . List  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  i  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												b . WriteString ( ", " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											b . WriteString ( w . nodeString ( w . namelessType ( f . Type ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									b . WriteByte ( ')' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ft . Results  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  nr  :=  len ( ft . Results . List ) ;  nr  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											b . WriteByte ( ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  nr  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												b . WriteByte ( '(' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  i ,  f  :=  range  ft . Results . List  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  i  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													b . WriteString ( ", " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												b . WriteString ( w . nodeString ( w . namelessType ( f . Type ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  nr  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												b . WriteByte ( ')' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  b . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// namelessType returns a type node that lacks any variable names. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  namelessType ( t  interface { } )  interface { }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ft ,  ok  :=  t . ( * ast . FuncType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & ast . FuncType { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Params :   w . namelessFieldList ( ft . Params ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Results :  w . namelessFieldList ( ft . Results ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// namelessFieldList returns a deep clone of fl, with the cloned fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// lacking names. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  namelessFieldList ( fl  * ast . FieldList )  * ast . FieldList  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									fl2  :=  & ast . FieldList { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  fl  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  f  :=  range  fl . List  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											fl2 . List  =  append ( fl2 . List ,  w . namelessField ( f ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  fl2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// namelessField clones f, but not preserving the names of fields. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// (comments and tags are also ignored) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  namelessField ( f  * ast . Field )  * ast . Field  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & ast . Field { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Type :  f . Type , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( w  * Walker )  emitFeature ( feature  string )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 21:04:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ! w . wantedPkg [ w . curPackageName ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-25 17:47:57 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									f  :=  strings . Join ( w . scope ,  ", " )  +  ", "  +  feature 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  _ ,  dup  :=  w . features [ f ] ;  dup  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										panic ( "duplicate feature inserted: "  +  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  strings . Contains ( f ,  "\n" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// TODO: for now, just skip over the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// runtime.MemStatsType.BySize type, which this tool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// doesn't properly handle. It's pretty low-level, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// though, so not super important to protect against. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  strings . HasPrefix ( f ,  "pkg runtime" )  &&  strings . Contains ( f ,  "BySize [61]struct" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										panic ( "feature contains newlines: "  +  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w . features [ f ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  * verbose  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										log . Printf ( "feature: %s" ,  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  strListContains ( l  [ ] string ,  s  string )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  v  :=  range  l  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  v  ==  s  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}