initial vendor commit

This commit is contained in:
swaits committed 2015-02-14 21:53:22 -08:00
1 parent 747c805a82
commit 21e1fb3451
660 files changed
+133146

No files matched your search

Binary file not shown.
@@ -0,0 +1,299 @@
!<arch>
__.PKGDEF 0 0 0 644 10858 `
go object darwin amd64 go1.4.1 X:precisestack
$$
package astutil
import ast "go/ast"
import runtime "runtime"
import strconv "strconv"
import strings "strings"
import fmt "fmt"
import sort "sort"
import token "go/token"
type @"go/token".Pos int
func (@"go/token".p·2 @"go/token".Pos) IsValid () (? bool) { return @"go/token".p·2 != @"go/token".Pos(0x0) }
type @"go/ast".Node interface { End() (? @"go/token".Pos); Pos() (? @"go/token".Pos) }
type @"go/ast".Comment struct { Slash @"go/token".Pos; Text string }
func (@"go/ast".c·2 *@"go/ast".Comment "esc:0x0") End () (? @"go/token".Pos) { return @"go/token".Pos(int(@"go/ast".c·2.Slash) + len(@"go/ast".c·2.Text)) }
func (@"go/ast".c·2 *@"go/ast".Comment "esc:0x0") Pos () (? @"go/token".Pos) { return @"go/ast".c·2.Slash }
type @"go/ast".CommentGroup struct { List []*@"go/ast".Comment }
func (@"go/ast".g·2 *@"go/ast".CommentGroup "esc:0x0") End () (? @"go/token".Pos)
func (@"go/ast".g·2 *@"go/ast".CommentGroup "esc:0x0") Pos () (? @"go/token".Pos)
func (@"go/ast".g·2 *@"go/ast".CommentGroup "esc:0x0") Text () (? string)
type @"go/ast".ObjKind int
func (@"go/ast".kind·2 @"go/ast".ObjKind) String () (? string) { return @"go/ast".objKindStrings[@"go/ast".kind·2] }
type @"go/ast".Object struct { Kind @"go/ast".ObjKind; Name string; Decl interface {}; Data interface {}; Type interface {} }
func (@"go/ast".obj·2 *@"go/ast".Object "esc:0x0") Pos () (? @"go/token".Pos)
type @"go/ast".Ident struct { NamePos @"go/token".Pos; Name string; Obj *@"go/ast".Object }
func (@"go/ast".x·2 *@"go/ast".Ident "esc:0x0") End () (? @"go/token".Pos) { return @"go/token".Pos(int(@"go/ast".x·2.NamePos) + len(@"go/ast".x·2.Name)) }
func (@"go/ast".id·2 *@"go/ast".Ident "esc:0x0") IsExported () (? bool)
func (@"go/ast".x·2 *@"go/ast".Ident "esc:0x0") Pos () (? @"go/token".Pos) { return @"go/ast".x·2.NamePos }
func (@"go/ast".id·2 *@"go/ast".Ident "esc:0x1") String () (? string) { if @"go/ast".id·2 != nil { return @"go/ast".id·2.Name }; return "<nil>" }
func (? *@"go/ast".Ident) @"go/ast".exprNode () { }
type @"go/ast".Decl interface { End() (? @"go/token".Pos); Pos() (? @"go/token".Pos); @"go/ast".declNode() }
type @"go/ast".Scope struct { Outer *@"go/ast".Scope; Objects map[string]*@"go/ast".Object }
func (@"go/ast".s·2 *@"go/ast".Scope "esc:0x0") Insert (@"go/ast".obj·3 *@"go/ast".Object) (@"go/ast".alt·1 *@"go/ast".Object) { if @"go/ast".alt·1 = @"go/ast".s·2.Objects[@"go/ast".obj·3.Name]; @"go/ast".alt·1 == nil { @"go/ast".s·2.Objects[@"go/ast".obj·3.Name] = @"go/ast".obj·3 }; return }
func (@"go/ast".s·2 *@"go/ast".Scope "esc:0x0") Lookup (@"go/ast".name·3 string "esc:0x0") (? *@"go/ast".Object) { return @"go/ast".s·2.Objects[@"go/ast".name·3] }
func (@"go/ast".s·2 *@"go/ast".Scope) String () (? string)
type @"go/token".Token int
func (@"go/token".tok·2 @"go/token".Token) IsKeyword () (? bool) { return @"go/token".Token(0x3C) < @"go/token".tok·2 && @"go/token".tok·2 < @"go/token".Token(0x56) }
func (@"go/token".tok·2 @"go/token".Token) IsLiteral () (? bool) { return @"go/token".Token(0x3) < @"go/token".tok·2 && @"go/token".tok·2 < @"go/token".Token(0xA) }
func (@"go/token".tok·2 @"go/token".Token) IsOperator () (? bool) { return @"go/token".Token(0xB) < @"go/token".tok·2 && @"go/token".tok·2 < @"go/token".Token(0x3B) }
func (@"go/token".op·2 @"go/token".Token) Precedence () (? int)
func (@"go/token".tok·2 @"go/token".Token) String () (? string)
type @"go/ast".BasicLit struct { ValuePos @"go/token".Pos; Kind @"go/token".Token; Value string }
func (@"go/ast".x·2 *@"go/ast".BasicLit "esc:0x0") End () (? @"go/token".Pos) { return @"go/token".Pos(int(@"go/ast".x·2.ValuePos) + len(@"go/ast".x·2.Value)) }
func (@"go/ast".x·2 *@"go/ast".BasicLit "esc:0x0") Pos () (? @"go/token".Pos) { return @"go/ast".x·2.ValuePos }
func (? *@"go/ast".BasicLit) @"go/ast".exprNode () { }
type @"go/ast".ImportSpec struct { Doc *@"go/ast".CommentGroup; Name *@"go/ast".Ident; Path *@"go/ast".BasicLit; Comment *@"go/ast".CommentGroup; EndPos @"go/token".Pos }
func (@"go/ast".s·2 *@"go/ast".ImportSpec "esc:0x0") End () (? @"go/token".Pos)
func (@"go/ast".s·2 *@"go/ast".ImportSpec "esc:0x0") Pos () (? @"go/token".Pos)
func (? *@"go/ast".ImportSpec) @"go/ast".specNode () { }
type @"go/ast".File struct { Doc *@"go/ast".CommentGroup; Package @"go/token".Pos; Name *@"go/ast".Ident; Decls []@"go/ast".Decl; Scope *@"go/ast".Scope; Imports []*@"go/ast".ImportSpec; Unresolved []*@"go/ast".Ident; Comments []*@"go/ast".CommentGroup }
func (@"go/ast".f·2 *@"go/ast".File "esc:0x0") End () (? @"go/token".Pos)
func (@"go/ast".f·2 *@"go/ast".File "esc:0x0") Pos () (? @"go/token".Pos) { return @"go/ast".f·2.Package }
func @"".PathEnclosingInterval (@"".root·3 *@"go/ast".File, @"".start·4 @"go/token".Pos, @"".end·5 @"go/token".Pos) (@"".path·1 []@"go/ast".Node, @"".exact·2 bool)
func @"".NodeDescription (@"".n·2 @"go/ast".Node) (? string)
import sync "sync" // indirect
type @"sync".Mutex struct { @"sync".state int32; @"sync".sema uint32 }
func (@"sync".m·1 *@"sync".Mutex) Lock ()
func (@"sync".m·1 *@"sync".Mutex) Unlock ()
type @"sync".Locker interface { Lock(); Unlock() }
type @"sync".RWMutex struct { @"sync".w @"sync".Mutex; @"sync".writerSem uint32; @"sync".readerSem uint32; @"sync".readerCount int32; @"sync".readerWait int32 }
func (@"sync".rw·1 *@"sync".RWMutex) Lock ()
func (@"sync".rw·1 *@"sync".RWMutex) RLock ()
func (@"sync".rw·2 *@"sync".RWMutex "esc:0x2") RLocker () (? @"sync".Locker) { return (*@"sync".rlocker)(@"sync".rw·2) }
func (@"sync".rw·1 *@"sync".RWMutex) RUnlock ()
func (@"sync".rw·1 *@"sync".RWMutex) Unlock ()
type @"go/token".lineInfo struct { Offset int; Filename string; Line int }
type @"go/token".Position struct { Filename string; Offset int; Line int; Column int }
func (@"go/token".pos·2 *@"go/token".Position "esc:0x0") IsValid () (? bool) { return @"go/token".pos·2.Line > 0x0 }
func (@"go/token".pos·2 @"go/token".Position "esc:0x2") String () (? string)
type @"go/token".File struct { @"go/token".set *@"go/token".FileSet; @"go/token".name string; @"go/token".base int; @"go/token".size int; @"go/token".lines []int; @"go/token".infos []@"go/token".lineInfo }
func (@"go/token".f·1 *@"go/token".File) AddLine (@"go/token".offset·2 int)
func (@"go/token".f·1 *@"go/token".File) AddLineInfo (@"go/token".offset·2 int, @"go/token".filename·3 string, @"go/token".line·4 int)
func (@"go/token".f·2 *@"go/token".File "esc:0x0") Base () (? int) { return @"go/token".f·2.@"go/token".base }
func (@"go/token".f·2 *@"go/token".File "esc:0x0") Line (@"go/token".p·3 @"go/token".Pos) (? int)
func (@"go/token".f·2 *@"go/token".File) LineCount () (? int)
func (@"go/token".f·1 *@"go/token".File) MergeLine (@"go/token".line·2 int)
func (@"go/token".f·2 *@"go/token".File "esc:0x1") Name () (? string) { return @"go/token".f·2.@"go/token".name }
func (@"go/token".f·2 *@"go/token".File "esc:0x0") Offset (@"go/token".p·3 @"go/token".Pos) (? int)
func (@"go/token".f·2 *@"go/token".File "esc:0x0") Pos (@"go/token".offset·3 int) (? @"go/token".Pos)
func (@"go/token".f·2 *@"go/token".File "esc:0x0") Position (@"go/token".p·3 @"go/token".Pos) (@"go/token".pos·1 @"go/token".Position)
func (@"go/token".f·2 *@"go/token".File "esc:0x0") PositionFor (@"go/token".p·3 @"go/token".Pos, @"go/token".adjusted·4 bool) (@"go/token".pos·1 @"go/token".Position)
func (@"go/token".f·2 *@"go/token".File) SetLines (@"go/token".lines·3 []int) (? bool)
func (@"go/token".f·1 *@"go/token".File) SetLinesForContent (@"go/token".content·2 []byte "esc:0x0")
func (@"go/token".f·2 *@"go/token".File "esc:0x0") Size () (? int) { return @"go/token".f·2.@"go/token".size }
func (@"go/token".f·2 *@"go/token".File "esc:0x0") @"go/token".position (@"go/token".p·3 @"go/token".Pos, @"go/token".adjusted·4 bool) (@"go/token".pos·1 @"go/token".Position)
func (@"go/token".f·4 *@"go/token".File "esc:0x1") @"go/token".unpack (@"go/token".offset·5 int, @"go/token".adjusted·6 bool) (@"go/token".filename·1 string, @"go/token".line·2 int, @"go/token".column·3 int)
type @"go/token".FileSet struct { @"go/token".mutex @"sync".RWMutex; @"go/token".base int; @"go/token".files []*@"go/token".File; @"go/token".last *@"go/token".File }
func (@"go/token".s·2 *@"go/token".FileSet) AddFile (@"go/token".filename·3 string, @"go/token".base·4 int, @"go/token".size·5 int) (? *@"go/token".File)
func (@"go/token".s·2 *@"go/token".FileSet) Base () (? int)
func (@"go/token".s·2 *@"go/token".FileSet) File (@"go/token".p·3 @"go/token".Pos) (@"go/token".f·1 *@"go/token".File)
func (@"go/token".s·1 *@"go/token".FileSet) Iterate (@"go/token".f·2 func(? *@"go/token".File) (? bool) "esc:0x0")
func (@"go/token".s·2 *@"go/token".FileSet) Position (@"go/token".p·3 @"go/token".Pos) (@"go/token".pos·1 @"go/token".Position)
func (@"go/token".s·2 *@"go/token".FileSet) PositionFor (@"go/token".p·3 @"go/token".Pos, @"go/token".adjusted·4 bool) (@"go/token".pos·1 @"go/token".Position)
func (@"go/token".s·2 *@"go/token".FileSet) Read (@"go/token".decode·3 func(? interface {}) (? error) "esc:0x0") (? error)
func (@"go/token".s·2 *@"go/token".FileSet) Write (@"go/token".encode·3 func(? interface {}) (? error) "esc:0x0") (? error)
func (@"go/token".s·2 *@"go/token".FileSet) @"go/token".file (@"go/token".p·3 @"go/token".Pos) (? *@"go/token".File)
func @"".AddImport (@"".fset·2 *@"go/token".FileSet, @"".f·3 *@"go/ast".File, @"".ipath·4 string "esc:0x0") (@"".added·1 bool)
func @"".AddNamedImport (@"".fset·2 *@"go/token".FileSet, @"".f·3 *@"go/ast".File, @"".name·4 string, @"".ipath·5 string "esc:0x0") (@"".added·1 bool)
func @"".DeleteImport (@"".fset·2 *@"go/token".FileSet, @"".f·3 *@"go/ast".File, @"".path·4 string "esc:0x0") (@"".deleted·1 bool)
func @"".RewriteImport (@"".fset·2 *@"go/token".FileSet "esc:0x0", @"".f·3 *@"go/ast".File "esc:0x0", @"".oldPath·4 string "esc:0x0", @"".newPath·5 string "esc:0x0") (@"".rewrote·1 bool)
func @"".UsesImport (@"".f·2 *@"go/ast".File, @"".path·3 string) (@"".used·1 bool)
func @"".Imports (@"".fset·2 *@"go/token".FileSet, @"".f·3 *@"go/ast".File "esc:0x0") (? [][]*@"go/ast".ImportSpec)
type @"go/ast".Expr interface { End() (? @"go/token".Pos); Pos() (? @"go/token".Pos); @"go/ast".exprNode() }
func @"".Unparen (@"".e·2 @"go/ast".Expr "esc:0x2") (? @"go/ast".Expr)
func @"".init ()
var @"go/ast".objKindStrings [7]string
type @"sync".rlocker struct { @"sync".w @"sync".Mutex; @"sync".writerSem uint32; @"sync".readerSem uint32; @"sync".readerCount int32; @"sync".readerWait int32 }
func (@"sync".r·1 *@"sync".rlocker) Lock ()
func (@"sync".r·1 *@"sync".rlocker) Unlock ()
$$
_go_.6 0 0 0 644 215208 `
go object darwin amd64 go1.4.1 X:precisestack
!
go13ld
fmt.ago/ast.ago/token.a sort.astrconv.astrings.aþ0"".PathEnclosingIntervalÀeH‹ %H�D$ÈH;AwèëåH�ì¸HÇ„$ØHÇ„$àHÇ„$èÆ„$ðHÇ„$ØHÇ„$àHÇ„$èHÇD$XH�¼$�1ÀèH�œ$�H�-H‰+H�¬$ØH‰kH�¬$ÈH‰kH�¬$ÐH‰kH�l$XH‰k H‰\$XH‹œ$ÈH‹¬$ÐH9ë~ H‹„$ÈH‹œ$ÐH‰œ$ÈH‰„$ÐH‹œ$ÀH‰$èH‹Œ$ÀH‹D$H‹œ$ÈH9Ã�*H‹YH‹¬$ÐH9ë�H‹œ$ÈH‹¬$ÐH9ëuH‹œ$ÈHÿÃH‰œ$ÐH‰L$`H‹1íH9脤H‹L$`H‰D$hH‰$H‰L$pH‰L$H‹T$XH‹ÿÓ¶\$ˆœ$ðH‹Œ$à1ÀH‰ËHÁû?H‰ÍH)ÝH‰ëHÑûH9ÃŽHH‰ËHÿËH)ÃH‰\$PH‰ËH‰L$@HÿËH)ÃH‰ÙH‹œ$ØH‰\$xH‹œ$àH‰œ$€H‹œ$èH‰œ$ˆH‹œ$ØL‹„$àH‰ÅL9ÀƒÙHkíHëH‹+H‰l$hH‹kH‰l$pH‹œ$ØH‰ÅH‰D$HL‹„$àL9Àƒ™HkíHëH‰$H‹œ$ØL‹„$àH‰ÍL9ÁsoHkíHëH�l$H‰ïH‰ÞH¥H¥èH‹\$xH‹l$PL‹„$€L9Ås6HkíHëH‰$H‹\$hH‰\$H‹\$pH‰\$èH‹L$@H‹D$HHÿÀé¸þÿÿè è è è H�ĸÃH�H‰$H�H‰\$H�H‰\$èH‹D$é*þÿÿH‰L$`H‹1íH9è„öH‹\$`H‰\$pH‰D$hH‹”$ØH‹Œ$àH‹œ$èH‰ØH)ËHƒû}LH�H‰$H‰T$xH‰T$H‰Œ$€H‰L$H‰„$ˆH‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$€H‰„$ˆH‰ÓH‰T$xH‰ÍHkíHëH‰$H‹\$hH‰\$H‹\$pH‰\$èH‹T$xH‹Œ$€H‹„$ˆH‰”$ØH‰Œ$àH‰„$èé¹þÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$éØþÿÿ2
*0runtime.morestack_noctxtŒì runtime.duffzeroª"".func·001 $go/ast.(*File).Endî@go.itab.*go/ast.File.go/ast.NodeÌ
ê
2runtime.writebarrierifaceà 2runtime.writebarrierifaceŽ $runtime.panicindexœ $runtime.panicindexª $runtime.panicindex¸ $runtime.panicindexÚ "type.*go/ast.Fileð  type.go/ast.Nodeˆ␍@go.itab.*go/ast.File.go/ast.Nodeœ␍ runtime.typ2ItabÈ␍@go.itab.*go/ast.File.go/ast.NodeÒ$type.[]go/ast.Node¾"runtime.growsliceæ2runtime.writebarrierifaceØ"type.*go/ast.Fileî type.go/ast.Node†@go.itab.*go/ast.File.go/ast.Nodeš runtime.typ2Itabpð,"".autotmp_0023type.int"".autotmp_0022type.int"".autotmp_0021$type.[]go/ast.Node"".autotmp_0020type.*uint8"".autotmp_0019 type.go/ast.Node"".autotmp_0018 type.go/ast.Node"".autotmp_0017$type.[]go/ast.Node"".autotmp_0015type.int"".autotmp_0012OØtype.struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }"".autotmp_0009"type.*go/ast.File"".autotmp_0008type.int"".autotmp_0007Ïtype.int"".autotmp_0005¯"type.*go/ast.File"".autotmp_0004"type.go/token.Pos"".lïtype.int"".ißtype.int"".visit¿6type.func(go/ast.Node) bool"".exact`type.bool"".path0$type.[]go/ast.Node "".end "type.go/token.Pos"".start"type.go/token.Pos"".root"type.*go/ast.File"ð‡ïðö  P|r ŠS DE&Ÿ␍2ˆ72�—Ž;G‘TZTgclocals·b707c77a9bd5ebaa2f42f19cc98ab913Tgclocals·a1df20860d464b11efcaaf93a370c869®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ "".tokenNode.Pos H‹\$H‰\$Ã0 "".~r0 "type.go/token.Pos"".n"type."".tokenNodeÖTgclocals·f90cfd099b5ec2b453c391fece9d42bbTgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ "".tokenNode.End H‹\$H‰\$Ã0 "".~r0 "type.go/token.Pos"".n"type."".tokenNodeÞTgclocals·f90cfd099b5ec2b453c391fece9d42bbTgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ "".tokÀÀeH‹ %H;awèëêHƒì@H‹D$HHÇD$XHÇD$`HÇD$0HÇD$8H‰D$0H‹\$PHÃH‰\$8H�H‰$H�H‰\$H�H‰\$H�\$0H‰\$èH‹\$ H‰\$XH‹\$(H‰\$`HƒÄ@Ã
 0runtime.morestack_noctxt°"type."".tokenNodeÆ type.go/ast.NodeÞ@go.itab."".tokenNode.go/ast.Node†runtime.convT2I@€"".autotmp_0032"type."".tokenNode "".~r2  type.go/ast.Node "".lentype.int "".pos"type.go/token.Pos€…  ä1o ‚Tgclocals·693fd2e6f4da98598ef49a51d91c93cdTgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".childrenOf ‰މeH‹ %H�„$°öÿÿH;AwèëâH�ìÐ H�H‰$èH‹|$H‰¼$H�¬$Ø H‰îH¥H¥HÇ„$è HÇ„$ð HÇ„$ø H�H‰$èH‹\$H‰œ$H�H‰$èH‹D$H�-H‰(H‰„$øH‰$Hƒ<$„sÁHƒ$H‹œ$H‰\$èH‹œ$øH‰$Hƒ<$„9ÁHƒ$H‹œ$H‰\$èH‹´$H�,$H‰ïH¥H¥H‹œ$øH‰\$èH‹œ$H‹ H‹kH‰Œ$0 H‰ $H‰¬$8 H‰l$è‹D$=/_‡Þ^=4ù @‡�-=Ns;/‡/=¡<ý‡1‰D$D= § …ìH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹\$¶\$ €û„«H‹œ$H‹+H‰¬$  H‹kH‰¬$¨ H‹kH‰¬$° H�H‰$H�H‰\$H�H‰\$H�œ$  H‰\$èH�\$ H�,$H‰ïH‰ÞH¥H¥èH‹œ$H‹+H‰¬$è H‹kH‰¬$ð H‹kH‰¬$ø H�ÄÐ Ã=‰kÏuAH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹\$¶\$ €û… ÿÿÿ=¡<ý…4H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹D$¶\$ €û„÷H‹hH‰¬$HÇ„$xHÇ„$ HÇ„$(HÇ„$8HÇ„$@H‹œ$H‰œ$8H‹œ$xH‹¬$HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ H‹œ$ H‰œ$(H‹œ$ H‰œ$ H‹œ$(H‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$È H‰œ$H‹œ$ H‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$¸ H‹œ$(H‰œ$À H‹œ$ H‰œ$È H‹œ$¸ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èéÎûÿÿH‹œ$0 H‰œ$ÐH‹œ$8 H‰œ$ØH�œ$P HÇHÇCH�œ$P H‰œ$èH‹œ$èH‰œ$Hƒ¼$„=HÇ„$øHÇ„$ H‹œ$H‰œ$p H‹œ$øH‰œ$x H‹œ$ H‰œ$€ H‹œ$ÐH‰$H‹œ$ØH‰\$èH‹\$H‰œ$ðH‹\$H‰œ$øH‹œ$p H‰$H‹œ$ðH‰\$H‹œ$øH‰\$èH�H�,$H‰ïH‰ÞH¥H¥H‹œ$p H‰\$H‹œ$x H‰\$H‹œ$€ H‰\$ èH‹\$(H‰œ$@ H‹\$0H‰œ$H H�H‰$H�œ$@ H‰\$èH�\$H�,$H‰ïH‰ÞH¥H¥è ‰%é·þÿÿ‰D$D=GžõuAH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹\$¶\$ €û…Óùÿÿ=´~‚…NH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„ H‹œ$HÇHÇCHÇCH‰”$¸H‹ZH‹+H‰¬$ˆHÇ„$HÇ„$@HÇ„$HHÇ„$8HÇ„$@H‹œ$ˆH‰œ$8H‹œ$H‹¬$ˆHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$@H‹œ$( H‰œ$HH‹œ$@H‰œ$ H‹œ$HH‰œ$( H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èH‹¬$¸H‹]1íH9ë„FH‹H‰œ$ðH‹œ$ð1íH9ë„~ H‹œ$¸H‹kH‰¬$àH‹œ$àH‰œ$( H‹œ$ðH‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èH‹H‰œ$ðH‹œ$ð1íH9ë„þ H‹œ$¸H‹kH‰¬$àH‹œ$àH‰œ$( H‹œ$ðH‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$˜ H‰œ$H‹œ$ H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$ˆ H‹œ$(H‰œ$� H‹œ$ H‰œ$˜ H‹œ$ˆ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èH‹¬$¸H‹mH‹]1íH9ë„JH‹H‰œ$ðH‹œ$ð1íH9ë„cH‹œ$¸H‹[H‹kH‰¬$àH‹œ$àH‰œ$( H‹œ$ðH‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$ H‹œ$ HÿÃH‰œ$(H‹œ$˜ H‰œ$H‹œ$(H‰œ$H‹œ$Line truncated
‰D$D=ä’H….H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„íH‹)H‰l$XHÇ„$HHÇ„$€HÇ„$ˆHÇ„$8HÇ„$@H‹\$XH‰œ$8H‹œ$HH‹l$XHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$€H‹œ$ H‰œ$ˆH‹œ$€H‰œ$ H‹œ$ˆH‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èéƒÏÿÿ=¡©ƒJ…‚H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„AH‰”$¨H‹jH‰,$èH‹\$H‰œ$` H‹\$H‰œ$h H‹œ$h H‰œ$(H‹œ$¨H‹+H‰¬$XH‹œ$(H‰œ$HÇ„$ðHÇ„$øHÇ„$8HÇ„$@H‹œ$XH‰œ$8H‹œ$H‹¬$XHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ðH‹œ$ H‰œ$øH‹œ$ðH‰œ$ H‹œ$øH‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$˜ H‰œ$H‹œ$øH‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$ˆ H‹œ$ H‰œ$� H‹œ$øH‰œ$˜ H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èéöËÿÿ=·š×L…ÐÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹L$¶\$ €û„àÏÿÿH‰Œ$ÀH‹iH‰,$èH‹\$H‰œ$` H‹\$H‰œ$h H‹œ$h H‰œ$(H‹œ$ÀH‹+H‰¬$H‹œ$(H‰œ$¸HÇ„$`HÇ„$hHÇ„$8HÇ„$@H‹œ$H‰œ$8H‹œ$¸H‹¬$HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$`H‹œ$( H‰œ$hH‹œ$`H‰œ$ H‹œ$hH‰œ$( H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$˜ H‰œ$H‹œ$ H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$ˆ H‹œ$(H‰œ$� H‹œ$ H‰œ$˜ H‹œ$ˆ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èémÈÿÿ‰D$D=%ÚNuAH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹\$¶\$ €û…!Èÿÿ=ÛZðQ…7H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„öH‹)H‰¬$ÀHÇ„$èHÇ„$0HÇ„$8HÇ„$8HÇ„$@H‹œ$ÀH‰œ$8H‹œ$èH‹¬$ÀHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$0H‹œ$ H‰œ$8H‹œ$0H‰œ$ H‹œ$8H‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$˜ H‰œ$H‹œ$øH‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$ˆ H‹œ$ H‰œ$� H‹œ$øH‰œ$˜ H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èéßÄÿÿ=F¯4U…ÉÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹D$¶\$ €û„ÉÈÿÿH‹(H‰¬$°HÇ„$xHÇ„$ HÇ„$¨HÇ„$8HÇ„$@H‹œ$°H‰œ$8H‹œ$xH‹¬$°HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ H‹œ$ H‰œ$¨H‹œ$ H‰œ$ H‹œ$¨H‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$˜ H‰œ$H‹œ$ H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$ˆ H‹œ$(H‰œ$� H‹œ$ H‰œ$˜ H‹œ$ˆ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èé¡Áÿÿ=½Œ7X‡|‰D$D=¡ç]U…8H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„÷H‹iH‰¬$ÀHÇ„$HHÇ„$@HÇ„$HHÇ„$8HÇ„$@H‹œ$ÀH‰œ$8H‹œ$HH‹¬$ÀHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$@H‹œ$ H‰œ$HH‹œ$@H‰œ$ H‹œ$HH‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$HLine truncated
ò]‡-‰D$D=«Òf[…ÑH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„�H‰”$˜H‹jH‰,$èH‹\$H‰œ$` H‹\$H‰œ$h H‹œ$h H‰œ$øH‹œ$˜H‹kH‰l$hH‹œ$øH‰œ$ˆHÇ„$HÇ„$HÇ„$8HÇ„$@H‹\$hH‰œ$8H‹œ$ˆH‹l$hHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$H‹œ$( H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$( H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$ H‹œ$ HÿÃH‰œ$(H‹œ$˜ H‰œ$H‹œ$(H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$øH‹œ$H‰œ$(H‹œ$H‰œ$ˆ H‹œ$øH‰œ$� H‹œ$(H‰œ$˜ H‹œ$ˆ H‹¬$ HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èH‹„$˜H‹XHƒû„u¯ÿÿH‹hH‰¬$àHÇ„$ HÇ„$ HÇ„$(HÇ„$8HÇ„$@H‹œ$àH‰œ$8H‹œ$ H‹¬$àHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ H‹œ$ H‰œ$(H‹œ$˜H‹k8H‰l$xHÇ„$`HÇ„$ HÇ„$¨HÇ„$8HÇ„$@H‹\$xH‰œ$8H‹œ$`H‹l$xHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ H‹œ$ H‰œ$¨H‹œ$ H‰œ$ H‹œ$(H‰œ$ H‹œ$ H‰œ$ H‹œ$¨H‰œ$( H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HƒÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$(HÿÃH‰œ$(H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èé/«ÿÿ=
ò]…V¯ÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹\$¶\$ €û…çªÿÿé¯ÿÿ‰D$D=ø‘ç]…7H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„öH‹)H‰¬$°HÇ„$HÇ„$ HÇ„$¨HÇ„$8HÇ„$@H‹œ$°H‰œ$8H‹œ$H‹¬$°HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ H‹œ$ H‰œ$¨H‹œ$ H‰œ$ H‹œ$¨H‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$˜ H‰œ$H‹œ$øH‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$ˆ H‹œ$ H‰œ$� H‹œ$øH‰œ$˜ H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$è霧ÿÿ=/_…ëÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹L$¶\$ €û„†«ÿÿH‰Œ$ÐH‹YHÿËH‰œ$0H‹œ$0H‰œ$ðHÇ„$XHÇ„$àHÇ„$èHÇ„$8HÇ„$@H‹œ$ðH‰œ$8H‹œ$XH‹¬$ðHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$àH‹œ$( H‰œ$èH‹œ$ÐH‹kH‰¬$ðHÇ„$˜HÇ„$`HÇ„$hHÇ„$8HÇ„$@H‹œ$ðH‰œ$8H‹œ$˜H‹¬$ðHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$`H‹œ$( H‰œ$hH‹œ$ÐH‹k(H‰¬$0HÇ„$˜HÇ„$`HÇ„$hHÇ„$8HÇ„$@H‹œ$0H‰œ$8H‹œ$˜H‹¬$0HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$`H‹œ$( H‰œ$hH‹œ$àH‰œ$ H‹œ$èH‰œ$( H‹œ$`H‰œ$ H‹œ$hH‰œ$ H‹œ$`H‰œ$ H‹œ$hH‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$(H‹œ$(HƒÃH‰œ$øH‹œ$˜ H‰œ$H‹œ$øH‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$ˆ H‹œ$ H‰œ$� H‹œ$øH‰œ$˜ H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$(HÿÃH‰œ$(H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$(HÿÃH‰œ$(H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èé“¡ÿÿ=<
.¤‡k$=Ø4‹‡ý=èZòe‡4‰D$D=RΞe…�H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„NH‰”$�H‹jH‰l$PHÇ„$(HÇ„$�HÇ„$˜HÇ„$8HÇ„$@H‹\$PH‰œ$8H‹œ$(H‹l$PHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$�H‹œ$( H‰œ$˜H‹œ$�H‹k(H‰¬$€HÇ„$hHÇ„$PHÇ„$XHÇ„$8HÇ„$@H‹œ$€H‰œ$8H‹œ$hH‹¬$€HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$PH‹œ$( H‰œ$XH‹œ$�H‰œ$ H‹œ$˜H‰œ$( H‹œ$PH‰œ$ H‹œ$XH‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HƒÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$(HÿÃH‰œ$(H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èéÔœÿÿ=€+ËeuAH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹\$¶\$ €û…Œœÿÿ=èZòe…³ ÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹D$¶\$ €û„v ÿÿH‹hH‰¬$(H‹(H‰¬$øH‹œ$(H‰œ$àHÇ„$°HÇ„$¸HÇ„$8HÇ„$@H‹œ$øH‰œ$8H‹œ$àH‹¬$øHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$°H‹œ$( H‰œ$¸H‹œ$°H‰œ$ H‹œ$¸H‰œ$( H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$È H‰œ$H‹œ$ H‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$¸ H‹œ$(H‰œ$À H‹œ$ H‰œ$È H‹œ$¸ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èé>™ÿÿ‰D$D=Ë4{j…7H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„öH‹)H‰¬$pHÇ„$ØHÇ„$àHÇ„$èHÇ„$8HÇ„$@H‹œ$pH‰œ$8H‹œ$ØH‹¬$pHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$àH‹œ$( H‰œ$èH‹œ$àH‰œ$ H‹œ$èH‰œ$( H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$ H‹œ$ HÿÃH‰œ$(H‹œ$˜ H‰œ$H‹œ$(H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$øH‹œ$H‰œ$(H‹œ$H‰œ$ˆ H‹œ$øH‰œ$� H‹œ$(H‰œ$˜ H‹œ$ˆ H‹¬$ HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èéø•ÿÿ=^�s…/H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„îH‹iH‰l$HHÇ„$PHÇ„$€HÇ„$ˆHÇ„$8HÇ„$@H‹\$HH‰œ$8H‹œ$PH‹l$HHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$€H‹œ$ H‰œ$ˆH‹œ$€H‰œ$ H‹œ$ˆH‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èé¾’ÿÿ=Ø4‹…å–ÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹D$¶\$ €û„¨–ÿÿH‹(H‰¬$ÐHÇ„$¸HÇ„$ HÇ„$(HÇ„$8HÇ„$@H‹œ$ÐH‰œ$8H‹œ$¸H‹¬$ÐHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ H‹œ$ H‰œ$(H‹œ$ H‰œ$ H‹œ$(H‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$ H‹œ$ HÿÃH‰œ$(H‹œ$˜ H‰œ$H‹œ$(H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$øH‹œ$H‰œ$(H‹œ$H‰œ$ˆ H‹œ$øH‰œ$� H‹œ$(H‰œ$˜ H‹œ$ˆ H‹¬$ HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èé€�ÿÿ=¼—‡À ‰D$D=;¦5‘…ŽH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„MH‰”$€H‹*H‰¬$HÇ„$XHÇ„$ÀHÇ„$ÈHÇ„$8HÇ„$@H‹œ$H‰œ$8H‹œ$XH‹¬$HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ÀH‹œ$ H‰œ$ÈH‹œ$€H‹kH‰l$pHÇ„$(HÇ„$ÀHÇ„$ÈLine truncated
.¤…‘�ÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹\$¶\$ €û…"}ÿÿéO�ÿÿ=Üï·Š=Ÿ¾Æ‡b ‰D$D=àö³…ÆH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„…H‰”$PH‹*HÇÃHÇ„$PHÇ„$XHÇ„$8HÇ„$@H‰¬$8HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$PH‹œ$( H‰œ$XH‹œ$PHƒû„¨H‹kH‰¬$àH‹k H‰¬$èH‹œ$èH‰$H‹œ$àH‹[ ÿÓH‹\$H‰œ$0H‹œ$0H‰œ$ØHÇ„$ÀHÇ„$HÇ„$HÇ„$8HÇ„$@H‹œ$ØH‰œ$8H‹œ$ÀH‹¬$ØHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$H‹œ$( H‰œ$H‹œ$PH‰œ$ H‹œ$XH‰œ$( H‹œ$H‰œ$ H‹œ$H‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$(H‹œ$(HƒÃH‰œ$ H‹œ$˜ H‰œ$H‹œ$ H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$ˆ H‹œ$ H‰œ$� H‹œ$øH‰œ$˜ H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$(HÿÃH‰œ$(H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èé9xÿÿ‰éQüÿÿ==ÊO·…7H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„öH‹)H‰¬$@HÇ„$h HÇ„$@HÇ„$HHÇ„$8HÇ„$@H‹œ$@H‰œ$8H‹œ$hH‹¬$@HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$@H‹œ$( H‰œ$HH‹œ$@H‰œ$ H‹œ$HH‰œ$( H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$È H‰œ$H‹œ$øH‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$¸ H‹œ$ H‰œ$À H‹œ$øH‰œ$È H‹œ$¸ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èéðtÿÿ=Ÿ¾Æ…yÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹D$¶\$ €û„ÚxÿÿH‹Hƒû„›tÿÿH‹(H‰¬$àHÇ„$ˆHÇ„$HÇ„$HÇ„$8HÇ„$@H‹œ$àH‰œ$8H‹œ$ˆH‹¬$àHëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$( H‹œ$ H‰œ$H‹œ$( H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$( H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$˜ H‰œ$H‹œ$ H‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$ˆ H‹œ$(H‰œ$� H‹œ$ H‰œ$˜ H‹œ$ˆ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$( H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èé¥qÿÿ‰D$D=…Þ Ç…7H�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹L$¶\$ €û„öH‹)H‰¬$€HÇ„$¨HÇ„$ÀHÇ„$ÈHÇ„$8HÇ„$@H‹œ$€H‰œ$8H‹œ$¨H‹¬$€HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$ÀH‹œ$ H‰œ$ÈH‹œ$ÀH‰œ$ H‹œ$ÈH‰œ$ H‹œ$H‹+H‰¬$¸ H‹kH‰¬$À H‹kH‰¬$È H‹œ$È H‹¬$À H)ëHƒû}gH�H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$HÇD$ èH‹\$(H‰œ$¸ H‹\$0H‰œ$À H‹\$8H‰œ$È H‹œ$À H‰œ$øH‹œ$øHÿÃH‰œ$ H‹œ$È H‰œ$H‹œ$ H‰œ$H‹œ$¸ H‰œ$H‹œ$H‰œ$(H‹œ$H‰œ$ H‹œ$H‰œ$¸ H‹œ$(H‰œ$À H‹œ$ H‰œ$È H‹œ$¸ H‹¬$øHkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$¸ H‰œ$ˆ H‹œ$À H‰œ$� H‹œ$È H‰œ$˜ H‹œ$H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$èé_nÿÿ=ˆp=Ì…ƒH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$è‹D$DH‹T$¶\$ €û„BH‰”$pH‹j H‰,$èH‹\$H‰œ$` H‹\$H‰œ$h H‹œ$h H‰œ$(H‹œ$pH‹kH‰¬$H‹œ$(H‰œ$ HÇ„$�HÇ„$˜HÇ„$8HÇ„$@H‹œ$H‰œ$8H‹œ$ H‹¬$HëH‰œ$@H�H‰$H�H‰\$H�H‰\$H�œ$8H‰\$èH‹\$ H‰œ$ H‹\$(H‰œ$ H‹œ$ H‰œ$�H‹œ$ H‰œ$˜H‹œ$�H‰œ$ H‹œ$˜H‰œ$ H‹œ$H‹+H‰¬$ˆ H‹kH‰¬$� H‹kH‰¬$˜ H‹œ$˜ H‹¬$� H)ëHƒû}gH�H‰$H‹œ$ˆ H‰\$H‹œ$� H‰\$H‹œ$˜ H‰\$HÇD$ èH‹\$(H‰œ$ˆ H‹\$0H‰œ$� H‹\$8H‰œ$˜ H‹œ$� H‰œ$(H‹œ$(HÿÃH‰œ$øH‹œ$˜ H‰œ$H‹œ$øH‰œ$H‹œ$ˆ H‰œ$H‹œ$H‰œ$ H‹œ$H‰œ$øH‹œ$H‰œ$ˆ H‹œ$ H‰œ$� H‹œ$øH‰œ$˜ H‹œ$ˆ H‹¬$(HkíHëH‰$H‹œ$ H‰\$H‹œ$ H‰\$èH‹œ$ˆ H‰œ$¸ H‹œ$� H‰œ$À H‹œ$˜ H‰œ$È H‹œ$H‰$H‹œ$¸ H‰\$H‹œ$À H‰\$H‹œ$È H‰\$èéÑjÿÿ=ÜïÎ…ønÿÿH�H‰$H‹œ$0 H‰\$H‹œ$8 H‰\$èH‹D$¶\$ €û„»nÿÿHƒx…øH‰„$ˆH‹(H‰¬$(HÇ„$`HÇ„$HÇ„$HÇ„$8HÇ„$@H‹œ$(H‰œ$8H‹œ$`H‹¬$(HëH‰œ$@H�H‰$H�H‰\$H�H‰\$Line truncated
00runtime.morestack_noctxtP type.go/ast.Nodeb"runtime.newobjectð$type.[]go/ast.Node‚"runtime.newobjectªztype.struct { F uintptr; A0 *go/ast.Node; A1 *[]go/ast.Node }¼"runtime.newobjectÔ"".func·002.runtime.writebarrierptr’.runtime.writebarrierptrÜgo/ast.Inspect$runtime.ifacethashÂ.type.*go/ast.ImportSpecˆ$runtime.assertI2T2štype."".byPos°&type.sort.InterfaceÈ>go.itab."".byPos.sort.Interfaceöruntime.convT2I¦ sort.Sort¨
,type.*go/ast.EmptyStmtî
$runtime.assertI2T2À *type.*go/ast.SendStmt† $runtime.assertI2T2 "type."".tokenNode type.go/ast.NodeÎ@go.itab."".tokenNode.go/ast.Nodeüruntime.convT2IÆ$type.[]go/ast.Node¸"runtime.growsliceÀ2runtime.writebarrieriface�2runtime.writebarrierslice²runtime.convI2E¼2runtime.writebarrierifaceÊFgo.string."unexpected node type %T"¾fmt.Sprintf€type.string¬runtime.convT2EÜruntime.gopanicœ$type.*go/ast.Fieldâ$runtime.assertI2T2´ *type.*go/ast.FuncDeclú $runtime.assertI2T2ð#"type."".tokenNode†$ type.go/ast.Nodež$@go.itab."".tokenNode.go/ast.NodeÌ$runtime.convT2I–'$type.[]go/ast.Nodeˆ("runtime.growslice�,2runtime.writebarrierifaceà-2runtime.writebarriersliceœ.Jgo.itab.*go/ast.FieldList.go/ast.NodeÐ0$type.[]go/ast.NodeÂ1"runtime.growsliceÊ52runtime.writebarrierifaceš72runtime.writebarrierslice¨7Bgo.itab.*go/ast.Ident.go/ast.NodeÜ9$type.[]go/ast.NodeÎ:"runtime.growsliceÖ>2runtime.writebarrieriface¦@2runtime.writebarriersliceê@Jgo.itab.*go/ast.FieldList.go/ast.Node¦C$type.[]go/ast.Node˜D"runtime.growslice H2runtime.writebarrierifaceðI2runtime.writebarrierslice´JJgo.itab.*go/ast.FieldList.go/ast.NodeðL$type.[]go/ast.NodeâM"runtime.growsliceêQ2runtime.writebarrierifaceºS2runtime.writebarriersliceöSJgo.itab.*go/ast.BlockStmt.go/ast.NodeªV$type.[]go/ast.NodeœW"runtime.growslice¤[2runtime.writebarrierifaceô\2runtime.writebarriersliceŒ],type.*go/ast.BlockStmt¢] type.go/ast.Nodeº]Jgo.itab.*go/ast.BlockStmt.go/ast.NodeÎ] runtime.typ2Itab€^,type.*go/ast.FieldList–^ type.go/ast.Node®^Jgo.itab.*go/ast.FieldList.go/ast.NodeÂ^ runtime.typ2Itabô^,type.*go/ast.FieldListŠ_ type.go/ast.Node¢_Jgo.itab.*go/ast.FieldList.go/ast.Node¶_ runtime.typ2Itabè_$type.*go/ast.Identþ_ type.go/ast.Node–`Bgo.itab.*go/ast.Ident.go/ast.Nodeª` runtime.typ2ItabÜ`,type.*go/ast.FieldListò` type.go/ast.NodeŠaJgo.itab.*go/ast.FieldList.go/ast.Nodeža runtime.typ2Itabæa$type.*go/ast.Ident¬b$runtime.assertI2T2äd"type."".tokenNodeúd type.go/ast.Node’e@go.itab."".tokenNode.go/ast.NodeÀeruntime.convT2IŠh$type.[]go/ast.Nodeüh"runtime.growslice„m2runtime.writebarrierifaceÔn2runtime.writebarrierslice o2type.*go/ast.CompositeLitæo$runtime.assertI2T2˜r"type."".tokenNode®r type.go/ast.NodeÆr@go.itab."".tokenNode.go/ast.Nodeôrruntime.convT2Iìu"type."".tokenNode‚v type.go/ast.Nodešv@go.itab."".tokenNode.go/ast.NodeÈvruntime.convT2IÒy$type.[]go/ast.NodeÄz"runtime.growsliceÎ~2runtime.writebarrierifaceè2runtime.writebarrieriface¸�2runtime.writebarriersliceÞ�,type.*go/ast.ValueSpec¤‚$runtime.assertI2T2ö‚(type.*go/ast.ForStmt¼ƒ$runtime.assertI2T2Ô…"type."".tokenNodeê… type.go/ast.Node‚†@go.itab."".tokenNode.go/ast.Node°†runtime.convT2Iúˆ$type.[]go/ast.Nodeì‰"runtime.growsliceô�2runtime.writebarrierifaceÄ�2runtime.writebarriersliceú�,type.*go/ast.FieldListÀ�$runtime.assertI2T2ð’"type."".tokenNode†“ type.go/ast.Nodež“@go.itab."".tokenNode.go/ast.NodeÌ“runtime.convT2IÄ–"type."".tokenNodeÚ– type.go/ast.Nodeò–@go.itab."".tokenNode.go/ast.Node —runtime.convT2Iªš$type.[]go/ast.Nodeœ›"runtime.growslice¦Ÿ2runtime.writebarrierifaceÀ 2runtime.writebarrieriface�¢2runtime.writebarrierslice¾¢*type.*go/ast.Ellipsis„£$runtime.assertI2T2¤¥"type."".tokenNodeº¥ type.go/ast.NodeÒ¥@go.itab."".tokenNode.go/ast.Node€¦runtime.convT2Iʨ$type.[]go/ast.Node¼©"runtime.growsliceÄ­2runtime.writebarrieriface”¯2runtime.writebarrierslice¯2type.*go/ast.KeyValueExprˆ°$runtime.assertI2T2�²"type."".tokenNode¦² type.go/ast.Node¾²@go.itab."".tokenNode.go/ast.Nodeì²runtime.convT2I¶µ$type.[]go/ast.Node¨¶"runtime.growslice°º2runtime.writebarrieriface€¼2runtime.writebarriersliceâ¼&type.*go/ast.GoStmt¨½$runtime.assertI2T2¶¿"type."".tokenNodeÌ¿ type.go/ast.Nodeä¿@go.itab."".tokenNode.go/ast.Node’Àruntime.convT2IÜÂ$type.[]go/ast.NodeÎÃ"runtime.growsliceÖÇ2runtime.writebarrieriface¦É2runtime.writebarriersliceÔÉ.type.*go/ast.BranchStmtšÊ$runtimeLine truncated
îš"type."".tokenNode„› type.go/ast.Nodeœ›@go.itab."".tokenNode.go/ast.NodeÊ›runtime.convT2IÔž$type.[]go/ast.NodeÆŸ"runtime.growsliceУ2runtime.writebarrierifaceê¤2runtime.writebarrierifaceº¦2runtime.writebarriersliceö¦4type.*go/ast.InterfaceType¼§$runtime.assertI2T2Ü©"type."".tokenNodeò© type.go/ast.NodeŠª@go.itab."".tokenNode.go/ast.Node¸ªruntime.convT2I‚­$type.[]go/ast.Nodeô­"runtime.growsliceü±2runtime.writebarrieriface̳2runtime.writebarriersliceú³*type.*go/ast.FuncTypeÀ´$runtime.assertI2T2ò¶"type."".tokenNodeˆ· type.go/ast.Node ·@go.itab."".tokenNode.go/ast.Nodeηruntime.convT2I˜º$type.[]go/ast.NodeŠ»"runtime.growslice’¿2runtime.writebarrierifaceâÀ2runtime.writebarrierslice˜Á.type.*go/ast.ReturnStmtÞÁ$runtime.assertI2T2þÃ"type."".tokenNode”Ä type.go/ast.Node¬Ä@go.itab."".tokenNode.go/ast.NodeÚÄruntime.convT2I¤Ç$type.[]go/ast.Node–È"runtime.growslicežÌ2runtime.writebarrierifaceîÍ2runtime.writebarriersliceœÎ.type.*go/ast.AssignStmtâÎ$runtime.assertI2T2ºÏ*go/token.Token.StringšÒ"type."".tokenNode°Ò type.go/ast.NodeÈÒ@go.itab."".tokenNode.go/ast.NodeöÒruntime.convT2IÀÕ$type.[]go/ast.Node²Ö"runtime.growsliceºÚ2runtime.writebarrierifaceŠÜ2runtime.writebarrierslice¸Ü.type.*go/ast.CommClauseþÜ$runtime.assertI2T2¼ß"type."".tokenNodeÒß type.go/ast.Nodeêß@go.itab."".tokenNode.go/ast.Node˜àruntime.convT2Iââ$type.[]go/ast.NodeÔã"runtime.growsliceÜç2runtime.writebarrieriface¬é2runtime.writebarrierslice°ë"type."".tokenNodeÆë type.go/ast.NodeÞë@go.itab."".tokenNode.go/ast.NodeŒìruntime.convT2IÖî$type.[]go/ast.NodeÈï"runtime.growsliceÐó2runtime.writebarrieriface õ2runtime.writebarrierslice¬÷"type."".tokenNodeÂ÷ type.go/ast.NodeÚ÷@go.itab."".tokenNode.go/ast.Nodeˆøruntime.convT2IÒú$type.[]go/ast.NodeÄû"runtime.growsliceÌÿ2runtime.writebarrierifaceœ�2runtime.writebarriersliceè�.type.*go/ast.IncDecStmt®‚$runtime.assertI2T2†ƒ*go/token.Token.Stringæ…"type."".tokenNodeü… type.go/ast.Node”†@go.itab."".tokenNode.go/ast.Node†runtime.convT2IŒ‰$type.[]go/ast.Nodeþ‰"runtime.growslice†Ž2runtime.writebarrierifaceÖ�2runtime.writebarrierslice„�,type.*go/ast.BlockStmtÊ�$runtime.assertI2T2ú’"type."".tokenNode�“ type.go/ast.Node¨“@go.itab."".tokenNode.go/ast.NodeÖ“runtime.convT2IΖ"type."".tokenNodeä– type.go/ast.Nodeü–@go.itab."".tokenNode.go/ast.Nodeª—runtime.convT2I´š$type.[]go/ast.Node¦›"runtime.growslice°Ÿ2runtime.writebarrierifaceÊ 2runtime.writebarrierifaceš¢2runtime.writebarriersliceÈ¢*type.*go/ast.ExprStmtŽ£$runtime.assertI2T2€¤&type.*go/ast.IfStmtƤ$runtime.assertI2T2æ¦"type."".tokenNodeü¦ type.go/ast.Node”§@go.itab."".tokenNode.go/ast.Node§runtime.convT2IŒª$type.[]go/ast.Nodeþª"runtime.growslice†¯2runtime.writebarrierifaceÖ°2runtime.writebarrierslice„±,type.*go/ast.DeferStmtʱ$runtime.assertI2T2â³"type."".tokenNodeø³ type.go/ast.Node�´@go.itab."".tokenNode.go/ast.Node¾´runtime.convT2Iˆ·$type.[]go/ast.Nodeú·"runtime.growslice‚¼2runtime.writebarrierifaceÒ½2runtime.writebarriersliceˆ¾*type.*go/ast.ChanTypeξ$runtime.assertI2T2ªÁ"type."".tokenNodeÀÁ type.go/ast.NodeØÁ@go.itab."".tokenNode.go/ast.Node†Âruntime.convT2IÐÄ$type.[]go/ast.NodeÂÅ"runtime.growsliceÊÉ2runtime.writebarrierifacešË2runtime.writebarriersliceºÍ"type."".tokenNodeÐÍ type.go/ast.NodeèÍ@go.itab."".tokenNode.go/ast.Node–Îruntime.convT2IàÐ$type.[]go/ast.NodeÒÑ"runtime.growsliceÚÕ2runtime.writebarrierifaceª×2runtime.writebarriersliceÊÙ"type."".tokenNodeàÙ type.go/ast.NodeøÙ@go.itab."".tokenNode.go/ast.Node¦Úruntime.convT2IðÜ$type.[]go/ast.NodeâÝ"runtime.growsliceêá2runtime.writebarrierifaceºã2runtime.writebarriersliceèã.type.*go/ast.CaseClause®ä$runtime.assertI2T2ìæ"type."".tokenNode‚ç type.go/ast.Nodešç@go.itab."".tokenNode.go/ast.NodeÈçruntime.convT2I’ê$type.[]go/ast.Node„ë"runtime.growsliceŒï2rLine truncated
"".&nŸ"type.*go/ast.Node "".~r2ß type.go/ast.Node "".len¯type.int "".posÿ"type.go/token.Pos "".~r2ß type.go/ast.Node "".lenïtype.int "".pos¿ "type.go/token.Pos "".~r2ß␍ type.go/ast.Node "".lenïtype.int "".pos¿""type.go/token.Pos "".~r2ß  type.go/ast.Node "".lenïtype.int "".pos¿"type.go/token.Pos "".~r2ß type.go/ast.Node "".lenïtype.int "".pos¿#"type.go/token.Pos "".~r2ß  type.go/ast.Node "".lenïtype.int "".pos¿!"type.go/token.Pos "".~r2ß type.go/ast.Node "".lenïtype.int "".posÿ!"type.go/token.Pos "".~r2ß type.go/ast.Node "".len¯type.int "".posÿ"type.go/token.Pos "".~r2ß
 type.go/ast.Node "".len¯type.int "".posÿ#"type.go/token.Pos "".~r2ß type.go/ast.Node "".len¯type.int "".posÿ "type.go/token.Pos "".~r2ß type.go/ast.Node "".len¯type.int "".posÿ""type.go/token.Pos "".~r2ß  type.go/ast.Node "".len¯type.int "".pos¿$"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".lenÏtype.int "".posŸ!"type.go/token.Pos "".~r2¿ type.go/ast.Node "".lenÏtype.int "".posÿ$"type.go/token.Pos "".~r2Ÿ  type.go/ast.Node "".len¯type.int "".posŸ"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".lenÏtype.int "".pos¿%"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".lenïtype.int "".posŸ#"type.go/token.Pos "".~r2¿ type.go/ast.Node "".lenÏtype.int "".posŸ$"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".len�type.int "".posŸ "type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".lenÏtype.int "".posß%"type.go/token.Pos "".~r2Ÿ
 type.go/ast.Node "".lenÏtype.int "".posŸ""type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenÏtype.int "".posŸ%"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenÏtype.int "".posÿ%"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".len�type.int "".posß "type.go/token.Pos "".~r2ß type.go/ast.Node "".len�type.int "".posß$"type.go/token.Pos "".~r2Ÿ␍ type.go/ast.Node "".lenŸtype.int "".posß""type.go/token.Pos "".~r2Ÿ  type.go/ast.Node "".len�type.int "".posï%"type.go/token.Pos "".~r2ß type.go/ast.Node "".lenßtype.int "".pos¯%"type.go/token.Pos "".~r2ß type.go/ast.Node "".lenßtype.int "".posß"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".len�type.int "".posÏ%"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".len�type.int "".posß#"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".len�type.int "".pos�%"type.go/token.Pos "".~r2Ÿ  type.go/ast.Node "".len¿type.int "".posß!"type.go/token.Pos "".~r2Ÿ type.go/ast.Node "".lenÿtype.int "".pos�&"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".len¿type.int "".pos�""type.go/token.Pos "".~r2¿ type.go/ast.Node "".lenŸtype.int "".pos� "type.go/token.Pos "".~r2ÿ  type.go/ast.Node "".lenŸtype.int "".pos�$"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenŸtype.int "".pos�!"type.go/token.Pos "".~r2ÿ␍ type.go/ast.Node "".lenŸtype.int "".pos�#"type.go/token.Pos "".~r2ÿ  type.go/ast.Node "".lenŸtype.int "".pos�"type.go/token.Pos "".~r2¿ type.go/ast.Node "".len¿type.int "".posÏ#"type.go/token.Pos "".~r2ÿ
 type.go/ast.Node "".lenßtype.int "".posÏ!"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenßtype.int "".posÏ""type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenßtype.int "".posÏ "type.go/token.Pos "".~r2ÿ  type.go/ast.Node "".lenßtype.int "".posÏ$"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenÿtype.int "".pos¯""type.go/token.Pos "".~r2¿ type.go/ast.Node "".len¿type.int "".pos¯ "type.go/token.Pos "".~r2¿
 type.go/ast.Node "".len¿type.int "".pos¯$"type.go/token.Pos "".~r2¿ type.go/ast.Node "".len¿type.int "".pos¯!"type.go/token.Pos "".~r2¿ type.go/ast.Node "".len¿type.int "".pos¯#"type.go/token.Pos "".~r2¿  type.go/ast.Node "".len¿type.int "".posÏ"type.go/token.Pos "".~r2¿ type.go/ast.Node "".lenÿtype.int "".posï#"type.go/token.Pos "".~r2¿  type.go/ast.Node "".lenÿtype.int "".posï!"type.go/token.Pos "".~r2¿ type.go/ast.Node "".lenÿtype.int "".posï""type.go/token.Pos "".~r2¿  type.go/ast.Node "".lenÿtype.int "".posï "type.go/token.Pos "".~r2¿␍ type.go/ast.Node "".lenÿtype.int "".posï$"type.go/token.Pos "".~r2¿ type.go/ast.Node "".lenßtype.int "".pos¯"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenßtype.int "".posï"type.go/token.Pos "".~r2ÿ type.go/ast.Node "".lenŸtype.int "".posï"type.go/token.Pos "".~r2ÿ type.go/ast.Node"".nÿ type.go/ast.Node"".nŸ,type.*go/ast.UnaryExpr"".nÿ6type.*go/ast.TypeAssertExpr"".nß,type.*go/ast.SliceExpr"".n¿,type.*go/ast.RangeStmt"".nŸ,type.*go/ast.ParenExpr"".nÿ,type.*go/ast.IndexExpr"".nï.type.*go/ast.IncDecStmt"".nï(type.*go/ast.GenDecl"".n¯*type.*go/ast.FuncDecl"".n¯,type.*go/ast.FieldList"".n�2type.*go/ast.CompositeLit"".n�.type.*go/ast.CommClause"".nÏ.type.*go/ast.CaseClause"".nï*type.*go/ast.CallExpr"".nÏ.type.*go/ast.BranchStmt"".n�,type.*go/ast.BlockStmt"".nß.type.*go/ast.BinaryExpr"".n¿.type.*go/ast.AssignStmt"".nÿ,type.*go/ast.ArrayType "".~r1 $type.[]go/ast.Node% 'äŸ' 'Æÿ
Єâôu ­†x3‰�°òV �÷˜îýÆÆÊÊÆþý:::::óH¾�È…[�êèô…�Öñ°…PÂéèÂ…L¨ñÞ…Hî阅f¶èÐ…L0¼Ö…Hê¼…˜þñˆ…H¢ñd…[öò�…L½è…H8êðòÈ…[¤¼âßÚ…HôóPäñ"…HÔýêÕ.…qÜá訅��î…PÌñ:…LÎ鸅HÀñF…[†éß~…LÆñ@…H�é«t…ŸôóP¸êèL…HôófĵþýLæñ …H–␍ñì…Pšñl…L½ö…Hn ù
úŠ�ù{[Ô½²…L&éèÞ…Hôó[ÆñÀ…H ñæ…PZ ñ¤©ñ¨¡ñ …HF ù
ú²µùY!Æ 0P=S-àx|w‡Þ„hÑx†7[}µÞ„hñ„hÚ„hù„hù„hñ„h-¯ÊÞ„hIÇêþ…Mh6†Þ„h>Æêþ…Mh:¾Þ„h:²Þ„hTµÞ„h:,"ÝÞ„h:($Ý!Þ„h:ŠÞ„h:ºÞ„hI¿Þ„h:,&Þ#Þ„ h:Ã(êþ…Mh¾%Þ„hI,2³„hŸþ…Mh:�Þ„h:Ö:êêž…MM1h_¾Fêþ/…Mh6–Þ„ h>¾Þ„h:Þ„h:ºÞ„hIÆJáþ3…Mh:¾Þ„ h:ÂNOÞþ9…MhEäTêþ=…@MEh:ˆZ�´C…FMKhA¾Þ„ h:ÇÞ„h>¾Þ„h:,`Þ]Þ„h:ÍbÞ„h°_Þ„h´`Þ„hIa,jÞgÞ„ h:ÆlêþU…@MEh:šÞ„ h:ºÞ„ h>ÜÞ„hœ„ hœ„ h:ÍpÞ„h°mÞ„ h´nÞ„h+Tgclocals·b02d744eb17eeda8e05eb668c4e722c3Tgclocals·cdc8cb48d8885d0f7f3cf4dadd793db1®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".byPos.Len H‹\$H‰\$ Ã@ "".~r00type.int
"".sltype."".byPos¨Tgclocals·13d3af77a5bf02af6db4588efb2ea811Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".byPos.Less „eH‹ %H;awèëêHƒì(H‹\$0H‹l$HL‹D$8L9щHkíHëH‹ H‹kH‰l$ H‰,$H‰L$H‹Y(ÿÓH‹\$H‰\$H‹\$0H‹l$PL‹D$8L9ÅsBHkíHëH‹ H‹kH‰l$ H‰,$H‰L$H‹Y(ÿÓH‹D$H‹\$H9Ã|
ÆD$XHƒÄ(ÃÆD$Xëôè è
 0runtime.morestack_noctxt¤
¤
ê$runtime.panicindexø$runtime.panicindex`P
"".autotmp_0739/"type.go/token.Pos "".~r2Ptype.bool"".j@type.int"".i0type.int
"".sltype."".byPosP’OP#Ь
R~Tgclocals·1d34c988be6c2d215996051490e513b2Tgclocals·d64e51a4c4bfeaa840e480961ec6b0b3®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".byPos.SwapàÎeH‹ %H;awèëêHƒì(H‹T$HH‹L$0H‹D$8H‰ËH‰ÕH9ƒ¨HkíHëH‹+H‰l$H‹kH‰l$ H‰ËH‰ÕH9Âs~HkíHëH‰$H‹l$PH‰ËH9Ås_HkíHëH�l$H‰ïH‰ÞH¥H¥èH‹\$0H‹l$PL‹D$8L9Ås)HkíHëH‰$H‹\$H‰\$H‹\$ H‰\$èHƒÄ(Ãè è è è 
 0runtime.morestack_noctxt”2runtime.writebarrieriface„2runtime.writebarrieriface˜$runtime.panicindex¦$runtime.panicindex´$runtime.panicindexÂ$runtime.panicindexPP"".autotmp_0743 type.go/ast.Node"".j@type.int"".i0type.int
"".sltype."".byPosP°OP%ð²)�%‰8/Tgclocals·aa3b86c1ca8acadbe172378c24a491bcTgclocals·cb9af6b3d97a54a99a5776dfe54028e3®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ$"".NodeDescriptionàtÊteH‹ %H�D$ÀH;AwèëåH�ìÀHÇ„$ØHÇ„$àH‹Œ$ÈH‹„$ÐH‰L$hH‰ $H‰D$pH‰D$èH‹T$hH‹L$p‹D$=RΞe‡=ä’H‡u=Ns;/‡ž=¡<ý‡i‰D$<= §␍u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=‰kÏu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=¡<ýuOH�H‰$H‰T$H‰L$èH‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH�œ$˜HÇHÇCH�œ$˜Hƒû„HÇD$@HÇD$HH‰œ$¨H‹\$@H‰œ$°H‹\$HH‰œ$¸H‹œ$ÈH‰$H‹œ$ÐH‰\$èH‹\$H‰\$XH‹\$H‰\$`H‹œ$¨H‰$H‹\$XH‰\$H‹\$`H‰\$èH�H�,$H‰ïH‰ÞH¥H¥H‹œ$¨H‰\$H‹œ$°H‰\$H‹œ$¸H‰\$ èH‹\$(H‰\$xH‹\$0H‰œ$€H�H‰$H�\$xH‰\$èH�\$H�,$H‰ïH‰ÞH¥H¥è ‰éâþÿÿ‰D$<=Gžõu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=´~‚u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Ns;/…âýÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„µýÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ= Û5‡*‰D$<=~␍#2u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Zîv3u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ= Û5…­üÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„€üÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ={-#?‡Æ‰D$<=KO«6u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ={-#?…ÜûÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„¯ûÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÉD$<=4ù @u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ä’H…ûÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„éúÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=bY~W‡ð=%ÚN‡!‰D$<=¡©ƒJ…H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹l$¶\$ €û„àH‹mH‰l$PH‹\$PHƒûAfH‹\$PHƒû=u&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH‹\$PHƒûA…úÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH‹\$PHƒûEu&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH‹\$PHƒûI…©ùÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=·š×L…ŽH�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹l$¶\$ €û„SH�œ$˜HÇHÇCH�œ$˜Hƒû„#HÇD$@HÇD$HH‰œ$¨H‹\$@H‰œ$°H‹\$HH‰œ$¸H�H‰$H‰l$Hƒ|$„ÇHƒD$èH‹\$H‰\$XH‹\$H‰\$`H‹œ$¨H‰$H‹\$XH‰\$H‹\$`H‰\$èH�H�,$H‰ïH‰ÞH¥H¥H‹œ$¨H‰\$H‹œ$°H‰\$H‹œ$¸H‰\$ èH‹\$(H‰œ$ˆH‹\$0H‰œ$�H‹œ$ˆH‰œ$ØH‹œ$�H‰œ$àH�ÄÀÉ%é-ÿÿÿ‰éÖþÿÿ=%ÚN…ß÷ÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„²÷ÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=F¯4U‡Æ‰D$<=ÛZðQu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=F¯4U…÷ÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„áöÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÉD$<=¡ç]Uu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=bY~W…HöÿÿH�H‰$H‰T$H‰L$èH‹L$¶\$ €û„öÿÿH�œ$˜HÇHÇCH�œ$˜Hƒû„#HÇD$HHÇD$@H‰œ$¨H‹\$HH‰œ$°H‹\$@H‰œ$¸H�H‰$H‰L$Hƒ|$„ÇHƒD$èH‹\$H‰\$XH‹\$H‰\$`H‹œ$¨H‰$H‹\$XH‰\$H‹\$`H‰\$èH�H�,$H‰ïH‰ÞH¥H¥H‹œ$¨H‰\$H‹œ$°H‰\$H‹œ$¸H‰\$ èH‹\$(H‰œ$ˆH‹\$0H‰œ$�H‹œ$ˆH‰œ$ØH‹œ$�H‰œ$àH�ÄÀÉ%é-ÿÿÿ‰éÖþÿÿ=«Òf[‡ä‰D$<=½Œ7Xu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=;JZu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=«Òf[…æóÿÿH�H‰$H‰T$H‰L$èH‹D$¶\$ €û„¹óÿÿH‹hH‰l$PH‹\$PHƒûKfH‹\$PHƒû@u&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH‹\$PHƒûK…eóÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH‹\$PHƒûTu&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH‹\$PHƒûU…ÿòÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ø‘ç]‡Æ‰D$<=
ò]u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ø‘ç]…[òÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„.òÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÉD$<=/_u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=RΞe…•ñÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„hñÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ==ÊO·‡Ë=Bj –‡e=Ë4{j‡*‰D$<=€+Ëeu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=èZòeu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Ë4{j…JðÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„ðÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Ø4‹‡Æ‰D$<=^�su]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Ø4‹…yïÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„LïÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÉD$<=;¦5‘…òH�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹l$¶\$ €û„·H�=H‰<$Hƒý„šH�mH�|$H‰îH¥H¥èH�\$H�,$H‰ïH‰ÞH¥H¥èH‹\$H‰œ$ˆH‹t$H‰´$�H�5H�,$H‰ïH¥H¥H‹œ$ˆH‰\$H‹œ$�H‰\$èH‹\$ H‰œ$ØH‹\$(H‰œ$àH�ÄÀÉEé^ÿÿÿ=Bj –…îÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„ííÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=í�‡*‰D$<=¼—u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Å÷£šu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=í�…åìÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„¸ìÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=<
.¤‡U‰D$<=ÒÄË u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=<
.¤…ìÿÿH�H‰$H‰T$H‰L$èH‹D$¶\$ €û„çëÿÿH�=H‰<$Hƒø„™H�(H�|$H‰îH¥H¥èH�\$H�,$H‰ïH‰ÞH¥H¥èH‹\$H‰œ$ˆH‹\$H‰œ$�H‹œ$ˆH‰$H‹´$�H‰t$H�5H�l$H‰ïH¥H¥èH‹\$ H‰œ$ØH‹\$(H‰œ$àH�ÄÀÉé`ÿÿÿ‰D$<=àö³u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ==ÊO·…¿êÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„’êÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=­õ©Ò‡ü=Ÿ¾Æ‡*‰D$<=X#V»u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ="8:½u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=Ÿ¾Æ…éÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„RéÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ˆp=̇ƉD$<=…Þ Çu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ˆp=Ì…®èÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„�èÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÉD$<=ÜïÎu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=­õ©Ò…èçÿÿH�H‰$H‰T$H‰L$èH‹D$¶\$ €û„»çÿÿH‹XHƒû%u&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ËGÞ‡*‰D$<=‘yç×u]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ÜÛu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=ËGÞ…ƒæÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„VæÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=õmç‡Æ‰D$<=Vù¼æu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=õmç…²åÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„…åÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÉD$<=±zùîu]H�H‰$H‰T$H‰L$èH‹T$hH‹L$p‹D$<H‹\$¶\$ €ût&H�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃ=5·‹ü…ìäÿÿH�H‰$H‰T$H‰L$èH‹\$¶\$ €û„¿äÿÿH�H‹+H‰¬$ØH‹kH‰¬$àH�ÄÀÃŒ
*0runtime.morestack_noctxt¼$runtime.ifacethashÔ.type.*go/ast.ImportSpecú$runtime.assertI2T2Â@go.string."import specification"œ,type.*go/ast.EmptyStmtÂ$runtime.assertI2T2Š6go.string."empty statement"ä*type.*go/ast.SendStmtŠ$runtime.assertI2T20go.string."channel send"êruntime.convI2EÜ 2runtime.writebarrierifaceê Hgo.string."unexpected node type: %T"Þ
fmt.Sprintfš type.stringÀ runtime.convT2Eð runtime.gopanic¦ $type.*go/ast.FieldÌ $runtime.assertI2T2” Dgo.string."field/method/parameter"î *type.*go/ast.FuncDecl”$runtime.assertI2T2Ü@go.string."function declaration"¾$type.*go/ast.Identä$runtime.assertI2T2˜,go.string."identifier"�2type.*go/ast.CompositeLit$runtime.assertI2T2þ:go.string."composite literal"Ø,type.*go/ast.ValueSpecþ$runtime.assertI2T2Æ>go.string."value specification"¨(type.*go/ast.ForStmtÎ$runtime.assertI2T2‚(go.string."for loop"ú,type.*go/ast.FieldList $runtime.assertI2T2èNgo.string."field/method/parameter list"Ê*type.*go/ast.Ellipsisð$runtime.assertI2T2¤(go.string."ellipsis"†2type.*go/ast.KeyValueExpr¬$runtime.assertI2T2ôBgo.string."key/value association"Ö&type.*go/ast.GoStmtü$runtime.assertI2T2°0go.string."go statement"Æ.type.*go/ast.BranchStmtì$runtime.assertI2T2ú6go.string."break statement"ä<go.string."continue statement"ÆDgo.string."fall-through statement"° 4go.string."goto statement"’!,type.*go/ast.UnaryExpr¸!$runtime.assertI2T2Â#&type.go/token.Token‚$runtime.convT2Eô$2runtime.writebarrieriface‚%<go.string."unary %s operation"ö%fmt.SprintfÄ'(type.*go/ast.Commentê'$runtime.assertI2T2ž(&go.string."comment"–)(type.*go/ast.MapType¼)$runtime.assertI2T2„*(go.string."map type"æ*.type.*go/ast.SelectStmtŒ+$runtime.assertI2T2À+8go.string."select statement"¢,0type.*go/ast.LabeledStmtÈ,$runtime.assertI2T2�-6go.string."statement label"ò-.type.*go/ast.BinaryExpr˜.$runtime.assertI2T2†0&type.go/token.TokenÆ0runtime.convT2E¸12runtime.writebarrierifaceÆ1>go.string."binary %s operation"º2fmt.Sprintfž4*type.*go/ast.CallExprÄ4$runtime.assertI2T2Œ5Rgo.string."function call (or conversion)"æ5(type.*go/ast.BadStmtŒ6$runtime.assertI2T2Ô62go.string."bad statement"¶7(type.*go/ast.GenDeclÜ7$runtime.assertI2T2Î8@go.string."constant declaration"¸9<go.string."import declaration"š:8go.string."type declaration"„;@go.string."variable declaration"ü;2type.*go/ast.CommentGroup¢<$runtime.assertI2T2ê<2go.string."comment group"Ì=6type.*go/ast.TypeSwitchStmtò=$runtime.assertI2T2¦>.go.string."type switch"ˆ?6type.*go/ast.TypeAssertExpr®?$runtime.assertI2T2ö?4go.string."type assertion"Ø@,type.*go/ast.IndexExprþ@$runtime.assertI2T2²A8go.string."index expression"ÖB2type.*go/ast.SelectorExprüB$runtime.assertI2T2ÄC(go.string."selector"žD*type.*go/ast.BasicLitÄD$runtime.assertI2T2ŒE2go.string."basic literal"îE.type.*go/ast.SwitchStmt”F$runtime.assertI2T2ÈF8go.string."switch statement"ÀG"type.*go/ast.FileæG$runtime.assertI2T2®H.go.string."source file"�I*type.*go/ast.StarExpr¶I$runtime.assertI2T2êI.go.string."*-operation"ÔJ,type.*go/ast.ParenExprúJ$runtime.assertI2T2ÊK type.go/ast.Node�Lruntime.convI2IÀL$"".NodeDescription‚M4go.string."parenthesized "ÖM*runtime.concatstring2ÎN.type.*go/ast.StructTypeôN$runtime.assertI2T2¨O.go.string."struct type" P,type.*go/ast.RangeStmtÆP$runtime.assertI2T2ŽQ,go.string."range loop"èQ*type.*go/ast.TypeSpecŽR$runtime.assertI2T2ÖR<go.string."type specification"¸S(type.*go/ast.FuncLitÞS$runtime.assertI2T2’T8go.string."function literal"ŠU,type.*go/ast.SliceExpr°U$runtime.assertI2T2øU8go.string."slice expression"ÚV*type.*go/ast.DeclStmt€W$runtime.assertI2T2´W type.go/ast.NodeøWruntime.convI2I¨X$"".NodeDescriptionœY,go.string." statement"¾Y*runtime.concatstring2´Z,type.*go/ast.ArrayTypeÚZ$runtime.assertI2T2¢[,go.string."array type"„\4type.*go/ast.InterfaceTypeª\$runtime.assertI2T2Þ\4go.string."interface type"ì](type.*go/ast.BadDecl’^$runtime.assertI2T2Ú^6go.string."bad declaration"´_(type.*go/ast.BadExprÚ_$runtime.assertI2T2¢`4go.string."bad expression"„a*type.*go/ast.FuncTypeªa$runtime.assertI2T2Þa2go.string."function type"Öb.type.*go/ast.ReturnStmtüb$runtime.assertI2T2Äc8go.string."return statement"¦d.type.*go/ast.AssignStmtÌd$runtime.assertI2T2€e,go.string."assignment"âe.type.*go/ast.CommClauseˆf$runtime.assertI2T2Ðf@go.string."commLine truncated
&&½MÖ&Õ> &8f&eM°&¯8Z&YBB&A8>1ú]§°z1FÌiÌih^hxËzzih^h—z…Ì£h^hÌihbK›ÌihíhtÌih^h™Ìih^hITgclocals·d97de2143caef5f2043ed3922c693858Tgclocals·350783fe72ac2d4150d0f21cc760a81a®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".AddImportàÐeH‹ %H;awèëêHƒì8H‹\$@H‰$H‹\$HH‰\$H�\$HÇHÇCH‹\$PH‰\$ H‹\$XH‰\$(è¶\$0ˆ\$`HƒÄ8Ã
 0runtime.morestack_noctxt¬""".AddNamedImportPp"".added@type.bool"".ipath type.string"".f"type.*go/ast.File"".fset,type.*go/token.FileSetpMo p
$V
UTgclocals·6e5d4a330d25067342b1b461a5d19024Tgclocals·3280bececceccd33cb74587feedb1f9fª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ""".AddNamedImport€Aø@eH‹ %H�„$�þÿÿH;AwèëâH�ìðH‹œ$H‰$H‹œ$H‰\$H‹œ$ H‰\$è¶\$€ûtÆ„$(H�ÄðÃH‹œ$H‰$H‹œ$ H‰\$èH‹\$H‰œ$8H‹\$H‰œ$@H�H‰$èH‹|$H‰¼$ðHƒÿ„l1ÀèH�H‰$èH‹|$H‰ùHƒÿ„<1ÀèHÇA H‰Œ$èH‰ $Hƒ<$„
Hƒ$H‹œ$8H‰\$H‹œ$@H‰\$èH‹œ$ðH‰$Hƒ<$„ÃHƒ$H‹œ$èH‰\$èH‹œ$ðH‰œ$˜H‹œ$Hƒû„’H�H‰$èH‹|$H‰ùHƒÿ„a1ÀèH‰Œ$àH‰ $Hƒ<$„7Hƒ$H‹œ$H‰\$H‹œ$H‰\$èH‹œ$˜H‰$Hƒ<$„ð␍Hƒ$H‹œ$àH‰\$èHÇD$pÿÿÿÿHÇD$HÿÿÿÿHÇ„$ HÇD$`ÿÿÿÿH‹œ$Hƒû„™␍H‹SH‹K H‹k(H‰¬$è1ÀH‰Œ$àH‰Œ$€H‰”$ØH‰ÑH‹¬$€H9è�èH‰ËH‰Œ$ØHƒù„;␍H‹ H‹kH‰„$ˆH‰D$hH‰Œ$(H‰¬$0H�H‰$H‰Œ$H‰L$H‰¬$H‰l$èH‹L$¶\$ €ûtNH‹YHƒûKuDH‹t$hH‰t$HH‰Œ$¨H‰ $H�5H�l$H‰ïH¥H¥èH‹Œ$¨¶\$€û„ H‹Œ$ØH‹„$ˆHƒÁHÿÀH‹¬$€H9èŒÿÿÿH‹œ$ 1íH9ë…sH�H‰$èH‹t$HH‹”$H‹|$H‰ùHƒÿ„®
1ÀèHÇAKH‰Œ$ HƒþŒN Hƒú„= H‹ZH‹B H‹j(H‰¬$èH‰œ$ØH‰õH‰„$àH9ƃ HkíHëH‹ H‹kH‰¬$0H‰,$H‰Œ$(H‹Y ÿÓH‹D$H‹œ$ H‰CH‹œ$Hƒû„´H‹SH‹K H‹[(H‰”$ØH‰Œ$àH‰œ$èH‰ØH)ËHƒû}OH�H‰$H‰”$�H‰T$H‰Œ$˜H‰L$H‰„$ H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰ÓH‰ÂH‰ØH‰ÍHkíHëHÇHÇCH‰„$�H‰´$˜H‰”$ H‹œ$H‰$Hƒ<$„ÒHƒ$H‰„$ØH‰D$H‰´$àH‰t$H‰”$èH‰T$èH‹L$HH‹”$H‰ÎHƒÁL‹b(L‹B I9È‚uI‰ËH‰ðHÿÀL‹R(H‹z H9Ç‚TI‰ÁH‹rI)ÈL‰ãH)ËH‰ÙHƒût␍L‰ÛHÁãHóH‰ÞI‰óL‰ÆH‰Œ$ H‹JH‰úH)ÂL‰ÓH)ÃH‰ØHƒût␍L‰ËHÁãHËH‰ÙH‰ÏH‰„$èH‰´$˜H‰ðH‰”$àH9ò}H‰ÐL‰œ$�L‰$H‰¼$ØH‰|$H‰ÃHÁãH‰\$èH‹œ$ H‰œ$ÈH‹\$HHÿÃH‰œ$€H‹1íH9è„FH‹œ$Hƒû„-H‹SH‹K H‹k(H‰¬$ H‰ÓH‰”$�H‹¬$€H‰Œ$˜H9̓îHkíHëH‰$H‹Œ$ÈH‰„$(H‰D$H‰Œ$0H‰L$èHÇD$XH‹\$`Hƒû|␍H‹\$`HÿÃH‰\$XH‹œ$ Hƒû„‚H‹S H‹K(H‹[0H‰”$ÀH‰Œ$ÈH‰œ$ÐH‰ØH)ËHƒû}OH�H‰$H‰”$xH‰T$H‰Œ$€H‰L$H‰„$ˆH‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰ÓH‰ÂH‰ØH‰ÍHkíHëHÇHÇCH‰„$xH‰´$€H‰”$ˆH‹œ$ H‰$Hƒ<$„ Hƒ$ H‰„$ÀH‰D$H‰´$ÈH‰t$H‰”$ÐH‰T$èH‹L$XH‹”$ H‰ÎHÿÁL‹R0L‹B(I9È‚DI‰ÉL‹Z0H‹z(H‰ðH9÷‚&I‰ôH‹r I)ÈL‰ÓH)ËH‰ÙHƒût␍L‰ËHÁãHóH‰ÞI‰ñL‰ÆH‰Œ$ˆH‹J H‰úH)ÂL‰ÛH)ÃH‰ØHƒût␍L‰ãHÁãHËH‰ÙH‰ÏH‰„$ÐH‰´$€H‰ðH‰”$ÈH9ò}H‰ÐL‰Œ$xL‰ $H‰¼$ÀH‰|$H‰ÃHÁãH‰\$èH‹œ$˜H‰œ$ðH‹1íH9è„(H‹œ$ Hƒû„H‹S H‹K(H‹k0H‰¬$ˆH‰ÓH‰”$xH‹l$XH‰Œ$€H9̓ÓHkíHëH‰$H‹Œ$ðH‰„$H‰D$H‰Œ$ H‰L$èH‹T$XH‹Œ$ H‹AHƒú~qH‰ÐHÿÈH‰ËH‹Q H‹I(H‹k0H‰¬$ÐH‰ÓH‰”$ÀH‰ÅH‰Œ$ÈH9ȃGHkíHëH‹ H‹kH‰¬$ H‰,$H‰Œ$H‹Y(ÿÓH‹Œ$ H‹D$H‹œ$˜H‹[H‰H‹œ$˜H‰C H‹i(Hƒý…MHÇAH‹œ$Hƒû„,H‹S8H‹K@H‹[HH‰”$`H‰Œ$hH‰œ$pH‰ØH)ËHƒû}OH�H‰$H‰”$HH‰T$H‰Œ$PH‰L$H‰„$XH‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$PH‰„$XH‰”$HH�ÊH‰$H‹œ$˜H‰\$èH‹”$HH‹Œ$PH‹„$XH‹œ$H‰$Hƒ<$tAHƒ$8H‰”$`H‰T$H‰Œ$hH‰L$H‰„$pH‰D$èÆ„$(H�ÄðÉ%붉éÍþÿÿH‹iHƒý…‚1À<…£þÿÿH‰ËHƒùtkH‹I H‹C(H‹k0H‰¬$ÐH‰ËH‰Œ$ÀHƒøH‰„$Èv7H‹ H‹kH‰¬$ H‰,$H‰Œ$H‹Y(ÿÓH‹D$H‹œ$ H‰Cé6þÿÿè ‰ë‘HÇÀétÿÿÿè è ‰éêüÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$é¦üÿÿè è ‰%éTûÿÿ‰éwúÿÿè ‰éÌùÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$éˆùÿÿè è ‰%é"øÿÿ‰éE÷ÿÿè ‰é¼öÿÿH‹jH‰iH‹œ$øH‰$H‹jH‰l$èH‹D$H‰„$°H‰$H‹œ$H‹kH‰l$èH‹\$H‰\$@H‹œ$Hƒû„ÓH‹ShH‹CpH‹kxH‰¬$¸1ÉH‰„$°H‰„$€H‰”$¨H‰ÐH‹¬$€H9é�~öÿÿH‰„$ÀH‹(H‰Œ$ˆH‰¬$¸H‰,$èH‹D$H‹œ$°H‰$H‰D$èH‹\$H‹l$@H9ë~é+öÿÿH‹œ$¸H‰$èH‹D$H‹œ$ H‰CH‹„$ÀH‹Œ$ˆHƒÀHÿÁé^ÿÿÿ‰é&ÿÿÿ‰éKõÿÿH‹i(HƒýuH‹\$pHƒûÿuH‰Œ$ H‰ËHƒù„@H‹Q H‹I(H‹k0H‰¬$Ð1ÀH‰Œ$ÈH‰L$xH‰”$ÀH‰ÑH‹l$xH9è�{ôÿÿH‰ËH‰Œ$ÐHƒù„èH‹ H‹kH‰„$�H‰D$PH‰Œ$H‰¬$ H�H‰$H‰Œ$øH‰L$H‰¬$H‰l$èH‹\$H‰$èH‹L$H‹D$H‰Œ$8H‰ $H‰„$@H‰D$H‹œ$H‰\$H‹œ$ H‰\$èH‹D$ H‹l$pH9è~H‰D$pH‹œ$¨H‰œ$ H‹\$PH‰\$`H‹Œ$ÐH‹„$�HƒÁHÿÀéõþÿÿ‰éÿÿÿ‰é¹þÿÿ‰é¾òÿÿ‰é`òÿÿ‰%éòÿÿ‰%é½ñÿÿ‰é˜ñÿÿ‰%é1ñÿÿ‰%éêðÿÿ‰é½ðÿÿ‰é�ðÿÿŠ
00runtime.morestack_noctxt˜"".importsˆstrconv.QuoteÊ,type.go/ast.ImportSpecÜ"runtime.newobject˜ì runtime.duffzero¦(type.go/ast.BasicLit¸"runtime.newobjectêð runtime.duffzeroð4runtime.writebarrierstringÌ.runtime.writebarrierptrž"type.go/ast.Ident°"runtime.newobjectâð runtime.duffzeroØ4runtime.writebarrierstring´.runtime.writebarrierptrª (type.*go/ast.GenDeclð $runtime.assertI2T2Ü go.string."C"þ "".declImports®&type.go/ast.GenDeclÀ"runtime.newobjectŒà runtime.duffzeroˆ
¸$type.[]go/ast.Declª"runtime.growsliceØ2runtime.writebarriersliceªruntime.memmoveøFgo.itab.*go/ast.GenDecl.go/ast.Decl†2runtime.writebarrierifaceÚ$type.[]go/ast.SpecÌ"runtime.growsliceú 2runtime.writebarriersliceÄ$runtime.memmoveò$Lgo.itab.*go/ast.ImportSpec.go/ast.Specú&2runtime.writebarrierifaceô(
þ*2type.[]*go/ast.ImportSpecð+"runtime.growsliceþ,.runtime.writebarrierptr¶.2runtime.writebarriersliceØ0
Š1$runtime.panicindex¸1$runtime.panicindexÆ1$runtime.panicindexæ1.type.*go/ast.ImportSpecü1 type.go/ast.Spec”2Lgo.itab.*go/ast.ImportSpec.go/ast.Spec¨2 runtime.typ2ItabÆ2$runtime.panicsliceÔ2$runtime.panicsliceˆ3$runtime.panicindex¨3(type.*go/ast.GenDecl¾3 type.go/ast.DeclÖ3Fgo.itab.*go/ast.GenDecl.go/ast.Declê3 runtime.typ2Itabˆ4$runtime.panicslice–4$runtime.panicsliceÊ4$runtime.panicindex 50go/token.(*FileSet).Fileî5*go/token.(*File).Lineò74go/ast.(*CommentGroup).Pos¨8*go/token.(*File).Lineò84go/ast.(*CommentGroup).End´<.type.*go/ast.ImportSpecú<"runtime.assertI2T–="".importPathš>"".matchLenpà¼"".autotmp_0863type.uint64"".autotmp_0862type.uint64"".autotmp_0861type.int"".autotmp_0860type.int"".autotmp_0859Ï2type.[]*go/ast.ImportSpec"".autotmp_0858Ÿ2type.[]*go/ast.ImportSpec"".autotmp_0857type.bool"".autotmp_0856type.*uint8"".autotmp_0855type.uintptr"".autotmp_0854type.int"".autotmp_0853$type.[]go/ast.Spec"".autotmp_0852$type.[]go/ast.Spec"".autotmp_0851type.uintptr"".autotmp_0850type.uint64"".autotmp_0849type.uint64"".autotmp_0848type.uint64"".autotmp_0847type.uintptr"".autotmp_0846type.uint64"".autotmp_0845type.uint64"".autotmp_0844type.uint64"".autotmp_0843type.int"".autotmp_0842type.uint64"".autotmp_0841type.uint64"".autotmp_0840type.int"".autotmp_0839type.int"".autotmp_0838ï$type.[]go/ast.Spec"".autotmp_0837$type.[]go/ast.Spec"".autotmp_0835type.int"".autotmp_0834type.uintptr"".autotmp_0833type.int"".autotmp_0832$type.[]go/ast.Decl"".autotmp_0831$type.[]go/ast.Decl"".autotmp_0826type.int"".autotmp_0825type.uintptr"".autotmp_0823type.uint64"".autotmp_0822type.uint64"".autotmp_0821type.int"".autotmp_0818type.int"".autotmp_0817type.int"".autotmp_0816¿$type.[]go/ast.Decl"".autotmp_0815$type.[]go/ast.Decl"".autotmp_0813ß4type.**go/ast.CommentGroup"".autotmp_0812type.int"".autotmp_0811type.int"".autotmp_0810Ï(type.*go/ast.GenDecl"".autotmp_0809¯ type.go/ast.Spec"".autotmp_0808¿"type.*go/ast.Spec"".autotmp_0807ïtype.int"".autotmp_0806type.int"".autotmp_0805� type.go/ast.Decl"".autotmp_0804¯"type.*go/ast.Decl"".autotmp_0803ßtype.int"".autotmp_0802Ïtype.int"".autotmp_0801Ÿ$type.*go/ast.Ident"".autotmp_0800�*type.*go/ast.BasicLit"".autotmp_0799ÿ.type.*go/ast.ImportSpec"".autotmp_07982type.[]*go/ast.ImportSpec"".autotmp_0797"type.go/token.Pos"".autotmp_0796type.int"".autotmp_0795"type.go/token.Pos"".autotmp_0794.type.*go/ast.ImportSpec"".autotmp_0793$type.[]go/ast.Spec"".autotmp_0792(type.*go/ast.GenDecl"".autotmp_0791$type.[]go/ast.Decl"".autotmp_0790"type.go/token.Pos"".autotmp_0789type.int"".autotmp_0788"type.go/token.Pos"".autotmp_0787�6type.[]*go/ast.CommentGroup"".autotmp_0786type.int"".autotmp_0782type.string"".autotmp_0781_$type.[]go/ast.Spec"".autotmp_0780¿type.int"".autotmp_0779type.bool"".autotmp_0778/$type.[]go/ast.Decl"".autotmp_0777ïtype.string"".insertAt¯type.int"".cï2type.*go/ast.CommentGroup"".pkgLineßtype.int"".fileÿ&type.*go/token.File"".specï type.go/ast.Spec"".j¿type.int "".gen�(type.*go/ast.GenDecl"".declÏ type.go/ast.Decl"".i�type.int"".impIndexŸtype.int"".impDeclŸ(type.*go/ast.GenDecl"".lastImportÏtype.int"".bestMatchÿtype.int"".newImport¯.type.*go/ast.ImportSpec"".added`type.bool"".ipath@type.string"".name type.string"".f"type.*go/ast.File"".fset,type.*go/token.FileSet(%àDßàÄßà‘ À Ú:%5 8.l. ’    �4
: (:>
s"¦Ü®  ␍¦Ø¨q  ¥ h   @@! ,g; "#'‚/P

*  |Kb.\.2T.ÞGa¥
³␍ G\’ORL'‚@„„Tgclocals·9f0cbf1ce8a0c588a35eb032ac79e3dbTgclocals·c9b1535c379046c28c79b2669f0279ffª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".DeleteImport /œ/eH‹ %H�„$ˆþÿÿH;AwèëâH�ìøH‹”$Æ„$ HÇ„$àHÇ„$èHÇ„$ð1ÀH‹j H9è�þH‰ÓH‹RH‹K H‹k(H‰¬$ H‰ÓH‰”$H‰ÅH‰D$`H‰Œ$H9ȃ$ HkíHëH‹ H‹kH�H‰$H‰Œ$�H‰L$H‰¬$˜H‰l$èH‹”$H‹D$¶\$ €û„[H‹XHƒûK…M1ÉH‹h(H9é�>H‰ÃH‰D$xH‹P H‹@(H‹k0H‰¬$H‰ÓH‰”$øH‰ÍH‰L$PH‰„$H9Áƒm
HkíHëH‹ H‹kH�H‰$H‰Œ$€H‰L$H‰¬$ˆH‰l$èH‹D$H‰D$pH‰$èH‹´$H‹”$H‹D$xH‹|$H‹L$H9ñ…„ H‰¼$ÐH‰<$H‰Œ$ØH‰L$H‹¬$H‰l$H‰t$èH‹”$H‹D$x¶\$ €û„9 H‹”$àH‹Œ$èH‹œ$ðH‰ØH)ËHƒû}OH�H‰$H‰”$ˆH‰T$H‰Œ$�H‰L$H‰„$˜H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$�H‰„$˜H‰”$ˆH�ÊH‰$H‹\$pH‰\$èH‹t$PH‹T$xH‹¬$ˆH‹Œ$�H‹„$˜H‰¬$àH‰Œ$èH‰„$ðÆ„$ L‹b0L‹B(H‰ñI9ð‚ªI‰óH‰ðHÿÀL‹R0H‹z(H9Ç‚‰I‰ÁH‹r I)ÈL‰ãH)ËH‰ÙHƒût␍L‰ÛHÁãHóH‰ÞI‰óH‰Œ$H‹J H‰úH)ÂL‰ÓH)ÃH‰ØHƒût␍L‰ËHÁãHËH‰ÙH‰ÎH‰„$€L‰„$L‰ÀH‰”$xL9Â}H‰ÐL‰œ$øL‰$H‰´$pH‰t$H‰ÃHÁãH‰\$èH‹”$H‹D$xH‹H(HÿÉH‹p0H9΂ºH‹x H‰¼$pH‰x H‰Œ$xH‰H(H‰´$€H‰p0H‹h(Hƒý…ÚL‹Z(H‹z H‹L$`H9Ï‚½H‹D$`I‰ÉHÿÀL‹b(L‹B I9À‚šI‰ÂH‹rH)ÏL‰ÛH)ËH‰ÙHƒût␍L‰ËHÁãHóH‰ÞI‰ñH‰Œ$ H‹JL‰ÂH)ÂL‰ãH)ÃH‰ØHƒût␍L‰ÓHÁãHËH‰ÙH‰ÎH‰„$hH‰¼$H‰øH‰”$`H9ú}H‰ÐL‰Œ$L‰ $H‰´$XH‰t$H‰ÃHÁãH‰\$èH‹”$H‹B HÿÈH‹J(H9Á‚ÐH‹rH‰´$XH‰rH‰„$`H‰B H‰Œ$hH‰J(H‹\$`HÿËH‰\$`H‹D$`HÿÀH‹j H9èŒûÿÿ1öH‹j@H9î�H‹J8H‹B@H‹jHH9ƃ[H�ñL‹H‹Œ$àL‹Œ$èH‹œ$ðH‰œ$È1ÀL‰Œ$ÀH‰Œ$¸L9È�OH‹)H‰D$XI9è…üL‹bHL‹B@H‰ðI9ð‚áI‰óH‰ñH‰t$hHÿÁL‹RHH‹z@H9Ï‚»I‰ÉH‹r8I)ÀL‰ãH)ÃH‰ØHƒût␍L‰ÛHÁãHóH‰ÞI‰óH‰„$˜H‹B8H‰úH)ÊL‰ÓH)ËH‰ÙHƒût␍L‰ËHÁãHÃH‰ØH‰ÆH‰Œ$PL‰„$�L‰ÀH‰”$HL9Â}H‰ÐL‰œ$ˆL‰$H‰´$@H‰t$H‰ÃHÁãH‰\$èL‹¬$àL‹¤$èL‹œ$ðL‹T$XH‹”$H‹B@HÿÈH‹JHH9Á‚ÔH‹r8H‰r8H‰B@H‰JHM‰ÙL‰ÑM9Ô‚®M‰ÐL‰ÐHÿÀM‰ÚL‰æI9Ä‚�I‰ÃL‰êL‰çH)ÏL‰ËH)ËH‰ÙHƒût␍L‰ÃHÁãHÓH‰ÚI‰ÐH‰Œ$PL‰éH‰òH)ÂL‰ÓH)ÃH‰ØHƒût␍L‰ÛHÁãHËH‰ÙH‰ÎH‰„$˜H‰¼$HH‰øH‰”$�H9ú}H‰ÐL‰„$@L‰$H‰´$ˆH‰t$H‰ÃHÁãH‰\$èH‹”$H‹„$èHÿÈH‹Œ$ðH9Á‚¼H‹¬$àH‰¬$àH‰„$èH‰Œ$ðH‹t$hHÿÎHÿÆH‹j@H9îŒJýÿÿH‹œ$èHƒûŽjH‹œ$àH‰œ$ H‹œ$èH‰œ$¨H‹œ$ðH‰œ$°H�œ$ÀHÇHÇCH�œ$ÀHƒû„
HÇÂHÇÁH‰œ$(H‰”$0H‰Œ$8H�H‰$H�œ$ H‰\$èH‹L$H‹D$H‹œ$(H‰$H‰Œ$ H‰L$H‰„$¨H‰D$èH�H�,$H‰ïH‰ÞH¥H¥H‹œ$(H‰\$H‹œ$0H‰\$H‹œ$8H‰\$ èH‹\$(H‰œ$°H‹\$0H‰œ$¸H�H‰$H�œ$°H‰\$èH�\$H�,$H‰ïH‰ÞH¥H¥è ‰éïþÿÿH�ÄøÃè è è è è è HƒÁHÿÀéÞûÿÿè è è è H‹h(Hƒý…—HÇ@H‹\$PHƒûŽH�H‰$H‹L$PHÿÉH‰ÃHƒø„YH‹P H‹@(H‹k0H‰¬$H‰ÓH‰”$øH‰ÍH‰„$H9ÁƒHkíHëH�l$H‰ïH‰ÞH¥H¥èH‹D$H‹œ$H‰$H‹XH‹+H‰l$èH�\$H�¬$ÐH‰ïH‰ÞèH‹œ$èH‰\$HH‹œ$H‰$H‹\$pH‹[H‹+H‰l$èH‹”$H‹D$xH�\$H�¬$ÐH‰ïH‰ÞèH‹œ$èH‰\$@H‹l$HH)ëHƒû~H‹\$PHÿËH‰\$PH‹L$PHÿÁé¯õÿÿH‹œ$H‰$H‹h8H‰l$èH‹\$H‰$H‹\$@H‰\$èH‹”$H‹D$xë¥è ‰é þÿÿélþÿÿè è è è è ^
00runtime.morestack_noctxtè(type.*go/ast.GenDecl®$runtime.assertI2T2È.type.*go/ast.ImportSpecŽ"runtime.assertI2T´"".importPathä runtime.eqstringð2type.[]*go/ast.ImportSpecâ "runtime.growsliceê
.runtime.writebarrierptr˜runtime.memmoveøruntime.memmoveæruntime.memmove–runtime.memmoveþ"2type.[]*go/ast.ImportSpecª#runtime.convT2E”$2runtime.writebarrieriface¢$pgo.string."deleted specs from Decls but not Imports: %v"–%fmt.SprintfØ%type.string„&runtime.convT2E´&runtime.gopanicà&$runtime.panicsliceî&$runtime.panicsliceü&$runtime.panicsliceŠ'$runtime.panicslice˜'$runtime.panicslice¦'$runtime.panicsliceÌ'$runtime.panicindexÚ'$runtime.panicsliceè'$runtime.panicsliceö'$runtime.panicsliceÒ(.type.*go/ast.ImportSpec *"runtime.assertI2Tä*8go/token.(*FileSet).Position”+ô runtime.duffcopyò+8go/token.(*FileSet).Position¼,ô runtime.duffcopyÚ-0go/token.(*FileSet).FileŠ.4go/token.(*File).MergeLine².$runtime.panicindexØ.$runtime.panicsliceæ.$runtime.panicsliceô.$runtime.panicslice‚/$runtime.panicindex�/$runtime.panicindexPðÊ"".autotmp_0998¯"type.interface {}"".autotmp_0996Ÿ&type.[]interface {}"".autotmp_0995type.uint64"".autotmp_0994type.uint64"".autotmp_0993type.int"".autotmp_0992type.uintptr"".autotmp_0991type.int"".autotmp_09902type.[]*go/ast.ImportSpec"".autotmp_09892type.[]*go/ast.ImportSpec"".autotmp_0988type.uintptr"".autotmp_0987type.uint64"".autotmp_0986type.uint64"".autotmp_0985type.uint64"".autotmp_0984type.int"".autotmp_0983type.uintptr"".autotmp_0982type.uint64"".autotmp_0981type.uint64"".autotmp_0980type.uint64"".autotmp_0979type.uint64"".autotmp_0978type.uint64"".autotmp_0977type.int"".autotmp_0976type.uintptr"".autotmp_0975type.int"".autotmp_0974ï2type.[]*go/ast.ImportSpec"".autotmp_09732type.[]*go/ast.ImportSpec"".autotmp_0972type.uintptr"".autotmp_0971type.uint64"".autotmp_0970type.uint64"".autotmp_0969type.uint64"".autotmp_0968type.int"".autotmp_0967type.uintptr"".autotmp_0966type.uint64"".autotmp_0965type.uint64"".autotmp_0964type.uint64"".autotmp_0961type.int"".autotmp_0960type.int"".autotmp_0959type.uint64"".autotmp_0958type.uint64"".autotmp_0957type.int"".autotmp_0956type.uintptr"".autotmp_0955type.int"".autotmp_0954¿$type.[]go/ast.Decl"".autotmp_0953$type.[]go/ast.Decl"".autotmp_0952type.uintptr"".autotmp_0951type.uint64"".autotmp_0950type.uint64"".autotmp_0949type.uint64"".autotmp_0948type.int"".autotmp_0947type.uintptr"".autotmp_0946type.uint64"".autotmp_0945type.uint64"".autotmp_0944type.uint64"".autotmp_0943type.uint64"".autotmp_0942type.uint64"".autotmp_0941type.int"".autotmp_0940type.uintptr"".autotmp_0939type.int"".autotmp_0938�$type.[]go/ast.Spec"".autotmp_0937$type.[]go/ast.Spec"".autotmp_0932type.int"".autotmp_0931type.uintptr"".autotmp_0929type.uint64"".autotmp_0928type.uint64"".autotmp_0923ß2type.[]*go/ast.ImportSpec"".autotmp_0922�type.string"".autotmp_0921¯2type.[]*go/ast.ImportSpec"".autotmp_0920ï(type.[1]interface {}"".autotmp_0919type.int"".autotmp_0918type.int"".autotmp_0917type.int"".autotmp_0916type.int"".autotmp_0915type.int"".autotmp_09142type.[]*go/ast.ImportSpec"".autotmp_0913type.int"".autotmp_0910type.int"".autotmp_0908,type.go/token.Position"".autotmp_0907O,type.go/token.Position"".autotmp_0906type.int"".autotmp_0905type.int"".autotmp_0904type.int"".autotmp_0903type.int"".autotmp_0902type.int"".autotmp_09012type.[]*go/ast.ImportSpec"".autotmp_0900Ïtype.string"".autotmp_0899type.int"".autotmp_0898type.int"".j¿type.int"".iŸtype.int"".lineïtype.int"".lastLineßtype.int"".impspec�.type.*go/ast.ImportSpec"".specï type.go/ast.Spec"".jÏtype.int "".genÿ(type.*go/ast.GenDecl"".declÏ type.go/ast.Decl"".i¯type.int"".delspecs¯2type.[]*go/ast.ImportSpec"".deleted@type.bool"".path type.string"".f"type.*go/ast.File"".fset,type.*go/token.FileSet%ð‰ïð¡Ðöœ5$I<N/� ââ<á<␍1fC ÿ$×<ê 7sBO␍O␍J? NÖ°×D—°Ù
v7.ài 8Tgclocals·c5ed0d16b268810424fec496daca103bTgclocals·bebe621981fff19b96c50a522b62dfb4ª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ "".RewriteImport ’eH‹ %H;awèëêH�ì€Æ„$¸H‹œ$�Hƒû„KH‹S8H‹C@H‹kHH‰l$x1ÉH‰D$pH‰D$(H‰T$hH‰ÐH‹l$(H9é�H‰D$@H‹(H‰L$0H‰l$8H‰,$èH‹Œ$ H‹T$H‹D$H9È…²H‰T$XH‰$H‰D$`H‰D$H‹¬$˜H‰l$H‰L$è¶\$ €ût~Æ„$¸H‹\$8H‰$èH‹D$H‹\$8H‰C H‹œ$¨H‰$H‹œ$°H‰\$èH‹L$H‹D$H‹\$8H‹kH‰,$Hƒ<$tEHƒ$H‰L$HH‰L$H‰D$PH‰D$èH‹D$@H‹L$0HƒÀHÿÁH‹l$(H9éŒùþÿÿH�ĀÉ%벉é®þÿÿ
 0runtime.morestack_noctxt‚"".importPathŒ runtime.eqstringÌ0go/ast.(*ImportSpec).End¤strconv.Quoteœ4runtime.writebarrierstringp€"".autotmp_10550type.**go/ast.ImportSpec"".autotmp_1054¯type.int"".autotmp_1053Ÿtype.int"".autotmp_1052otype.string"".autotmp_1050Otype.string"".autotmp_1049/2type.[]*go/ast.ImportSpec "".imp�.type.*go/ast.ImportSpec"".rewrote`type.bool"".newPath@type.string"".oldPath type.string"".f"type.*go/ast.File"".fset,type.*go/token.FileSet€Ûÿ€�,¶%R]Z  €ÍCTgclocals·aa0e8f76dd9a8794b45f8e6f5acad5f3Tgclocals·6b8f94768ba5968b1b94e44b07985fdaª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".UsesImportàÖeH‹ %H�D$àH;AwèëåH�ì Æ„$ÀH�H‰$èH‹\$H‰\$PH‹œ$¨H‰$H‹œ$°H‰\$H‹œ$¸H‰\$èH‹D$H‰D$(1íH9èuH‹\$P¶+@ˆ¬$ÀH�Ä ÃH�H‰$èH‹T$H‹\$(H‹C1íH9è„—Hƒø„†H‹HH‹@H‰T$XH‰$H‰L$`H‰L$H‰D$hH‰D$èH‹\$XH‹ H‰Œ$�H‹CHƒøufH‰ $H‰„$˜H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$�H‹„$˜¶\$ €ût H‹\$PÆH‹\$P¶+@ˆ¬$ÀH�Ä ÃHƒø…‰H‰ $H‰„$˜H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$�H‹„$˜¶\$ €û„?H‹œ$°H‰$H‹´$¸H‰t$H�5H�l$H‰ïH¥H¥èH‹¼$°H‹t$XH‹Œ$¸H‹D$ Hƒøÿ…˜H‰4$H‰|$H‰L$èH�H‰$èH‹D$H�-H‰(H‰D$8H‰$Hƒ<$„FHƒ$H‹\$XH‰\$èH‹\$8H‰$Hƒ<$„Hƒ$H‹\$PH‰\$èH‹\$8H‰\$HH‹œ$¨H‰\$@H‹5H‰t$01íH9î„™H‹1íH9ètTH‹T$HH‰´$€H‰4$H‰”$ˆH‰T$H‹L$@H‰D$pH‰D$H‰L$xH‰L$èH‹\$P¶+@ˆ¬$ÀH�Ä ÃH�H‰$H�H‰\$H�H‰\$èH‹t$0H‹D$éuÿÿÿH�H‰$H�H‰\$H�H‰\$èH‹t$H‰t$0é0ÿÿÿ‰%éâþÿÿ‰%é®þÿÿHÿÀH‰ÊH‰ÁH9Âr=H‰4$H‰øH)ÊHƒút H‰ËHÃH‰ØH‰„$�H‰D$H‰”$˜H‰T$èé0þÿÿè H‰„$˜Hƒø…þÿÿH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û… ýÿÿéàýÿÿ‰ésüÿÿH�H‹ H‹CéhüÿÿH
*0runtime.morestack_noctxtZtype.booll"runtime.newobjectÖ"".importSpectype.stringÈ"runtime.newobjectâ4runtime.writebarrierstringÆgo.string."."î runtime.eqstring¦"go.string."<nil>"Î runtime.eqstringÊgo.string."/"ì"strings.LastIndexÚ4runtime.writebarrierstringè^type.struct { F uintptr; A0 *string; A1 *bool }ú"runtime.newobject’ "".func·003è .runtime.writebarrierptr¸
.runtime.writebarrierptrô
Bgo.itab."".visitFn.go/ast.Visitor¢ @go.itab.*go/ast.File.go/ast.Node¨ go/ast.Walkæ "type.*go/ast.Fileü  type.go/ast.Node”␍@go.itab.*go/ast.File.go/ast.Node¨␍ runtime.typ2ItabÔ␍type."".visitFnê␍&type.go/ast.Visitor‚Bgo.itab."".visitFn.go/ast.Visitor– runtime.typ2Itabð4runtime.writebarrierstring„$runtime.panicsliceÌgo.string."_"ô runtime.eqstring"go.string."<nil>"@À"".autotmp_1067ßtype.*uint8"".autotmp_1066Ï`type.*struct { F uintptr; A0 *string; A1 *bool }"".autotmp_1063type.uint64"".autotmp_1062type.int"".autotmp_1061type.string"".autotmp_1060¿"type.*go/ast.File"".autotmp_1059¯type."".visitFn"".&usedŸtype.*bool"".&name�type.*string "".~r0type.string"".specï.type.*go/ast.ImportSpec"".pathtype.string"".f"type.*go/ast.File6"Àu¿ÀÜ¿Àº¿ÀÀðlÒD0 85]LTK
ç†FD)>559MF¿~ @ 7m
87Tgclocals·8540a2071a4dff4808f1c5123a5b6cd4Tgclocals·c1aa14cbd9772efa50f3b411dbc91d2bª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ "".visitFn.VisitàÈeH‹ %H;awèëêHƒì(HÇD$HHÇD$PH‹\$8H‰$H‹\$@H‰\$H‹T$0H‹ÿÓH‹\$0H‰\$ H‹1íH9ètH‹\$ H‰\$PH‰D$HHƒÄ(ÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë½
 0runtime.morestack_noctxtŽ
¬Bgo.itab."".visitFn.go/ast.Visitorðtype."".visitFn†&type.go/ast.VisitoržBgo.itab."".visitFn.go/ast.Visitor² runtime.typ2ItabPP"".autotmp_1076type."".visitFn "".~r10&type.go/ast.Visitor"".node type.go/ast.Node
"".fntype."".visitFnPZOP;°–,gGQTgclocals·2d29ece705ad6fb4c36ae535e41922d5Tgclocals·e1ae6533a9e39048ba0735a2264ce16aª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".importsÀ²eH‹ %H;awèëêHƒì H‹\$(H‰$H‹\$0H‰\$H‹\$8H‰\$èH‹\$1íH9ëu
ÆD$@HƒÄ ÃÆD$@ëô
 0runtime.morestack_noctxtp"".importSpec@@ "".~r20type.bool"".pathtype.string"".f"type.*go/ast.File@7?@` ¢F
7)Tgclocals·e0dd5664695c71438932a711825a98a4Tgclocals·3280bececceccd33cb74587feedb1f9fª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".importSpec –eH‹ %H;awèëêHƒìpH‹\$xHƒû„ÛH‹S8H‹C@H‹kHH‰l$h1ÉH‰D$`H‰D$(H‰T$XH‰ÐH‹l$(H9é�—H‰D$@H‹(H‰L$0H‰l$8H‰,$èH‹Œ$ˆH‹T$H‹D$H9ÈuFH‰T$HH‰$H‰D$PH‰D$H‹¬$€H‰l$H‰L$è¶\$ €ûtH‹\$8H‰œ$�HƒÄpÃH‹D$@H‹L$0HƒÀHÿÁH‹l$(H9éŒiÿÿÿHÇ„$�HƒÄpÉéÿÿÿ
 0runtime.morestack_noctxtæ"".importPathè runtime.eqstring@à"".autotmp_1084_0type.**go/ast.ImportSpec"".autotmp_1083�type.int"".autotmp_1082type.int"".autotmp_1081Otype.string"".autotmp_1080/2type.[]*go/ast.ImportSpec"".so.type.*go/ast.ImportSpec "".~r20.type.*go/ast.ImportSpec"".pathtype.string"".f"type.*go/ast.File&à¹ßà/ßà � ®OY
  ržTgclocals·9ff42bf311af152488d11f0f78c8d5ceTgclocals·283619d6755c7337ece602447ba790ffª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".importPath  eH‹ %H;awèëêHƒì0HÇD$@HÇD$HH‹t$8H‹~HƒÿtQH�wH�<$H¥H¥èH‹T$H‹L$H‹D$ H‹\$(HƒøuH‰T$@H‰L$HHƒÄ0ÃHÇD$@HÇD$HHƒÄ0Éë«
 0runtime.morestack_noctxt�strconv.Unquote0` "".~r1type.string"".s.type.*go/ast.ImportSpec`Z_`_`�Ä,4
GITgclocals·a08e9001cb8f9d822225de3b8e406515Tgclocals·3280bececceccd33cb74587feedb1f9fª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".declImportsàÊeH‹ %H�D$øH;AwèëåH�ìˆH‹„$�H‹XHƒûKtÆ„$¨H�ĈÃH‰ÃH‹P H‹@(H‹k0H‰¬$€1ÉH‰D$xH‰D$(H‰T$pH‰ÐH‹l$(H9é�ÑH‰D$8Hƒø„ÒH‹H‹hH‰L$0H‰T$PH‰l$XH�H‰$H‰T$@H‰T$H‰l$HH‰l$èH‹\$H‰$èH‹Œ$ H‹T$H‹D$H9ÈuDH‰T$`H‰$H‰D$hH‰D$H‹¬$˜H‰l$H‰L$è¶\$ €ûtÆ„$¨H�ĈÃH‹D$8H‹L$0HƒÀHÿÁH‹l$(H9éŒ/ÿÿÿÆ„$¨H�ĈÉé'ÿÿÿ
*0runtime.morestack_noctxtÊ.type.*go/ast.ImportSpec„"runtime.assertI2T "".importPath¢ runtime.eqstring@�"".autotmp_1091o type.go/ast.Spec"".autotmp_1090Ÿ"type.*go/ast.Spec"".autotmp_1089¿type.int"".autotmp_1088¯type.int"".autotmp_1087Otype.string"".autotmp_1086/$type.[]go/ast.Spec"".spec� type.go/ast.Spec "".~r20type.bool"".pathtype.string "".gen(type.*go/ast.GenDecl2"�!��ê��.��ð,Ö*
^)T  Á¯Tgclocals·9ff42bf311af152488d11f0f78c8d5ceTgclocals·642113c69b05a0b78729ce0d19febc89ª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".matchLenààeH‹ %H;awèëêL‹T$H‹|$H‹t$H‹T$ 1ÀH9ð}+H9Ð}&H9ðs.I�H9ÐsH�,¶m@8ëuHÿÀH9ð|ÕH‰D$(Ãè è 
 0runtime.morestack_noctxtÆ$runtime.panicindexÔ$runtime.panicindexP "".~r2@type.int"".y type.string"".xtype.stringpp ò*(
bTgclocals·f271231f400e778e0f59be25f7a26a56Tgclocals·3280bececceccd33cb74587feedb1f9fª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".isTopName †eH‹ %H;awèëêHƒì@H�H‰$H‹\$HH‰\$H‹\$PH‰\$èH‹L$`H‹T$¶\$ €ûtfH‰ÓH‰T$(Hƒút_H‹RH‹CH9ÈuKH‰T$0H‰$H‰D$8H‰D$H‹l$XH‰l$H‰L$è¶\$ €ûtH‹l$(H‹]1íH9ëu
ÆD$hHƒÄ@ÃÆD$hëô‰ë�
 0runtime.morestack_noctxt:$type.*go/ast.Identt$runtime.assertI2T2  runtime.eqstringP€
"".autotmp_1095type.string
"".id/$type.*go/ast.Ident "".~r2@type.bool"".name type.string"".n type.go/ast.Expr€�€Ð„3ƒ9VATgclocals·a971fb01c4253c6f983871ebc3812753Tgclocals·61e2515c69061b8fed0e66ece719f936ª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".ImportsàÈeH‹ %H�„$ðþÿÿH;AwèëâH�ì�HÇ„$¨HÇ„$°HÇ„$¸HÇ„$ØHÇ„$àHÇ„$èH‹œ$ Hƒû„ÞH‹SH‹C H‹k(H‰¬$`1ÉH‰„$XH‰D$hH‰”$PH‰ÐH‹l$hH9é�GH‰„$�Hƒø„‰H‹H‹hH‰L$pH‰”$ÈH‰¬$ÐH�H‰$H‰”$¨H‰T$H‰¬$°H‰l$èH‹L$¶\$ €û„ÜH‰Œ$€H‹YHƒûK…ÆH�H‰$èH‹\$Hƒû„ô1Ò1ÉH‰œ$ðH‰”$øH‰Œ$HÇD$PH‹œ$€Hƒû„¶H‹K H‹C(H‹k0H‰¬$H1ÒH‰„$@H‰D$`H‰Œ$8H‰ÈH‹l$`H9ê�H‰„$ˆHƒø„aH‹0H‹hH‰T$XH‰´$¸H‰¬$ÀH�H‰$H‰´$˜H‰t$H‰¬$ H‰l$èH‹D$H‰D$xH‹XH‹+H‹œ$˜H‰$H‰l$@H‰l$èH‹T$PH�\$H�¬$hH‰ïH‰ÞèH‹„$€H‰D$HHƒúŽXH‹\$@HƒûŽIH‰ÃH)ÓHƒûŽ9H‹”$ØH‹Œ$àH‹„$èH‰ÃH)ËHƒû}OH�H‰$H‰”$ H‰T$H‰Œ$(H‰L$H‰„$0H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰ÓH‰´$(H‰„$0H‰”$ H‰ÍHkíHëH‰$H‹œ$ðH‰\$H‹œ$øH‰\$H‹œ$H‰\$èH‹”$ H‹Œ$(H‹„$0H‰”$ØH‰Œ$àH‰„$èH�H‰$èH‹\$Hƒû„x1Ò1ÉH‰œ$ðH‰”$øH‰Œ$H‹”$ðH‹Œ$øH‹„$H‰ÃH)ËHƒû}OH�H‰$H‰”$H‰T$H‰Œ$H‰L$H‰„$H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$H‰„$H‰”$H�ÊH‰$H‹\$xH‰\$èH‹”$H‹Œ$H‹„$H‰”$ðH‰Œ$øH‰„$H‹\$HH‰\$PH‹„$ˆH‹T$XHƒÀHÿÂH‹l$`H9êŒìüÿÿH‹”$ØH‹Œ$àH‹„$èH‰ÃH)ËHƒû}OH�H‰$H‰”$ H‰T$H‰Œ$(H‰L$H‰„$0H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰ÓH‰´$(H‰„$0H‰”$ H‰ÍHkíHëH‰$H‹œ$ðH‰\$H‹œ$øH‰\$H‹œ$H‰\$èH‹”$ H‹Œ$(H‹„$0H‰”$ØH‰Œ$àH‰„$èH‹„$�H‹L$pHƒÀHÿÁH‹l$hH9錹úÿÿH‹œ$ØH‰œ$¨H‹œ$àH‰œ$°H‹œ$èH‰œ$¸H�Ä�Éé�ýÿÿ‰é˜ûÿÿ‰éCûÿÿ‰éûÿÿ‰épúÿÿ‰éúÿÿ*
00runtime.morestack_noctxtØ(type.*go/ast.GenDeclž$runtime.assertI2T2þ4type.[0]*go/ast.ImportSpec�"runtime.newobjectþ.type.*go/ast.ImportSpecÄ"runtime.assertI2Tœ 8go/token.(*FileSet).PositionÖ ô runtime.duffcopy˜ 6type.[][]*go/ast.ImportSpecŠ "runtime.growsliceÞ␍2runtime.writebarriersliceÌ4type.[0]*go/ast.ImportSpecÞ"runtime.newobjectŠ2type.[]*go/ast.ImportSpecü"runtime.growslice„.runtime.writebarrierptr’6type.[][]*go/ast.ImportSpec„"runtime.growsliceØ2runtime.writebarriersliceP H"".autotmp_1126type.uint64"".autotmp_1125type.uint64"".autotmp_1124type.int"".autotmp_1123type.int"".autotmp_11226type.[][]*go/ast.ImportSpec"".autotmp_1121type.uint64"".autotmp_1120type.uint64"".autotmp_1119type.int"".autotmp_1118type.int"".autotmp_1117�2type.[]*go/ast.ImportSpec"".autotmp_11166type.*[0]*go/ast.ImportSpec"".autotmp_1111ß6type.[][]*go/ast.ImportSpec"".autotmp_1110¯ type.go/ast.Spec"".autotmp_1109�"type.*go/ast.Spec"".autotmp_1108type.int"".autotmp_1107type.int"".autotmp_1105� type.go/ast.Decl"".autotmp_1104ÿ"type.*go/ast.Decl"".autotmp_1103Ïtype.int"".autotmp_1102¿type.int"".autotmp_11016type.[][]*go/ast.ImportSpec"".autotmp_1098O,type.go/token.Position"".autotmp_1097¯$type.[]go/ast.Spec"".autotmp_1096$type.[]go/ast.Decl"".line�type.int "".posŸ"type.go/token.Pos"".importSpec¯.type.*go/ast.ImportSpec"".specï type.go/ast.Spec"".lastLineÿtype.int"".group¿2type.[]*go/ast.ImportSpec"".genDeclŸ(type.*go/ast.GenDecl"".declÏ type.go/ast.Decl"".groupsï6type.[][]*go/ast.ImportSpec "".~r2 6type.[][]*go/ast.ImportSpec"".f"type.*go/ast.File"".fset,type.*go/token.FileSet% ” Ÿ 6ð j�I$|4; |/ E)þ;Ø
"þ'".8  :Ž9Ú,·j@ÓÀjÅTgclocals·9e66e6c90082b87eae91256279f90dd0Tgclocals·8893093c930d24f85c727fbb1c785e6bª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".UnparenÀ²eH‹ %H;awèëêHƒì(H‹L$0H‹D$8HÇD$@HÇD$HH�H‰$H‰L$0H‰L$H‰D$8H‰D$èH‹L$¶\$ €ûuH‹\$0H‰\$@H‹\$8H‰\$HHƒÄ(ÃH‰ËHƒùt
H‹IH‹C롉ëò
 0runtime.morestack_noctxtr,type.*go/ast.ParenExpr¬$runtime.assertI2T2@P "".~r1  type.go/ast.Expr"".e type.go/ast.ExprPgOP 6. 
UKTgclocals·78fd77a07ab543a063c3a3049973febeTgclocals·3280bececceccd33cb74587feedb1f9f¤/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/util.goþ"".func·001àÞeH‹ %H�„$`ÿÿÿH;AwèëâH�ì H‹BH‹ZH‰œ$ H‹ZH‰œ$°H‹Z H‰œ$˜H‰„$¨H‹H‹HH‹XH‰ØH)ËHƒû}OH�H‰$H‰”$ðH‰T$H‰Œ$øH‰L$H‰„$H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$øH‰„$H‰ÓH‰”$ðH‰ÍHkíHëH‰$H‹œ$(H‰\$H‹œ$0H‰\$èH‹”$ðH‹Œ$øH‹„$H‹œ$¨H‰$H‰”$H‰T$H‰Œ$H‰L$H‰„$H‰D$èH‹œ$0H‰$H‹œ$(H‹[(ÿÓH‹\$H‰\$@H‹œ$0H‰$H‹œ$(H‹[ ÿÓH‹´$ H‹”$°H‹L$@H‹D$H‹H9Ë}H‰H‹H‰D$HH9Ã~H‰H‹œ$(H‰$H‹œ$0H‰\$èH‹l$H‹L$H‹T$ H‰L$PH‰¬$ØH‰Œ$àH‰”$èH‰”$1ÀH‰Œ$øH‰L$pH‰¬$ðH‰éH‹l$pH9è�qH‰ËH‰Œ$�Hƒù„ÍH‹ H‹kH‰D$xH‰D$XH‰Œ$ÈH‰¬$ÐH‰¬$ÀH‰,$H‰Œ$¸H‹Y(ÿÓH‹\$H‰\$`H‹œ$ÀH‰$H‹œ$¸H‹[ ÿÓH‹L$XH‹\$H‰\$hH‹\$`H‰œ$€H‹D$hH‰„$ˆHƒù~bH‰ËHÿËH‹¬$ØL‹„$àL9ÃHkÛHÝH‹MH‹EH‰„$ÐH‰$H‰Œ$ÈH‹Y ÿÓH‹L$XH‹„$ˆH‹\$H‰œ$€H‹\$PHÿËH9ËŽ…H‰ËHÿÃH‹¬$ØL‹„$àL9ßHkÛHÝH‹MH‹EH‰„$ÐH‰$H‰Œ$ÈH‹Y(ÿÓH‹D$H‹œ$ H‹H‹¬$ˆH9ë| H‹œ$°H‹H9ÃÆ„$8H�Ä ÃH‹œ$ H‹H‹¬$€H9댕H‹œ$°H‹H9Ã��H�H‰$H‹œ$¸H‰\$H‹œ$ÀH‰\$è¶\$€ûuCH‹œ$¸H‰$H‹œ$ÀH‰\$H‹œ$˜H‹H‹ÿÓ¶\$€ûuÆ„$8H�Ä ÃÆ„$8ëîH‹œ$ H‹H‹l$hH9ë}ZH‹œ$°H‹H9Ã~JH‹œ$ H‹H‹l$@H9ëu%H‹œ$°H‹H‹l$HH9ëuÆ„$8H�Ä ÃÆ„$8H�Ä ÃH‹Œ$�H‹D$xHƒÁHÿÀéýÿÿè è ‰é,ýÿÿ$
0"runtime.morestackÞ$type.[]go/ast.NodeÐ"runtime.growsliceŠ2runtime.writebarrierifaceª2runtime.writebarriersliceâ
ª
Ì"".childrenOf¨
ð
Þ
Ä
¨"type."".tokenNodeî&runtime.assertI2TOKØ
$runtime.panicindexÄ$runtime.panicindex0À>"".autotmp_1161¯ type.go/ast.Node"".autotmp_1160Ÿ"type.*go/ast.Node"".autotmp_1159type.int"".autotmp_1158type.int"".autotmp_1154Ïtype.int"".autotmp_1153_$type.[]go/ast.Node"".autotmp_1151"type.go/token.Pos"".autotmp_1150"type.go/token.Pos"".autotmp_1149"type.go/token.Pos"".autotmp_1148"type.go/token.Pos"".autotmp_1147$type.[]go/ast.Node"".autotmp_1146type.int"".autotmp_1145$type.[]go/ast.Node"".autotmp_1144"type.go/token.Pos"".autotmp_1142/$type.[]go/ast.Node"".&visit�8type.*func(go/ast.Node) bool"".&endß$type.*go/token.Pos"".&startÿ$type.*go/token.Pos"".&pathï&type.*[]go/ast.Node"".augEnd¯"type.go/token.Pos"".augPos¿"type.go/token.Pos"".childEndï"type.go/token.Pos"".childPosÿ"type.go/token.Pos"".childÏ type.go/ast.Node"".i�type.int"".lŸtype.int"".children�$type.[]go/ast.Node"".nodeEnd¯"type.go/token.Pos"".nodePos¿"type.go/token.Pos "".~r1 type.bool"".node type.go/ast.Node@%À»¿À¦¿Àh¿À¿À/°
††MŒ$4
␍-~$)␍␍bM(0/R %*_&§]PÀ¢6 ÄTgclocals·f6029ea0d67dffd7eda0400f533b60c8Tgclocals·1a506ebd963062051172dcf732031ab9®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".func·002€èeH‹ %H;awèëêHƒìxH‹¼$€H‹BH‹ZH‰\$@H‹(H9ïuDH‰<$H‹¬$ˆH‰l$L�D$L‰ÇH‰ÆH¥H¥èH‹¼$€¶\$ €ût␍Æ„$�HƒÄxÃHƒÿ„âH‹\$@H‹H‹KH‹[H‰ØH)ËHƒû}NH�H‰$H‰T$HH‰T$H‰L$PH‰L$H‰D$XH‰D$HÇD$ èH‹¼$€H‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰t$PH‰D$XH‰ÓH‰T$HH‰ÍHkíHëH‰$H‰|$H‹œ$ˆH‰\$èH‹T$HH‹L$PH‹D$XH‹\$@H‰$H‰T$`H‰T$H‰L$hH‰L$H‰D$pH‰D$èÆ„$�HƒÄxÃ
 "runtime.morestack°runtime.ifaceeqÈ$type.[]go/ast.Node¨"runtime.growsliceÐ2runtime.writebarrierifaceÆ2runtime.writebarrierslice0ð
"".autotmp_1168_$type.[]go/ast.Node"".autotmp_1167/$type.[]go/ast.Node"".&childreno&type.*[]go/ast.Node "".~r1 type.bool"".node type.go/ast.Node ð`ïðøï␍€ü/?␍
âWÐ;Tgclocals·8ddc77fba2c550c84caa2407b9851a29Tgclocals·3c833c2cb5d04cedcd4b9fca2269862a®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ"".func·003ÀªeH‹ %H;awèëêHƒìpH‹ZH‰\$8H‹ZH‰\$0H�H‰$H‹\$xH‰\$H‹œ$€H‰\$èH‹L$¶\$ €û„ÛH‹\$8H‹3H‹SH‰ËHƒù„ÏH‹ H‹kH‰t$`H‰t$@H‰T$hH‰T$HH�H‰$H‰L$PH‰L$H‰l$XH‰l$èH‹T$HH‹L$¶\$ €ûttH‰ËH‰L$(HƒùtjH‹IH‹CH9ÐuYH‰L$`H‰ $H‰D$hH‰D$H‹l$@H‰l$H‰T$è¶\$ €ût(H‹l$(H‹]1íH9ëuHÇÀ<tH‹\$0ÆHƒÄpÃ1Àëë‰ë’‰é*ÿÿÿ
 "runtime.morestack^2type.*go/ast.SelectorExprž$runtime.assertI2T2º$type.*go/ast.Identô$runtime.assertI2T2  runtime.eqstring à"".autotmp_1178type.string"".autotmp_1176type.string
"".id�$type.*go/ast.Ident"".name_type.string"".n? type.go/ast.Expr"".&usedtype.*bool"".&nameotype.*string"".n type.go/ast.Nodeà«ßààþ,1ÜNkVQTgclocals·d87de576fbb46c1dd747a5e182d23851Tgclocals·dfc48d3ed38d46e45a22f3bd57ac395eª/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/imports.goþ"".initÀ¼eH‹ %H;awèëê€ût€ûuÃè ÆèèèèèÆÃ
 0runtime.morestack_noctxt2"".initdone·J"".initdone·`"runtime.throwinitp"".initdone·|strings.init†strconv.init�go/token.initšgo/ast.init¤fmt.init°"".initdone·```
/1Tgclocals·3280bececceccd33cb74587feedb1f9fTgclocals·3280bececceccd33cb74587feedb1f9f¤/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/util.goþ&"".(*tokenNode).PosàÈeH‹ %H;awèëêHƒì0H‹Y H…Ût␍H�|$8H9;uH‰#H‹\$81íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹\$8HƒûtH‹H‹kH‰D$@HƒÄ0Éëë
 0runtime.morestack_noctxt~&go.string."astutil"¨*go.string."tokenNode"Ôgo.string."Pos"ü"runtime.panicwrap ` "".~r0"type.go/token.Pos""..this$type.*"".tokenNode`…_`°°
}3Tgclocals·06cab038d51064a089bda21fa03e00f7Tgclocals·3280bececceccd33cb74587feedb1f9f<autogenerated>þ&"".(*tokenNode).EndàÈeH‹ %H;awèëêHƒì0H‹Y H…Ût␍H�|$8H9;uH‰#H‹\$81íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹\$8HƒûtH‹+H‹kH‰l$@HƒÄ0Éëë
 0runtime.morestack_noctxt~&go.string."astutil"¨*go.string."tokenNode"Ôgo.string."End"ü"runtime.panicwrap ` "".~r0"type.go/token.Pos""..this$type.*"".tokenNode`…_`°°
}3Tgclocals·06cab038d51064a089bda21fa03e00f7Tgclocals·3280bececceccd33cb74587feedb1f9f<autogenerated>þ"".(*byPos).LenàÐeH‹ %H;awèëêHƒì0H‹Y H…Ût␍H�|$8H9;uH‰#H‹\$81íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹\$8HƒûtH‹+H‹CH‹kH‰D$@HƒÄ0Éëç
 0runtime.morestack_noctxt~&go.string."astutil"¨"go.string."byPos"Ôgo.string."Len"ü"runtime.panicwrap ` "".~r0type.int""..thistype.*"".byPos`‰_` °°
}3Tgclocals·06cab038d51064a089bda21fa03e00f7Tgclocals·3280bececceccd33cb74587feedb1f9f<autogenerated>þ "".(*byPos).Less ŽeH‹ %H;awèëêHƒì0H‹Y H…Ût␍H�|$8H9;uH‰#H‹\$81íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹t$8Hƒþt4H�,$H‰ïH¥H¥H¥H‹\$@H‰\$H‹\$HH‰\$ è¶\$(ˆ\$PHƒÄ0ÉëÈ
 0runtime.morestack_noctxt~&go.string."astutil"¨"go.string."byPos"Ô go.string."Less"ü"runtime.panicwrapâ"".byPos.Less@` "".~r20type.bool"".j type.int"".itype.int""..thistype.*"".byPos`¨_`␍Ð
Ð
}STgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f<autogenerated>þ "".(*byPos).Swap †eH‹ %H;awèëêHƒì`H‹Y H…Ût␍H�|$hH9;uH‰#H‹\$h1íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹\$hHƒû„éH‹H‹KH‹kH‰l$XH‹D$pH‹t$xH‰ÓH‰ÅH9ȃ¹HkíHëH‹+H‰l$8H‹kH‰l$@H‰ÓH‰ÅH9ȃ‹HkíHëH‰$H‰ÓH‰T$HH‰õH‰t$0H‰L$PH9Îs_HkíHëH�l$H‰ïH‰ÞH¥H¥èH‹\$HH‹l$0L‹D$PL9Ås)HkíHëH‰$H‹\$8H‰\$H‹\$@H‰\$èHƒÄ`Ãè è è è ‰éÿÿÿ
 0runtime.morestack_noctxt~&go.string."astutil"¨"go.string."byPos"Ô go.string."Swap"ü"runtime.panicwrap¾2runtime.writebarrieriface®2runtime.writebarrierifaceÂ$runtime.panicindexÐ$runtime.panicindexÞ$runtime.panicindexì$runtime.panicindex0À "".autotmp_1181O type.go/ast.Node"".j_type.int
"".sl/type."".byPos"".j type.int"".itype.int""..thistype.*"".byPosÀÅ¿À0� �}¡8:Tgclocals·5719e95fd01d864484e48bd45fcc377fTgclocals·2ef756eb60fa93116ff3685e4ecee06e<autogenerated>þ4type..hash.[1]interface {}àÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtü(runtime.nilinterhash@` "".autotmp_1184type.int"".autotmp_1183type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".p*type.*[1]interface {}`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ0type..eq.[1]interface {}àÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$hHƒû„–H‰ÅHkíHëH‹ H‹sH‹\$`HƒûtvH‰ÅHkíHëH‹H‹SH9ÈuVH‰D$8H‰$H‰T$@H‰T$H‰L$HH‰L$H‰t$PH‰t$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxtÂruntime.efaceeq@°"".autotmp_1188?"type.interface {}"".autotmp_1187"type.interface {}"".autotmp_1186_type.int"".autotmp_1185Otype.int "".~r30type.bool"".s type.uintptr"".q*type.*[1]interface {}"".p*type.*[1]interface {}&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/ast/astutil/enclosing.goþ&"".(*visitFn).VisitÀ¨eH‹ %H;awèëêHƒì0H‹Y H…Ût␍H�|$8H9;uH‰#HÇD$PHÇD$XH‹\$81íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹\$8H‹+H‰,$H‹\$@H‰\$H‹\$HH‰\$èH‹L$H‹D$ H‰L$PH‰D$XHƒÄ0Ã
 0runtime.morestack_noctxt¢&go.string."astutil"Ì&go.string."visitFn"ø"go.string."Visit" "runtime.panicwrapî "".visitFn.VisitP` "".~r10&type.go/ast.Visitor"".node type.go/ast.Node""..this type.*"".visitFn`¹_␍àà �QTgclocals·57e1009a600f832f844e0e3c49ba5a89Tgclocals·3280bececceccd33cb74587feedb1f9f<autogenerated>þ,@go.itab.*go/ast.File.go/ast.NodeþTgclocals·a1df20860d464b11efcaaf93a370c869PP@ª
@ª@ª²Bª
@ª²@ªBªþTgclocals·b707c77a9bd5ebaa2f42f19cc98ab913PP–––––––þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·f90cfd099b5ec2b453c391fece9d42bbþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·f90cfd099b5ec2b453c391fece9d42bbþ,@go.itab."".tokenNode.go/ast.NodeþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·693fd2e6f4da98598ef49a51d91c93cdþ,Jgo.itab.*go/ast.FieldList.go/ast.Nodeþ,Bgo.itab.*go/ast.Ident.go/ast.Nodeþ,Jgo.itab.*go/ast.BlockStmt.go/ast.Nodeþ,>go.itab."".byPos.sort.InterfaceþFgo.string."unexpected node type %T"PPunexpected node type %T Fgo.string."unexpected node type %T"þTgclocals·cdc8cb48d8885d0f7f3cf4dadd793db1�3�3Db€€ ,,  À  À,ì, ,À €€  , ì À   À ÂÀÀÀÀîÀ.À,€ÀÀÀ€ÀÀ,,À ,À €<<€<þTgclocals·b02d744eb17eeda8e05eb668c4e722c3°°D
þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·13d3af77a5bf02af6db4588efb2ea811þTgclocals·d64e51a4c4bfeaa840e480961ec6b0b3þTgclocals·1d34c988be6c2d215996051490e513b2 BþTgclocals·cb9af6b3d97a54a99a5776dfe54028e3  þTgclocals·aa3b86c1ca8acadbe172378c24a491bc 
BBþ,go.string."array type"@6
array type ,go.string."array type"þ,go.string."assignment"@6
assignment ,go.string."assignment"þ6go.string."bad declaration"@@bad declaration 6go.string."bad declaration"þ4go.string."bad expression"@>bad expression 4go.string."bad expression"þ2go.string."bad statement"@<␍bad statement 2go.string."bad statement"þ2go.string."basic literal"@<␍basic literal 2go.string."basic literal"þ>go.string."binary %s operation"PHbinary %s operation >go.string."binary %s operation"þ"go.string."block"0,block "go.string."block"þ6go.string."break statement"@@break statement 6go.string."break statement"þ<go.string."continue statement"PFcontinue statement <go.string."continue statement"þ4go.string."goto statement"@>goto statement 4go.string."goto statement"þDgo.string."fall-through statement"PNfall-through statement Dgo.string."fall-through statement"þRgo.string."function call (or conversion)"`\function call (or conversion) Rgo.string."function call (or conversion)"þ.go.string."case clause"@8 case clause .go.string."case clause"þ0go.string."channel type"@: channel type 0go.string."channel type"þ@go.string."communication clause"PJcommunication clause @go.string."communication clause"þ&go.string."comment"00comment &go.string."comment"þ2go.string."comment group"@<␍comment group 2go.string."comment group"þ:go.string."composite literal"PDcomposite literal :go.string."composite literal"þ,go.string." statement"@6
statement ,go.string." statement"þ6go.string."defer statement"@@defer statement 6go.string."defer statement"þ(go.string."ellipsis"@2ellipsis (go.string."ellipsis"þ6go.string."empty statement"@@empty statement 6go.string."empty statement"þ@go.string."expression statement"PJexpression statement @go.string."expression statement"þDgo.string."field/method/parameter"PNfield/method/parameter Dgo.string."field/method/parameter"þNgo.string."field/method/parameter list"`Xfield/method/parameter list Ngo.string."field/method/parameter list"þ.go.string."source file"@8 source file .go.string."source file"þ(go.string."for loop"@2for loop (go.string."for loop"þ@go.string."function declaration"PJfunction declaration @go.string."function declaration"þ8go.string."function literal"PBfunction literal 8go.string."function literal"þ2go.string."function type"@<␍function type 2go.string."function type"þ<go.string."import declaration"PFimport declaration <go.string."import declaration"þ@go.string."constant declaration"PJconstant declaration @go.string."constant declaration"þ8go.string."type declaration"PBtype declaration 8go.string."type declaration"þ@go.string."variable declaration"PJvariable declaration @go.string."variable declaration"þ0go.string."go statement"@: go statement 0go.string."go statement"þ,go.string."identifier"@6
identifier ,go.string."identifier"þ0go.string."if statement"@: if statement 0go.string."if statement"þ@go.string."import specification"PJimport specification @go.string."import specification"þ>go.string."increment statement"PHincrement statement >go.string."increment statement"þ>go.string."decrement statement"PHdecrement statement >go.string."decrement statement"þ8go.string."index expression"PBindex expression 8go.string."index expression"þ4go.string."interface type"@>interface type 4go.string."interface type"þBgo.string."key/value association"PLkey/value association Bgo.string."key/value association"þ6go.string."statement label"@@statement label 6go.string."statement label"þ(go.string."map type"@2map type (go.string."map type"þ&go.string."package"00package &go.string."package"þ4go.string."parenthesized "@>parenthesized  4go.string."parenthesized "þ,go.string."range loop"@6
range loop ,go.string."range loop"þ8go.string."return statement"PBreturn statement 8go.string."return statement"þ8go.string."select statement"PBselect statement 8go.string."select statement"þ(go.string."selector"@2selector (go.string."selector"þ0go.string."channel send"@: channel send 0go.string."channel send"þ8go.string."slice expression"PBslice expression 8go.string."slice expression"þ.go.string."*-operation"@8 *-operation .go.string."*-operation"þ.go.string."struct type"@8 struct type .go.string."struct type"þ8go.string."switch statement"PBswitch statement 8go.string."switch statement"þ4go.string."type assertion"@>type assertion 4go.string."type assertion"þ<go.string."type specification"PFtype specification <go.string."type specification"þ.go.string."type switch"@8 type switch .go.string."type switch"þ<go.string."unary %s operation"PFunary %s operation <go.string."unary %s operation"þ>go.string."value specification"PHvalue specification >go.string."value specification"þHgo.string."unexpected node type: %T"`Runexpected node type: %T Hgo.string."unexpected node type: %T"þTgclocals·350783fe72ac2d4150d0f21cc760a81a88°/þTgclocals·d97de2143caef5f2043ed3922c69385888 þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·6e5d4a330d25067342b1b461a5d19024
*þ,Fgo.itab.*go/ast.GenDecl.go/ast.Declþ,Lgo.itab.*go/ast.ImportSpec.go/ast.Specþgo.string."C"0$C go.string."C"þTgclocals·c9b1535c379046c28c79b2669f0279ff¨¨V€ €
**€
ŠŠ
Š
€ þTgclocals·9f0cbf1ce8a0c588a35eb032ac79e3db˜˜*****************þpgo.string."deleted specs from Decls but not Imports: %v"€z,deleted specs from Decls but not Imports: %v pgo.string."deleted specs from Decls but not Imports: %v"þTgclocals·bebe621981fff19b96c50a522b62dfb4°° b 
€ð€ ð ò þTgclocals·c5ed0d16b268810424fec496daca103bXX
*********þTgclocals·6b8f94768ba5968b1b94e44b07985fda((
þTgclocals·aa0e8f76dd9a8794b45f8e6f5acad5f3((***þ,Bgo.itab."".visitFn.go/ast.Visitorþ"go.string."<nil>"0,<nil> "go.string."<nil>"þgo.string."."0$. go.string."."þgo.string."_"0$_ go.string."_"þgo.string."/"0$/ go.string."/"þTgclocals·c1aa14cbd9772efa50f3b411dbc91d2bPP(( €
ˆ
þTgclocals·8540a2071a4dff4808f1c5123a5b6cd4PP
þTgclocals·e1ae6533a9e39048ba0735a2264ce16a þTgclocals·2d29ece705ad6fb4c36ae535e41922d5 
..þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·e0dd5664695c71438932a711825a98a4
þTgclocals·283619d6755c7337ece602447ba790ff 
þTgclocals·9ff42bf311af152488d11f0f78c8d5ce 
þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·a08e9001cb8f9d822225de3b8e406515þTgclocals·642113c69b05a0b78729ce0d19febc89 þTgclocals·9ff42bf311af152488d11f0f78c8d5ce 
þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·f271231f400e778e0f59be25f7a26a56
"þTgclocals·61e2515c69061b8fed0e66ece719f936 þTgclocals·a971fb01c4253c6f983871ebc3812753 
++þTgclocals·8893093c930d24f85c727fbb1c785e6b˜˜ F€ˆ ‚¢‚¢€¢¢  €€€þTgclocals·9e66e6c90082b87eae91256279f90dd0hh
þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·78fd77a07ab543a063c3a3049973febe þTgclocals·1a506ebd963062051172dcf732031ab9pp$¨¨(*.,þTgclocals·f6029ea0d67dffd7eda0400f533b60c8@@ þTgclocals·3c833c2cb5d04cedcd4b9fca2269862a((
þTgclocals·8ddc77fba2c550c84caa2407b9851a29(( þTgclocals·dfc48d3ed38d46e45a22f3bd57ac395e00(ˆ
þTgclocals·d87de576fbb46c1dd747a5e182d2385100 þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·3280bececceccd33cb74587feedb1f9fþ,"".initdone·type.uint8þ6"".PathEnclosingInterval·f0"".PathEnclosingIntervalþ"".func·001·f"".func·001þ*go/ast.(*File).End·f$go/ast.(*File).Endþ&runtime.typ2Itab·f runtime.typ2Itabþ*runtime.panicindex·f$runtime.panicindexþ8runtime.writebarrieriface·f2runtime.writebarrierifaceþ(runtime.growslice·f"runtime.growsliceþ,runtime.throwreturn·f&runtime.throwreturnþ&"".tokenNode.Pos·f "".tokenNode.Posþ&"".tokenNode.End·f "".tokenNode.Endþ"".tok·f "".tokþ$runtime.convT2I·fruntime.convT2Iþ "".childrenOf·f"".childrenOfþ(runtime.newobject·f"runtime.newobjectþ"".func·002·f"".func·002þ4runtime.writebarrierptr·f.runtime.writebarrierptrþ"go/ast.Inspect·fgo/ast.Inspectþ*runtime.ifacethash·f$runtime.ifacethashþ*runtime.assertI2T2·f$runtime.assertI2T2þ8runtime.writebarrierslice·f2runtime.writebarriersliceþ0go/token.Token.String·f*go/token.Token.Stringþ$runtime.convI2E·fruntime.convI2Eþfmt.Sprintf·ffmt.Sprintfþ$runtime.convT2E·fruntime.convT2Eþ$runtime.gopanic·fruntime.gopanicþsort.Sort·fsort.Sortþ"".byPos.Len·f"".byPos.Lenþ "".byPos.Less·f"".byPos.Lessþ "".byPos.Swap·f"".byPos.Swapþ*"".NodeDescription·f$"".NodeDescriptionþ$runtime.convI2I·fruntime.convI2Iþ0runtime.concatstring2·f*runtime.concatstring2þ"".AddImport·f"".AddImportþ("".AddNamedImport·f""".AddNamedImportþ"".imports·f"".importsþ strconv.Quote·fstrconv.Quoteþ:runtime.writebarrierstring·f4runtime.writebarrierstringþ""".declImports·f"".declImportsþ(runtime.assertI2T·f"runtime.assertI2Tþ "".importPath·f"".importPathþ"".matchLen·f"".matchLenþ6go/token.(*FileSet).File·f0go/token.(*FileSet).Fileþ0go/token.(*File).Line·f*go/token.(*File).Lineþ:go/ast.(*CommentGroup).Pos·f4go/ast.(*CommentGroup).Posþ:go/ast.(*CommentGroup).End·f4go/ast.(*CommentGroup).Endþ*runtime.panicslice·f$runtime.panicsliceþ$runtime.memmove·fruntime.memmoveþ$"".DeleteImport·f"".DeleteImportþ&runtime.eqstring·f runtime.eqstringþ>go/token.(*FileSet).Position·f8go/token.(*FileSet).Positionþ:go/token.(*File).MergeLine·f4go/token.(*File).MergeLineþ&"".RewriteImport·f "".RewriteImportþ6go/ast.(*ImportSpec).End·f0go/ast.(*ImportSpec).Endþ "".UsesImport·f"".UsesImportþ "".importSpec·f"".importSpecþ(strings.LastIndex·f"strings.LastIndexþ"".func·003·f"".func·003þgo/ast.Walk·fgo/ast.Walkþ&"".visitFn.Visit·f "".visitFn.Visitþ$strconv.Unquote·fstrconv.Unquoteþ"".isTopName·f"".isTopNameþ"".Imports·f"".Importsþ"".Unparen·f"".Unparenþ,runtime.assertI2TOK·f&runtime.assertI2TOKþ$runtime.ifaceeq·fruntime.ifaceeqþ"".init·f"".initþ(runtime.throwinit·f"runtime.throwinitþstrings.init·fstrings.initþstrconv.init·fstrconv.initþ go/token.init·fgo/token.initþgo/ast.init·fgo/ast.initþfmt.init·ffmt.initþbruntime.gcbits.0x48844400000000000000000000000000 H„Dþ,go.string."[]ast.Node"@6
[]ast.Node ,go.string."[]ast.Node"þ$type.[]go/ast.Node  8UÐÙ   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P,go.string."[]ast.Node"p6go.weak.type.*[]go/ast.Node€"runtime.zerovalue� type.go/ast.NodeþHgo.typelink.[]ast.Node/[]go/ast.Node$type.[]go/ast.Nodeþbruntime.gcbits.0x88000000000000000000000000000000 ˆþ>go.string."func(ast.Node) bool"PHfunc(ast.Node) bool >go.string."func(ast.Node) bool"þ6type.func(go/ast.Node) bool  �Nš3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P>go.string."func(ast.Node) bool"pHgo.weak.type.*func(go/ast.Node) bool€"runtime.zerovalue €6type.func(go/ast.Node) boolÐ�6type.func(go/ast.Node) bool€ type.go/ast.Node�type.boolþ.go.string."*[]ast.Node"@8 *[]ast.Node .go.string."*[]ast.Node"þ&type.*[]go/ast.Node  w7­n6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P.go.string."*[]ast.Node"p8go.weak.type.**[]go/ast.Node€"runtime.zerovalue�$type.[]go/ast.Nodeþ@go.string."*func(ast.Node) bool"PJ*func(ast.Node) bool @go.string."*func(ast.Node) bool"þ8type.*func(go/ast.Node) bool  Þ€W86   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P@go.string."*func(ast.Node) bool"pJgo.weak.type.**func(go/ast.Node) bool€"runtime.zerovalue�6type.func(go/ast.Node) boolþbruntime.gcbits.0x84884888880000000000000000000000 „ˆHˆˆþÎgo.string."struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool }"àØ[struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool } Îgo.string."struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool }"þgo.string."F"0$F go.string."F"þgo.string."A0"0&A0 go.string."A0"þgo.string."A1"0&A1 go.string."A1"þgo.string."A2"0&A2 go.string."A2"þgo.string."A3"0&A3 go.string."A3"þØtype.struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }ÐÐ(­ªÙ  runtime.algarray0bruntime.gcbits.0x84884888880000000000000000000000PÎgo.string."struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool }"pêgo.weak.type.*struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }€"runtime.zerovalue�ÀØtype.struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }Àgo.string."F"àtype.uintptr�go.string."A0"°&type.*[]go/ast.Nodeàgo.string."A1"€$type.*go/token.Pos°go.string."A2"Ð$type.*go/token.Pos€go.string."A3" 8type.*func(go/ast.Node) boolþÐgo.string."*struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool }"àÚ\*struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool } Ðgo.string."*struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool }"þÚtype.*struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }  ƒÌSí6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PÐgo.string."*struct { F uintptr; A0 *[]ast.Node; A1 *token.Pos; A2 *token.Pos; A3 *func(ast.Node) bool }"pìgo.weak.type.**struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }€"runtime.zerovalue�Øtype.struct { F uintptr; A0 *[]go/ast.Node; A1 *go/token.Pos; A2 *go/token.Pos; A3 *func(go/ast.Node) bool }þ<go.string."*astutil.tokenNode"PF*astutil.tokenNLine truncated
+þTgclocals·5719e95fd01d864484e48bd45fcc377f þHgo.string."func(*astutil.byPos) int"`Rfunc(*astutil.byPos) int Hgo.string."func(*astutil.byPos) int"þ0type.func(*"".byPos) int  cÇR3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PHgo.string."func(*astutil.byPos) int"pBgo.weak.type.*func(*"".byPos) int€"runtime.zerovalue €0type.func(*"".byPos) intÐ�0type.func(*"".byPos) int€type.*"".byPos�type.intþ^go.string."func(*astutil.byPos, int, int) bool"ph#func(*astutil.byPos, int, int) bool ^go.string."func(*astutil.byPos, int, int) bool"þFtype.func(*"".byPos, int, int) boolÀÀ‚nH3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P^go.string."func(*astutil.byPos, int, int) bool"pXgo.weak.type.*func(*"".byPos, int, int) bool€"runtime.zerovalue €Ftype.func(*"".byPos, int, int) boolаFtype.func(*"".byPos, int, int) bool€type.*"".byPos�type.int type.int°type.boolþTgo.string."func(*astutil.byPos, int, int)"`^func(*astutil.byPos, int, int) Tgo.string."func(*astutil.byPos, int, int)"þ<type.func(*"".byPos, int, int)°°õ�I3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PTgo.string."func(*astutil.byPos, int, int)"pNgo.weak.type.*func(*"".byPos, int, int)€"runtime.zerovalue €<type.func(*"".byPos, int, int)а<type.func(*"".byPos, int, int)€type.*"".byPos�type.int type.intþ,go.string."func() int"@6
func() int ,go.string."func() int"þtype.func() int��å†9à3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P,go.string."func() int"p0go.weak.type.*func() int€"runtime.zerovalue €type.func() intЀtype.func() int€type.intþ>go.string."func(int, int) bool"PHfunc(int, int) bool >go.string."func(int, int) bool"þ0type.func(int, int) bool°°¢"3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P>go.string."func(int, int) bool"pBgo.weak.type.*func(int, int) bool€"runtime.zerovalue €0type.func(int, int) boolР0type.func(int, int) bool€type.int�type.int type.boolþ4go.string."func(int, int)"@>func(int, int) 4go.string."func(int, int)"þ&type.func(int, int)  %Ç„3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P4go.string."func(int, int)"p8go.weak.type.*func(int, int)€"runtime.zerovalue €&type.func(int, int)Р&type.func(int, int)€type.int�type.intþtype.*"".byPos��ærôñ6.   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P4go.string."*astutil.byPos"p.go.weak.type.**"".byPos€"runtime.zerovalue�type."".byPos` type.*"".byPosÀðtype.*"".byPosðgo.string."Len"�type.func() int 0type.func(*"".byPos) int°"".(*byPos).LenÀ"".(*byPos).LenÐ go.string."Less"ð0type.func(int, int) bool€Ftype.func(*"".byPos, int, int) bool� "".(*byPos).Less  "".(*byPos).Less° go.string."Swap"Ð&type.func(int, int)à<type.func(*"".byPos, int, int)ð "".(*byPos).Swap€ "".(*byPos).Swapþ2go.string."astutil.byPos"@< astutil.byPos 2go.string."astutil.byPos"þFgo.string."func(astutil.byPos) int"PPfunc(astutil.byPos) int Fgo.string."func(astutil.byPos) int"þ.type.func("".byPos) int  Ò¬3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PFgo.string."func(astutil.byPos) int"p@go.weak.type.*func("".byPos) int€"runtime.zerovalue €.type.func("".byPos) intÐ�.type.func("".byPos) int€type."".byPos�type.intþ\go.string."func(astutil.byPos, int, int) bool"pf"func(astutil.byPos, int, int) bool \go.string."func(astutil.byPos, int, int) bool"þDtype.func("".byPos, int, int) boolÀÀé‚ëk3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P\go.string."func(astutil.byPos, int, int) bool"pVgo.weak.type.*func("".byPos, int, int) bool€"runtime.zerovalue €Dtype.func("".byPos, int, int) boolаDtype.func("".byPos, int, int) bool€type."".byPos�type.int type.int°type.boolþRgo.string."func(astutil.byPos, int, int)"`\func(astutil.byPos, int, int) Rgo.string."func(astutil.byPos, int, int)"þ:type.func("".byPos, int, int)°°A?n&3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PRgo.string."func(astutil.byPos, int, int)"pLgo.weak.type.*func("".byPos, int, int)€"runtime.zerovalue €:type.func("".byPos, int, int)а:type.func("".byPos, int, int)€type."".byPos�type.int type.intþtype."".byPos��™Å¥þLine truncated
[]ast.Decl ,go.string."[]ast.Decl"þ$type.[]go/ast.Decl  q|�+   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P,go.string."[]ast.Decl"p6go.weak.type.*[]go/ast.Decl€"runtime.zerovalue� type.go/ast.DeclþHgo.typelink.[]ast.Decl/[]go/ast.Decl$type.[]go/ast.Declþ,go.string."[]ast.Spec"@6
[]ast.Spec ,go.string."[]ast.Spec"þ$type.[]go/ast.Spec  0Ž4   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P,go.string."[]ast.Spec"p6go.weak.type.*[]go/ast.Spec€"runtime.zerovalue� type.go/ast.SpecþHgo.typelink.[]ast.Spec/[]go/ast.Spec$type.[]go/ast.Specþ:go.string."[]*ast.ImportSpec"PD[]*ast.ImportSpec :go.string."[]*ast.ImportSpec"þ2type.[]*go/ast.ImportSpec  Xˆ]³   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P:go.string."[]*ast.ImportSpec"pDgo.weak.type.*[]*go/ast.ImportSpec€"runtime.zerovalue�.type.*go/ast.ImportSpecþdgo.typelink.[]*ast.ImportSpec/[]*go/ast.ImportSpec2type.[]*go/ast.ImportSpecþ>go.string."[]*ast.CommentGroup"PH[]*ast.CommentGroup >go.string."[]*ast.CommentGroup"þ6type.[]*go/ast.CommentGroup  •bÒi   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P>go.string."[]*ast.CommentGroup"pHgo.weak.type.*[]*go/ast.CommentGroup€"runtime.zerovalue�2type.*go/ast.CommentGroupþlgo.typelink.[]*ast.CommentGroup/[]*go/ast.CommentGroup6type.[]*go/ast.CommentGroupþ<go.string."**ast.CommentGroup"PF**ast.CommentGroup <go.string."**ast.CommentGroup"þ4type.**go/ast.CommentGroup  F/6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P<go.string."**ast.CommentGroup"pFgo.weak.type.***go/ast.CommentGroup€"runtime.zerovalue�2type.*go/ast.CommentGroupþ8go.string."**ast.ImportSpec"PB**ast.ImportSpec 8go.string."**ast.ImportSpec"þ0type.**go/ast.ImportSpec  S`ìq6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P8go.string."**ast.ImportSpec"pBgo.weak.type.***go/ast.ImportSpec€"runtime.zerovalue�.type.*go/ast.ImportSpecþlgo.string."struct { F uintptr; A0 *string; A1 *bool }"€v*struct { F uintptr; A0 *string; A1 *bool } lgo.string."struct { F uintptr; A0 *string; A1 *bool }"þ^type.struct { F uintptr; A0 *string; A1 *bool }°°dkÛÑ  runtime.algarray0bruntime.gcbits.0x84488800000000000000000000000000Plgo.string."struct { F uintptr; A0 *string; A1 *bool }"ppgo.weak.type.*struct { F uintptr; A0 *string; A1 *bool }€"runtime.zerovalue�À^type.struct { F uintptr; A0 *string; A1 *bool }Àgo.string."F"àtype.uintptr�go.string."A0"°type.*stringàgo.string."A1"€type.*boolþ8go.string."*astutil.visitFn"PB*astutil.visitFn 8go.string."*astutil.visitFn"þ&go.string."visitFn"00visitFn &go.string."visitFn"þ"go.string."Visit"0,Visit "go.string."Visit"þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·57e1009a600f832f844e0e3c49ba5a89
.þpgo.string."func(*astutil.visitFn, ast.Node) ast.Visitor"€z,func(*astutil.visitFn, ast.Node) ast.Visitor pgo.string."func(*astutil.visitFn, ast.Node) ast.Visitor"þdtype.func(*"".visitFn, go/ast.Node) go/ast.Visitor°°™º13 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000Ppgo.string."func(*astutil.visitFn, ast.Node) ast.Visitor"pvgo.weak.type.*func(*"".visitFn, go/ast.Node) go/ast.Visitor€"runtime.zerovalue €dtype.func(*"".visitFn, go/ast.Node) go/ast.VisitorРdtype.func(*"".visitFn, go/ast.Node) go/ast.Visitor€ type.*"".visitFn� type.go/ast.Node &type.go/ast.VisitorþLgo.string."func(ast.Node) ast.Visitor"`Vfunc(ast.Node) ast.Visitor Lgo.string."func(ast.Node) ast.Visitor"þJtype.func(go/ast.Node) go/ast.Visitor  cZ…z3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PLgo.string."func(ast.Node) ast.Visitor"p\go.weak.type.*func(go/ast.Node) go/ast.Visitor€"runtime.zerovalue €Jtype.func(go/ast.Node) go/ast.VisitorÐ�Jtype.func(go/ast.Node) go/ast.Visitor€ type.go/ast.Node�&type.go/ast.Visitorþ type.*"".visitFnÐÐ¥,Ï6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P8go.string."*astutil.visitFn"p2go.weak.type.**"".visitFn€"runtime.zerovalue�type."".visitFn`  type.*"".visitFnÀð type.*"".visitFnð"go.string."Visit"�Jtype.func(go/ast.Node) go/ast.Visitor dtype.func(*"".visitFn, go/ast.Node) go/ast.Visitor°&"".(*visitFn).VisitÀ&"".(*visitFn).Visitþ6go.string."astutil.visitFn"@@astutil.visitFn 6go.string."astutil.visitFn"þngo.string."func(astutil.visitFn, ast.Node) ast.Visitor"€x+func(astutil.visitFn, ast.Node) ast.Visitor ngo.string."func(astutil.visitFn, ast.Node) ast.Visitor"þbtype.func("".visitFn, go/ast.Node) go/ast.Visitor°°¤•þ3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000Pngo.string."func(astutil.visitFn, ast.Node) ast.Visitor"ptgo.weak.type.*func("".visitFn, go/ast.Node) go/ast.Visitor€"runtime.zerovalue €btype.func("".visitFn, go/ast.Node) go/ast.VisitorРbtype.func("".visitFn, go/ast.Node) go/ast.Visitor€type."".visitFn� type.go/ast.Node &type.go/ast.Visitorþtype."".visitFnÀÀØ¢W]3" € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P6go.string."astutil.visitFn"p type.*"".visitFn€"runtime.zerovalue €type."".visitFnÐ�type."".visitFn€ type.go/ast.Node`�type."".visitFn�&go.string."visitFn" "go.importpath."".°àtype."".visitFnà"go.string."Visit"€Jtype.func(go/ast.Node) go/ast.Visitor�btype.func("".visitFn, go/ast.Node) go/ast.Visitor  "".visitFn.Visit° "".visitFn.Visitþngo.string."*struct { F uintptr; A0 *string; A1 *bool }"€x+*struct { F uintptr; A0 *string; A1 *bool } ngo.string."*struct { F uintptr; A0 *string; A1 *bool }"þ`type.*struct { F uintptr; A0 *string; A1 *bool }  µÝì 6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000Pngo.string."*struct { F uintptr; A0 *string; A1 *bool }"prgo.weak.type.**struct { F uintptr; A0 *string; A1 *bool }€"runtime.zerovalue�^type.struct { F uintptr; A0 *string; A1 *bool }þ<go.string."[0]*ast.ImportSpec"PF[0]*ast.ImportSpec <go.string."[0]*ast.ImportSpec"þ4type.[0]*go/ast.ImportSpecÀÀÈí5‘  runtime.algarray0^runtime.gcbits.0x000000000000000000000000000000P<go.string."[0]*ast.ImportSpec"pFgo.weak.type.*[0]*go/ast.ImportSpec€"runLine truncated
@@ -0,0 +1,319 @@
!<arch>
__.PKGDEF 0 0 0 644 9308 `
go object darwin amd64 go1.4.1 X:precisestack
$$
package gcimporter
import scanner "text/scanner"
import runtime "runtime"
import bufio "bufio"
import errors "errors"
import exact "golang.org/x/tools/go/exact"
import io "io"
import filepath "path/filepath"
import os "os"
import strconv "strconv"
import strings "strings"
import types "golang.org/x/tools/go/types"
import fmt "fmt"
import build "go/build"
import token "go/token"
type @"io".Reader interface { Read(@"io".p []byte) (@"io".n int, @"io".err error) }
type @"io".Writer interface { Write(@"io".p []byte) (@"io".n int, @"io".err error) }
type @"bufio".Reader struct { @"bufio".buf []byte; @"bufio".rd @"io".Reader; @"bufio".r int; @"bufio".w int; @"bufio".err error; @"bufio".lastByte int; @"bufio".lastRuneSize int }
func (@"bufio".b·2 *@"bufio".Reader "esc:0x0") Buffered () (? int) { return @"bufio".b·2.@"bufio".w - @"bufio".b·2.@"bufio".r }
func (@"bufio".b·3 *@"bufio".Reader) Peek (@"bufio".n·4 int) (? []byte, ? error)
func (@"bufio".b·3 *@"bufio".Reader) Read (@"bufio".p·4 []byte) (@"bufio".n·1 int, @"bufio".err·2 error)
func (@"bufio".b·3 *@"bufio".Reader) ReadByte () (@"bufio".c·1 byte, @"bufio".err·2 error)
func (@"bufio".b·3 *@"bufio".Reader) ReadBytes (@"bufio".delim·4 byte) (@"bufio".line·1 []byte, @"bufio".err·2 error)
func (@"bufio".b·4 *@"bufio".Reader) ReadLine () (@"bufio".line·1 []byte, @"bufio".isPrefix·2 bool, @"bufio".err·3 error)
func (@"bufio".b·4 *@"bufio".Reader) ReadRune () (@"bufio".r·1 rune, @"bufio".size·2 int, @"bufio".err·3 error)
func (@"bufio".b·3 *@"bufio".Reader) ReadSlice (@"bufio".delim·4 byte) (@"bufio".line·1 []byte, @"bufio".err·2 error)
func (@"bufio".b·3 *@"bufio".Reader) ReadString (@"bufio".delim·4 byte) (@"bufio".line·1 string, @"bufio".err·2 error)
func (@"bufio".b·1 *@"bufio".Reader) Reset (@"bufio".r·2 @"io".Reader)
func (@"bufio".b·2 *@"bufio".Reader "esc:0x0") UnreadByte () (? error)
func (@"bufio".b·2 *@"bufio".Reader "esc:0x0") UnreadRune () (? error) { if @"bufio".b·2.@"bufio".lastRuneSize < 0x0 || @"bufio".b·2.@"bufio".r < @"bufio".b·2.@"bufio".lastRuneSize { return @"bufio".ErrInvalidUnreadRune }; @"bufio".b·2.@"bufio".r -= @"bufio".b·2.@"bufio".lastRuneSize; @"bufio".b·2.@"bufio".lastByte = -0x1; @"bufio".b·2.@"bufio".lastRuneSize = -0x1; return nil }
func (@"bufio".b·3 *@"bufio".Reader) WriteTo (@"bufio".w·4 @"io".Writer) (@"bufio".n·1 int64, @"bufio".err·2 error)
func (@"bufio".b·1 *@"bufio".Reader) @"bufio".fill ()
func (@"bufio".b·2 *@"bufio".Reader "esc:0x1") @"bufio".readErr () (? error) { var @"bufio".err·3 error; ; @"bufio".err·3 = @"bufio".b·2.@"bufio".err; @"bufio".b·2.@"bufio".err = nil; return @"bufio".err·3 }
func (@"bufio".b·1 *@"bufio".Reader "esc:0x0") @"bufio".reset (@"bufio".buf·2 []byte, @"bufio".r·3 @"io".Reader) { *@"bufio".b·1 = (@"bufio".Reader{ @"bufio".buf:@"bufio".buf·2, @"bufio".rd:@"bufio".r·3, @"bufio".lastByte:-0x1, @"bufio".lastRuneSize:-0x1 }) }
func (@"bufio".b·3 *@"bufio".Reader) @"bufio".writeBuf (@"bufio".w·4 @"io".Writer) (? int64, ? error)
func @"".FindExportData (@"".r·2 *@"bufio".Reader) (@"".err·1 error)
func @"".FindPkg (@"".path·3 string, @"".srcDir·4 string) (@"".filename·1 string, @"".id·2 string)
type @"go/token".Pos int
func (@"go/token".p·2 @"go/token".Pos) IsValid () (? bool) { return @"go/token".p·2 != @"go/token".Pos(0x0) }
type @"golang.org/x/tools/go/types".Type interface { String() (? string); Underlying() (? @"golang.org/x/tools/go/types".Type) }
type @"golang.org/x/tools/go/types".Object interface { Exported() (? bool); Id() (? string); Name() (? string); Parent() (? *@"golang.org/x/tools/go/types".Scope); Pkg() (? *@"golang.org/x/tools/go/types".Package); Pos() (? @"go/token".Pos); String() (? string); Type() (? @"golang.org/x/tools/go/types".Type); @"golang.org/x/tools/go/types".order() (? uint32); @"golang.org/x/tools/go/types".sameId(@"golang.org/x/tools/go/types".pkg *@"golang.org/x/tools/go/types".Package, @"golang.org/x/tools/go/types".name string) (? bool); @"golang.org/x/tools/go/types".setOrder(? uint32); @"golang.org/x/tools/go/types".setParent(? *@"golang.org/x/tools/go/types".Scope) }
type @"golang.org/x/tools/go/types".Scope struct { @"golang.org/x/tools/go/types".parent *@"golang.org/x/tools/go/types".Scope; @"golang.org/x/tools/go/types".children []*@"golang.org/x/tools/go/types".Scope; @"golang.org/x/tools/go/types".comment string; @"golang.org/x/tools/go/types".elems map[string]@"golang.org/x/tools/go/types".Object }
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope "esc:0x0") Child (@"golang.org/x/tools/go/types".i·3 int) (? *@"golang.org/x/tools/go/types".Scope) { return @"golang.org/x/tools/go/types".s·2.@"golang.org/x/tools/go/types".children[@"golang.org/x/tools/go/types".i·3] }
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope) Insert (@"golang.org/x/tools/go/types".obj·3 @"golang.org/x/tools/go/types".Object) (? @"golang.org/x/tools/go/types".Object)
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope "esc:0x0") Len () (? int) { return len(@"golang.org/x/tools/go/types".s·2.@"golang.org/x/tools/go/types".elems) }
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope "esc:0x0") Lookup (@"golang.org/x/tools/go/types".name·3 string "esc:0x0") (? @"golang.org/x/tools/go/types".Object) { return @"golang.org/x/tools/go/types".s·2.@"golang.org/x/tools/go/types".elems[@"golang.org/x/tools/go/types".name·3] }
func (@"golang.org/x/tools/go/types".s·3 *@"golang.org/x/tools/go/types".Scope "esc:0x2") LookupParent (@"golang.org/x/tools/go/types".name·4 string "esc:0x0") (? *@"golang.org/x/tools/go/types".Scope, ? @"golang.org/x/tools/go/types".Object)
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope "esc:0x0") Names () (? []string)
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope "esc:0x0") NumChildren () (? int) { return len(@"golang.org/x/tools/go/types".s·2.@"golang.org/x/tools/go/types".children) }
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope "esc:0x1") Parent () (? *@"golang.org/x/tools/go/types".Scope) { return @"golang.org/x/tools/go/types".s·2.@"golang.org/x/tools/go/types".parent }
func (@"golang.org/x/tools/go/types".s·2 *@"golang.org/x/tools/go/types".Scope) String () (? string)
func (@"golang.org/x/tools/go/types".s·1 *@"golang.org/x/tools/go/types".Scope) WriteTo (@"golang.org/x/tools/go/types".w·2 @"io".Writer, @"golang.org/x/tools/go/types".n·3 int, @"golang.org/x/tools/go/types".recurse·4 bool)
type @"golang.org/x/tools/go/types".Package struct { @"golang.org/x/tools/go/types".path string; @"golang.org/x/tools/go/types".name string; @"golang.org/x/tools/go/types".scope *@"golang.org/x/tools/go/types".Scope; @"golang.org/x/tools/go/types".complete bool; @"golang.org/x/tools/go/types".imports []*@"golang.org/x/tools/go/types".Package; @"golang.org/x/tools/go/types".fake bool }
func (@"golang.org/x/tools/go/types".pkg·2 *@"golang.org/x/tools/go/types".Package "esc:0x0") Complete () (? bool) { return @"golang.org/x/tools/go/types".pkg·2.@"golang.org/x/tools/go/types".complete }
func (@"golang.org/x/tools/go/types".pkg·2 *@"golang.org/x/tools/go/types".Package "esc:0x1") Imports () (? []*@"golang.org/x/tools/go/types".Package) { return @"golang.org/x/tools/go/types".pkg·2.@"golang.org/x/tools/go/types".imports }
func (@"golang.org/x/tools/go/types".pkg·1 *@"golang.org/x/tools/go/types".Package "esc:0x0") MarkComplete () { @"golang.org/x/tools/go/types".pkg·1.@"golang.org/x/tools/go/types".complete = true }
func (@"golang.org/x/tools/go/types".pkg·2 *@"golang.org/x/tools/go/types".Package "esc:0x1") Name () (? string) { return @"golang.org/x/tools/go/types".pkg·2.@"golang.org/x/tools/go/types".name }
func (@"golang.org/x/tools/go/types".pkg·2 *@"golang.org/x/tools/go/types".Package "esc:0x1") Path () (? string) { return @"golang.org/x/tools/go/types".pkg·2.@"golang.org/x/tools/go/types".path }
func (@"golang.org/x/tools/go/types".pkg·2 *@"golang.org/x/tools/go/types".Package "esc:0x1") Scope () (? *@"golang.org/x/tools/go/types".Scope) { return @"golang.org/x/tools/go/types".pkg·2.@"golang.org/x/tools/go/types".scope }
func (@"golang.org/x/tools/go/types".pkg·1 *@"golang.org/x/tools/go/types".Package "esc:0x0") SetImports (@"golang.org/x/tools/go/types".list·2 []*@"golang.org/x/tools/go/types".Package) { @"golang.org/x/tools/go/types".pkg·1.@"golang.org/x/tools/go/types".imports = @"golang.org/x/tools/go/types".list·2 }
func (@"golang.org/x/tools/go/types".pkg·2 *@"golang.org/x/tools/go/types".Package) String () (? string)
func @"".ImportData (@"".imports·3 map[string]*@"golang.org/x/tools/go/types".Package, @"".filename·4 string, @"".id·5 string, @"".data·6 @"io".Reader) (@"".pkg·1 *@"golang.org/x/tools/go/types".Package, @"".err·2 error)
func @"".Import (@"".imports·3 map[string]*@"golang.org/x/tools/go/types".Package, @"".path·4 string) (@"".pkg·1 *@"golang.org/x/tools/go/types".Package, @"".err·2 error)
func @"".init ()
var @"bufio".ErrInvalidUnreadRune error
$$
_go_.6 0 0 0 644 225337 `
go object darwin amd64 go1.4.1 X:precisestack
!
go13ldbufio.aerrors.a
fmt.aio.astrconv.astrings.ago/build.ago/token.aos.apath/filepath.atext/scanner.a:golang.org/x/tools/go/exact.a:golang.org/x/tools/go/types.aþ&"".readGopackHeaderÀªeH‹ %H�D$ÀH;AwèëåH�ìÀHÇ„$èHÇ„$ðHÇ„$àHÇ„$ÐHÇ„$ØH�H‰$HÇD$<HÇD$<èH‹T$H‹L$ H‹D$(H‰”$�H‰Œ$˜H‰„$ H‹œ$ÈH‰\$HH‹1íH9è„H‹L$HH‰„$€H‰$H‰Œ$ˆH‰L$H‹œ$�H‰\$H‹œ$˜H‰\$H‹œ$ H‰\$ èH‹D$0H‹\$8H‰œ$ðHƒøH‰„$ètH�ÄÀÃH‹¬$ H‹Œ$˜Hƒù0‚ŠH‹„$�H‰ÊHƒê0H‰éHƒé0HƒùtHƒÀ0H‰ÅH‰ÈHƒù
‚SHÇÁ
H‰¬$¨H‰,$H‰Œ$°H‰L$H‰„$¸H‰D$èH�\$H�,$H‰ïH‰ÞH¥H¥èH‹L$H‹D$H‰L$pH‰ $H‰D$xH‰D$èH‹”$�H‹„$˜H‹\$H‰œ$àH‹L$H‹\$ H‰œ$ðHƒùH‰Œ$è…ÀH‰ÅHƒíH9Ń�H�*€û`… H‰ÅHÿÍH9ŃiH�*€û
…�H‹„$ HƒørlHÇÁH‰”$¨H‰$H‰Œ$°H‰L$H‰„$¸H‰D$èH�\$H�,$H‰ïH‰ÞH¥H¥èH‹L$H‹D$H‰Œ$ÐH‰„$ØH�ÄÀÃè H�H‹+H‰l$`H‹kH‰l$hHÇD$PHÇD$XH�H‰$èH‹D$H‰D$@H‰$Hƒ<$t}H‹\$`H‰\$H‹\$hH‰\$èH‹\$@H‰\$@H‹1íH9ètH‹L$@H‰„$èH‰Œ$ðH�ÄÀÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%éwÿÿÿè è è è H�H‰$H�H‰\$H�H‰\$èH‹D$é±üÿÿ:
*0runtime.morestack_noctxtÂtype.[]uint8ø"runtime.makesliceî>go.itab.*bufio.Reader.io.Reader˜io.ReadFullà2runtime.slicebytetostring�"strings.TrimSpaceÔstrconv.AtoiÔ
2runtime.slicebytetostring„ "strings.TrimSpaceÒ $runtime.panicsliceä Dgo.string."invalid archive header"¸ .type.errors.errorStringÊ "runtime.newobject¦␍4runtime.writebarrierstringÈ␍Bgo.itab.*errors.errorString.errorž0type.*errors.errorString´type.errorÌBgo.itab.*errors.errorString.errorà runtime.typ2Itab�$runtime.panicindexž$runtime.panicindex¬$runtime.panicsliceº$runtime.panicsliceÌ$type.*bufio.Readerâtype.io.Readerú>go.itab.*bufio.Reader.io.ReaderŽ runtime.typ2Itab`€&"".autotmp_0022type.uint64"".autotmp_0021type.*uint8"".autotmp_0019ÿ0type.*errors.errorString"".autotmp_0018type.uint64"".autotmp_0017type.[]uint8"".autotmp_0010type.string"".autotmp_00090type.*errors.errorString"".autotmp_0008type.int"".autotmp_0007type.int"".autotmp_0003ï$type.*bufio.Reader"".autotmp_0002/type.[]uint8 "".~r0ßtype.errorerrors.text·2¿type.string"".sŸtype.string "".hdr_type.[]uint8 "".err@type.error"".size0type.int"".nametype.string"".r$type.*bufio.Reader8"€•ÿ€¯ÿ€£ÿ€” J&^I{ žGQr•;=0{�¤ú? < .u␍?Tgclocals·7c73a419403a83e4569fc85cf965927bTgclocals·c9e3c6d5f2e780a232dcf01774689094®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ""".FindExportDataàÒeH‹ %H�„$HÿÿÿH;AwèëâH�ì8HÇ„$HHÇ„$PH‹œ$@H‰$ÆD$
èH‹T$H‹L$H‹D$ H‹l$(H‹\$0H‰œ$PHƒýH‰¬$HtH�Ä8ÃH‰”$H‰$H‰Œ$H‰L$H‰„$H‰D$èH‹L$H‰Œ$àH‹D$ H‰„$èHƒø…&H‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û„ôHÇ„$ÀHÇ„$ÈH‹œ$@H‰$èH‹L$H‰Œ$ÀH‹D$H‹\$H‰\$@H‹T$ H‹\$(H‰œ$PHƒúH‰”$HtH�Ä8ÃHƒø …H‰ $H‰„$ÈH‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$ÀH‹„$ȶ\$ €û„ÄH�H‰$HÇD$HÇD$èH‹D$@H‹l$H‹T$ H‹L$(H‰¬$ðH‰”$øH‰Œ$HƒøŽâH‰D$@H‰ÁH‰D$HH=~ HÇÁH‰L$HH‹œ$@H‰\$XH‹1íH9è„õH‹”$H9Ê‚ÝH‹l$XH‰„$ÐH‰$H‰¬$ØH‰l$H‹¬$ðH‰¬$ H‰l$H‰Œ$(H‰L$H‰”$0H‰T$ èH‹D$0H‹\$8H‰œ$PHƒøH‰„$HtH�Ä8ÃH‹D$@H‹l$HH)èHƒø�ÿÿÿH‹œ$@H‰$èH‹L$H‰Œ$ÀH‹D$H‹\$H‹T$ H‹\$(H‰œ$PHƒúH‰”$HtH�Ä8ÃH‰„$ÈHƒø …H‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û„ÐH‹œ$@H‰$ÆD$
èH‹\$H‰œ$H‹\$H‰œ$H‹\$ H‰œ$H‹D$(H‹\$0H‰œ$PHƒøH‰„$HtH�Ä8ÃH‹œ$H‰$H‹œ$H‰\$H‹œ$H‰\$èH‹¼$H‹´$L‹L$H‹T$ L‰Œ$àL‰Œ$ H‰”$èH�L‹L‰„$°H‹CH‰”$¨H‰„$¸H9ÂŒÑH9‚ÏL‰Œ$àH‰„$èH9À…¯L‰ $H‰D$L‰D$H‰D$èH‹¼$H‹´$¶\$ €û„yHÇÀ<…èH�H‹+H‰¬$�H‹kH‰¬$˜HÇD$pHÇD$xH�H‰$èH‹D$H‰D$PH‰$Hƒ<$„ƒH‹œ$�H‰\$H‹œ$˜H‰\$èH‹\$PH‰\$PH‹1íH9ètH‹T$PH‰„$HH‰”$PH�Ä8ÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%éqÿÿÿH‰¼$HƒþH‰´$ve€û$tUH‹œ$@H‰$ÆD$
èH‹|$H‹t$H‹\$ H‰œ$H‹D$(H‹\$0H‰œ$PHƒøH‰„$Ht•H�Ä8ÃH�Ä8Ãè 1Àé‡þÿÿè H�H‹+H‰¬$€H‹kH‰¬$ˆHÇD$`HÇD$hH�H‰$èH‹D$H‰D$PH‰$Hƒ<$„ƒH‹œ$€H‰\$H‹œ$ˆH‰\$èH‹\$PH‰\$PH‹1íH9ètH‹L$PH‰„$HH‰Œ$PH�Ä8ÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%éqÿÿÿè H�H‰$H�H‰\$H�H‰\$èH‹L$HH‹D$éÔúÿÿHƒø …¼ûÿÿH‰ $H‰„$ÈH‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$ÀH‹„$ȶ\$ €û…èùÿÿémûÿÿ`
00runtime.morestack_noctxtž2bufio.(*Reader).ReadSliceâ2runtime.slicebytetostringÊ*go.string."!<arch>\n"ò runtime.eqstringà&"".readGopackHeader¬*go.string."__.SYMDEF"Ô runtime.eqstringžtype.[]uint8Ô"runtime.makesliceª >go.itab.*bufio.Reader.io.Reader† io.ReadFull¦ &"".readGopackHeaderè␍*go.string."__.PKGDEF"� runtime.eqstringØ2bufio.(*Reader).ReadSliceÌ2runtime.slicebytetostring¾,go.string."go object "‚ runtime.eqstringê@go.string."not a go object file"Ê.type.errors.errorStringÜ"runtime.newobjectÌ4runtime.writebarrierstringîBgo.itab.*errors.errorString.errorÄ0type.*errors.errorStringÚtype.erroròBgo.itab.*errors.errorString.error† runtime.typ2Itab”2bufio.(*Reader).ReadSlice¬$runtime.panicindexÈ$runtime.panicsliceÚVgo.string."go archive is missing __.PKGDEF"º.type.errors.errorStringÌ"runtime.newobject¼4runtime.writebarrierstringÞBgo.itab.*errors.errorString.error´0type.*errors.errorStringÊtype.errorâBgo.itab.*errors.errorString.errorö runtime.typ2Itab¦$runtime.panicslice¸$type.*bufio.ReaderÎtype.io.Readeræ>go.itab.*bufio.Reader.io.Readerú runtime.typ2ItabÜ.go.string."__.GOSYMDEF"„ runtime.eqstring0ð<"".autotmp_0062type.*uint8"".autotmp_0061type.error"".autotmp_00600type.*errors.errorString"".autotmp_0059type.uint64"".autotmp_0058type.uint64"".autotmp_0057type.string"".autotmp_0055type.string"".autotmp_0054type.*uint8"".autotmp_0052Ï0type.*errors.errorString"".autotmp_0048¯type.string"".autotmp_00470type.*errors.errorString"".autotmp_0045type.int"".autotmp_0044type.int"".autotmp_00430type.*errors.errorString"".autotmp_0042type.int"".autotmp_0041¿$type.*bufio.Reader"".autotmp_0040/type.[]uint8 "".~r0�type.errorerrors.text·2Ïtype.string"strings.prefix·3�type.stringstrings.s·2¯type.string "".~r0¯type.errorerrors.text·2ïtype.string"".nßtype.int "".tmp�type.[]uint8"".sizeïtype.int"".nameïtype.string"".line_type.[]uint8 "".errtype.error"".r$type.*bufio.Reader†%ðdïðíïðöïðfïð¨ïðŸïð­ïðïðÁïðÙð¨Z=7�M
TN
␍ ¢␍
H
D] ó¥; M ␍¥;>T( PNbz@ÙP“ˆ 8¤ œ
8u *E/Tgclocals·7ae61b314b311606103e579d12906a42Tgclocals·256afd28bf6c775e086b317de2798892®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ"".init·1€veH‹ %H;awèëêHƒìH�H‰$H�H‰\$èHƒÄÃ
 0runtime.morestack_noctxt:Rgolang.org/x/tools/go/types.DefaultImportP"".Import·fd.runtime.writebarrierptr  @<

1Tgclocals·3280bececceccd33cb74587feedb1f9fTgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".FindPkgÀeH‹ %H�„$`ÿÿÿH;AwèëâH�ì H‹”$(H‹Œ$0HÇ„$XHÇ„$`HÇ„$HHÇ„$PHƒùuH�Ä ÃH‰”$XH‰Œ$`HÇD$XHÇD$`H‰$H‰L$è¶\$€û„OH�¼$À1ÀèH�œ$ÀHƒû„'HÇÂHÇÁH‰”$°H‰Œ$¸H‰œ$¨H‰$H‹œ$8H‰\$H‹œ$@H‰\$èH‹œ$¨HƒÃH‰$H‹œ$(H‰\$H‹œ$0H‰\$èH‹œ$¨H‰$H‹œ$°H‰\$H‹œ$¸H‰\$èH‹L$H‹D$ H‰L$XH‰D$`H‹\$XH‰œ$XH‹\$`H‰œ$`H�H�¬$àH‰ïH‰Þè1ÉHÇD$HH�œ$àH‰ØH‹l$HH9é�ñH‰D$PHƒø„H‹H‹hH‰L$@H‰”$˜H‰¬$ H‹\$XH‰$H‹\$`H‰\$H‰T$xH‰T$H‰¬$€H‰l$èH‹L$ H‹D$(H‰Œ$HH‰ $H‰„$PH‰D$èH‹T$H‰T$hH‹L$H‰L$pH‹D$ H‹\$(H‰œ$�HƒøH‰„$ˆuH‰ $H‹Z ÿÓ¶\$€ûuH�Ä ÃH‹D$PH‹L$@HƒÀHÿÁH‹l$HH9éŒÿÿÿHÇ„$HHÇ„$PH�Ä Éé÷þÿÿ‰éÒýÿÿH‹œ$(H‰$H‹œ$0H‰\$èH‹¬$0H‹”$(¶\$€ûtH‰T$XH‰l$`é\þÿÿH‰$H‰l$H‹œ$8H‰\$H‹œ$@H‰\$HÇD$ èH‹D$(H‹˜ HƒûuH�Ä ÃH�¨˜H�$H‰ßH‰îH¥H¥H�H�l$H‰ïH‰ÞH¥H¥èH‹L$ H‹D$(H‰L$XH‰D$`éÈýÿÿ
00runtime.morestack_noctxt¾,go/build.IsLocalImportøð runtime.duffzero®4runtime.writebarrierstringŒ4runtime.writebarrierstringâ$path/filepath.JoinÌ"".pkgExtsò  runtime.duffcopyî*runtime.concatstring2¾ os.Stat¾
´ &path/filepath.IsAbsè␍go/build.ImportÔgo.string.".a"ü$strings.TrimSuffix€À&"".autotmp_0086type.string"".autotmp_0085Ÿtype.*string"".autotmp_0084type.int"".autotmp_0083type.int"".autotmp_0081ïtype.[]string"".autotmp_0080type.bool"".autotmp_0079type.[4]string"".autotmp_0077type.string"".autotmp_0076¿type.[2]string"".autotmp_0074�type.string"".autotmp_0073¯type.int "".err¯type.error"".fï type.os.FileInfo "".extÏtype.string"".noext�type.string
"".id`type.string"".filename@type.string"".srcDir type.string"".pathtype.string@%ÀM¿À¿¿À>¿ÀŸ¿ÀNàhReØi9f8
%6␍D
*žxZÆ(» ¤#Tgclocals·ab722441bfdc8df693d04875bdfd44c5Tgclocals·d6cd9281b01f077327dbc65f008cabfc®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".ImportData ŠeH‹ %H;awèëêHƒìXHÇ„$˜HÇ„$ HÇ„$¨HÇ„$ HÇ„$¨HÇ„$˜HÇD$HHÇD$PH�\$HH�-H‰+H�¬$ H‰kSjèYYH…À…˜H�H‰$èH‹L$H‰L$@H‰ $H‹\$hH‰\$H‹\$pH‰\$H‹\$xH‰\$H‹œ$€H‰\$ H‹œ$ˆH‰\$(H‹œ$�H‰\$0H‹\$`H‰\$8èH‹\$@H‰$èH‹\$H‰œ$˜�èHƒÄXÃ�èHƒÄXÃ
 0runtime.morestack_noctxtø"".func·001¦"runtime.deferprocÊtype."".parserÜ"runtime.newobject """.(*parser).init¼0"".(*parser).parseExportâ&runtime.deferreturnø&runtime.deferreturn °"".autotmp_0092Htype.struct { F uintptr; A0 *error }
"".&p/type.*"".parser "".err€type.error "".pkgpRtype.*golang.org/x/tools/go/types.Package"".dataPtype.io.Reader
"".id0type.string"".filenametype.string"".importshtype.map[string]*golang.org/x/tools/go/types.Package0°v ¯°
¯ Ð ¼b@] ’b!Tgclocals·a06e15cefa04c4de83b680fa5eac8b43Tgclocals·ddbab3f08e263922f15c2d23c4448f9a®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".ImportÀ¦eH‹ %H�„$XÿÿÿH;AwèëâH�ì(H‹Œ$@HÇ„$HHÇ„$PHÇ„$XHÇ„$PHÇ„$XHÇ„$HHƒùupH‹´$8H‰4$H‰L$H�5L�D$L‰ÇH¥H¥èH‹Œ$@¶\$ €ût5H‹H‰œ$HHÇ„$PHÇ„$X�èH�Ä(ÃH�H‹+H‰l$pH‹kH‰l$xH‹œ$8H‰$H‰L$è¶\$€û„çèH‹$H‰\$pH‹\$H‰\$xH‹\$H‰œ$PH‹\$H‰œ$XHƒ¼$Pt�èH�Ä(ÃH‹œ$8H‰$H‹œ$@H‰\$H‹\$pH‰\$H‹\$xH‰\$èH‹\$ H‰œ$�H‹\$(H‰œ$˜H‹T$0H‹L$8H‹œ$˜Hƒû…1H‰”$€H‰”$ÐH‰Œ$ˆH‰Œ$ØH�œ$àHÇHÇCH�œ$àHƒû„áHÇÅHÇÂH‰œ$ðH‰¬$øH‰”$H�H‰$H�œ$ÐH‰\$èH‹T$H‹L$H‹œ$ðH‰$H‰”$°H‰T$H‰Œ$¸H‰L$èH�H�,$H‰ïH‰ÞH¥H¥H‹œ$ðH‰\$H‹œ$øH‰\$H‹œ$H‰\$ èH‹T$(H‹L$0H‰”$PH‰Œ$X�èH�Ä(ÉéÿÿÿH‰”$€H‰Œ$ˆH�H‰$H‹œ$0H‰\$H‰”$ÀH‰T$H‰Œ$ÈH‰L$èH‹\$ H‹+H‰¬$HH‹œ$H1íH9ët H‹œ$H¶k(@€ýt�èH�Ä(ÃH‹œ$�H‰$H‹œ$˜H‰\$èH‹\$H‰\$PH‹\$H‰œ$PH‹\$ H‰œ$XHƒ¼$Pt�èH�Ä(ÃHÇ„$HÇ„$HÇ„$HÇ„$ H�œ$H�-H‰+H�l$PH‰kH�¬$PH‰kH�¬$�H‰kSjèYYH…À…žH‹\$PH‰\$hH‹␍1íH9é„PH‹T$hH‰Œ$ H‰ $H‰”$¨H‰T$èH‹L$H‰L$XH‰ $èH‹T$H‹L$H‰”$PH‰Œ$XHƒ¼$Pt�èH�Ä(ÃH‹\$XH‰\$`H‹␍1íH9é„™H‹œ$0H‰$H‹œ$�H‰\$H‹œ$˜H‰\$H‹œ$€H‰\$H‹œ$ˆH‰\$ H‹T$`H‰Œ$ H‰L$(H‰”$¨H‰T$0èH‹\$8H‰œ$HH‹\$@H‰œ$PH‹\$HH‰œ$X�èH�Ä(ÃH�H‰$H�H‰\$H�H‰\$èH‹L$é5ÿÿÿH�H‰$H�H‰\$H�H‰\$èH‹L$é~þÿÿ�èH�Ä(Ãé_ûÿÿP
00runtime.morestack_noctxtž$go.string."unsafe"À runtime.eqstringòDgolang.org/x/tools/go/types.Unsafe¾&runtime.deferreturnÜgo.string."."ª,go/build.IsLocalImportÐos.GetwdÌ&runtime.deferreturnÀ"".FindPkg˜ type.stringÄ runtime.convT2E®
2runtime.writebarrieriface¼
Bgo.string."can't find import: %s"° fmt.Errorfð &runtime.deferreturn¼ htype.map[string]*golang.org/x/tools/go/types.Packageœ␍4runtime.mapaccess1_faststrŠ&runtime.deferreturnÖos.OpenÀ&runtime.deferreturnÎ"".func·002¦"runtime.deferprocÞ4go.itab.*os.File.io.Readerºbufio.NewReaderà""".FindExportData&runtime.deferreturnè>go.itab.*bufio.Reader.io.ReaderÆ"".ImportData &runtime.deferreturn¾$type.*bufio.ReaderÔtype.io.Readerì>go.itab.*bufio.Reader.io.Reader€ runtime.typ2Itab¢type.*os.File¸type.io.ReaderÐ4go.itab.*os.File.io.Readerä runtime.typ2Itab„&runtime.deferreturn`Ð("".autotmp_0109type.*uint8"".autotmp_0107?|type.struct { F uintptr; A0 **os.File; A1 *error; A2 *string }"".autotmp_0105ï"type.interface {}"".autotmp_0103o&type.[]interface {}"".autotmp_0102$type.*bufio.Reader"".autotmp_0101type.error"".autotmp_0100�$type.*bufio.Reader"".autotmp_0099ÿtype.*os.File"".autotmp_0097Ïtype.string"".autotmp_0095¯type.string"".autotmp_0094�(type.[1]interface {} "".bufŸ$type.*bufio.Reader"".f¯type.*os.File
"".idÏtype.string"".filename¯type.string"".srcDirïtype.string "".err@type.error "".pkg0Rtype.*golang.org/x/tools/go/types.Package"".pathtype.string"".importshtype.map[string]*golang.org/x/tools/go/types.Packageˆ%ÐÅÏІÏБÏÐŒÏÐZÏÐd�ÏдÏÐqÏР xîuA5$2 Vœ
xB vD3§2 2+TŸuºvW6'4t]*‰,12 Tgclocals·db214e47c3002302e2d8d591927a97c0Tgclocals·739a6a9cc2d64913442fa65f1f961dee®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ""".(*parser).init€êeH‹ %H;awèëêHƒìPH�H‰$èH‹D$H‹l$XH‰(H‰D$HH‹(H‰,$Hƒ<$„›H‹œ$€H‰\$H‹œ$ˆH‰\$èH�H‰$èH‹D$H�-H‰(H‰D$@H‰$Hƒ<$„=Hƒ$H‹\$HH‰\$èH‹\$HH‹+H‰,$Hƒ<$„H�$ØH‹\$@H‰\$èH‹D$HH‹HǃèlH‹H½H‰«ðH‹(H‰,$Hƒ<$„ªH�$H‹\$`H‰\$H‹\$hH‰\$èH‹\$HH‹+H‰,$èH‹\$HH‹+H‰,$Hƒ<$t\H�$@H‹\$pH‰\$H‹\$xH‰\$èH‹\$HH‹+H‰,$Hƒ<$tH�$PH‹œ$�H‰\$èHƒÄPÉ%ëØ‰%뛉%éJÿÿÿ‰%éîþÿÿ‰%é·þÿÿ‰%éYþÿÿ
 0runtime.morestack_noctxt:type.*"".parserL"runtime.newobjectÒ8text/scanner.(*Scanner).InitàRtype.struct { F uintptr; A0 **"".parser }ò"runtime.newobjectŠ"".func·003à.runtime.writebarrierptr¼.runtime.writebarrierptrð4runtime.writebarrierstring’""".(*parser).nextú4runtime.writebarrierstringÔ.runtime.writebarrierptr€  "".autotmp_0121Ttype.*struct { F uintptr; A0 **"".parser }
"".&p type.**"".parser"".importsphtype.map[string]*golang.org/x/tools/go/types.Package "".srcPtype.io.Reader
"".id0type.string"".filenametype.string ˜Ÿ M€@ò76z34-   %CG.ÌWTgclocals·c8dbfc7901f18862149c14c7613c5f6bTgclocals·34cda72afdcfdf8fef15e82264bcd4b3®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ""".(*parser).next ˜eH‹ %H;awèëêHƒìPH‹\$XH‰$Hƒ<$„ÒèH‹L$X‹D$‰�(‹©(ƒýû��ƒýúubH‰ $Hƒ<$tNèH‹L$H‹D$H‹\$XH‰$Hƒ<$t&H�$0H‰L$@H‰L$H‰D$HH‰D$èHƒÄPÉ%ëщ%멃ýût™HƒùtH�©0HÇEHÇEëʼnëãƒýý„mÿÿÿƒýþ„dÿÿÿ�ý·„Xÿÿÿ뽉%é"ÿÿÿ
 0runtime.morestack_noctxt^8text/scanner.(*Scanner).ScanÄBtext/scanner.(*Scanner).TokenTextº4runtime.writebarrierstring "".autotmp_0134type.int32"".autotmp_0130type.string"".ptype.*"".parser ‹Ÿ j�<˜(K␍
   .âTgclocals·519efd86263089ddb84df3cfe7fd2992Tgclocals·d64e51a4c4bfeaa840e480961ec6b0b3®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".declTypeName€ ð eH‹ %H�D$°H;AwèëåH�ìÐH‹œ$ØH‹k H‰l$@H‹”$àH‹Œ$èHÇD$`HÇD$hH‰”$ H‰Œ$¨H�H‰$H‹m0H‰l$H‰”$ÀH‰T$H‰Œ$ÈH‰L$èH‹\$ Hƒû„JH‹H‹kH‰T$`H‰l$hH‰¬$ˆHƒúH‰”$€t/H�H‰$H‰T$H‰l$èH‹\$H‰œ$ðH�ÄÐÃHÇD$8H‹œ$ØH‰\$HH‹œ$àH‰œ$�H‹œ$èH‰œ$˜HÇD$pHÇD$xH�H‰$èH‹D$1íH‰(H‹l$8H‰hH‰D$XH‰$Hƒ<$„iHƒ$H‹\$HH‰\$èH‹\$XH‰$Hƒ<$„5Hƒ$H‹œ$�H‰\$H‹œ$˜H‰\$èH‹\$XH‰$Hƒ<$„ñHƒ$(H‹\$pH‰\$H‹\$xH‰\$èH‹D$XÇ@8H‰D$PH‰$H�\$HÇHÇCH�\$HÇHÇCHÇCèH‹\$PH‰\$XH‹1íH9ètBH‹\$@H‰$H‹L$XH‰„$°H‰D$H‰Œ$¸H‰L$èH‹\$PH‰œ$ðH�ÄÐÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë�‰%éÿÿÿ‰%é¿þÿÿ‰%é‹þÿÿ‰é¯ýÿÿ$
*0runtime.morestack_noctxtÐdtype.map[string]golang.org/x/tools/go/types.Object¨4runtime.mapaccess1_faststr¢Ttype.*golang.org/x/tools/go/types.TypeNameÈ"runtime.assertI2T�Rtype.golang.org/x/tools/go/types.TypeName¢"runtime.newobject˜.runtime.writebarrierptrˆ4runtime.writebarrierstringì2runtime.writebarrieriface€ Hgolang.org/x/tools/go/types.NewNamed¢  go.itab.*golang.org/x/tools/go/types.TypeName.golang.org/x/tools/go/types.ObjectŠ
Vgolang.org/x/tools/go/types.(*Scope).InsertÂ
Ttype.*golang.org/x/tools/go/types.TypeNameØ
Ntype.golang.org/x/tools/go/types.Objectð
 go.itab.*golang.org/x/tools/go/types.TypeName.golang.org/x/tools/go/types.Object„  runtime.typ2Itab@ """.autotmp_0147ïTtype.*golang.org/x/tools/go/types.TypeName"".autotmp_0146Ttype.*golang.org/x/tools/go/types.TypeName"".autotmp_0145Ttype.*golang.org/x/tools/go/types.TypeName"".autotmp_0144?Ntype.golang.org/x/tools/go/types.Object"".autotmp_0143type.stringDgolang.org/x/tools/go/types.typ·5¿Jtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4type.stringDgolang.org/x/tools/go/types.pkg·3�Rtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2¯"type.go/token.Pos "".~r0ßNtype.golang.org/x/tools/go/types.ObjectFgolang.org/x/tools/go/types.name·3_type.string "".objÿTtype.*golang.org/x/tools/go/types.TypeName "".objŸNtype.golang.org/x/tools/go/types.Object"".scopeŸNtype.*golang.org/x/tools/go/types.Scope "".~r20Ttype.*golang.org/x/tools/go/types.TypeName"".nametype.string "".pkgRtype.*golang.org/x/tools/go/types.Package(" ÚŸ  Ÿ b€4²"  /‰>E/$,“Pm;82JE=?Tgclocals·64edff1305d2d6a98f11ba36de028fc9Tgclocals·b47ffc4cc29bc609be6ec658396bb73a®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ("".importError.Error€ôeH‹ %H�D$ðH;AwèëåH�ì�HÇ„$ÐHÇ„$ØH�|$`1ÀèH�\$`Hƒû„^HÇÂHÇÁH‰\$HH‰T$PH‰L$XH�H‰$H�œ$˜H‰\$èH‹L$H‹D$H‹\$HH‰$H‰L$8H‰L$H‰D$@H‰D$èH�H‰$H�œ$˜H‰\$HƒD$èH‹L$H‹D$H‹\$HHƒÃH‰$H‰L$8H‰L$H‰D$@H‰D$èH�œ$ÀH�,$H‰ïH‰ÞH¥H¥èH‹L$H‹D$H‹\$HHƒÃ H‰$H‰L$8H‰L$H‰D$@H‰D$èH�H�,$H‰ïH‰ÞH¥H¥H‹\$HH‰\$H‹\$PH‰\$H‹\$XH‰\$ èH‹L$(H‹D$0H‰Œ$ÐH‰„$ØH�Ä�Éé›þÿÿ
*0runtime.morestack_noctxt„è runtime.duffzeroê4type.text/scanner.Position–runtime.convT2Eî2runtime.writebarrierifaceütype.int´runtime.convT2E”2runtime.writebarrierifaceÊruntime.convI2Eª2runtime.writebarrieriface¸dgo.string."import error %s (byte offset = %d): %s"šfmt.Sprintf� "".autotmp_0157"type.interface {}"".autotmp_0156"type.interface {}"".autotmp_0155¯"type.interface {}"".autotmp_0153�&type.[]interface {}"".autotmp_0151_(type.[3]interface {} "".~r0ptype.string"".e&type."".importError" �Ÿ ␍ÀÞ:†Š‚4Tgclocals·5abb3cfee363877c00470c6b5dfdf02aTgclocals·4e66f52b20879c06cabd165d1374ec07®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ$"".(*parser).error  † eH‹ %H�D$¨H;AwèëåH�ìØH�H‰$H‹œ$èH‰\$H‹œ$ðH‰\$èH‹l$H‰l$XH‹T$ H‰T$`¶\$(€û„»H‰l$HH‰T$PHÇD$8HÇD$@H�H‰$èH‹D$H‰D$0H‰$Hƒ<$„„H‹\$HH‰\$H‹\$PH‰\$èH‹\$0H‰\$0H‹1íH9è„H‹T$0H‰D$hH‰T$pH‰D$8H‰$H‰T$@H‰T$èH‹\$H‰œ$èH‹\$H‰œ$ðH‹œ$àH‰$Hƒ<$„¹èH�\$H�l$xH‰ïH‰ÞèH�¼$ 1ÀèH�œ$ H�l$xH‰ßH‰îèH�H‰$H‹œ$èH‰\$H‹œ$ðH‰\$èH�\$H�¬$ÈH‰ïH‰ÞH¥H¥H�H‰$H�œ$ H‰\$èH�\$H�,$H‰ïH‰ÞH¥H¥è ‰%é;ÿÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$é±þÿÿ‰%épþÿÿ,
*0runtime.morestack_noctxtJtype.string�$runtime.assertE2T2š.type.errors.errorString¬"runtime.newobject�4runtime.writebarrierstring²Bgo.itab.*errors.errorString.error–runtime.convI2E‚6text/scanner.(*Scanner).Pos¬ô runtime.duffcopyÊä runtime.duffzeroúô runtime.duffcopyˆtype.errorÎ"runtime.assertE2IŠ&type."".importErrorruntime.convT2Eæruntime.gopanic�0type.*errors.errorString¦type.error¾Bgo.itab.*errors.errorString.errorÒ runtime.typ2Itab0°"".autotmp_0165ßtype.error"".autotmp_0164Ï0type.*errors.errorString"".autotmp_0163o&type."".importError"".autotmp_0162¿4type.text/scanner.Position"".autotmp_01610type.*errors.errorString "".~r0¿type.errorerrors.text·2Ÿtype.string"".sÿtype.string "".err"type.interface {}"".ptype.*"".parser"°®Ðæ"L»ÜK"GN2Cœ‚(Tgclocals·12fd79131d0da3ce43d987c2561c2890Tgclocals·02742a319e22af0c972118f91befa02c®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ&"".(*parser).errorfàÊeH‹ %H;awèëêHƒìHH‹\$XH‰$H‹\$`H‰\$H‹\$hH‰\$H‹\$pH‰\$H‹\$xH‰\$ èH‹\$(H‰\$8H‹\$0H‰\$@H�H‰$H�\$8H‰\$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹\$PH‰$èHƒÄHÃ
 0runtime.morestack_noctxt˜fmt.SprintfÎtype.stringôruntime.convT2E¸$"".(*parser).error`�"".autotmp_0168type.string"".args0&type.[]interface {}"".formattype.string"".ptype.*"".parser�Š� °ö†K.7Tgclocals·9d0fdb5a8b6bdb6e912289f44b76055aTgclocals·8d600a433c6aaa81a4fe446d95c5546b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ&"".(*parser).expect 
’
eH‹ %H�D$¸H;AwèëåH�ìÈH‹Œ$Ћ„$ØHÇ„$àHÇ„$èHƒù„/H‹©0H‰l$0H‹©8H‰l$8‹™(9Ä׉$èH‹\$H‰\$pH‹\$H‰\$xH‹œ$Ћ«(‰,$èH‹\$H‰\$`H‹\$H‰\$hH‹\$0H‰\$PH‹\$8H‰\$XH�¼$˜1ÀèH�œ$˜Hƒû„‡HÇÂHÇÁH‰œ$€H‰”$ˆH‰Œ$�H�H‰$H�\$pH‰\$èH‹L$H‹D$H‹œ$€H‰$H‰L$@H‰L$H‰D$HH‰D$èH�H‰$H�\$`H‰\$èH‹L$H‹D$H‹œ$€HƒÃH‰$H‰L$@H‰L$H‰D$HH‰D$èH�H‰$H�\$PH‰\$èH‹L$H‹D$H‹œ$€HƒÃ H‰$H‰L$@H‰L$H‰D$HH‰D$èH‹´$ÐH‰4$H�5H�l$H‰ïH¥H¥H‹œ$€H‰\$H‹œ$ˆH‰\$ H‹œ$�H‰\$(èH‹Œ$ÐH‰ $èH‹\$0H‰œ$àH‹\$8H‰œ$èH�ÄÈÉérþÿÿ‰éÊýÿÿ"
*0runtime.morestack_noctxtú0text/scanner.TokenStringÎ0text/scanner.TokenString¼è runtime.duffzeroºtype.stringàruntime.convT2E¾2runtime.writebarrierifaceÌtype.stringòruntime.convT2EØ2runtime.writebarrierifaceætype.stringŒruntime.convT2Eò2runtime.writebarrieriface˜Hgo.string."expected %s, got %s (%s)"ˆ &"".(*parser).errorfª """.(*parser).next@�"".autotmp_0177"type.interface {}"".autotmp_0176"type.interface {}"".autotmp_0175�"type.interface {}"".autotmp_0173�&type.[]interface {}"".autotmp_0172ïtype.string"".autotmp_0171Ïtype.string"".autotmp_0170¯type.string"".autotmp_0169_(type.[3]interface {} "".lit¯type.string "".~r1 type.string "".toktype.int32"".ptype.*"".parser"�Ø���&þI"× "|*‰”<Tgclocals·2ccccd421c51251ab29254eab393497eTgclocals·449e7cdcf39a300f599f326278b49fc6®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4"".(*parser).expectSpecialàÖeH‹ %H�D$ØH;AwèëåH�ì¨H‹¼$¸H‹´$°H‹”$ÀAºx1ÀH9Ð}}‹ž(H‰D$8H9ЃÉH�,¶m9ëu]Aƒú ~WH‰4$Hƒ<$„œè‹\$‰\$4H‹œ$°H‰$èD‹T$4H‹¼$¸H‹´$°H‹”$ÀH‹D$8HÿÀH9Ð|ƒH9Ð�IH‰|$`H‰T$hH9‚/H‰|$PH‰D$XH�¼$ˆ1ÀèH�œ$ˆHƒû„ýHÇÂHÇÁH‰\$pH‰T$xH‰Œ$€H�H‰$H�\$`H‰\$èH‹L$H‹D$H‹\$pH‰$H‰L$@H‰L$H‰D$HH‰D$èH�H‰$H�\$PH‰\$èH‹L$H‹D$H‹\$pHƒÃH‰$H‰L$@H‰L$H‰D$HH‰D$èH‹´$°H‰4$H�5H�l$H‰ïH¥H¥H‹\$pH‰\$H‹\$xH‰\$ H‹œ$€H‰\$(èH�ĨÉéüþÿÿè ëè‰%éXþÿÿè 
*0runtime.morestack_noctxtú8text/scanner.(*Scanner).Peek¬""".(*parser).nextêð runtime.duffzeroÜtype.string‚runtime.convT2EÚ2runtime.writebarrierifaceètype.stringŽruntime.convT2Eî2runtime.writebarrieriface”>go.string."expected %q, got %q"ø&"".(*parser).errorf $runtime.panicsliceÊ$runtime.panicindex0Ð"".autotmp_0193"type.interface {}"".autotmp_0192Ï"type.interface {}"".autotmp_0190o&type.[]interface {}"".autotmp_0187¯type.string"".autotmp_0186�type.string"".autotmp_0185?(type.[2]interface {}"".autotmp_0184type.int"".ißtype.int "".sepçtype.int32 "".toktype.string"".ptype.*"".parser"ÐåÏÐ(°B�:+.
³␍  |Ä» Tgclocals·2018557e3ee0abccf2865b16663e690bTgclocals·99efdbc93924abe75b70e7be6ddbd650®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4"".(*parser).expectKeywordàÐeH‹ %H�D$ØH;AwèëåH�ì¨H‹œ$°H‰$ÇD$þÿÿÿèH‹”$ÀH‹L$H‹D$H‰L$0H9ÐuIH‹l$0H‰,$H‰D$8H‰D$H‹¬$¸H‰l$H‰T$èH‹D$8H‹”$À¶\$ €ûtH�ĨÃH‹œ$¸H‰\$`H‰T$hH‹\$0H‰\$PH‰D$8H‰D$XH�¼$ˆ1ÀèH�œ$ˆHƒû„úHÇÂHÇÁH‰\$pH‰T$xH‰Œ$€H�H‰$H�\$`H‰\$èH‹L$H‹D$H‹\$pH‰$H‰L$@H‰L$H‰D$HH‰D$èH�H‰$H�\$PH‰\$èH‹L$H‹D$H‹\$pHƒÃH‰$H‰L$@H‰L$H‰D$HH‰D$èH‹´$°H‰4$H�5H�l$H‰ïH¥H¥H‹\$pH‰\$H‹\$xH‰\$ H‹œ$€H‰\$(èé·þÿÿ‰éÿþÿÿ
*0runtime.morestack_noctxtn&"".(*parser).expectú runtime.eqstring¢ð runtime.duffzero”type.stringºruntime.convT2E’2runtime.writebarrieriface type.stringÆruntime.convT2E¦2runtime.writebarrierifaceÌNgo.string."expected keyword %s, got %q"°&"".(*parser).errorf0Ð"".autotmp_0206"type.interface {}"".autotmp_0205Ï"type.interface {}"".autotmp_0203o&type.[]interface {}"".autotmp_0202¯type.string"".autotmp_0201�type.string"".autotmp_0200?(type.[2]interface {} "".litïtype.string"".keywordtype.string"".ptype.*"".parser"Ð}ÏÐÐð"ª"0F¼6F »Tgclocals·2018557e3ee0abccf2865b16663e690bTgclocals·b5f842672308ee6e2fa72d6ff2f86a79®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ6"".(*parser).parsePackageId€üeH‹ %H;awèëêHƒì`HÇD$pHÇD$xH‹\$hH‰$ÇD$úÿÿÿèH‹L$H‹D$H‰L$PH‰ $H‰D$XH‰D$èH‹t$H‰t$0H‹L$H‰L$8H‹D$ H‹T$(HƒøtDH‰D$@H‰$H‰T$HH‰T$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹\$hH‰$èH‹t$0H‹L$8HƒùuH‹\$hHƒûtH‹³@H‹‹HH‰t$pH‰L$xHƒÄ`Éëß
 0runtime.morestack_noctxt|&"".(*parser).expectÀstrconv.Unquote¸runtime.convI2Eü$"".(*parser).error0À
"".autotmp_0210type.string "".err?type.error
"".id_type.string "".~r0type.string"".ptype.*"".parserÀß¿À€$Â,VD=^eTgclocals·d7e8a62d22b1cde6d92b17a55c33fe8fTgclocals·23c4785fa8abd7e258acfe91c9f325f3®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ:"".(*parser).parsePackageNameÀeH‹ %H;awèëêHƒì HÇD$0HÇD$8H‹\$(H‰$ÇD$þÿÿÿèH‹L$H‹D$H‰L$0H‰D$8HƒÄ Ã
 0runtime.morestack_noctxt|&"".(*parser).expect0@ "".~r0type.string"".ptype.*"".parser@@?` à,4
=#Tgclocals·a08e9001cb8f9d822225de3b8e406515Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4"".(*parser).parseDotIdent€öeH‹ %H;awèëêHƒìXH‹D$`HÇD$hHÇD$pHÇD$8HÇD$@‹˜(ƒûý„ιx‹˜(ƒûþ…¦ƒù ޱH‹T$8H‹L$@H‰T$HH‰$H‰L$PH‰L$Hƒø„ÞH�¨0H�\$H‰ßH‰îH¥H¥èH‹\$ H‰\$8H‹\$(H‰\$@H‹\$`H‰$Hƒ<$„�è‹\$‰\$4H‹\$`H‰$è‹L$4H‹D$`‹˜(ƒûþ„Zÿÿÿ‹˜(ƒûýu>ƒù �OÿÿÿH‹\$@HƒûuH‰$ÇD$þÿÿÿèH‹\$8H‰\$hH‹\$@H‰\$pHƒÄX˘(�û·u½éþþÿÿ‰%éeÿÿÿ‰éÿÿÿ
 0runtime.morestack_noctxtÚ*runtime.concatstring2´8text/scanner.(*Scanner).Peekà""".(*parser).nextð&"".(*parser).expect0°
"".autotmp_0212type.string "".sepGtype.int32"".ident?type.string "".~r0type.string"".ptype.*"".parser°º¯°+€@ê1V!#   ¬-§Tgclocals·d7e8a62d22b1cde6d92b17a55c33fe8fTgclocals·29f0050a5ee7c2b9348a75428171d7de®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ>"".(*parser).parseQualifiedName ’eH‹ %H;awèëêHƒì HÇD$@HÇD$HHÇD$0HÇD$8H‹\$(H‰$ÇD$@èH‹\$(H‰$èH‹L$H‹D$H‰L$0H‰D$8H‹\$(H‰$ÇD$.èH‹D$(‹˜(ƒû?uH‰$èHƒÄ ÃH‰$èH‹L$H‹D$H‰L$@H‰D$HëÜ
 0runtime.morestack_noctxt &"".(*parser).expect¼6"".(*parser).parsePackageId�&"".(*parser).expectÂ""".(*parser).nextÞ4"".(*parser).parseDotIdentP@"".autotmp_0215type.string"".name0type.string
"".idtype.string"".ptype.*"".parser@�?@&Ð(Ž>"   O8'"Tgclocals·bae0cb6de1cb890aa8f1070add725460Tgclocals·0372b889336bbdf612862c172920463d®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ&"".(*parser).getPkgÀ¼eH‹ %H;awèëêHƒìXH‹D$pHƒøuIH‹t$hH‰4$H‰D$H�5L�D$L‰ÇH¥H¥èH‹D$p¶\$ €ûtH‹H‰œ$ˆHƒÄXÃH‹L$hH�H‰$H‹\$`H‹«PH‰l$H‰L$HH‰L$H‰D$PH‰D$èH‹Œ$€H‹\$ H‹1íH9è…ŽHƒù„„H‹\$hH‰$H‹\$pH‰\$H‹\$xH‰\$H‰L$èH‹D$ H‹\$hH‰\$8H‹\$pH‰\$@H‰D$(H‰D$0H�H‰$H‹\$`H‹«PH‰l$H�\$8H‰\$H�\$0H‰\$èH‹D$(H‰„$ˆHƒÄXÃ
 0runtime.morestack_noctxtl$go.string."unsafe"Ž runtime.eqstringºDgolang.org/x/tools/go/types.Unsafeìhtype.map[string]*golang.org/x/tools/go/types.PackageÈ4runtime.mapaccess1_faststràLgolang.org/x/tools/go/types.NewPackage´htype.map[string]*golang.org/x/tools/go/types.Package�$runtime.mapassign1`°"".autotmp_0220ORtype.*golang.org/x/tools/go/types.Package"".autotmp_0219?type.string"".autotmp_0218Rtype.*golang.org/x/tools/go/types.Package"".autotmp_0216type.string "".pkg_Rtype.*golang.org/x/tools/go/types.Package "".~r2PRtype.*golang.org/x/tools/go/types.Package"".name0type.string
"".idtype.string"".ptype.*"".parser °S¯°ï¯à$°;J,XF�Tgclocals·9d0fdb5a8b6bdb6e912289f44b76055aTgclocals·73433c54fb853071f1115ac5da3c80d0®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ<"".(*parser).parseExportedName€âeH‹ %H�D$øH;AwèëåH�ìˆHÇ„$ HÇ„$¨H‹œ$�H‰$èH‹L$H‹D$H‹\$H‰œ$ H‹\$ H‰œ$¨H‹œ$�H‰$H‰L$0H‰L$H‰D$8H‰D$H�\$HÇHÇCèH‹D$(H‰„$˜1íH9è…âH‹\$0H‰\$PH‹\$8H‰\$XH�\$`HÇHÇCH�\$`Hƒû„³HÇÂHÇÁH‰\$pH‰T$xH‰Œ$€H�H‰$H�\$PH‰\$èH‹L$H‹D$H‹\$pH‰$H‰L$@H‰L$H‰D$HH‰D$èH‹´$�H‰4$H�5H�l$H‰ïH¥H¥H‹\$pH‰\$H‹\$xH‰\$ H‹œ$€H‰\$(èH�ĈÉéFÿÿÿ
*0runtime.morestack_noctxtŽ>"".(*parser).parseQualifiedNameÈ&"".(*parser).getPkg´type.stringÚruntime.convT2E²2runtime.writebarrierifaceØ@go.string."%s package not found"¼&"".(*parser).errorf@�"".autotmp_0226�"type.interface {}"".autotmp_0224/&type.[]interface {}"".autotmp_0223otype.string"".autotmp_0222O(type.[1]interface {}
"".id¯type.string"".name type.string "".pkgRtype.*golang.org/x/tools/go/types.Package"".ptype.*"".parser"�‡��À"Ð:5>âF]‰q#Tgclocals·9c40096308bb5d08ee85877960396436Tgclocals·68a955d9197f50134fd00c00810c9e06®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ6"".(*parser).parseBasicTypeà Ö eH‹ %H�D$¸H;AwèëåH�ìÈHÇ„$ØHÇ„$àH‹œ$ÐH‰$ÇD$þÿÿÿèH‹T$H‹L$H‹H‰T$`H‰L$hHÇD$0HÇD$8H‰T$PH‰L$XH�H‰$H‹h0H‰l$H‰”$ H‰T$H‰Œ$¨H‰L$èH‹\$ Hƒû„˜H‹ H‹kH‰L$0H‰l$8H�H‰$H‰L$@H‰L$H‰l$HH‰l$èH‹L$¶\$ €ût-Hƒùt#H‰ËH‹I(H‹k0H‰Œ$ØH‰¬$àH�ÄÈÉëÙH‹\$`H‰œ$€H‹\$hH‰œ$ˆH�œ$�HÇHÇCH�œ$�Hƒû„ÝHÇÂHÇÁH‰œ$°H‰”$¸H‰Œ$ÀH�H‰$H�œ$€H‰\$èH‹L$H‹D$H‹œ$°H‰$H‰L$pH‰L$H‰D$xH‰D$èH‹´$ÐH‰4$H�5H�l$H‰ïH¥H¥H‹œ$°H‰\$H‹œ$¸H‰\$ H‹œ$ÀH‰\$(èHÇ„$ØHÇ„$àH�ÄÈÉéÿÿÿ‰éaþÿÿ
*0runtime.morestack_noctxtž&"".(*parser).expectÀHgolang.org/x/tools/go/types.Universešdtype.map[string]golang.org/x/tools/go/types.Objectò4runtime.mapaccess1_faststrÀTtype.*golang.org/x/tools/go/types.TypeNameú$runtime.assertI2T2Òtype.stringþruntime.convT2EÜ2runtime.writebarrieriface‚@go.string."not a basic type: %s"ò&"".(*parser).errorf0�"".autotmp_0237¯"type.interface {}"".autotmp_0235/&type.[]interface {}"".autotmp_0234�type.string"".autotmp_0233o(type.[1]interface {}"".autotmp_0231type.string"".autotmp_0230Otype.string "".~r0¯Ntype.golang.org/x/tools/go/types.ObjectFgolang.org/x/tools/go/types.name·3ïtype.string "".obj�Ntype.golang.org/x/tools/go/types.Object
"".idÏtype.string "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parser("�–��£��ð,ì:#€3-€  Nj†z8Tgclocals·1ee14e32cec51f1cde6c2b0577d81887Tgclocals·0028a114a78b775944525d29ef16e5c0®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ6"".(*parser).parseArrayType žeH‹ %H�D$ðH;AwèëåH�ì�HÇ„$ HÇ„$¨H‹œ$˜H‰$ÇD$ýÿÿÿèH‹L$H‹D$H‰L$PH‰D$XH‹œ$˜H‰$ÇD$]èH‹œ$˜H‰$èH‹L$H‹D$H‰Œ$€H‰„$ˆH‹\$PH‰$H‹\$XH‰\$HÇD$
HÇD$@èH‹\$ H‰\$8H‹D$(H‹L$0H‰L$hHƒøH‰D$`t3H‰$H‰L$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹œ$˜H‰$èH‹œ$€H‰\$pH‹œ$ˆH‰\$xH‹\$8H‰\$@H�H‰$èH‹D$H‹l$@H‰(H‰D$HH‰$Hƒ<$„‚Hƒ$H‹\$pH‰\$H‹\$xH‰\$èH‹\$HH‰\$HH‹1íH9ètH‹\$HH‰œ$¨H‰„$ H�Ä�ÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%érÿÿÿ
*0runtime.morestack_noctxtž&"".(*parser).expectø&"".(*parser).expectš,"".(*parser).parseType¢ strconv.ParseInt†runtime.convI2EÐ$"".(*parser).error¦Ltype.golang.org/x/tools/go/types.Array¸"runtime.newobject2runtime.writebarrierifaceØ–go.itab.*golang.org/x/tools/go/types.Array.golang.org/x/tools/go/types.Type®Ntype.*golang.org/x/tools/go/types.ArrayÄJtype.golang.org/x/tools/go/types.TypeÜ–go.itab.*golang.org/x/tools/go/types.Array.golang.org/x/tools/go/types.Typeð runtime.typ2Itab0 "".autotmp_0245�Ntype.*golang.org/x/tools/go/types.Array"".autotmp_0244Ntype.*golang.org/x/tools/go/types.Array"".autotmp_0243Ntype.*golang.org/x/tools/go/types.ArrayDgolang.org/x/tools/go/types.len·3Ÿtype.int64Fgolang.org/x/tools/go/types.elem·2?Jtype.golang.org/x/tools/go/types.Type "".err_type.error"".n¯type.int64"".elemJtype.golang.org/x/tools/go/types.Type "".littype.string "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parser" ±Ÿ <�&„:-+C 3äN-U‹?vTgclocals·b46c7a32cd3cbdb99d262657bbb5cb46Tgclocals·3b54427f77b858635567cdebca418360®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ2"".(*parser).parseMapType ˆeH‹ %H;awèëêHƒìhHÇD$xHÇ„$€H‹t$pH‰4$H�5H�l$H‰ïH¥H¥èH‹\$pH‰$ÇD$[èH‹\$pH‰$èH‹L$H‹D$H‰L$8H‰D$@H‹\$pH‰$ÇD$]èH‹\$pH‰$èH‹L$H‹D$H‹\$8H‰\$(H‹\$@H‰\$0H‰L$XH‰L$HH‰D$`H‰D$PH�H‰$èH‹D$H‰D$ H‰$Hƒ<$„±H‹\$(H‰\$H‹\$0H‰\$èH‹\$ H‰$Hƒ<$t|Hƒ$H‹\$HH‰\$H‹\$PH‰\$èH‹\$ H‰\$ H‹1íH9ètH‹\$ H‰œ$€H‰D$xHƒÄhÃH�H‰$H�H‰\$H�H‰\$èH‹D$뺉%éxÿÿÿ‰%éCÿÿÿ"
 0runtime.morestack_noctxtvgo.string."map"˜4"".(*parser).expectKeywordÄ&"".(*parser).expectà,"".(*parser).parseType´&"".(*parser).expectÐ,"".(*parser).parseTypeÂHtype.golang.org/x/tools/go/types.MapÔ"runtime.newobject¸2runtime.writebarrieriface”2runtime.writebarrieriface’go.itab.*golang.org/x/tools/go/types.Map.golang.org/x/tools/go/types.Type€Jtype.*golang.org/x/tools/go/types.Map–Jtype.golang.org/x/tools/go/types.Type®’go.itab.*golang.org/x/tools/go/types.Map.golang.org/x/tools/go/types.Type runtime.typ2Itab0Ð"".autotmp_0252�Jtype.*golang.org/x/tools/go/types.Map"".autotmp_0251Jtype.*golang.org/x/tools/go/types.Map"".autotmp_0250Jtype.*golang.org/x/tools/go/types.Map"".autotmp_0249Jtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.elem·3?Jtype.golang.org/x/tools/go/types.TypeDgolang.org/x/tools/go/types.key·2Jtype.golang.org/x/tools/go/types.Type"".elemJtype.golang.org/x/tools/go/types.Type "".key_Jtype.golang.org/x/tools/go/types.Type "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parserÐâÏÐSÐ" /!"šKNP2.‡Tgclocals·b46c7a32cd3cbdb99d262657bbb5cb46Tgclocals·9904a18ebecacd70db484009ca7b051b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ,"".(*parser).parseNameàÚeH‹ %H;awèëêHƒìPH‹D$XHÇD$pHÇD$xHÇD$h‹¨(ƒýþunH�=H‰<$H‹°PH‰t$H�°@H�|$H¥H¥èH‹L$XH‹\$ H‹+H‰l$hHƒùt&H‹©0H‰l$pH‹©8H‰l$xH‰ $èHƒÄPÉëÖƒý?uIH�=H‰<$H‹°PH‰t$H�°@H�|$H¥H¥èH‹\$ H‹+H‰l$hH‹\$XH‰$è멃ý@…ÊHÇD$0HÇD$8H‰$èH‹L$H‹D$H‹\$H‰\$pH‹\$ H‰\$x€|$`„\ÿÿÿH‹\$XH‰$H‰L$0H‰L$H‰D$8H‰D$H�\$HÇHÇCèH‹D$(H‰D$h1íH9è…ÿÿÿH‹\$0H‰$H‹\$8H‰\$H�\$HÇHÇCèH‹\$ H‰\$héÖþÿÿH�H‹+H‰l$@H‹kH‰l$HH�H‰$H�\$@H‰\$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹\$XH‰$èé}þÿÿ
 0runtime.morestack_noctxt�htype.map[string]*golang.org/x/tools/go/types.PackageÚ4runtime.mapaccess1_faststrÌ""".(*parser).nextöhtype.map[string]*golang.org/x/tools/go/types.PackageÀ4runtime.mapaccess1_fastströ""".(*parser).nextÂ>"".(*parser).parseQualifiedName€&"".(*parser).getPkg‚Lgolang.org/x/tools/go/types.NewPackage®2go.string."name expected"Þtype.string„runtime.convT2EÈ$"".(*parser).errorP "".autotmp_0259type.string"".autotmp_0258Rtype.*golang.org/x/tools/go/types.Package"".autotmp_0257Rtype.*golang.org/x/tools/go/types.Package"".autotmp_0256Rtype.*golang.org/x/tools/go/types.Package
"".id?type.string"".name0type.string "".pkg Rtype.*golang.org/x/tools/go/types.Package""".materializePkgtype.bool"".ptype.*"".parser ”Ÿ �°\Æ:> ()9  ' ;6 T&l9:&_AA/Tgclocals·73838a813f5b7a9652ab0ab1a7cfc095Tgclocals·e621a0ba6eb379ba26c5eb53e098e9d1®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".derefÀªeH‹ %H;awèëêHƒì(HÇD$@HÇD$HH�H‰$H‹\$0H‰\$H‹\$8H‰\$èH‹D$1íH9èt HƒøtH‹H‹hH‰L$@H‰l$HHƒÄ(ÉëæH‹\$0H‰\$@H‹\$8H‰\$HHƒÄ(Ã
 0runtime.morestack_noctxt^Rtype.*golang.org/x/tools/go/types.Pointer˜$runtime.assertI2T2@P "".~r1 Jtype.golang.org/x/tools/go/types.Type "".typJtype.golang.org/x/tools/go/types.TypeP]OPO  þ,0 $
KUTgclocals·78fd77a07ab543a063c3a3049973febeTgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ."".(*parser).parseField †eH‹ %H�„$ÿÿÿH;AwèëâH�ìpHÇ„$ˆHÇ„$�H‹œ$xH‰$ÆD$èH‹\$H‰\$HH‹\$H‰œ$ØH‹\$ H‰œ$àH‹œ$xH‰$èH‹L$H‹D$H‰Œ$ˆH‰„$�ÆD$3H‹œ$àHƒû…èH‹œ$ˆH‰$H‹œ$�H‰\$èH‹L$H‹D$H‰Œ$(H‰„$0H‰Œ$H‰ $H‰„$H‰D$è‹T$‰T$4�úX Áâ…FH�H‰$H‹œ$H‰\$H‹œ$H‰\$è‹T$4H‹L$¶\$ €û„HÇD$HH‰ËHƒù„èH‹IH‹kH‰L$XH‰Œ$ØH‰l$`H‰¬$àÆD$3HÇ„$¨HÇ„$°H‹¬$x‹�(ƒûú…òH‹œ$xH‰$ÇD$úÿÿÿèH‹L$H‹D$HÇ„$èHÇ„$ðH‰Œ$¸H‰ $H‰„$ÀH‰D$èH‹\$H‰œ$¨H‹\$H‰œ$°H‹D$ H‹\$(H‰œ$ðHƒøH‰„$è„[H‹œ$¸H‰œ$H‹œ$ÀH‰œ$ H�¼$P1ÀèH�œ$PHƒû„³HÇÂHÇÁH‰œ$8H‰”$@H‰Œ$HH�H‰$H�œ$H‰\$èH‹L$H‹D$H‹œ$8H‰$H‰Œ$øH‰L$H‰„$H‰D$èH‹œ$èH‰$H‹œ$ðH‰\$èH‹L$H‹D$H‹œ$8HƒÃH‰$H‰Œ$øH‰L$H‰„$H‰D$èH‹´$xH‰4$H�5H�l$H‰ïH¥H¥H‹œ$8H‰\$H‹œ$@H‰\$ H‹œ$HH‰\$(èHÇD$8H‹\$HH‰\$@H‹œ$ØH‰œ$ÈH‹œ$àH‰œ$ÐH‹œ$ˆH‰\$xH‹œ$�H‰œ$€¶\$3ˆ\$2H�H‰$èH‹L$H‰ÏHƒù„1Àè1íH‰)H‹l$8H‰iH‰L$PH‰ $Hƒ<$„âHƒ$H‹\$@H‰\$èH‹\$PH‰$Hƒ<$„®Hƒ$H‹œ$ÈH‰\$H‹œ$ÐH‰\$èH‹\$PH‰$Hƒ<$tqHƒ$(H‹\$xH‰\$H‹œ$€H‰\$èH‹D$PÇ@8¶l$2@ˆh@HÇÅ@ˆhBH‰„$€H‹œ$¨H‰œ$ˆH‹œ$°H‰œ$�H�ÄpÉ%놉%éFÿÿÿ‰%éÿÿÿ‰éâþÿÿ‰éFýÿÿ‰éüÿÿ�úúÒŽúumH�H‰$H‹œ$H‰\$H‹œ$H‰\$èH‹D$¶\$ €ût4H‹Hƒût'H‹KH‹k H‰L$hH‰Œ$ØH‰l$pH‰¬$àéÂûÿÿ‰ëÕH‹œ$H‰œ$˜H‹œ$H‰œ$ H‹´$xH‰4$H�5H�l$H‰ïH¥H¥H�\$HÇHÇCHÇCèéYûÿÿ8
00runtime.morestack_noctxtž,"".(*parser).parseNameˆ,"".(*parser).parseType¦"".deref–$runtime.ifacethashÌNtype.*golang.org/x/tools/go/types.Basic’$runtime.assertI2T2Ê&"".(*parser).expectÊstrconv.Unquote¤
ð runtime.duffzero¢ type.stringÎ runtime.convT2E¸ 2runtime.writebarrierifaceô runtime.convI2Eæ␍2runtime.writebarrierifaceŒJgo.string."invalid struct tag %s: %s"ü&"".(*parser).errorf¼Htype.golang.org/x/tools/go/types.VarÎ"runtime.newobject€Ü runtime.duffzeroì.runtime.writebarrierptrÜ4runtime.writebarrierstring¾2runtime.writebarrierifaceèNtype.*golang.org/x/tools/go/types.Named®$runtime.assertI2T2šHgo.string."anonymous field expected"ô&"".(*parser).errorf@à:"".autotmp_0274¿Jtype.*golang.org/x/tools/go/types.Var"".autotmp_0273Jtype.*golang.org/x/tools/go/types.Var"".autotmp_0272"type.interface {}"".autotmp_0271ï"type.interface {}"".autotmp_0269o&type.[]interface {}"".autotmp_0268÷type.uint32"".autotmp_0266ÏJtype.golang.org/x/tools/go/types.Type"".autotmp_0265¯type.string"".autotmp_0264?(type.[2]interface {}"".autotmp_0262Jtype.golang.org/x/tools/go/types.Type"".autotmp_0261�Jtype.golang.org/x/tools/go/types.TypePgolang.org/x/tools/go/types.anonymous·6ûtype.boolDgolang.org/x/tools/go/types.typ·5ïJtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4Ïtype.stringDgolang.org/x/tools/go/types.pkg·3ßRtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2ï"type.go/token.Pos "".~r0�type.string "".~r0¯type.string "".err�type.error"".sïtype.string "".tag�type.string "".typ¯Jtype.golang.org/x/tools/go/types.Type"".anonymousùtype.bool "".typÏJtype.golang.org/x/tools/go/types.Type"".name¯type.string "".pkgÏRtype.*golang.org/x/tools/go/types.Package "".~r1 type.string "".~r0Jtype.*golang.org/x/tools/go/types.Var"".ptype.*"".parser%à�
ßà�Ð r�=:+« / #JÛ™A
+ @LN5O8Ú@ÂS„iO81¸£Tgclocals·36220f0e6724f53c97d45e8865178a15Tgclocals·23f2ba6ee7d6cd04ab5c29bd12b9e67e®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ8"".(*parser).parseStructType žeH‹ %H�D$¸H;AwèëåH�ìÈHÇ„$ØHÇ„$àHÇ„$€HÇ„$ˆHÇ„$�HÇD$hHÇD$pHÇD$xH‹´$ÐH‰4$H�5H�l$H‰ïH¥H¥èH‹œ$ÐH‰$ÇD${èH‹´$Ð1À‹ž(ƒû}„‚‹ž(ƒûÿ„sH‰D$@Hƒø~H‰4$ÇD$;èH‹´$ÐH‰4$èH‹D$@H‹T$hH‹\$H‰\$HH‹\$H‰\$XH‹\$H‰\$`H‹\$`Hƒût9Hƒúu3H�H‰$H‰D$H‰D$èH‹T$H‹L$ H‹D$(H‰L$pH‰D$xHƒúH‰T$h„ÔH‹L$pH‹\$xH‰ØH)ËHƒû}OH�H‰$H‰”$°H‰T$H‰Œ$¸H‰L$H‰„$ÀH‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$¸H‰„$ÀH‰ÓH‰”$°H‰ÍHkíHëH‰$H‹\$XH‰\$H‹\$`H‰\$èH‹”$°H‹Œ$¸H‹„$ÀH‰T$hH‰L$pH‰D$xH‹”$€H‹Œ$ˆH‹œ$�H‰ØH)ËHƒû}OH�H‰$H‰”$˜H‰T$H‰Œ$ H‰L$H‰„$¨H‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÍHÿÅH‰¬$ H‰„$¨H‰”$˜H�ÊH‰$H‹\$HH‰\$èH‹´$ÐH‹”$˜H‹Œ$ H‹„$¨H‰”$€H‰Œ$ˆH‰„$�H‹D$@HÿÀ‹ž(ƒû}…~ýÿÿH‰4$ÇD$}èH‹œ$€H‰$H‹œ$ˆH‰\$H‹œ$�H‰\$H‹\$hH‰\$H‹\$pH‰\$ H‹\$xH‰\$(èH‹\$0H‰\$PH‹1íH9ètH‹\$PH‰œ$àH‰„$ØH�ÄÈÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´,
*0runtime.morestack_noctxt�$go.string."struct"²4"".(*parser).expectKeywordä&"".(*parser).expectì&"".(*parser).expectŽ."".(*parser).parseFieldŽtype.[]string´"runtime.makeslice¾type.[]string°"runtime.growsliceÞ4runtime.writebarrierstring‚
Ntype.[]*golang.org/x/tools/go/types.Varô
"runtime.growsliceü .runtime.writebarrierptr¼␍&"".(*parser).expectÎJgolang.org/x/tools/go/types.NewStructð˜go.itab.*golang.org/x/tools/go/types.Struct.golang.org/x/tools/go/types.TypeÆPtype.*golang.org/x/tools/go/types.StructÜJtype.golang.org/x/tools/go/types.Typeô˜go.itab.*golang.org/x/tools/go/types.Struct.golang.org/x/tools/go/types.Typeˆ runtime.typ2Itab0� "".autotmp_0292type.uint64"".autotmp_0291type.uint64"".autotmp_0290type.int"".autotmp_0289type.int"".autotmp_0288_Ntype.[]*golang.org/x/tools/go/types.Var"".autotmp_0284type.int"".autotmp_0283type.[]string"".autotmp_0282ïPtype.*golang.org/x/tools/go/types.Struct"".autotmp_0278/type.[]string "".tagßtype.string "".fldÿJtype.*golang.org/x/tools/go/types.Var"".i�type.int"".tags¿type.[]string"".fields�Ntype.[]*golang.org/x/tools/go/types.Var "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parser"�½��0�NÐ:$$!  13Ôà®.˜ÁÕ‹D`I] ␍Tgclocals·65da895b3dbef1b5b79355c3852ec825Tgclocals·2675b89e255790cd90da655dc803218d®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ6"".(*parser).parseParameter€␍ü eH‹ %H�D$èH;AwèëåH�ì˜Æ„$°H‹œ$ H‰$ÆD$èH‹L$H‹D$ H‰L$xH‰ $H‰„$€H‰D$H�H�l$H‰ïH‰ÞH¥H¥èH‹”$ H‹D$ Hƒø|#H‹Œ$€H9Á‚˜H‹L$xH‰L$xH‰„$€‹š(ƒû.u/H‰$H�H�l$H‰ïH‰ÞH¥H¥èH‹”$ Æ„$°H‰$èH‹T$H‹L$H‰T$XH‰L$`€¼$°„†H‰”$ˆH‰Œ$�H�H‰$èH‹D$H‰D$@H‰$Hƒ<$„ÜH‹œ$ˆH‰\$H‹œ$�H‰\$èH‹\$@H‰\$@H‹1íH9è„oH‹L$@H‰L$`H‰ÂH‰D$XH‹¬$ ‹�(ƒûúuH‹œ$ H‰$èH‹T$XH‹L$`HÇD$(HÇD$0H‹\$xH‰\$hH‹œ$€H‰\$pH‰T$HH‰L$PH�H‰$èH‹L$H‰ÏHƒù„Ó1Àè1íH‰)H‹l$(H‰iH‰L$8H‰ $Hƒ<$„žHƒ$H‹\$0H‰\$èH‹\$8H‰$Hƒ<$tqHƒ$H‹\$hH‰\$H‹\$pH‰\$èH‹\$8H‰$Hƒ<$t:Hƒ$(H‹\$HH‰\$H‹\$PH‰\$èH‹D$8Ç@8H‰„$¨H�ĘÉ%뽉%놉%éVÿÿÿ‰é&ÿÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$é_þÿÿ‰%éþÿÿè 0
*0runtime.morestack_noctxtx,"".(*parser).parseNameÆgo.string."·"îstrings.Index†go.string."..."®4"".(*parser).expectSpecialà,"".(*parser).parseTypeÒLtype.golang.org/x/tools/go/types.Sliceä"runtime.newobjectÔ2runtime.writebarrierifaceö–go.itab.*golang.org/x/tools/go/types.Slice.golang.org/x/tools/go/types.Typeø""".(*parser).next€Htype.golang.org/x/tools/go/types.Var’"runtime.newobjectÄÜ runtime.duffzero° .runtime.writebarrierptrŒ
4runtime.writebarrierstringè
2runtime.writebarrierifaceø Ntype.*golang.org/x/tools/go/types.SliceŽ Jtype.golang.org/x/tools/go/types.Type¦ –go.itab.*golang.org/x/tools/go/types.Slice.golang.org/x/tools/go/types.Typeº  runtime.typ2Itabð $runtime.panicslice0°"".autotmp_0310¿Jtype.*golang.org/x/tools/go/types.Var"".autotmp_0309Jtype.*golang.org/x/tools/go/types.Var"".autotmp_0307¯Ntype.*golang.org/x/tools/go/types.Slice"".autotmp_0306Ntype.*golang.org/x/tools/go/types.Slice"".autotmp_0303Ntype.*golang.org/x/tools/go/types.SliceDgolang.org/x/tools/go/types.typ·5ŸJtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4_type.stringDgolang.org/x/tools/go/types.pkg·3ÏRtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2ß"type.go/token.PosFgolang.org/x/tools/go/types.elem·2Jtype.golang.org/x/tools/go/types.Type "".typJtype.golang.org/x/tools/go/types.Type"".name?type.string"".isVariadic type.bool "".parJtype.*golang.org/x/tools/go/types.Var"".ptype.*"".parser"°±¯°lÀL„* D# '†‚%␍> :;;`B8RMO..i  Tgclocals·3591272cda6ee607a1a868780763d60cTgclocals·6a2917e131227f3ce58256bd9b19a984®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ8"".(*parser).parseParameters€ îeH‹ %H;awèëêHƒìxÆ„$ HÇ„$ˆHÇ„$�HÇ„$˜H‹œ$€H‰$ÇD$(èH‹´$€‹ž(ƒû)„¦‹ž(ƒûÿ„—H‹œ$�HƒûŽ›H‰4$ÇD$,èH‹´$€H‰4$èH‹\$H‰\$H¶\$ˆ\$GH‹”$ˆH‹Œ$�H‹œ$˜H‰ØH)ËHƒû}FH�H‰$H‰T$`H‰T$H‰L$hH‰L$H‰D$pH‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰t$hH‰D$pH‰T$`H�ÊH‰$H‹\$HH‰\$èH‹´$€H‹T$`H‹L$hH‹D$pH‰”$ˆH‰Œ$�H‰„$˜€|$G„Ëþÿÿ€¼$ t_H�H‹+H‰l$PH‹kH‰l$XH�H‰$H�\$PH‰\$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹œ$€H‰$èH‹´$€Æ„$ ‹ž(ƒû)…ZþÿÿH‰4$ÇD$)èHƒÄxÃéyþÿÿ
 0runtime.morestack_noctxt&"".(*parser).expectÈ&"".(*parser).expectê6"".(*parser).parseParameteræNtype.[]*golang.org/x/tools/go/types.VarÆ"runtime.growslice¼.runtime.writebarrierptrÒJgo.string."... not on final argument"‚type.string¨runtime.convT2Eò$"".(*parser).errorÒ&"".(*parser).expectPð"".autotmp_0318type.int"".autotmp_0317/Ntype.[]*golang.org/x/tools/go/types.Var"".autotmp_0316Otype.string"".variadicatype.bool "".par_Jtype.*golang.org/x/tools/go/types.Var"".isVariadic@type.bool"".listNtype.[]*golang.org/x/tools/go/types.Var"".ptype.*"".parserð—ïðÀB¸F!Å 
_ZÈ;vUTgclocals·45293744f10a4f121a8740fb3c189a68Tgclocals·9fa61dd53bc165eaa4cad5bd08ec0f05®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ6"".(*parser).parseSignatureàÒeH‹ %H;awèëêH�ì€H‹œ$ˆH‰$èH‹„$ˆH‹\$H‰\$hH‹\$H‰\$pH‹\$H‰\$x¶\$ ˆ\$7HÇD$PHÇD$XHÇD$`‹˜(ƒû(…ˆH‰$èH‹\$H‰\$PH‹\$H‰\$XH‹\$H‰\$`¶\$ €ûtWH�H‹+H‰l$@H‹kH‰l$HH�H‰$H�\$@H‰\$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹œ$ˆH‰$èH‹\$hH‰$H‹\$pH‰\$H‹\$xH‰\$èH‹\$H‰\$8H‹\$PH‰$H‹\$XH‰\$H‹\$`H‰\$èH‹D$HÇ$H‹œ$�H‰\$H‹\$8H‰\$H‰D$¶\$7ˆ\$ èH‹\$(H‰œ$˜H�Ä€Ã
 0runtime.morestack_noctxtT8"".(*parser).parseParameters˜8"".(*parser).parseParametersöXgo.string."... not permitted on result type"¦type.stringÌruntime.convT2E–$"".(*parser).errorÚHgolang.org/x/tools/go/types.NewTuple²Hgolang.org/x/tools/go/types.NewTuple Pgolang.org/x/tools/go/types.NewSignature0€"".autotmp_0326�Ntype.*golang.org/x/tools/go/types.Tuple"".autotmp_0325type.string"".results_Ntype.[]*golang.org/x/tools/go/types.Var"".isVariadic‘type.bool"".params/Ntype.[]*golang.org/x/tools/go/types.Var "".~r1 Vtype.*golang.org/x/tools/go/types.Signature"".recvJtype.*golang.org/x/tools/go/types.Var"".ptype.*"".parser€‹ÿ°&æ@,W¡)bZG,7!Tgclocals·ab01a2d55089ff50c402006df1039c39Tgclocals·80d0fa02e2185bd68d71e001e5be726f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ>"".(*parser).parseInterfaceType  eH‹ %H�D$¨H;AwèëåH�ìØHÇ„$èHÇ„$ðHÇ„$¨HÇ„$°HÇ„$¸H‹´$àH‰4$H�5H�l$H‰ïH¥H¥èH‹œ$àH‰$ÇD${èH‹´$à1À‹ž(ƒû}„¼‹ž(ƒûÿ„­H‰D$HHƒø~H‰4$ÇD$;èH‹´$àH‰4$ÆD$èH‹\$H‰\$XH‹\$H‰œ$˜H‹\$ H‰œ$ H‹œ$àH‰$HÇD$èH‹D$HÇD$@H‹\$XH‰\$PH‹œ$˜H‰œ$ˆH‹œ$ H‰œ$�HÇD$xHÇ„$€1íH9èt)H‰D$pH‹1íH9è„ÀH‹\$pH‰œ$€H‰D$xH�H‰$èH‹D$1íH‰(H‹l$@H‰hH‰D$`H‰$Hƒ<$„kHƒ$H‹\$PH‰\$èH‹\$`H‰$Hƒ<$„7Hƒ$H‹œ$ˆH‰\$H‹œ$�H‰\$èH‹\$`H‰$Hƒ<$„óHƒ$(H‹\$xH‰\$H‹œ$€H‰\$èH‹D$`Ç@8H‰D$`H‹”$¨H‹Œ$°H‹œ$¸H‰ØH)ËHƒû}OH�H‰$H‰”$ÀH‰T$H‰Œ$ÈH‰L$H‰„$ÐH‰D$HÇD$ èH‹T$(H‹L$0H‹D$8H‰ÎHÿÆH‰´$ÈH‰„$ÐH‰”$ÀH�ÊH‰$H‹\$`H‰\$èH‹´$àH‹”$ÀH‹Œ$ÈH‹„$ÐH‰”$¨H‰Œ$°H‰„$¸H‹D$HHÿÀ‹ž(ƒû}…DýÿÿH‰4$ÇD$}èH‹œ$¨H‰$H‹œ$°H‰\$H‹œ$¸H‰\$H�\$HÇHÇCHÇCèH‹\$0H‰$èH‹\$H‰\$hH‹1íH9ètH‹\$hH‰œ$ðH‰„$èH�ÄØÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%éþÿÿ‰%é½ýÿÿ‰%é‰ýÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$éýÿÿ:
*0runtime.morestack_noctxtÚ*go.string."interface"ü4"".(*parser).expectKeyword®&"".(*parser).expect&"".(*parser).expectâ,"".(*parser).parseNameÞ6"".(*parser).parseSignaturežžgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.TypeæJtype.golang.org/x/tools/go/types.Funcø"runtime.newobjectî.runtime.writebarrierptrÞ4runtime.writebarrierstringÈ 2runtime.writebarrierifaceÀ
Ptype.[]*golang.org/x/tools/go/types.Func² "runtime.growsliceº .runtime.writebarrierptrú␍&"".(*parser).expectˆPgolang.org/x/tools/go/types.NewInterface¤bgolang.org/x/tools/go/types.(*Interface).CompleteÆžgo.itab.*golang.org/x/tools/go/types.Interface.golang.org/x/tools/go/types.TypeœVtype.*golang.org/x/tools/go/types.Interface²Jtype.golang.org/x/tools/go/types.TypeÊžgo.itab.*golang.org/x/tools/go/types.Interface.golang.org/x/tools/go/types.TypeÞ runtime.typ2ItabÂVtype.*golang.org/x/tools/go/types.SignatureØJtype.golang.org/x/tools/go/types.Typeðžgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.Type„ runtime.typ2Itab0°("".autotmp_0344type.*uint8"".autotmp_0340type.int"".autotmp_0339/Ptype.[]*golang.org/x/tools/go/types.Func"".autotmp_0338Ltype.*golang.org/x/tools/go/types.Func"".autotmp_0337ïLtype.*golang.org/x/tools/go/types.Func"".autotmp_0336Ltype.*golang.org/x/tools/go/types.Func"".autotmp_0334Vtype.*golang.org/x/tools/go/types.Interface"".autotmp_0333ßVtype.*golang.org/x/tools/go/types.Interface"".autotmp_0330Vtype.*golang.org/x/tools/go/types.Signature"".autotmp_0329ÏVtype.*golang.org/x/tools/go/types.SignatureDgolang.org/x/tools/go/types.typ·6¿Jtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4Ÿtype.stringDgolang.org/x/tools/go/types.pkg·3�Rtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2¯"type.go/token.Pos"".nametype.string "".pkgÿRtype.*golang.org/x/tools/go/types.Package"".iŸtype.int"".methods_Ptype.[]*golang.org/x/tools/go/types.Func "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parser"°è¯°…� @– :$$!  2¡ ¹ V:}±�;85uD`GkS␍Tgclocals·60e60903d0890b79099524ef4cd0028eTgclocals·37a72310bd3c2f86450f233168baf55b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4"".(*parser).parseChanTypeÀ°eH‹ %H;awèëêHƒìXH‹D$`HÇD$hHÇD$pHÇD$(‹˜(ƒûþ…AH‰$H�H�l$H‰ïH‰ÞH¥H¥èH‹l$`‹�(ƒû<u*H‹t$`H‰4$H�5H�l$H‰ïH¥H¥èHÇD$(H‹\$`H‰$èH‹L$H‹D$H‹\$(H‰\$ H‰L$HH‰L$8H‰D$PH‰D$@H�H‰$èH‹D$H‹l$ H‰(H‰D$0H‰$Hƒ<$tyHƒ$H‹\$8H‰\$H‹\$@H‰\$èH‹\$0H‰\$0H‹1íH9ètH‹\$0H‰\$pH‰D$hHƒÄXÃH�H‰$H�H‰\$H�H‰\$èH‹D$뽉%é{ÿÿÿH‰$H�H�l$H‰ïH‰ÞH¥H¥èH‹t$`H‰4$H�5H�l$H‰ïH¥H¥èHÇD$(éÊþÿÿ&
 0runtime.morestack_noctxt  go.string."chan"È4"".(*parser).expectKeywordˆgo.string."<-"ª4"".(*parser).expectSpecialØ,"".(*parser).parseTypeJtype.golang.org/x/tools/go/types.ChanÈ"runtime.newobject¾2runtime.writebarrierifaceà”go.itab.*golang.org/x/tools/go/types.Chan.golang.org/x/tools/go/types.Type¤Ltype.*golang.org/x/tools/go/types.ChanºJtype.golang.org/x/tools/go/types.TypeÒ”go.itab.*golang.org/x/tools/go/types.Chan.golang.org/x/tools/go/types.Typeæ runtime.typ2Itab¢go.string."<-"Ê4"".(*parser).expectSpecialê go.string."chan"Œ4"".(*parser).expectKeyword0°"".autotmp_0353OLtype.*golang.org/x/tools/go/types.Chan"".autotmp_0352Ltype.*golang.org/x/tools/go/types.Chan"".autotmp_0351Ltype.*golang.org/x/tools/go/types.ChanFgolang.org/x/tools/go/types.elem·3?Jtype.golang.org/x/tools/go/types.TypeDgolang.org/x/tools/go/types.dir·2oPtype.golang.org/x/tools/go/types.ChanDir"".elemJtype.golang.org/x/tools/go/types.Type "".dir_Ptype.golang.org/x/tools/go/types.ChanDir "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parser°´¯°‘à: 1 ! Ð ! ␍c€;†<Tgclocals·6d340c3bdac448a6ef1256f331f68dd3Tgclocals·3ea018d3d3bf08cc71b1924be27582a2®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ,"".(*parser).parseTypeÀ!À!eH‹ %H�D$�H;AwèëåH�ìðH‹Œ$øHÇ„$HÇ„$‹©(ƒý*�Fƒýþ…6H‰ËH‹‰0H‹ƒ8H‰Œ$˜H‰ $H‰„$ H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$˜H‹„$ H‹\$ Hƒû�uHƒøuqH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$˜H‹„$ ¶\$ €ût3H‹œ$øH‰$èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÃHƒø…ÁH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û„�H‹œ$øH‰$èH‹œ$øH‰$HÇD$èH‹\$H‰\$@H‹1íH9ètH‹\$@H‰œ$H‰„$H�ÄðÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´H‹œ$øH‰$èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÃHƒø uqH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$˜H‹„$ ¶\$ €ût3H‹œ$øH‰$èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÃHƒøuqH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹Œ$˜H‹„$ ¶\$ €ût3H‹œ$øH‰$èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÃHƒø…ÕþÿÿH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û„£þÿÿH‹œ$øH‰$èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÃý(uiH‰ $èH‹œ$øH‰$èH‹L$H‹D$H‰L$HH‰D$PH‹œ$øH‰$ÇD$)èH‹\$HH‰œ$H‹\$PH‰œ$H�ÄðÃý*…æH‰ $èH‹œ$øH‰$èH‹L$H‹D$H‰L$xH‰„$€H�H‰$èH‹D$H‰D$0H‰$Hƒ<$„€H‹\$xH‰\$H‹œ$€H‰\$èH‹\$0H‰\$0H‹1íH9ètH‹\$0H‰œ$H‰„$H�ÄðÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%étÿÿÿ‹©(‰,$èH‹\$H‰œ$¨H‹\$H‰œ$°H�¼$Ð1ÀèH�œ$ÐHƒû„ZHÇÂHÇÁH‰œ$¸H‰”$ÀH‰Œ$ÈH�H‰$H�œ$¨H‰\$èH‹L$H‹D$H‹œ$¸H‰$H‰Œ$ˆH‰L$H‰„$�H‰D$èH�H‰$H‹œ$øH‰\$Hƒ|$„²H�D$0èH‹L$H‹D$H‹œ$¸HƒÃH‰$H‰Œ$ˆH‰L$H‰„$�H‰D$èH‹´$øH‰4$H�5H�l$H‰ïH¥H¥H‹œ$¸H‰\$H‹œ$ÀH‰\$ H‹œ$ÈH‰\$(èHÇ„$HÇ„$H�ÄðÉ%éBÿÿÿ‰éŸþÿÿƒý<u+H‰ $èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÃý@udH‰ $èH‹D$H‹T$H‹L$H‰$H‰T$XH‰T$H‰L$`H‰L$èH‹\$Hƒût H‹K(H‹k0H‰Œ$H‰¬$H�ÄðÉë܃ý[…´ýÿÿH‰ $èH‹„$ø‹˜(ƒû]…ÜH‰$èH‹œ$øH‰$èH‹L$H‹D$H‰L$hH‰D$pH�H‰$èH‹D$H‰D$8H‰$Hƒ<$t}H‹\$hH‰\$H‹\$pH‰\$èH‹\$8H‰\$8H‹1íH9ètH‹\$8H‰œ$H‰„$H�ÄðÃH�H‰$H�H‰\$H�H‰\$èH‹D$ë´‰%éwÿÿÿH‰$èH‹L$H‹D$H‰Œ$H‰„$H�ÄðÀ
*0runtime.morestack_noctxtŽ go.string."func""runtime.cmpstring  go.string."chan"È runtime.eqstringž4"".(*parser).parseChanType– go.string."func"¾ runtime.eqstringü""".(*parser).next°6"".(*parser).parseSignatureÒžgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.Type¨Vtype.*golang.org/x/tools/go/types.Signature¾Jtype.golang.org/x/tools/go/types.TypeÖžgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.Typeê runtime.typ2Itabš6"".(*parser).parseBasicTypeŠ *go.string."interface"²  runtime.eqstringˆ
>"".(*parser).parseInterfaceTypeø
go.string."map"   runtime.eqstringö 2"".(*parser).parseMapTypeî $go.string."struct"–␍ runtime.eqstringÔ␍8"".(*parser).parseStructType´""".(*parser).nextÖ,"".(*parser).parseType°&"".(*parser).expect˜""".(*parser).nextº,"".(*parser).parseTypeöPtype.golang.org/x/tools/go/types.Pointerˆ"runtime.newobjectò2runtime.writebarrieriface”šgo.itab.*golang.org/x/tools/go/types.Pointer.golang.org/x/tools/go/types.TypeêRtype.*golang.org/x/tools/go/types.Pointer€Jtype.golang.org/x/tools/go/types.Type˜šgo.itab.*golang.org/x/tools/go/types.Pointer.golang.org/x/tools/go/types.Type¬ runtime.typ2Itabî0text/scanner.TokenStringÀð runtime.duffzero¾type.stringêruntime.convT2EÔ2runtime.writebarrierifaceâtype.string¸runtime.convT2Eª2runtime.writebarrierifaceÐLgo.string."expected type, got %s (%q)"À&"".(*parser).errorfÂ4"".(*parser).parseChanType¢<"".(*parser).parseExportedNameú"".declTypeNameü""".(*parser).next¼""".(*parser).nextÞ,"".(*parser).parseType”Ltype.golang.org/x/tools/go/types.Slice¦"runtime.newobject‚2runtime.writebarrieriface¤–go.itab.*golang.org/x/tools/go/types.Slice.golang.org/x/tools/go/types.TypeúNtype.*golang.org/x/tools/go/types.Slice� Jtype.golang.org/x/tools/go/types.Type¨ –go.itab.*golang.org/x/tools/go/types.Slice.golang.org/x/tools/go/types.Type¼  runtime.typ2Itabô 6"".(*parser).parseArrayType0à<"".autotmp_0384"type.interface {}"".autotmp_0383Ï"type.interface {}"".autotmp_0381o&type.[]interface {}"".autotmp_0380type.*uint8"".autotmp_0379ÿRtype.*golang.org/x/tools/go/types.Pointer"".autotmp_0378Rtype.*golang.org/x/tools/go/types.Pointer"".autotmp_0377type.*uint8"".autotmp_0376ïNtype.*golang.org/x/tools/go/types.Slice"".autotmp_0375Ntype.*golang.org/x/tools/go/types.Slice"".autotmp_0373¯type.string"".autotmp_0371�type.string"".autotmp_0370?(type.[2]interface {}"".autotmp_0369Jtype.golang.org/x/tools/go/types.Type"".autotmp_0368Jtype.golang.org/x/tools/go/types.Type"".autotmp_0367Rtype.*golang.org/x/tools/go/types.Pointer"".autotmp_0366Jtype.golang.org/x/tools/go/types.Type"".autotmp_0365Jtype.golang.org/x/tools/go/types.Type"".autotmp_0364Ntype.*golang.org/x/tools/go/types.Slice"".autotmp_0363Jtype.golang.org/x/tools/go/types.Type"".autotmp_0361Jtype.golang.org/x/tools/go/types.Type"".autotmp_0360Jtype.golang.org/x/tools/go/types.Type"".autotmp_0359Jtype.golang.org/x/tools/go/types.Type"".autotmp_0358ßVtype.*golang.org/x/tools/go/types.Signature"".autotmp_0357Jtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.elem·2ïJtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.elem·2�Jtype.golang.org/x/tools/go/types.Type "".typÏJtype.golang.org/x/tools/go/types.Type"".name¯type.string "".~r0Jtype.golang.org/x/tools/go/types.Type"".ptype.*"".parser¬"à’ßà›ßàaßàvßàvßànßàmßà³ßàÑßàBßàdßàÍßàeßà¢ú B dD3<~ 3D3D3<3< %"  Ý÷ +!L  Ó+\štæL+L+Ý485~ ~ëAò .y␍'Tgclocals·2414cc3a9e5b7e18ceaad46208847f11Tgclocals·6fae770f4aaaf5843fb0a929a5d0c93b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ8"".(*parser).parseImportDeclààeH‹ %H;awèëêHƒìPH‹t$XH‰4$H�5H�l$H‰ïH¥H¥èH‹\$XH‰$èH‹L$H‹D$H‰L$0H‰D$8H‹\$XH‰$èH‹L$H‹D$H‹\$XH‰$H‰L$@H‰L$H‰D$HH‰D$H‹\$0H‰\$H‹\$8H‰\$ èHƒÄPÃ
 0runtime.morestack_noctxtL$go.string."import"n4"".(*parser).expectKeywordŠ:"".(*parser).parsePackageNameÎ6"".(*parser).parsePackageIdÎ&"".(*parser).getPkg "".autotmp_0392type.string"".autotmp_0391type.string"".name?type.string"".ptype.*"".parser •Ÿ°ä
!"N60@
Tgclocals·ac5bea9c8a91f5fb1d31bdacc5067b57Tgclocals·29f0050a5ee7c2b9348a75428171d7de®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ*"".(*parser).parseIntàØeH‹ %H;awèëêHƒìPH‹L$XHÇD$`HÇD$hHÇD$0HÇD$8‹©(ƒý+unH‰ $èH‹L$XH‰ $ÇD$ýÿÿÿèH‹L$H‹D$H‹\$0H‰$H‹\$8H‰\$H‰L$@H‰L$H‰D$HH‰D$èH‹\$ H‰\$`H‹\$(H‰\$hHƒÄPÃý-u›H�H‹+H‰l$0H‹kH‰l$8H‰ $èH‹L$Xépÿÿÿ
 0runtime.morestack_noctxt¦""".(*parser).nextÒ&"".(*parser).expect¾*runtime.concatstring2ˆgo.string."-"¼""".(*parser).next0 "".autotmp_0393type.string"".s?type.string "".~r0type.string"".ptype.*"".parser ¡Ÿ 4ð,ô
1`  RL?Tgclocals·d7e8a62d22b1cde6d92b17a55c33fe8fTgclocals·29f0050a5ee7c2b9348a75428171d7de®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ0"".(*parser).parseNumber  eH‹ %H�D$ÈH;AwèëåH�ì¸HÇ„$ÐHÇ„$ØH‹œ$ÀH‰$èH‹L$H‹D$H‰Œ$¨H‰ $H‰„$°H‰D$HÇD$èH‹L$H‹D$ H‰D$`HƒùH‰L$XuUH�H‹+H‰¬$ˆH‹kH‰¬$�H�H‰$H�œ$ˆH‰\$èH�\$H�,$H‰ïH‰ÞH¥H¥è H‹œ$ÀHƒû„ÌH‹“0H‹ƒ8Hƒø…ˆH‰”$¨H‰$H‰„$°H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹L$X¶\$ €û„AH‹œ$ÀH‰$èH‹œ$ÀH‰$èH‹L$H‹D$H‰Œ$¨H‰ $H‰„$°H‰D$HÇD$
HÇD$èH‹t$XH‹l$`H‹L$ H‰L$8H‹D$(H‹T$0H‰T$pHƒøH‰D$htBH‰$H‰T$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹œ$ÀH‰$èH‹t$XH‹l$`H‹L$8Hƒù�HÇÀHÇD$HHÇD$PH‰D$@H�H‰$H�H‰\$H�H‰\$H�\$@H‰\$èH‹L$ H‹D$(H‰Œ$˜H‰„$ H‰L$HH‰D$PH‰L$xH‰ $H‰„$€H‰D$HÇD$H‹\$8H÷ÛH‰\$èH‹L$ H‹D$(H‹H‰œ$ÈH‹\$XH‰$H‹\$`H‰\$HÇD$H‰L$xH‰L$H‰„$€H‰D$ èH‹L$(H‹D$0H‰Œ$ÐH‰„$ØH�ĸÃHƒù~&H‰4$H‰l$HÇD$H‰L$èH‹t$ H‹l$(H‹H‰œ$ÈH‰´$ÐH‰¬$ØH�ĸÃH‹H‰œ$ÈH‰Œ$ÐH‹\$`H‰œ$ØH�ĸÉé-ýÿÿ2
*0runtime.morestack_noctxtŽ*"".(*parser).parseIntðVgolang.org/x/tools/go/exact.MakeFromLiteral²8go.string."invalid mantissa"îtype.stringšruntime.convT2EÊruntime.gopanicâgo.string."p"Š runtime.eqstringÒ""".(*parser).nextô*"".(*parser).parseIntè strconv.ParseIntàruntime.convI2Eª$"".(*parser).error¦ Rtype.golang.org/x/tools/go/exact.int64Val¼ Ltype.golang.org/x/tools/go/exact.ValueÔ œgo.itab.golang.org/x/tools/go/exact.int64Val.golang.org/x/tools/go/exact.Valueü runtime.convT2I¦ Bgolang.org/x/tools/go/exact.ShiftÈ à>golang.org/x/tools/go/types.TypÈ Hgolang.org/x/tools/go/exact.BinaryOpÐ␍Bgolang.org/x/tools/go/exact.Shiftò␍à>golang.org/x/tools/go/types.TypÀÀ>golang.org/x/tools/go/types.Typ@ð$"".autotmp_0404Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0403type.string"".autotmp_0402Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0401Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0400Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0399ïRtype.golang.org/x/tools/go/exact.int64Val"".autotmp_0398type.string"".autotmp_0397_type.string"".autotmp_0396?Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0395type.string "".~r0ßLtype.golang.org/x/tools/go/exact.Value"".denomLtype.golang.org/x/tools/go/exact.Value "".errŸtype.error "".expÿtype.int64"".mant¿Ltype.golang.org/x/tools/go/exact.Value "".val Ltype.golang.org/x/tools/go/exact.Value "".typNtype.*golang.org/x/tools/go/types.Basic"".ptype.*"".parser2"ð§ïðRïð+ïðÐd� :Q Uqn B
t;R&/F†xßDiTgclocals·d1568ce269a1ce9779fe2e06f6738fb9Tgclocals·a6a5fa841c0cffe34acd16ef31ddb86c®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ6"".(*parser).parseConstDecl€0ú/eH‹ %H�„$øþÿÿH;AwèëâH�ìˆH‹´$�H‰4$H�5H�l$H‰ïH¥H¥èH‹œ$�H‰$èH‹”$�H‹\$H‰\$XH‹\$H‰œ$ðH‹\$H‰œ$øHÇ„$°HÇ„$¸‹š(ƒû=t+H‰$èH‹”$�H‹L$H‹D$H‰Œ$°H‰„$¸H‰$ÇD$=èH‹”$�HÇ„$ÀHÇ„$ÈHÇ„$�HÇ„$˜‹ª(ƒýý�œƒýú…H‹1íH9è„ËH‹=H‰¼$ÈH‰„$ÀHƒú„£H�ª0H�<$H‰îH¥H¥HÇD$ èH‹L$H‹D$ H‰Œ$�H‰„$˜H‹œ$�H‰$èHƒ¼$°u H‹œ$ÀH‰œ$°H‹œ$ÈH‰œ$¸H‹\$XH‹k H‰l$HHÇD$@H‹\$XH‰\$PH‹œ$ðH‰œ$àH‹œ$øH‰œ$èH‹œ$°H‰œ$ H‹œ$¸H‰œ$¨H‹œ$�H‰œ$€H‹œ$˜H‰œ$ˆH�H‰$èH‹D$1íH‰(H‹l$@H‰hH‰D$`H‰$Hƒ<$„iHƒ$H‹\$PH‰\$èH‹\$`H‰$Hƒ<$„5Hƒ$H‹œ$àH‰\$H‹œ$èH‰\$èH‹\$`H‰$Hƒ<$„ñHƒ$(H‹œ$ H‰\$H‹œ$¨H‰\$èH‹D$`Ç@8H‰$Hƒ<$„¦Hƒ$@H‹œ$€H‰\$H‹œ$ˆH‰\$èH‹D$`1í@ˆhPH‰D$`H‹1íH9èt5H‹\$HH‰$H‹L$`H‰„$H‰D$H‰Œ$H‰L$èH�ĈÃH�H‰$H�H‰\$H�H‰\$èH‹D$뜉%éNÿÿÿ‰%éÿÿÿ‰%é¿þÿÿ‰%é‹þÿÿ‰éVýÿÿH�H‰$H�H‰\$H�H‰\$èH‹”$�H‹D$éûüÿÿƒýû…¹H‹1íH9ètqH‹=H‰¼$ÈH‰„$ÀHƒútPH�ª0H�<$H‰îH¥H¥HÇD$èH‹L$H‹D$ H‰Œ$�H‰„$˜H‹œ$�H‰$èéãüÿÿ‰ë¬H�H‰$H�H‰\$H�H‰\$èH‹”$�H‹D$éUÿÿÿƒýý…‘H‹H‰D$h1íH9ètBH‰$èH‹D$H‹\$H‰œ$�H‹\$H‰œ$˜H‰„$ÈH‹\$hH‰œ$ÀéGüÿÿH�H‰$H�H‰\$H�H‰\$èH‹”$�H‹\$H‰\$hë‚‹ª(‰,$èH‹\$H‰œ$`H‹\$H‰œ$hH�œ$PHÇHÇCH�œ$PHƒû„ÈHÇÂHÇÁH‰œ$pH‰”$xH‰Œ$€H�H‰$H�œ$`H‰\$èH‹L$H‹D$H‹œ$pH‰$H‰Œ$ H‰L$H‰„$(H‰D$èH‹´$�H‰4$H�5H�l$H‰ïH¥H¥H‹œ$pH‰\$H‹œ$xH‰\$ H‹œ$€H‰\$(èéòúÿÿ‰é1ÿÿÿƒýþ…¬H‹Š0H‹‚8Hƒø…¸H‰Œ$@H‰ $H‰„$HH‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹”$�¶\$ €û„nH‹1íH9è„"H‹H‰œ$ÈH‰„$ÀHƒú„úH‹Š0H‰Œ$@H‹‚8H‰„$HHƒø…ËH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û„™HÇÀHÇD$pHÇD$xˆD$?H�H‰$H�H‰\$H�H‰\$H�\$?H‰\$èH‹L$ H‹D$(H‰Œ$0H‰„$8H‰L$pH‰Œ$�H‰D$xH‰„$˜H‹œ$�H‰$èéZùÿÿ1Àégÿÿÿ‰éÿþÿÿH�H‰$H�H‰\$H�H‰\$èH‹”$�H‹D$é¤þÿÿHƒú„ËH‹Š0H‰Œ$@H‹‚8H‰„$HHƒøu:H‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹”$�¶\$ €û…*þÿÿH�H‹+H‰¬$`H‹kH‰¬$hH�H‰$H�œ$`H‰\$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹œ$�H‰$èH‹”$�é½ýÿÿ‰é.ÿÿÿƒý(…iH‰$èH‹„$�‹˜(ƒûû…ÂH‰$èH‹œ$�H‰$ÇD$+èH‹1íH9èt`H‹H‰œ$ÈH‰„$ÀH‹œ$�H‰$èH‹\$H‰œ$�H‹\$H‰œ$˜H‹œ$�H‰$ÇD$)èé}÷ÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$énÿÿÿH‰$èH‹\$H‰œ$ÐH‹\$H‰œ$ØH‹œ$�H‰$ÇD$+èH‹œ$�H‰$èH‹\$H‰œ$H‹\$H‰œ$H‹´$�H‰4$H�5H�l$H‰ïH¥H¥èH‹œ$�H‰$ÇD$)èH‹1íH9脟H‹H‰œ$ÈH‰„$ÀH‹œ$H‰$H‹œ$H‰\$èH‹L$H‹D$H‹œ$ÐH‰$H‹œ$ØH‰\$HÇD$ H‰Œ$0H‰L$H‰„$8H‰D$ èH‹L$(H‹D$0H‰Œ$�H‰„$˜éöõÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$é/ÿÿÿƒý-„ùÿÿé«ùÿÿº
00runtime.morestack_noctxth"go.string."const"Š4"".(*parser).expectKeyword¬<"".(*parser).parseExportedNameÜ,"".(*parser).parseTypeÂ&"".(*parser).expectð–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Type”€>golang.org/x/tools/go/types.TypˆVgolang.org/x/tools/go/exact.MakeFromLiteralÞ""".(*parser).nextÄ Ltype.golang.org/x/tools/go/types.ConstÖ "runtime.newobjectÌ
.runtime.writebarrierptr¼ 4runtime.writebarrierstring¬ 2runtime.writebarrierifaceª 2runtime.writebarrierifaceØ šgo.itab.*golang.org/x/tools/go/types.Const.golang.org/x/tools/go/types.ObjectÀVgolang.org/x/tools/go/types.(*Scope).InsertÞNtype.*golang.org/x/tools/go/types.ConstôNtype.golang.org/x/tools/go/types.ObjectŒšgo.itab.*golang.org/x/tools/go/types.Const.golang.org/x/tools/go/types.Object  runtime.typ2ItabªNtype.*golang.org/x/tools/go/types.BasicÀJtype.golang.org/x/tools/go/types.TypeØ–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Typeì runtime.typ2Itab°–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.TypeÌÐ>golang.org/x/tools/go/types.Typ¸Vgolang.org/x/tools/go/exact.MakeFromLiteralŽ""".(*parser).next®Ntype.*golang.org/x/tools/go/types.BasicÄJtype.golang.org/x/tools/go/types.TypeÜ–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Typeð runtime.typ2Itab´–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.TypeÞ0"".(*parser).parseNumberÞNtype.*golang.org/x/tools/go/types.BasicôJtype.golang.org/x/tools/go/types.TypeŒ–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Type  runtime.typ2Itabä0text/scanner.TokenStringÄtype.stringðruntime.convT2EÚ2runtime.writebarrieriface€Fgo.string."expected literal got %s"ð&"".(*parser).errorfŠ go.string."true"² runtime.eqstringì–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Type�°>golang.org/x/tools/go/types.Typ´ go.string."true"Ü runtime.eqstringÀPtype.golang.org/x/tools/go/exact.boolValÖLtype.golang.org/x/tools/go/exact.Valueîšgo.itab.golang.org/x/tools/go/exact.boolVal.golang.org/x/tools/go/exact.Value– runtime.convT2I !""".(*parser).nextÔ!Ntype.*golang.org/x/tools/go/types.Basicê!Jtype.golang.org/x/tools/go/types.Type‚"–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Type–" runtime.typ2Itab¶#"go.string."false"Þ# runtime.eqstring˜$Dgo.string."expected true or false"Ô$type.string€%runtime.convT2EÊ%$"".(*parser).error–&""".(*parser).nextÖ&""".(*parser).nextˆ'&"".(*parser).expect–'–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Type²'Ð>golang.org/x/tools/go/types.Typô'0"".(*parser).parseNumberÚ(&"".(*parser).expectò(Ntype.*golang.org/x/tools/go/types.Basicˆ)Jtype.golang.org/x/tools/go/types.Type )–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Type´) runtime.typ2ItabÚ)0"".(*parser).parseNumberÀ*&"".(*parser).expectâ*0"".(*parser).parseNumber¼+go.string."i"Þ+4"".(*parser).expectKeyword�,&"".(*parser).expectž,–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.TypeÂ,ð>golang.org/x/tools/go/types.Typž-Hgolang.org/x/tools/go/exact.MakeImag´.Hgolang.org/x/tools/go/exact.BinaryOp€/Ntype.*golang.org/x/tools/go/types.Basic–/Jtype.golang.org/x/tools/go/types.Type®/–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.TypeÂ/ runtime.typ2Itab�L"".autotmp_0433type.*uint8"".autotmp_0432ÏNtype.*golang.org/x/tools/go/types.Const"".autotmp_0431Ntype.*golang.org/x/tools/go/types.Const"".autotmp_0430Ï"type.interface {}"".autotmp_0428/&type.[]interface {}"".autotmp_0427type.*uint8"".autotmp_0426type.*uint8"".autotmp_0425type.*uint8"".autotmp_0424type.*uint8"".autotmp_0423type.*uint8"".autotmp_0421¯Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0420type.string"".autotmp_0418¿type.*uint8"".autotmp_0417type.string"".autotmp_0416�type.string"".autotmp_0414Ntype.*golang.org/x/tools/go/types.Const"".autotmp_0413type.string"".autotmp_0412o(type.[1]interface {}"".autotmp_0411Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0410Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0408Ltype.golang.org/x/tools/go/exact.Value"".autotmp_0407‘Ptype.golang.org/x/tools/go/exact.boolVal"".autotmp_0406Otype.stringDgolang.org/x/tools/go/types.val·6�Ltype.golang.org/x/tools/go/exact.ValueDgolang.org/x/tools/go/types.typ·5ÏJtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4Ïtype.stringDgolang.org/x/tools/go/types.pkg·3ïRtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2�"type.go/token.Pos "".~r0ÿNtype.*golang.org/x/tools/go/types.Scope "".~r0¯Ltype.golang.org/xLine truncated
"".im�Ltype.golang.org/x/tools/go/exact.Value
"".reïLtype.golang.org/x/tools/go/exact.Value "".valïLtype.golang.org/x/tools/go/exact.Value "".typ�Jtype.golang.org/x/tools/go/types.Type"".typ0¯Jtype.golang.org/x/tools/go/types.Type"".name¯type.string "".pkgßRtype.*golang.org/x/tools/go/types.Package"".ptype.*"".parser%�†��Ô€œâ %$= +N )D  Æ_: %@:1 PJI<D”Y b)çRS:hh  %+692
#+$)ƒ$%2' H Di3£+¼;88?K0 ff+17a␍"† €a•¢;µKo3-FO`K G Tgclocals·bcc772abe81b036416e664f43e7d04eaTgclocals·1e9d3be895560c458124d34fcba3c5d7®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4"".(*parser).parseTypeDecl †eH‹ %H;awèëêHƒìhH‹t$pH‰4$H�5H�l$H‰ïH¥H¥èH‹\$pH‰$èH‹D$H‹T$H‹L$H‰$H‰T$XH‰T$H‰L$`H‰L$èH‹\$H‰\$ H‹\$pH‰$èH‹L$H‹D$H‰L$HH‰D$PH‹\$ Hƒû„ŒH‹K(H‹k0H�H‰$H‰L$(H‰L$H‰l$0H‰l$èH‹D$HÇD$8HÇD$@Hƒøt?H‹hH‰l$8H‹hH‰l$@H�\$8Hƒ;uH‰$H‹\$HH‰\$H‹\$PH‰\$èHƒÄhÉ뽉émÿÿÿ
 0runtime.morestack_noctxtL go.string."type"n4"".(*parser).expectKeywordŠ<"".(*parser).parseExportedNameâ"".declTypeName’,"".(*parser).parseTypeöNtype.*golang.org/x/tools/go/types.Named°"runtime.assertI2TÞdgolang.org/x/tools/go/types.(*Named).SetUnderlyingÐ "".~r0_Jtype.golang.org/x/tools/go/types.Type "".~r0Jtype.golang.org/x/tools/go/types.Type "".typ?Jtype.golang.org/x/tools/go/types.Type "".obj�Ttype.*golang.org/x/tools/go/types.TypeName"".nametype.string"".ptype.*"".parserÐ�ÏÐÐ(î !'"u6ROW"Tgclocals·15395a9df917b4c9aa74d5c6c7e1ebf4Tgclocals·effafd59fffff9c30c776c5effd52018®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ2"".(*parser).parseVarDeclÀ ¢ eH‹ %H�D$àH;AwèëåH�ì H‹´$¨H‰4$H�5H�l$H‰ïH¥H¥èH‹œ$¨H‰$èH‹\$H‰\$@H‹\$H‰œ$€H‹\$H‰œ$ˆH‹œ$¨H‰$èH‹t$@H‹T$H‹L$H‹n H‰l$0HÇD$(H‰t$8H‹œ$€H‰\$pH‹œ$ˆH‰\$xH‰T$`H‰T$PH‰L$hH‰L$XH�H‰$èH‹L$H‰ÏHƒù„H1Àè1íH‰)H‹l$(H‰iH‰L$HH‰ $Hƒ<$„Hƒ$H‹\$8H‰\$èH‹\$HH‰$Hƒ<$„ßHƒ$H‹\$pH‰\$H‹\$xH‰\$èH‹\$HH‰$Hƒ<$„¡Hƒ$(H‹\$PH‰\$H‹\$XH‰\$èH‹D$HÇ@8H‰D$HH‹1íH9èt5H‹\$0H‰$H‹L$HH‰„$�H‰D$H‰Œ$˜H‰L$èH�Ä ÃH�H‰$H�H‰\$H�H‰\$èH‹D$뜉%éSÿÿÿ‰%éÿÿÿ‰%éáþÿÿ‰é±þÿÿ$
*0runtime.morestack_noctxtbgo.string."var"„4"".(*parser).expectKeyword¦<"".(*parser).parseExportedName�,"".(*parser).parseTypeÆHtype.golang.org/x/tools/go/types.VarØ"runtime.newobjectŠÜ runtime.duffzeroö.runtime.writebarrierptrÚ4runtime.writebarrierstring¾2runtime.writebarrierifaceî–go.itab.*golang.org/x/tools/go/types.Var.golang.org/x/tools/go/types.ObjectÖVgolang.org/x/tools/go/types.(*Scope).InsertôJtype.*golang.org/x/tools/go/types.VarŠNtype.golang.org/x/tools/go/types.Object¢–go.itab.*golang.org/x/tools/go/types.Var.golang.org/x/tools/go/types.Object runtime.typ2ItabÀ"".autotmp_0450¯Jtype.*golang.org/x/tools/go/types.Var"".autotmp_0449Jtype.*golang.org/x/tools/go/types.Var"".autotmp_0448Jtype.*golang.org/x/tools/go/types.VarDgolang.org/x/tools/go/types.typ·5ŸJtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4_type.stringDgolang.org/x/tools/go/types.pkg·3ÏRtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2ï"type.go/token.Pos "".~r0ßNtype.*golang.org/x/tools/go/types.Scope "".typJtype.golang.org/x/tools/go/types.Type"".name?type.string "".pkg¿Rtype.*golang.org/x/tools/go/types.Package"".ptype.*"".parser"ÀÔ¿Àià"”␍"$5 Ôi&AFdO22L 0
FTgclocals·2c09ec81c5cb12328d7183f25bc48833Tgclocals·f6d8c5f6f2849a252db82714c192d569®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ,"".(*parser).parseFunc ‚eH‹ %H;awèëêHƒì(H‹\$0H‰$H‹\$8H‰\$èH‹L$0H‹\$H‰\$ ‹™(ƒû{uTH‰ $èH‹T$0HÇÁH‰L$Hƒù~4‹ª(ƒý{u8H‰ËHÿÃH‰\$H‰$èH‹T$0H‹L$H‰L$HƒùÌH‹\$ H‰\$@HƒÄ(Ãý}uÎH‰ËHÿËH‰\$ëÁ
 0runtime.morestack_noctxt\6"".(*parser).parseSignature¢""".(*parser).nextŽ""".(*parser).next0P "".autotmp_0456type.int"".itype.int "".sigVtype.*golang.org/x/tools/go/types.Signature "".~r1 Vtype.*golang.org/x/tools/go/types.Signature"".recvJtype.*golang.org/x/tools/go/types.Var"".ptype.*"".parserP”OP!Ð8¨␍'    -#€Tgclocals·bd51743682bd6c0f7b9f2e8e6dffed99Tgclocals·e1ae6533a9e39048ba0735a2264ce16a®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ8"".(*parser).parseMethodDeclÀ ¾ eH‹ %H�D$ØH;AwèëåH�ì¨H‹œ$°H‰$ÇD$(èH‹œ$°H‰$èH‹\$H‰\$0H‹œ$°H‰$ÇD$)èH‹\$0Hƒû„ZH‹K(H‹k0H‰L$XH‰ $H‰l$`H‰l$èH‹L$H‹D$H�H‰$H‰Œ$˜H‰L$H‰„$ H‰D$èH‹\$H‰\$@H‹œ$°H‰$ÆD$èH‹\$H‰œ$ˆH‹\$ H‰œ$�H‹œ$°H‰$H‹\$0H‰\$èH‹L$H‹\$@H‹+Hƒý„’H‹mHÇD$(H‰l$8H‹œ$ˆH‰\$xH‹œ$�H‰œ$€HÇD$hHÇD$p1íH9ét&H‰L$PH‹1íH9è„H‹\$PH‰\$pH‰D$hH�H‰$èH‹D$1íH‰(H‹l$(H‰hH‰D$HH‰$Hƒ<$„¯Hƒ$H‹\$8H‰\$èH‹\$HH‰$Hƒ<$tHƒ$H‹\$xH‰\$H‹œ$€H‰\$èH‹\$HH‰$Hƒ<$tEHƒ$(H‹\$hH‰\$H‹\$pH‰\$èH‹D$HÇ@8H‹\$@H‰$H‰D$èH�ĨÉ%벉%éuÿÿÿ‰%éEÿÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$éÍþÿÿ‰Eéfþÿÿ‰éŸýÿÿ*
*0runtime.morestack_noctxtn&"".(*parser).expect�6"".(*parser).parseParameterÖ&"".(*parser).expect´"".derefÖNtype.*golang.org/x/tools/go/types.Namedœ"runtime.assertI2TÜ,"".(*parser).parseNameÆ,"".(*parser).parseFuncœžgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.TypeÞJtype.golang.org/x/tools/go/types.Funcð"runtime.newobjectæ.runtime.writebarrierptrÈ4runtime.writebarrierstring¤ 2runtime.writebarrierifaceâ \golang.org/x/tools/go/types.(*Named).AddMethodÂ
Vtype.*golang.org/x/tools/go/types.SignatureØ
Jtype.golang.org/x/tools/go/types.Typeð
žgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.Type„  runtime.typ2ItabÐ"".autotmp_0463¿Ltype.*golang.org/x/tools/go/types.Func"".autotmp_0462Ltype.*golang.org/x/tools/go/types.Func"".autotmp_0460Vtype.*golang.org/x/tools/go/types.Signature"".autotmp_0459¯Vtype.*golang.org/x/tools/go/types.Signature"".autotmp_0458Jtype.golang.org/x/tools/go/types.TypeDgolang.org/x/tools/go/types.typ·6Jtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4_type.stringDgolang.org/x/tools/go/types.pkg·3ßRtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2ÿ"type.go/token.Pos "".~r0ŸJtype.golang.org/x/tools/go/types.Type"".name?type.string"".baseÏNtype.*golang.org/x/tools/go/types.Named"".recvïJtype.*golang.org/x/tools/go/types.Var"".ptype.*"".parser"ÐÚÏÐcà:Î␍"m0 
³S ␍264ƒ5•;1.QTgclocals·63bae81cfd8a678616fd0ed83955df76Tgclocals·3eca4ffcd48a84d93645911c98c5f24d®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4"".(*parser).parseFuncDeclà Ú eH‹ %H�D$èH;AwèëåH�ì˜H‹œ$ H‰$èH‹\$H‰\$@H‹\$H‰\$xH‹\$H‰œ$€H‹œ$ H‰$HÇD$èH‹T$@H‹L$H‹j H‰l$0HÇD$(H‰T$8H‹\$xH‰\$hH‹œ$€H‰\$pHÇD$XHÇD$`1íH9ét&H‰L$PH‹1íH9è„eH‹\$PH‰\$`H‰D$XH�H‰$èH‹D$1íH‰(H‹l$(H‰hH‰D$HH‰$Hƒ<$„Hƒ$H‹\$8H‰\$èH‹\$HH‰$Hƒ<$„ßHƒ$H‹\$hH‰\$H‹\$pH‰\$èH‹\$HH‰$Hƒ<$„¡Hƒ$(H‹\$XH‰\$H‹\$`H‰\$èH‹D$HÇ@8H‰D$HH‹1íH9èt5H‹\$0H‰$H‹L$HH‰„$ˆH‰D$H‰Œ$�H‰L$èH�ĘÃH�H‰$H�H‰\$H�H‰\$èH‹D$뜉%éSÿÿÿ‰%éÿÿÿ‰%éáþÿÿH�H‰$H�H‰\$H�H‰\$èH‹D$éiþÿÿ(
*0runtime.morestack_noctxt^<"".(*parser).parseExportedNameÔ,"".(*parser).parseFuncŽžgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.TypeÐJtype.golang.org/x/tools/go/types.Funcâ"runtime.newobjectØ.runtime.writebarrierptr¼4runtime.writebarrierstring 2runtime.writebarrierifaceИgo.itab.*golang.org/x/tools/go/types.Func.golang.org/x/tools/go/types.Object¸Vgolang.org/x/tools/go/types.(*Scope).InsertÖLtype.*golang.org/x/tools/go/types.FuncìNtype.golang.org/x/tools/go/types.Object„˜go.itab.*golang.org/x/tools/go/types.Func.golang.org/x/tools/go/types.Object˜ runtime.typ2ItabüVtype.*golang.org/x/tools/go/types.Signature’ Jtype.golang.org/x/tools/go/types.Typeª žgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.Type¾  runtime.typ2Itab°"".autotmp_0471type.*uint8"".autotmp_0470ŸLtype.*golang.org/x/tools/go/types.Func"".autotmp_0469Ltype.*golang.org/x/tools/go/types.Func"".autotmp_0467Ltype.*golang.org/x/tools/go/types.Func"".autotmp_0466Vtype.*golang.org/x/tools/go/types.Signature"".autotmp_0465�Vtype.*golang.org/x/tools/go/types.SignatureDgolang.org/x/tools/go/types.typ·6Jtype.golang.org/x/tools/go/types.TypeFgolang.org/x/tools/go/types.name·4_type.stringDgolang.org/x/tools/go/types.pkg·3¿Rtype.*golang.org/x/tools/go/types.PackageDgolang.org/x/tools/go/types.pos·2ß"type.go/token.Pos "".~r0ÏNtype.*golang.org/x/tools/go/types.Scope"".name?type.string "".pkg¯Rtype.*golang.org/x/tools/go/types.Package"".ptype.*"".parser"°Å¯°ˆð þ␍"2$èˆ,.;‡;22L 0 STgclocals·ce3ac48024ab99dccf70ef1fe4c8779eTgclocals·8a726de051bf5b6e966a4a4626fa226d®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ,"".(*parser).parseDeclÀ ¸ eH‹ %H;awèëêHƒì8H‹l$@‹�(ƒûþ…°H‹\$@Hƒû„H‹‹0H‹ƒ8H‰L$(H‰ $H‰D$0H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹L$(H‹D$0H‹\$ Hƒû�ÒHƒøuaH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹L$(H‹D$0¶\$ €ût)H‹\$@H‰$èH‹\$@H‰$ÇD$
èHƒÄ8ÃHƒøußH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €ût±H‹\$@H‰$èH‹D$@‹˜(ƒû(u H‰$èëˆH‰$èézÿÿÿHƒøuKH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹L$(H‹D$0¶\$ €ûtH‹\$@H‰$èé)ÿÿÿHƒøuKH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹L$(H‹D$0¶\$ €ûtH‹\$@H‰$èéØþÿÿHƒø…ÎþÿÿH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥è¶\$ €û„œþÿÿH‹\$@H‰$èé‰þÿÿ‰éáýÿÿ,
 0runtime.morestack_noctxt go.string."func"ê"runtime.cmpstringÈ"go.string."const"ð runtime.eqstring´6"".(*parser).parseConstDeclà&"".(*parser).expect– go.string."func"¾ runtime.eqstringî""".(*parser).next 8"".(*parser).parseMethodDecl4"".(*parser).parseFuncDeclì$go.string."import"” runtime.eqstringØ8"".(*parser).parseImportDeclŽ go.string."type" runtime.eqstringú4"".(*parser).parseTypeDecl¸go.string."var"à runtime.eqstring˜ 2"".(*parser).parseVarDeclp"".autotmp_0475type.string"".ptype.*"".parserpÞopçàd�d>4   !> ><#  te°"/"dTgclocals·ac5bea9c8a91f5fb1d31bdacc5067b57Tgclocals·8d600a433c6aaa81a4fe446d95c5546b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ0"".(*parser).parseExportàÔeH‹ %H�D$°H;AwèëåH�ìÐH‹´$ØH‰4$H�5H�l$H‰ïH¥H¥èH‹œ$ØH‰$èH‹”$ØH‹L$H‹D$H‰Œ$ˆH‰L$HH‰„$�H‰D$P‹š(ƒûþukH‹Š0H‰Œ$ˆH‹‚8H‰„$�HƒøuGH‰ $H‰D$H�-L�D$L‰ÇH‰îH¥H¥èH‹”$ض\$ €ûtH‰$èH‹”$ØH‰$ÇD$
èH‹„$ØH‰$Hƒø„CH�¨@H�\$H‰ßH‰îH¥H¥H‹\$HH‰\$H‹\$PH‰\$ èH‹„$ØH‹\$(H‰\$@‹˜(ƒû$t'‹˜(ƒûÿtH‰$èH‹„$Ø‹˜(ƒû$uÙH‰$Hƒ<$„µèH‹Œ$Ø‹D$‰D$0‹™(ƒû$…(ƒø$…H‹©àHƒý„âH‰l$8H�\$hHÇHÇCH�\$hHƒû„ßHÇÁHÇÂH‰œ$˜H‰Œ$ H‰”$¨H�H‰$H�\$8H‰\$èH‹L$H‹D$H‹œ$˜H‰$H‰L$XH‰L$H‰D$`H‰D$èH‹´$ØH‰4$H�5H�l$H‰ïH¥H¥H‹œ$˜H‰\$H‹œ$ H‰\$ H‹œ$¨H‰\$(èH‹\$@HÇÅ@ˆk(H‹\$@H‰œ$àH�ÄÐÉéÿÿÿ‹©(‰,$èH‹\$H‰\$xH‹\$H‰œ$€‹\$0‰\$4H�¼$°1ÀèH�œ$°Hƒû„HÇÂHÇÁH‰œ$˜H‰”$ H‰Œ$¨H�H‰$H�\$xH‰\$èH‹L$H‹D$H‹œ$˜H‰$H‰L$XH‰L$H‰D$`H‰D$èH�H‰$H�\$4H‰\$èH‹L$H‹D$H‹œ$˜HƒÃH‰$H‰L$XH‰L$H‰D$`H‰D$èH‹´$ØH‰4$H�5H�l$H‰ïH¥H¥H‹œ$˜H‰\$H‹œ$ H‰\$ H‹œ$¨H‰\$(èH‹Œ$Øéýÿÿ‰éåþÿÿ‰%é?ýÿÿ‰é¶üÿÿ6
*0runtime.morestack_noctxtb&go.string."package"„4"".(*parser).expectKeyword¦:"".(*parser).parsePackageNameü go.string."safe"¤ runtime.eqstringÚ""".(*parser).nextŒ&"".(*parser).expect–&"".(*parser).getPkgø,"".(*parser).parseDeclÆ8text/scanner.(*Scanner).Peekâtype.intˆ runtime.convT2Eæ 2runtime.writebarrierifaceŒ
\go.string."expected no scanner errors, got %d"ü
&"".(*parser).errorfð 0text/scanner.TokenStringÌ ð runtime.duffzeroÊ␍type.stringð␍runtime.convT2EÎ2runtime.writebarrierifaceÜtype.int32‚runtime.convT2Eè2runtime.writebarrierifaceŽHgo.string."expected '$$', got %s %c"þ&"".(*parser).errorf  """.autotmp_0491"type.interface {}"".autotmp_0489&type.[]interface {}"".autotmp_0488"type.interface {}"".autotmp_0487ï"type.interface {}"".autotmp_0485o&type.[]interface {}"".autotmp_0484type.string"".autotmp_0483¯type.int"".autotmp_0482Ï(type.[1]interface {}"".autotmp_0481·type.int32"".autotmp_0480¯type.string"".autotmp_0479?(type.[2]interface {}"".autotmp_0476�type.string
"".ch¿type.int32 "".pkgŸRtype.*golang.org/x/tools/go/types.Package"".name�type.string "".~r0Rtype.*golang.org/x/tools/go/types.Package"".ptype.*"".parser" ÄŸ ‰ð\Ê"$=eO < â Ý ␍2A�y1Èz:€Ç2Tgclocals·3be0b30e44224793f9e9b8c26d600a35Tgclocals·18915aee5cae0126f2a06e3df303b719®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".func·001ÀºeH‹ %H�D$�H;AwèëåH�ìðH‹ZH‰\$XH�œ$øH‰$èH‹L$H‹D$H‰L$pH‰D$xH‰L$`H‰ $H‰D$hH‰D$èL‹D$hH‹T$`‹\$HƒúuH�ÄðÃ�ûAÇe“…½H�H‰$H‰T$L‰D$èL‹D$hH‹T$`H�œ$€H�l$H‰ßH‰îè¶\$P€ûtwH�œ$€H�¬$¸H‰ïH‰ÞèH�H‰$H�H‰\$H�H‰\$H�œ$¸H‰\$èH�\$ H�l$H‰ïH‰ÞH¥H¥H‹\$XH‰$èé/ÿÿÿH‰$L‰D$è 
*"runtime.morestackp"runtime.gorecoverÈ$runtime.efacethash¦&type."".importErrorÌ$runtime.assertE2T2�¼ runtime.duffcopyÚ¼ runtime.duffcopyè&type."".importErrorþtype.error–8go.itab."".importError.errorÄruntime.convT2Iˆ2runtime.writebarrieriface®runtime.gopanicà
"".autotmp_0500Ÿ"type.interface {}"".autotmp_0499o&type."".importError"".autotmp_0498ÿ"type.interface {}"".&err¯type.*error"".rß&type."".importError"àaßàÜà À+QRr7,¾"
Tgclocals·7c13896baab3273e10662a9a37b348ceTgclocals·087fc05a011aec2a651c47fa3f82d746®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".func·002€âeH‹ %H�D$ÐH;AwèëåH�ì°H‹BH‹ZH‰\$@H‹ZH‰\$8H‹(H‰,$èH‹\$@Hƒ;„OH‹\$8H‹+H‰l$hH‹kH‰l$pH�¼$�1ÀèH�œ$�Hƒû„ HÇÂHÇÁH‰\$xH‰”$€H‰Œ$ˆH�H‰$H�\$hH‰\$èH‹L$H‹D$H‹\$xH‰$H‰L$HH‰L$H‰D$PH‰D$èH‹t$@H�,$H‰ïH¥H¥èH‹L$H‹D$H‹\$xHƒÃH‰$H‰L$HH‰L$H‰D$PH‰D$èH�H�,$H‰ïH‰ÞH¥H¥H‹\$xH‰\$H‹œ$€H‰\$H‹œ$ˆH‰\$ èH‹L$(H‹D$0H‹\$@H‰$H‰L$XH‰L$H‰D$`H‰D$èH�İÉéÙþÿÿ
*"runtime.morestack€ os.(*File).Closeèð runtime.duffzeroàtype.string†runtime.convT2EÞ2runtime.writebarrierifaceˆruntime.convI2Eè2runtime.writebarrierifaceöNgo.string."reading export data: %s: %v"äfmt.Errorf¼2runtime.writebarrierifaceà"".autotmp_0509"type.interface {}"".autotmp_0508Ï"type.interface {}"".autotmp_0506o&type.[]interface {}"".autotmp_0505¯type.error"".autotmp_0504�type.string"".autotmp_0503?(type.[2]interface {}"".&filenameïtype.*string"".&errßtype.*error"à‡ßàÀ¨8 Ï?ƒ¯,#Tgclocals·7c13896baab3273e10662a9a37b348ceTgclocals·ed94f01d04841dfbdf3c0776abaef34c®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".func·003€öeH‹ %H;awèëêHƒì8H‹ZH‰\$ H‹\$HH‰\$(H‹\$PH‰\$0H�H‰$H�\$(H‰\$èH�\$H�l$H‰ïH‰ÞH¥H¥H‹\$ H‹+H‰,$èHƒÄ8Ã
 "runtime.morestackttype.stringšruntime.convT2Eä$"".(*parser).error0p"".autotmp_0513type.string
"".&p/ type.**"".parser "".msgtype.stringp`o€
ö€L%Tgclocals·3cd76c4f8d01c613585e17871258aa07Tgclocals·38df2c0cbd72e8d8851524e0890ca535®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ"".init ŒeH‹ %H;awèëê€ût€ûuÃè ÆèèèèèèèèèèèèèÆÃ(
 0runtime.morestack_noctxt2"".initdone·J"".initdone·`"runtime.throwinitp"".initdone·|@golang.org/x/tools/go/types.init†@golang.org/x/tools/go/exact.init�"text/scanner.initš$path/filepath.init¤os.init®go/token.init¸go/build.initÂstrings.initÌstrconv.initÖio.initàfmt.initêbufio.initô"".init·1€"".initdone·��
„�
/aTgclocals·3280bececceccd33cb74587feedb1f9fTgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/gcimporter.goþ4type..hash.[1]interface {}àÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtü(runtime.nilinterhash@` "".autotmp_0516type.int"".autotmp_0515type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".p*type.*[1]interface {}`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ0type..eq.[1]interface {}àÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$hHƒû„–H‰ÅHkíHëH‹ H‹sH‹\$`HƒûtvH‰ÅHkíHëH‹H‹SH9ÈuVH‰D$8H‰$H‰T$@H‰T$H‰L$HH‰L$H‰t$PH‰t$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxtÂruntime.efaceeq@°"".autotmp_0520?"type.interface {}"".autotmp_0519"type.interface {}"".autotmp_0518_type.int"".autotmp_0517Otype.int "".~r30type.bool"".s type.uintptr"".q*type.*[1]interface {}"".p*type.*[1]interface {}&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ(type..hash.[2]stringàÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtüruntime.strhash@` "".autotmp_0523type.int"".autotmp_0522type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".ptype.*[2]string`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ$type..eq.[2]stringàÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$`Hƒû„–H‰ÅHkíHëH‹3H‹KH‹\$hHƒûtvH‰ÅHkíHëH‹H‹CH9ÁuVH‰t$HH‰4$H‰L$PH‰L$H‰T$8H‰T$H‰D$@H‰D$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxt runtime.eqstring@°"".autotmp_0527?type.string"".autotmp_0526type.string"".autotmp_0525_type.int"".autotmp_0524Otype.int "".~r30type.bool"".s type.uintptr"".qtype.*[2]string"".ptype.*[2]string&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ(type..hash.[4]stringàÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtüruntime.strhash@` "".autotmp_0530type.int"".autotmp_0529type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".ptype.*[4]string`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ$type..eq.[4]stringàÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$`Hƒû„–H‰ÅHkíHëH‹3H‹KH‹\$hHƒûtvH‰ÅHkíHëH‹H‹CH9ÁuVH‰t$HH‰4$H‰L$PH‰L$H‰T$8H‰T$H‰D$@H‰D$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxt runtime.eqstring@°"".autotmp_0534?type.string"".autotmp_0533type.string"".autotmp_0532_type.int"".autotmp_0531Otype.int "".~r30type.bool"".s type.uintptr"".qtype.*[4]string"".ptype.*[4]string&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ(type..hash.[8]stringàÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtüruntime.strhash@` "".autotmp_0537type.int"".autotmp_0536type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".ptype.*[8]string`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ$type..eq.[8]stringàÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$`Hƒû„–H‰ÅHkíHëH‹3H‹KH‹\$hHƒûtvH‰ÅHkíHëH‹H‹CH9ÁuVH‰t$HH‰4$H‰L$PH‰L$H‰T$8H‰T$H‰D$@H‰D$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxt runtime.eqstring@°"".autotmp_0541?type.string"".autotmp_0540type.string"".autotmp_0539_type.int"".autotmp_0538Otype.int "".~r30type.bool"".s type.uintptr"".qtype.*[8]string"".ptype.*[8]string&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ4type..hash.[3]interface {}àÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtü(runtime.nilinterhash@` "".autotmp_0544type.int"".autotmp_0543type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".p*type.*[3]interface {}`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ0type..eq.[3]interface {}àÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$hHƒû„–H‰ÅHkíHëH‹ H‹sH‹\$`HƒûtvH‰ÅHkíHëH‹H‹SH9ÈuVH‰D$8H‰$H‰T$@H‰T$H‰L$HH‰L$H‰t$PH‰t$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxtÂruntime.efaceeq@°"".autotmp_0548?"type.interface {}"".autotmp_0547"type.interface {}"".autotmp_0546_type.int"".autotmp_0545Otype.int "".~r30type.bool"".s type.uintptr"".q*type.*[3]interface {}"".p*type.*[3]interface {}&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ`type..hash.[8]golang.org/x/tools/go/types.ObjectàÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtü"runtime.interhash@` "".autotmp_0551type.int"".autotmp_0550type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".pVtype.*[8]golang.org/x/tools/go/types.Object`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ\type..eq.[8]golang.org/x/tools/go/types.ObjectàÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$hHƒû„–H‰ÅHkíHëH‹ H‹sH‹\$`HƒûtvH‰ÅHkíHëH‹H‹SH9ÈuVH‰D$8H‰$H‰T$@H‰T$H‰L$HH‰L$H‰t$PH‰t$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxtÂruntime.ifaceeq@°"".autotmp_0555?Ntype.golang.org/x/tools/go/types.Object"".autotmp_0554Ntype.golang.org/x/tools/go/types.Object"".autotmp_0553_type.int"".autotmp_0552Otype.int "".~r30type.bool"".s type.uintptr"".qVtype.*[8]golang.org/x/tools/go/types.Object"".pVtype.*[8]golang.org/x/tools/go/types.Object&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ2type..hash."".importErrorÀªeH‹ %H;awèëêHƒì H‹\$(H‰$Hƒ<$tbHÇD$(H‹\$8H‰\$èH‹D$H‹\$(H‰$Hƒ<$t,Hƒ$(HÇD$H‰D$8H‰D$èH‹\$H‰\$@HƒÄ É%ëˉ%ë•
 0runtime.morestack_noctxt|@type..hash.text/scanner.Positionà"runtime.interhash@@
"".autotmp_0557type.uintptr "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".p(type.*"".importError@h?@  
=cTgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ.type..eq."".importError€ôeH‹ %H;awèëêHƒìxH‹Œ$€Hƒù„GH‹„$ˆHƒø„.H‰L$0H‹1H‹IH‰D$(H‹H‹@H9Á…H‰t$hH‰4$H‰L$pH‰L$H‰T$XH‰T$H‰D$`H‰D$èH‹L$0H‹D$(¶\$ €û„¼H‹YH‹hH9ë…«H‹YH‹hH9ë…šH‹Y H‹h H9ë…‰H‹œ$ˆHƒûtwH‹K(H‹s0H‹œ$€Hƒût]H‹C(H‹S0H9ÈuCH‰D$8H‰$H‰T$@H‰T$H‰L$HH‰L$H‰t$PH‰t$è¶\$ €ût␍Æ„$˜HƒÄxÃÆ„$˜HƒÄxÉ량ë…Æ„$˜HƒÄxÉéËþÿÿ‰é²þÿÿ
 0runtime.morestack_noctxtŽ runtime.eqstringÞruntime.ifaceeq@ð"".autotmp_0563type.error"".autotmp_0562_type.error"".autotmp_0561?type.string"".autotmp_0560type.string"".autotmp_0559Ÿ6type.*text/scanner.Position"".autotmp_0558�6type.*text/scanner.Position "".~r30type.bool"".s type.uintptr"".q(type.*"".importError"".p(type.*"".importError2ð¯ïð ïðïð€€†¨RTgclocals·fa7203fd5ed88aea99b7be572f707eb0Tgclocals·6a8507892607404f128e2c479beb1c2b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ."".(*importError).Error žeH‹ %H;awèëêHƒìHH‹Y H…Ût␍H�|$PH9;uH‰#HÇD$XHÇD$`H‹\$P1íH9ëuHH�H�,$H‰ïH‰ÞH¥H¥H�H�l$H‰ïH‰ÞH¥H¥H�H�l$ H‰ïH‰ÞH¥H¥è H‹t$PHƒþt*H�,$H‰ïèèH‹L$8H‹D$@H‰L$XH‰D$`HƒÄHÉëÒ
 0runtime.morestack_noctxt¢,go.string."gcimporter"Ì.go.string."importError"ø"go.string."Error" "runtime.panicwrapÒ¼ runtime.duffcopyÜ("".importError.Error0� "".~r0type.string""..this(type.*"".importError�°��ÐÐ �ATgclocals·a08e9001cb8f9d822225de3b8e406515Tgclocals·3280bececceccd33cb74587feedb1f9f<autogenerated>þ4type..hash.[2]interface {}àÎeH‹ %H;awèëêHƒì0H‹L$H1ÀHÇD$ H‹l$ H9è}eH‰D$(H‰ÅH‰ÈHÁÀH»¿c�»kïRH¯ØH‰ØH‹\$8HƒûtDHkíHëH‰$HÇD$H‰D$HH‰D$èH‹L$H‹D$(HÿÀH‹l$ H9è|›H‰L$PHƒÄ0Éë¸
 0runtime.morestack_noctxtü(runtime.nilinterhash@` "".autotmp_0567type.int"".autotmp_0566type.int "".~r30type.uintptr"".h type.uintptr"".stype.uintptr"".p*type.*[2]interface {}`ˆ_`␍°°
}3Tgclocals·2dc77d960dd3e4b3de2361f9cbd75783Tgclocals·3280bececceccd33cb74587feedb1f9f®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ0type..eq.[2]interface {}àÈeH‹ %H;awèëêHƒìX1ÀHÇD$(H‹l$(H9è�’H‰D$0H‹\$hHƒû„–H‰ÅHkíHëH‹ H‹sH‹\$`HƒûtvH‰ÅHkíHëH‹H‹SH9ÈuVH‰D$8H‰$H‰T$@H‰T$H‰L$HH‰L$H‰t$PH‰t$è¶\$ €ût H‹D$0HÿÀH‹l$(H9èŒnÿÿÿÆD$xHƒÄXÃÆD$xHƒÄXÉ놉écÿÿÿ
 0runtime.morestack_noctxtÂruntime.efaceeq@°"".autotmp_0571?"type.interface {}"".autotmp_0570"type.interface {}"".autotmp_0569_type.int"".autotmp_0568Otype.int "".~r30type.bool"".s type.uintptr"".q*type.*[2]interface {}"".p*type.*[2]interface {}&°´¯° ¯°ðð  PTgclocals·9c703c5c7b9c1932c840b69f8ebce236Tgclocals·44568aa369055d8938d809aa5d80843b®/Users/swaits/Code/docrawler/.vendor/src/golang.org/x/tools/go/gcimporter/exportdata.goþ,>go.itab.*bufio.Reader.io.Readerþ,Bgo.itab.*errors.errorString.errorþ,go.string."header: %s"@6
header: %s ,go.string."header: %s"þDgo.string."invalid archive header"PNinvalid archive header Dgo.string."invalid archive header"þTgclocals·c9e3c6d5f2e780a232dcf01774689094PP  þTgclocals·7c73a419403a83e4569fc85cf965927bPP JJJ
B JJþ*go.string."!<arch>\n"@2!<arch>
 *go.string."!<arch>\n"þ*go.string."__.SYMDEF"@4 __.SYMDEF *go.string."__.SYMDEF"þ.go.string."__.GOSYMDEF"@8 __.GOSYMDEF .go.string."__.GOSYMDEF"þ*go.string."__.PKGDEF"@4 __.PKGDEF *go.string."__.PKGDEF"þVgo.string."go archive is missing __.PKGDEF"``go archive is missing __.PKGDEF Vgo.string."go archive is missing __.PKGDEF"þ,go.string."go object "@6
go object  ,go.string."go object "þ@go.string."not a go object file"PJnot a go object file @go.string."not a go object file"þTgclocals·256afd28bf6c775e086b317de2798892��:€  þTgclocals·7ae61b314b311606103e579d12906a42PP.þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·3280bececceccd33cb74587feedb1f9fþgo.string.".a"0&.a go.string.".a"þTgclocals·d6cd9281b01f077327dbc65f008cabfc€€4€  
"
"þTgclocals·ab722441bfdc8df693d04875bdfd44c5HH"""""" " ""þTgclocals·ddbab3f08e263922f15c2d23c4448f9a00$$&þTgclocals·a06e15cefa04c4de83b680fa5eac8b4300Š,Ь Š, Š, þ,4go.itab.*os.File.io.Readerþ$go.string."unsafe"0.unsafe $go.string."unsafe"þgo.string."."0$. go.string."."þBgo.string."can't find import: %s"PLcan't find import: %s Bgo.string."can't find import: %s"þTgclocals·739a6a9cc2d64913442fa65f1f961dee€€6òò   @*@*‚ @*
@*" @*@*þTgclocals·db214e47c3002302e2d8d591927a97c0ˆˆ
Š Š Š Š Š
Š Š Š Š Š Š
þHgo.string."no package name for %s\n"PPno package name for %s
 Hgo.string."no package name for %s\n"þTgclocals·34cda72afdcfdf8fef15e82264bcd4b3((
þTgclocals·c8dbfc7901f18862149c14c7613c5f6b((ЬЬЬþ4go.string."%s: %q -> %q\n"@<␍%s: %q -> %q
 4go.string."%s: %q -> %q\n"þTgclocals·d64e51a4c4bfeaa840e480961ec6b0b3þTgclocals·519efd86263089ddb84df3cfe7fd2992þ, go.itab.*golang.org/x/tools/go/types.TypeName.golang.org/x/tools/go/types.ObjectþTgclocals·b47ffc4cc29bc609be6ec658396bb73a   $
° ‚° ‚°‚"¢ þTgclocals·64edff1305d2d6a98f11ba36de028fc9XX 
þdgo.string."import error %s (byte offset = %d): %s"pn&import error %s (byte offset = %d): %s dgo.string."import error %s (byte offset = %d): %s"þTgclocals·4e66f52b20879c06cabd165d1374ec07(( ü?ü?þTgclocals·5abb3cfee363877c00470c6b5dfdf02a((R-R-R-þTgclocals·02742a319e22af0c972118f91befa02cPP*€ ÕþTgclocals·12fd79131d0da3ce43d987c2561c289000>>>>þTgclocals·8d600a433c6aaa81a4fe446d95c5546b þTgclocals·9d0fdb5a8b6bdb6e912289f44b76055a  ŠŠþHgo.string."expected %s, got %s (%s)"`Rexpected %s, got %s (%s) Hgo.string."expected %s, got %s (%s)"þTgclocals·449e7cdcf39a300f599f326278b49fc6``&""ü?"ü?þTgclocals·2ccccd421c51251ab29254eab393497e88þ>go.string."expected %q, got %q"PHexpected %q, got %q >go.string."expected %q, got %q"þTgclocals·99efdbc93924abe75b70e7be6ddbd65000 "ü üþTgclocals·2018557e3ee0abccf2865b16663e690b00
þNgo.string."expected keyword %s, got %q"`Xexpected keyword %s, got %q Ngo.string."expected keyword %s, got %q"þTgclocals·b5f842672308ee6e2fa72d6ff2f86a7900"Â?"À?þTgclocals·2018557e3ee0abccf2865b16663e690b00
þTgclocals·23c4785fa8abd7e258acfe91c9f325f3  þTgclocals·d7e8a62d22b1cde6d92b17a55c33fe8f þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·a08e9001cb8f9d822225de3b8e406515þTgclocals·29f0050a5ee7c2b9348a75428171d7de þTgclocals·d7e8a62d22b1cde6d92b17a55c33fe8f þTgclocals·0372b889336bbdf612862c172920463dþTgclocals·bae0cb6de1cb890aa8f1070add72546000
‚Š
þTgclocals·73433c54fb853071f1115ac5da3c80d0  *þTgclocals·9d0fdb5a8b6bdb6e912289f44b76055a  ŠŠþ@go.string."%s package not found"PJ%s package not found @go.string."%s package not found"þTgclocals·68a955d9197f50134fd00c00810c9e0600òòþTgclocals·9c40096308bb5d08ee8587796039643600"**þ@go.string."not a basic type: %s"PJnot a basic type: %s @go.string."not a basic type: %s"þTgclocals·0028a114a78b775944525d29ef16e5c0PP&  þTgclocals·1ee14e32cec51f1cde6c2b0577d8188700þ,–go.itab.*golang.org/x/tools/go/types.Array.golang.org/x/tools/go/types.TypeþTgclocals·3b54427f77b858635567cdebca41836088À,þTgclocals·b46c7a32cd3cbdb99d262657bbb5cb4688þ,’go.itab.*golang.org/x/tools/go/types.Map.golang.org/x/tools/go/types.Typeþgo.string."map"0(map go.string."map"þTgclocals·9904a18ebecacd70db484009ca7b051b88À,,,þTgclocals·b46c7a32cd3cbdb99d262657bbb5cb4688þ2go.string."name expected"@<␍name expected 2go.string."name expected"þTgclocals·e621a0ba6eb379ba26c5eb53e098e9d1@@ þTgclocals·73838a813f5b7a9652ab0ab1a7cfc095@@
¦†&†¦þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·78fd77a07ab543a063c3a3049973febe þHgo.string."anonymous field expected"`Ranonymous field expected Hgo.string."anonymous field expected"þJgo.string."invalid struct tag %s: %s"`Tinvalid struct tag %s: %s Jgo.string."invalid struct tag %s: %s"þTgclocals·23f2ba6ee7d6cd04ab5c29bd12b9e67e°° L€,€,€,,€€,€,€€ð,€€€ð,€€ðÀ À À þTgclocals·36220f0e6724f53c97d45e8865178a15pp þ,˜go.itab.*golang.org/x/tools/go/types.Struct.golang.org/x/tools/go/types.Typeþ$go.string."struct"0.struct $go.string."struct"þTgclocals·2675b89e255790cd90da655dc803218dHH ‚"€€ þTgclocals·65da895b3dbef1b5b79355c3852ec825HHþ,–go.itab.*golang.org/x/tools/go/types.Slice.golang.org/x/tools/go/types.Typeþgo.string."·"0&· go.string."·"þgo.string."..."0(... go.string."..."þTgclocals·6a2917e131227f3ce58256bd9b19a984hh È ,‚ȂÈþTgclocals·3591272cda6ee607a1a868780763d60chh þJgo.string."... not on final argument"`T... not on final argument Jgo.string."... not on final argument"þTgclocals·9fa61dd53bc165eaa4cad5bd08ec0f0588 €þTgclocals·45293744f10a4f121a8740fb3c189a6888


þXgo.string."... not permitted on result type"pb ... not permitted on result type Xgo.string."... not permitted on result type"þTgclocals·80d0fa02e2185bd68d71e001e5be726f88 ˆ €þTgclocals·ab01a2d55089ff50c402006df1039c3988
þ,žgo.itab.*golang.org/x/tools/go/types.Signature.golang.org/x/tools/go/types.Typeþ,žgo.itab.*golang.org/x/tools/go/types.Interface.golang.org/x/tools/go/types.Typeþ*go.string."interface"@4 interface *go.string."interface"þTgclocals·37a72310bd3c2f86450f233168baf55bÀÀ "€ˆ‚€¬€ ¬€ ,€ € €þTgclocals·60e60903d0890b79099524ef4cd0028ehh þ,”go.itab.*golang.org/x/tools/go/types.Chan.golang.org/x/tools/go/types.Typeþ go.string."chan"0*chan go.string."chan"þgo.string."<-"0&<- go.string."<-"þTgclocals·3ea018d3d3bf08cc71b1924be27582a2((
,þTgclocals·6d340c3bdac448a6ef1256f331f68dd3((þ,šgo.itab.*golang.org/x/tools/go/types.Pointer.golang.org/x/tools/go/types.Typeþ go.string."func"0*func go.string."func"þLgo.string."expected type, got %s (%q)"`Vexpected type, got %s (%q) Lgo.string."expected type, got %s (%q)"þTgclocals·6fae770f4aaaf5843fb0a929a5d0c93b°°
0 À,À€ÿ€ÿþTgclocals·2414cc3a9e5b7e18ceaad46208847f11``
þ$go.string."import"0.import $go.string."import"þTgclocals·29f0050a5ee7c2b9348a75428171d7de þTgclocals·ac5bea9c8a91f5fb1d31bdacc5067b57 þgo.string."-"0$- go.string."-"þTgclocals·29f0050a5ee7c2b9348a75428171d7de þTgclocals·d7e8a62d22b1cde6d92b17a55c33fe8f þ,œgo.itab.golang.org/x/tools/go/exact.int64Val.golang.org/x/tools/go/exact.Valueþ8go.string."invalid mantissa"PBinvalid mantissa 8go.string."invalid mantissa"þgo.string."p"0$p go.string."p"þTgclocals·a6a5fa841c0cffe34acd16ef31ddb86c00°þTgclocals·d1568ce269a1ce9779fe2e06f6738fb900
þ,–go.itab.*golang.org/x/tools/go/types.Basic.golang.org/x/tools/go/types.Typeþ,šgo.itab.golang.org/x/tools/go/exact.boolVal.golang.org/x/tools/go/exact.Valueþ,šgo.itab.*golang.org/x/tools/go/types.Const.golang.org/x/tools/go/types.Objectþ"go.string."const"0,const "go.string."const"þ go.string."true"0*true go.string."true"þ"go.string."false"0,false "go.string."false"þDgo.string."expected true or false"PNexpected true or false Dgo.string."expected true or false"þgo.string."i"0$i go.string."i"þFgo.string."expected literal got %s"PPexpected literal got %s Fgo.string."expected literal got %s"þTgclocals·1e9d3be895560c458124d34fcba3c5d7¨¨P  , ì ,ì ,€ ,, ,,È ì. , ,ì¼ ,ì¼
À€‚À€‚À‚À‚þTgclocals·bcc772abe81b036416e664f43e7d04ea˜˜þ go.string."type"0*type go.string."type"þTgclocals·effafd59fffff9c30c776c5effd52018((,þTgclocals·15395a9df917b4c9aa74d5c6c7e1ebf4((þ,–go.itab.*golang.org/x/tools/go/types.Var.golang.org/x/tools/go/types.Objectþgo.string."var"0(var go.string."var"þTgclocals·f6d8c5f6f2849a252db82714c192d569@@
‚ ‚ ‚þTgclocals·2c09ec81c5cb12328d7183f25bc48833@@þTgclocals·e1ae6533a9e39048ba0735a2264ce16a þTgclocals·bd51743682bd6c0f7b9f2e8e6dffed99 
þTgclocals·3eca4ffcd48a84d93645911c98c5f24dXX " €((À
 À
 À þTgclocals·63bae81cfd8a678616fd0ed83955df76XX þ,˜go.itab.*golang.org/x/tools/go/types.Func.golang.org/x/tools/go/types.ObjectþTgclocals·8a726de051bf5b6e966a4a4626fa226dHH 
‚
¬‚¬‚,‚þTgclocals·ce3ac48024ab99dccf70ef1fe4c8779eHHþTgclocals·8d600a433c6aaa81a4fe446d95c5546b þTgclocals·ac5bea9c8a91f5fb1d31bdacc5067b57 þ&go.string."package"00package &go.string."package"þ go.string."safe"0*safe go.string."safe"þHgo.string."expected '$$', got %s %c"`Rexpected '$$', got %s %c Hgo.string."expected '$$', got %s %c"þ\go.string."expected no scanner errors, got %d"pf"expected no scanner errors, got %d \go.string."expected no scanner errors, got %d"þTgclocals·18915aee5cae0126f2a06e3df303b719€€$€€ð€ð<€<þTgclocals·3be0b30e44224793f9e9b8c26d600a35HHþ,8go.itab."".importError.errorþTgclocals·087fc05a011aec2a651c47fa3f82d746``&>R-R-þTgclocals·7c13896baab3273e10662a9a37b348ceþNgo.string."reading export data: %s: %v"`Xreading export data: %s: %v Ngo.string."reading export data: %s: %v"þTgclocals·ed94f01d04841dfbdf3c0776abaef34c88
 Â? À? À?þTgclocals·7c13896baab3273e10662a9a37b348ceþTgclocals·38df2c0cbd72e8d8851524e0890ca535((
þTgclocals·3cd76c4f8d01c613585e17871258aa07((
þgo.string.".5"0&.5 go.string.".5"þgo.string.".6"0&.6 go.string.".6"þgo.string.".8"0&.8 go.string.".8"þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·3280bececceccd33cb74587feedb1f9fþ*"".pkgExts€type.[4]string€ go.string.".a"  go.string.".5"@ go.string.".6"` go.string.".8"þ,"".initdone·type.uint8þ,"".readGopackHeader·f&"".readGopackHeaderþ(runtime.makeslice·f"runtime.makesliceþ&runtime.typ2Itab·f runtime.typ2Itabþio.ReadFull·fio.ReadFullþ$runtime.convT2E·fruntime.convT2Eþ8runtime.writebarrieriface·f2runtime.writebarrierifaceþfmt.Printf·ffmt.Printfþ*runtime.panicslice·f$runtime.panicsliceþ8runtime.slicebytetostring·f2runtime.slicebytetostringþ(strings.TrimSpace·f"strings.TrimSpaceþstrconv.Atoi·fstrconv.Atoiþ*runtime.panicindex·f$runtime.panicindexþ(runtime.newobject·f"runtime.newobjectþ:runtime.writebarrierstring·f4runtime.writebarrierstringþ,runtime.throwreturn·f&runtime.throwreturnþ("".FindExportData·f""".FindExportDataþ8bufio.(*Reader).ReadSlice·f2bufio.(*Reader).ReadSliceþ&runtime.eqstring·f runtime.eqstringþ"".init·1·f"".init·1þ"".Import·f"".Importþ4runtime.writebarrierptr·f.runtime.writebarrierptrþ"".FindPkg·f"".FindPkgþ2go/build.IsLocalImport·f,go/build.IsLocalImportþ,path/filepath.IsAbs·f&path/filepath.IsAbsþ$go/build.Import·fgo/build.Importþ*strings.TrimSuffix·f$strings.TrimSuffixþ*path/filepath.Join·f$path/filepath.Joinþ0runtime.concatstring2·f*runtime.concatstring2þos.Stat·fos.Statþ "".ImportData·f"".ImportDataþ"".func·001·f"".func·001þ(runtime.deferproc·f"runtime.deferprocþ,runtime.deferreturn·f&runtime.deferreturnþ("".(*parser).init·f""".(*parser).initþ6"".(*parser).parseExport·f0"".(*parser).parseExportþos.Getwd·fos.Getwdþfmt.Errorf·ffmt.Errorfþ:runtime.mapaccess1_faststr·f4runtime.mapaccess1_faststrþos.Open·fos.Openþ"".func·002·f"".func·002þ$bufio.NewReader·fbufio.NewReaderþ>text/scanner.(*Scanner).Init·f8text/scanner.(*Scanner).Initþ"".func·003·f"".func·003þ("".(*parser).next·f""".(*parser).nextþ,runtime.mapiterinit·f&runtime.mapiterinitþ,runtime.mapiternext·f&runtime.mapiternextþ>text/scanner.(*Scanner).Scan·f8text/scanner.(*Scanner).ScanþHtext/scanner.(*Scanner).TokenText·fBtext/scanner.(*Scanner).TokenTextþ6text/scanner.TokenString·f0text/scanner.TokenStringþ$"".declTypeName·f"".declTypeNameþ(runtime.assertI2T·f"runtime.assertI2TþNgolang.org/x/tools/go/types.NewNamed·fHgolang.org/x/tools/go/types.NewNamedþ\golang.org/x/tools/go/types.(*Scope).Insert·fVgolang.org/x/tools/go/types.(*Scope).Insertþ."".importError.Error·f("".importError.Errorþ$runtime.convI2E·fruntime.convI2Eþfmt.Sprintf·ffmt.Sprintfþ*"".(*parser).error·f$"".(*parser).errorþ*runtime.assertE2T2·f$runtime.assertE2T2þ<text/scanner.(*Scanner).Pos·f6text/scanner.(*Scanner).Posþ(runtime.assertE2I·f"runtime.assertE2Iþ$runtime.gopanic·fruntime.gopanicþ,"".(*parser).errorf·f&"".(*parser).errorfþ,"".(*parser).expect·f&"".(*parser).expectþ:"".(*parser).expectSpecial·f4"".(*parser).expectSpecialþ>text/scanner.(*Scanner).Peek·f8text/scanner.(*Scanner).Peekþ:"".(*parser).expectKeyword·f4"".(*parser).expectKeywordþ<"".(*parser).parseLine truncated
   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P(go.string."[]string"p,go.weak.type.*[]string€"runtime.zerovalue�type.stringþ:go.typelink.[]string/[]stringtype.[]stringþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·2dc77d960dd3e4b3de2361f9cbd75783þTgclocals·44568aa369055d8938d809aa5d80843bþTgclocals·9c703c5c7b9c1932c840b69f8ebce236þ0type..hashfunc.[2]string(type..hash.[2]stringþ,type..eqfunc.[2]string$type..eq.[2]stringþ&type..alg.[2]string 0type..hashfunc.[2]string,type..eqfunc.[2]stringþbruntime.gcbits.0x48480000000000000000000000000000 HHþ*go.string."[2]string"@4 [2]string *go.string."[2]string"þtype.[2]stringÀÀ PXåé &type..alg.[2]string0bruntime.gcbits.0x48480000000000000000000000000000P*go.string."[2]string"p.go.weak.type.*[2]string€"runtime.zerovalue�type.string type.[]stringþ>go.typelink.[2]string/[2]stringtype.[2]stringþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·2dc77d960dd3e4b3de2361f9cbd75783þTgclocals·44568aa369055d8938d809aa5d80843bþTgclocals·9c703c5c7b9c1932c840b69f8ebce236þ0type..hashfunc.[4]string(type..hash.[4]stringþ,type..eqfunc.[4]string$type..eq.[4]stringþ&type..alg.[4]string 0type..hashfunc.[4]string,type..eqfunc.[4]stringþbruntime.gcbits.0x48484848000000000000000000000000 HHHHþ*go.string."[4]string"@4 [4]string *go.string."[4]string"þtype.[4]stringÀÀ@УJ &type..alg.[4]string0bruntime.gcbits.0x48484848000000000000000000000000P*go.string."[4]string"p.go.weak.type.*[4]string€"runtime.zerovalue�type.string type.[]stringþ>go.typelink.[4]string/[4]stringtype.[4]stringþ,go.string."*[2]string"@6
*[2]string ,go.string."*[2]string"þtype.*[2]string   f<6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P,go.string."*[2]string"p0go.weak.type.**[2]string€"runtime.zerovalue�type.[2]stringþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·2dc77d960dd3e4b3de2361f9cbd75783þTgclocals·44568aa369055d8938d809aa5d80843bþTgclocals·9c703c5c7b9c1932c840b69f8ebce236þ0type..hashfunc.[8]string(type..hash.[8]stringþ,type..eqfunc.[8]string$type..eq.[8]stringþ&type..alg.[8]string 0type..hashfunc.[8]string,type..eqfunc.[8]stringþbruntime.gcbits.0x48484848484848480000000000000000 HHHHHHHHþ*go.string."[8]string"@4 [8]string *go.string."[8]string"þtype.[8]stringÀÀ€USŒ> &type..alg.[8]string0bruntime.gcbits.0x48484848484848480000000000000000P*go.string."[8]string"p.go.weak.type.*[8]string€"runtime.zerovalue�type.string type.[]stringþ>go.typelink.[8]string/[8]stringtype.[8]stringþ8go.string."[]*types.Package"PB[]*types.Package 8go.string."[]*types.Package"þVtype.[]*golang.org/x/tools/go/types.Package  S`Ð=   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P8go.string."[]*types.Package"phgo.weak.type.*[]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�Rtype.*golang.org/x/tools/go/types.Packageþ†go.typelink.[]*types.Package/[]*golang.org/x/tools/go/types.PackageVtype.[]*golang.org/x/tools/go/types.Packageþbruntime.gcbits.0x88888888000000000000000000000000 ˆˆˆˆþ:go.string."[8]*types.Package"PD[8]*types.Package :go.string."[8]*types.Package"þXtype.[8]*golang.org/x/tools/go/types.PackageÀÀ@ŽFóù  runtime.algarray0bruntime.gcbits.0x88888888000000000000000000000000P:go.string."[8]*types.Package"pjgo.weak.type.*[8]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�Rtype.*golang.org/x/tools/go/types.Package Vtype.[]*golang.org/x/tools/go/types.PackageþŠgo.typelink.[8]*types.Package/[8]*golang.org/x/tools/go/types.PackageXtype.[8]*golang.org/x/tools/go/types.PackageþZgo.string."*map.bucket[string]*types.Package"pd!*map.bucket[string]*types.Package Zgo.string."*map.bucket[string]*types.Package"þxtype.*map.bucket[string]*golang.org/x/tools/go/types.Package  ¼ÚŒ^6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PZgo.string."*map.bucket[string]*types.Package"pŠgo.weak.type.**map.bucket[string]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�vtype.map.bucket[string]*golang.org/x/tools/go/types.Packageþbruntime.gcbits.0x84848484848484848488888888000000 „„„„„„„„„ˆˆˆˆþXgo.string."map.bucket[string]*types.Package"pb map.bucket[string]*types.Package Xgo.string."map.bucket[string]*types.Package"þ go.string."keys"0*keys go.string."keys"þ$go.string."values"0.values $go.string."values"þ(go.string."overflow"@2overflow (go.string."overflow"þvtype.map.bucket[string]*golang.org/x/tools/go/types.Package°°ÐÃAâˆÈ à runtime.algarray0bruntime.gcbits.0x84848484848484848488888888000000PXgo.string."map.bucket[string]*types.Package"pˆgo.weak.type.*map.bucket[string]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�Àvtype.map.bucket[string]*golang.org/x/tools/go/types.PackageÀ go.string."keys"àtype.[8]string�$go.string."values"°Xtype.[8]*golang.org/x/tools/go/types.Packageà(go.string."overflow"€xtype.*map.bucket[string]*golang.org/x/tools/go/types.Packageþbruntime.gcbits.0x44844800000000000000000000000000 D„HþRgo.string."map.hdr[string]*types.Package"`\map.hdr[string]*types.Package Rgo.string."map.hdr[string]*types.PacLine truncated
oldbuckets ,go.string."oldbuckets"þptype.map.hdr[string]*golang.org/x/tools/go/types.Packageàà0Dj›è  à runtime.algarray0bruntime.gcbits.0x44844800000000000000000000000000PRgo.string."map.hdr[string]*types.Package"p‚go.weak.type.*map.hdr[string]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�Àptype.map.hdr[string]*golang.org/x/tools/go/types.PackageÀ&go.string."buckets"àxtype.*map.bucket[string]*golang.org/x/tools/go/types.Package�,go.string."oldbuckets"°xtype.*map.bucket[string]*golang.org/x/tools/go/types.PackageþJgo.string."map[string]*types.Package"`Tmap[string]*types.Package Jgo.string."map[string]*types.Package"þhtype.map[string]*golang.org/x/tools/go/types.PackageÜܽ$65Ð € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PJgo.string."map[string]*types.Package"pzgo.weak.type.*map[string]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�type.string Rtype.*golang.org/x/tools/go/types.Package°vtype.map.bucket[string]*golang.org/x/tools/go/types.PackageÀptype.map.hdr[string]*golang.org/x/tools/go/types.Packageþªgo.typelink.map[string]*types.Package/map[string]*golang.org/x/tools/go/types.Packagehtype.map[string]*golang.org/x/tools/go/types.Packageþ,type..gcprog."".parser:: �(U•UUUUVZ•™þ:go.string."gcimporter.parser"PDgcimporter.parser :go.string."gcimporter.parser"þ&go.string."scanner"00scanner &go.string."scanner"þgo.string."tok"0(tok go.string."tok"þgo.string."lit"0(lit go.string."lit"þgo.string."id"0&id go.string."id"þ&go.string."imports"00imports &go.string."imports"þ$go.string."parser"0.parser $go.string."parser"þtype."".parser  Xßr*dY(0@P2 à runtime.algarray@,type..gcprog."".parserP:go.string."gcimporter.parser"ptype.*"".parser€"runtime.zerovalue�Àtype."".parserÀ&go.string."scanner"Ð"go.importpath."".à2type.text/scanner.Scanner�go.string."tok" "go.importpath."".°type.int32àgo.string."lit"ð"go.importpath."".€type.string°go.string."id"À"go.importpath."".Ðtype.string€&go.string."imports"�"go.importpath."". htype.map[string]*golang.org/x/tools/go/types.Package`Ðtype."".parserÐ$go.string."parser"à"go.importpath."".ð type."".parserþ<go.string."*gcimporter.parser"PF*gcimporter.parser <go.string."*gcimporter.parser"þdgo.string."func(*gcimporter.parser, interface {})"pn&func(*gcimporter.parser, interface {}) dgo.string."func(*gcimporter.parser, interface {})"þFtype.func(*"".parser, interface {})  Ì�ôm3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000Pdgo.string."func(*gcimporter.parser, interface {})"pXgo.weak.type.*func(*"".parser, interface {})€"runtime.zerovalue €Ftype.func(*"".parser, interface {})РFtype.func(*"".parser, interface {})€type.*"".parser�"type.interface {}þzgo.string."func(*gcimporter.parser, string, ...interface {})"�„1func(*gcimporter.parser, string, ...interface {}) zgo.string."func(*gcimporter.parser, string, ...interface {})"þ\type.func(*"".parser, string, ...interface {})°°+bK’3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000Pzgo.string."func(*gcimporter.parser, string, ...interface {})"pngo.weak.type.*func(*"".parser, string, ...interface {})€"runtime.zerovalue €\type.func(*"".parser, string, ...interface {})а\type.func(*"".parser, string, ...interLine truncated
“ 3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P:go.string."func() types.Type"pjgo.weak.type.*func() golang.org/x/tools/go/types.Type€"runtime.zerovalue €Xtype.func() golang.org/x/tools/go/types.TypeЀXtype.func() golang.org/x/tools/go/types.Type€Jtype.golang.org/x/tools/go/types.Typeþ4go.string."parseBasicType"@>parseBasicType 4go.string."parseBasicType"þ2go.string."parseChanType"@<␍parseChanType 2go.string."parseChanType"þ4go.string."parseConstDecl"@>parseConstDecl 4go.string."parseConstDecl"þ*go.string."parseDecl"@4 parseDecl *go.string."parseDecl"þ2go.string."parseDotIdent"@<␍parseDotIdent 2go.string."parseDotIdent"þ2go.string."func() string"@<␍func() string 2go.string."func() string"þ$type.func() string��¢mË3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P2go.string."func() string"p6go.weak.type.*func() string€"runtime.zerovalue €$type.func() stringЀ$type.func() string€type.stringþ.go.string."parseExport"@8 parseExport .go.string."parseExport"þBgo.string."func() *types.Package"PLfunc() *types.Package Bgo.string."func() *types.Package"þ`type.func() *golang.org/x/tools/go/types.Package��EFÔ{3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PBgo.string."func() *types.Package"prgo.weak.type.*func() *golang.org/x/tools/go/types.Package€"runtime.zerovalue €`type.func() *golang.org/x/tools/go/types.PackageЀ`type.func() *golang.org/x/tools/go/types.Package€Rtype.*golang.org/x/tools/go/types.Packageþ:go.string."parseExportedName"PDparseExportedName :go.string."parseExportedName"þVgo.string."func() (*types.Package, string)"``func() (*types.Package, string) Vgo.string."func() (*types.Package, string)"þttype.func() (*golang.org/x/tools/go/types.Package, string)  £ky3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PVgo.string."func() (*types.Package, string)"p†go.weak.type.*func() (*golang.org/x/tools/go/types.Package, string)€"runtime.zerovalue €ttype.func() (*golang.org/x/tools/go/types.Package, string)Ѐttype.func() (*golang.org/x/tools/go/types.Package, string)€Rtype.*golang.org/x/tools/go/types.Package�type.stringþ,go.string."parseField"@6
parseField ,go.string."parseField"þNgo.string."func() (*types.Var, string)"`Xfunc() (*types.Var, string) Ngo.string."func() (*types.Var, string)"þltype.func() (*golang.org/x/tools/go/types.Var, string)  8CDò3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PNgo.string."func() (*types.Var, string)"p~go.weak.type.*func() (*golang.org/x/tools/go/types.Var, string)€"runtime.zerovalue €ltype.func() (*golang.org/x/tools/go/types.Var, string)Ѐltype.func() (*golang.org/x/tools/go/types.Var, string)€Jtype.*golang.org/x/tools/go/types.Var�type.stringþ*go.string."parseFunc"@4 parseFunc *go.string."parseFunc"þZgo.string."func(*types.Var) *types.Signature"pd!func(*types.Var) *types.Signature Zgo.string."func(*types.Var) *types.Signature"þ¤type.func(*golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.Signature  T eÿ3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PZgo.string."func(*types.Var) *types.Signature"pgo.weak.type.*func(*golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.Signature€"runtime.zerovalue €¤type.func(*golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.SignatureÐ�¤type.func(*golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.Signature€Jtype.*golang.org/x/tools/go/types.Var�Vtype.*golang.org/x/tools/go/types.Signatureþ2go.string."parseFuncDecl"@< parseFuncDecl 2go.string."parseFuncDecl"þ6go.string."parseImportDecl"@@parseImportDecl 6go.string."parseImportDecl"þ(go.string."parseInt"@2parseInt (go.string."parseInt"þ<go.string."parseInterfaceType"PFparseInterfaceType <go.string."parseInterfaceType"þ0go.string."parseMapType"@: parseMapType 0go.string."parseMapType"þ6go.string."parseMethodDecl"@@parseMethodDecl 6go.string."parseMethodDecl"þ*go.string."parseName"@4 parseName *go.string."parseName"þ^go.string."func(bool) (*types.Package, string)"ph#func(bool) (*types.Package, string) ^go.string."func(bool) (*types.Package, string)"þ|type.func(bool) (*golang.org/x/tools/go/types.Package, string)°°1…e3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P^go.string."func(bool) (*types.Package, string)"pŽgo.weak.type.*func(bool) (*golang.org/x/tools/go/types.Package, string)€"runtime.zerovalue €|type.func(bool) (*golang.org/x/tools/go/types.Package, string)Ð�|type.func(bool) (*golang.org/x/tools/go/types.Package, string)€type.bool�Rtype.*golang.org/x/tools/go/types.Package type.stringþ.go.string."parseNumber"@8 parseNumber .go.string."parseNumber"þ\go.string."func() (*types.Basic, exact.Value)"pf"func() (*types.Basic, exact.Value) \go.string."func() (*types.Basic, exact.Value)"þ¦type.func() (*golang.org/x/tools/go/types.Basic, golang.org/x/tools/go/exact.Value)  §· .3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P\go.string."func() (*types.Basic, exact.Value)"p¸go.weak.type.*func() (*golang.org/x/tools/go/types.Basic, golang.org/x/tools/go/exact.Value)€"runtime.zerovalue €¦type.func() (*golang.org/x/tools/go/types.Basic, golang.org/x/tools/go/exact.Value)Ѐ¦type.func() (*golang.org/x/tools/go/types.Basic, golang.org/x/tools/go/exact.Value)€Ntype.*golang.org/x/tools/go/types.Basic�Ltype.golang.org/x/tools/go/exact.Valueþ4go.string."parsePackageId"@>parsePackageId 4go.string."parsePackageId"þ8go.string."parsePackageName"PBparsePackageName 8go.string."parsePackageName"þ4go.string."parseParameter"@>parseParameter 4go.string."parseParameter"þJgo.string."func() (*types.Var, bool)"`Tfunc() (*types.Var, bool) Jgo.string."func() (*types.Var, bool)"þhtype.func() (*golang.org/x/tools/go/types.Var, bool)  Line truncated
4"".(*parser).parseChanType�
4go.string."parseConstDecl" 
"go.importpath."".°
type.func()À
*type.func(*"".parser)Ð
6"".(*parser).parseConstDeclà
6"".(*parser).parseConstDeclð
*go.string."parseDecl"€ "go.importpath."".� type.func()  *type.func(*"".parser)° ,"".(*parser).parseDeclÀ ,"".(*parser).parseDeclÐ 2go.string."parseDotIdent"à "go.importpath."".ð $type.func() string€ 8type.func(*"".parser) string� 4"".(*parser).parseDotIdent  4"".(*parser).parseDotIdent° .go.string."parseExport"À "go.importpath."".Ð `type.func() *golang.org/x/tools/go/types.Packageà ttype.func(*"".parser) *golang.org/x/tools/go/types.Packageð 0"".(*parser).parseExport€ 0"".(*parser).parseExport� :go.string."parseExportedName"  "go.importpath."".° ttype.func() (*golang.org/x/tools/go/types.Package, string)À ˆtype.func(*"".parser) (*golang.org/x/tools/go/types.Package, string)Ð <"".(*parser).parseExportedNameà <"".(*parser).parseExportedNameð ,go.string."parseField"€"go.importpath."".�ltype.func() (*golang.org/x/tools/go/types.Var, string) €type.func(*"".parser) (*golang.org/x/tools/go/types.Var, string)°."".(*parser).parseFieldÀ."".(*parser).parseFieldÐ*go.string."parseFunc"à"go.importpath."".ð¤type.func(*golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.Signature€¼type.func(*"".parser, *golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.Signature�,"".(*parser).parseFunc ,"".(*parser).parseFunc°2go.string."parseFuncDecl"À"go.importpath."".Ðtype.func()à*type.func(*"".parser)ð4"".(*parser).parseFuncDecl€4"".(*parser).parseFuncDecl�6go.string."parseImportDecl" "go.importpath."".°type.func()À*type.func(*"".parser)Ð8"".(*parser).parseImportDeclà8"".(*parser).parseImportDeclð(go.string."parseInt"€"go.importpath."".�$type.func() string 8type.func(*"".parser) string°*"".(*parser).parseIntÀ*"".(*parser).parseIntÐ<go.string."parseInterfaceType"à"go.importpath."".ðXtype.func() golang.org/x/tools/go/types.Type€ltype.func(*"".parser) golang.org/x/tools/go/types.Type�>"".(*parser).parseInterfaceType >"".(*parser).parseInterfaceType°0go.string."parseMapType"À"go.importpath."".ÐXtype.func() golang.org/x/tools/go/types.Typeàltype.func(*"".parser) golang.org/x/tools/go/types.Typeð2"".(*parser).parseMapType€2"".(*parser).parseMapType�6go.string."parseMethodDecl" "go.importpath."".°type.func()À*type.func(*"".parser)Ð8"".(*parser).parseMethodDeclà8"".(*parser).parseMethodDeclð*go.string."parseName"€"go.importpath."".�|type.func(bool) (*golang.org/x/tools/go/types.Package, string) ”type.func(*"".parser, bool) (*golang.org/x/tools/go/types.Package, string)°,"".(*parser).parseNameÀ,"".(*parser).parseNameÐ.go.string."parseNumber"à"go.importpath."".ð¦type.func() (*golang.org/x/tools/go/types.Basic, golang.org/x/tools/go/exact.Value)€ºtype.func(*"".parser) (*golang.org/x/tools/go/types.Basic, golang.org/x/tools/go/exact.Value)�0"".(*parser).parseNumber 0"".(*parser).parseNumber°4go.string."parsePackageId"À"go.importpath."".Ð$type.func() stringà8type.func(*"".parser) stringð6"".(*parser).parsePackageId€6"".(*parser).parsePackageId�8go.string."parsePackageName" "go.importpath."".°$type.func() stringÀ8type.func(*"".parser) stringÐ:"".(*parser).parsePackageNameà:"".(*parser).parsePackageNameð4go.string."parseParameter"€"go.importpath."".�htype.func() (*golang.org/x/tools/go/types.Var, bool) |type.func(*"".parser) (*golang.org/x/tools/go/types.Var, bool)°6"".(*parser).parseParameterÀ6"".(*parser).parseParameterÐ6go.string."parseParameters"à"go.importpath."".ðltype.func() ([]*golang.org/x/tools/go/types.Var, bool)€€type.func(*"".parser) ([]*golang.org/x/tools/go/types.Var, bool)�8"".(*parser).parseParameters 8"".(*parser).parseParameters°<go.string."parseQualifiedName"À"go.importpath."".Ð8type.func() (string, string)àLtype.func(*"".parser) (string, string)ð>"".(*parser).parseQualifiedName€>"".(*parser).parseQualifiedName�4go.string."parseSignature" "go.importpath."".°¤type.func(*golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.SignatureÀ¼type.func(*"".parser, *golang.org/x/tools/go/types.Var) *golang.org/x/tools/go/types.SignatureÐ6"".(*parser).parseSignatureà6"".(*parser).parseSignatureð6go.string."parseStructType"€"go.importpath."".�Xtype.func() golaLine truncated
[4]uintptr ,go.string."[4]uintptr"þtype.[4]uintptrÀÀ l<‘  runtime.algarray0^runtime.gcbits.0x000000000000000000000000000000P,go.string."[4]uintptr"p0go.weak.type.*[4]uintptr€"runtime.zerovalue�type.uintptr type.[]uintptrþBgo.typelink.[4]uintptr/[4]uintptrtype.[4]uintptrþbruntime.gcbits.0x88888844440000000000000000000000 ˆˆˆDDþTgo.string."map.iter[string]*types.Package"`^map.iter[string]*types.Package Tgo.string."map.iter[string]*types.Package"þgo.string."key"0(key go.string."key"þgo.string."val"0(val go.string."val"þgo.string."t"0$t go.string."t"þgo.string."h"0$h go.string."h"þ go.string."bptr"0*bptr go.string."bptr"þ"go.string."other"0,other "go.string."other"þrtype.map.iter[string]*golang.org/x/tools/go/types.PackageððPxO1 (0( à runtime.algarray0bruntime.gcbits.0x88888844440000000000000000000000PTgo.string."map.iter[string]*types.Package"p„go.weak.type.*map.iter[string]*golang.org/x/tools/go/types.Package€"runtime.zerovalue�Àrtype.map.iter[string]*golang.org/x/tools/go/types.PackageÀgo.string."key"àtype.*string�go.string."val"°Ttype.**golang.org/x/tools/go/types.Packageàgo.string."t"€type.*uint8°go.string."h"Ðrtype.*map.hdr[string]*golang.org/x/tools/go/types.Package€&go.string."buckets" xtype.*map.bucket[string]*golang.org/x/tools/go/types.PackageÐ go.string."bptr"ðxtype.*map.bucket[string]*golang.org/x/tools/go/types.Package "go.string."other"Àtype.[4]uintptrþrgo.string."*struct { F uintptr; A0 **gcimporter.parser }"€|-*struct { F uintptr; A0 **gcimporter.parser } rgo.string."*struct { F uintptr; A0 **gcimporter.parser }"þTtype.*struct { F uintptr; A0 **"".parser }  &8·6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000Prgo.string."*struct { F uintptr; A0 **gcimporter.parser }"pfgo.weak.type.**struct { F uintptr; A0 **"".parser }€"runtime.zerovalue�Rtype.struct { F uintptr; A0 **"".parser }þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·2dc77d960dd3e4b3de2361f9cbd75783þTgclocals·44568aa369055d8938d809aa5d80843bþTgclocals·9c703c5c7b9c1932c840b69f8ebce236þ<type..hashfunc.[3]interface {}4type..hash.[3]interface {}þ8type..eqfunc.[3]interface {}0type..eq.[3]interface {}þ2type..alg.[3]interface {} <type..hashfunc.[3]interface {}8type..eqfunc.[3]interface {}þbruntime.gcbits.0xcccccc00000000000000000000000000 ÌÌÌþ6go.string."[3]interface {}"@@[3]interface {} 6go.string."[3]interface {}"þ(type.[3]interface {}ÀÀ0ÝÏÙ 2type..alg.[3]interface {}0bruntime.gcbits.0xcccccc00000000000000000000000000P6go.string."[3]interface {}"p:go.weak.type.*[3]interface {}€"runtime.zerovalue�"type.interface {} &type.[]interface {}þVgo.typelink.[3]interface {}/[3]interface {}(type.[3]interface {}þ8go.string."*[3]interface {}"PB*[3]interface {} 8go.string."*[3]interface {}"þ*type.*[3]interface {}  °þ¹6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P8go.string."*[3]interface {}"p<go.weak.type.**[3]interface {}€"runtime.zerovalue�(type.[3]interface {}þ4go.string."[]types.Object"@>[]types.Object 4go.string."[]types.Object"þRtype.[]golang.org/x/tools/go/types.Object  Ìj�ò   runtime.algarray0bruntime.gcbits.0x48844400000000000000000000000000P4go.string."[]types.Object"pdgo.weak.type.*[]golang.org/x/tools/gLine truncated
þTgo.string."map.bucket[string]types.Object"`^map.bucket[string]types.Object Tgo.string."map.bucket[string]types.Object"þrtype.map.bucket[string]golang.org/x/tools/go/types.Object°°‹»¶Yˆ à runtime.algarray0ztype..gc.map.bucket[string]golang.org/x/tools/go/types.Object@‚type..gcprog.map.bucket[string]golang.org/x/tools/go/types.ObjectPTgo.string."map.bucket[string]types.Object"p„go.weak.type.*map.bucket[string]golang.org/x/tools/go/types.Object€"runtime.zerovalue�Àrtype.map.bucket[string]golang.org/x/tools/go/types.ObjectÀ go.string."keys"àtype.[8]string�$go.string."values"°Ttype.[8]golang.org/x/tools/go/types.Objectà(go.string."overflow"€ttype.*map.bucket[string]golang.org/x/tools/go/types.ObjectþNgo.string."map.hdr[string]types.Object"`Xmap.hdr[string]types.Object Ngo.string."map.hdr[string]types.Object"þltype.map.hdr[string]golang.org/x/tools/go/types.Objectàà0¾ŸÖ  à runtime.algarray0bruntime.gcbits.0x44844800000000000000000000000000PNgo.string."map.hdr[string]types.Object"p~go.weak.type.*map.hdr[string]golang.org/x/tools/go/types.Object€"runtime.zerovalue�Àltype.map.hdr[string]golang.org/x/tools/go/types.ObjectÀ&go.string."buckets"àttype.*map.bucket[string]golang.org/x/tools/go/types.Object�,go.string."oldbuckets"°ttype.*map.bucket[string]golang.org/x/tools/go/types.ObjectþFgo.string."map[string]types.Object"PPmap[string]types.Object Fgo.string."map[string]types.Object"þdtype.map[string]golang.org/x/tools/go/types.ObjectÜÜ×9¹5 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PFgo.string."map[string]types.Object"pvgo.weak.type.*map[string]golang.org/x/tools/go/types.Object€"runtime.zerovalue�type.string Ntype.golang.org/x/tools/go/types.Object°rtype.map.bucket[string]golang.org/x/tools/go/types.ObjectÀltype.map.hdr[string]golang.org/x/tools/go/types.Objectþ¢go.typelink.map[string]types.Object/map[string]golang.org/x/tools/go/types.Objectdtype.map[string]golang.org/x/tools/go/types.ObjectþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·2dc77d960dd3e4b3de2361f9cbd75783þTgclocals·6a8507892607404f128e2c479beb1c2b 
þTgclocals·fa7203fd5ed88aea99b7be572f707eb0 þ:type..hashfunc."".importError2type..hash."".importErrorþ6type..eqfunc."".importError.type..eq."".importErrorþ0type..alg."".importError :type..hashfunc."".importError6type..eqfunc."".importErrorþFgo.string."*gcimporter.importError"PP*gcimporter.importError Fgo.string."*gcimporter.importError"þ,go.string."gcimporter"@6
gcimporter ,go.string."gcimporter"þ.go.string."importError"@8 importError .go.string."importError"þ"go.string."Error"0,Error "go.string."Error"þTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·a08e9001cb8f9d822225de3b8e406515þ`go.string."func(*gcimporter.importError) string"pj$func(*gcimporter.importError) string `go.string."func(*gcimporter.importError) string"þBtype.func(*"".importError) string  ÕÓ‹3 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P`go.string."func(*gcimporter.importError) string"pTgo.weak.type.*func(*"".importError) string€"runtime.zerovalue €Btype.func(*"".importError) stringÐ�Btype.func(*"".importError) string€(type.*"".importError�type.stringþ(type.*"".importErrorÐÐ)p)?6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000PFgo.string."*gcimporter.importError"p:go.weak.type.**"".importError€"runtime.zerovalue�&type."".importError` (type.*"".importErrorÀð(type.*"".importErrorð"go.string."Error"�$type.func() string Btype.func(*"".importError) string°."".(*importError).ErrorÀ."".(*importError).Errorþbruntime.gcbits.0x4844c48844448c000000000000000000 HDĈDDŒþDgo.string."gcimporter.importError"PNgcimporter.importError Dgo.string."gcimporter.importError"þgo.string."pos"0(pos go.string."pos"þgo.string."err"0(err go.string."err"þ^go.string."func(gcimporter.importError) string"ph#func(gcimporter.importError) string ^go.string."func(gcimporter.importError) string"þ@type.func("".importError) string  .}þ23 € runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P^go.string."func(gcimporter.importError) string"pRgo.weak.type.*func("".importError) string€"runtime.zerovalue €@type.func("".importError) stringÐ�@type.func("".importError) string€&type."".importError�type.stringþ&type."".importError��8AÇe“(* 0type..alg."".importError0bruntime.gcbits.0x4844c48844448c000000000000000000PDgo.string."gcimporter.importError"p(type.*"".importError€"runtime.zerovalue�À&type."".importErrorÀgo.string."pos"Ð"go.importpath."".à4type.text/scanner.Position�go.string."err" "go.importpath."".°type.error`à&type."".importErrorà.go.string."importError"ð"go.importpath."".€°&type."".importError°"go.string."Error"Ð$type.func() stringà@type.func("".importError) stringð."".(*importError).Error€("".importError.ErrorþTgclocals·3280bececceccd33cb74587feedb1f9fþTgclocals·2dc77d960dd3e4b3de2361f9cbd75783þTgclocals·44568aa369055d8938d809aa5d80843bþTgclocals·9c703c5c7b9c1932c840b69f8ebce236þ<type..hashfunc.[2]interface {}4type..hash.[2]interface {}þ8type..eqfunc.[2]interface {}0type..eq.[2]interface {}þ2type..alg.[2]interface {} <type..hashfunc.[2]interface {}8type..eqfunc.[2]interface {}þbruntime.gcbits.0xcccc0000000000000000000000000000 ÌÌþ6go.string."[2]interface {}"@@[2]interface {} 6go.string."[2]interface {}"þ(type.[2]interface {}ÀÀ ,Y¤ñ 2type..alg.[2]interface {}0bruntime.gcbits.0xcccc0000000000000000000000000000P6go.string."[2]interface {}"p:go.weak.type.*[2]interface {}€"runtime.zerovalue�"type.interface {} &type.[]interface {}þVgo.typelink.[2]interface {}/[2]interface {}(type.[2]interface {}þ8go.string."*[2]interface {}"PB*[2]interface {} 8go.string."*[2]interface {}"Line truncated
*[4]string ,go.string."*[4]string"þtype.*[4]string  àik6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P,go.string."*[4]string"p0go.weak.type.**[4]string€"runtime.zerovalue�type.[4]stringþ,go.string."*[8]string"@6
*[8]string ,go.string."*[8]string"þtype.*[8]string  ­”o6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P,go.string."*[8]string"p0go.weak.type.**[8]string€"runtime.zerovalue�type.[8]stringþ8go.string."*[8]types.Object"PB*[8]types.Object 8go.string."*[8]types.Object"þVtype.*[8]golang.org/x/tools/go/types.Object  Ý;'¢6   runtime.algarray0bruntime.gcbits.0x88000000000000000000000000000000P8go.string."*[8]types.Object"phgo.weak.type.**[8]golang.org/x/tools/go/types.Object€"runtime.zerovalue�Ttype.[8]golang.org/x/tools/go/types.Objectþ0go.string."text/scanner"@: text/scanner 0go.string."text/scanner"þ6go.importpath.text/scanner.  0go.string."text/scanner"þ&go.string."runtime"00runtime &go.string."runtime"þ,go.importpath.runtime.  &go.string."runtime"þ"go.string."bufio"0,bufio "go.string."bufio"þ(go.importpath.bufio.  "go.string."bufio"þ$go.string."errors"0.errors $go.string."errors"þ*go.importpath.errors.  $go.string."errors"þNgo.string."golang.org/x/tools/go/exact"`Xgolang.org/x/tools/go/exact Ngo.string."golang.org/x/tools/go/exact"þTgo.importpath.golang.org/x/tools/go/exact.  Ngo.string."golang.org/x/tools/go/exact"þgo.string."io"0&io go.string."io"þ"go.importpath.io.  go.string."io"þ2go.string."path/filepath"@< path/filepath 2go.string."path/filepath"þ8go.importpath.path/filepath.  2go.string."path/filepath"þgo.string."os"0&os go.string."os"þ"go.importpath.os.  go.string."os"þ&go.string."strconv"00strconv &go.string."strconv"þ,go.importpath.strconv.  &go.string."strconv"þ&go.string."strings"00strings &go.string."strings"þ,go.importpath.strings.  &go.string."strings"þNgo.string."golang.org/x/tools/go/types"`Xgolang.org/x/tools/go/types Ngo.string."golang.org/x/tools/go/types"þTgo.importpath.golang.org/x/tools/go/types.  Ngo.string."golang.org/x/tools/go/types"þgo.string."fmt"0(fmt go.string."fmt"þ$go.importpath.fmt.  go.string."fmt"þ(go.string."go/build"@2go/build (go.string."go/build"þ.go.importpath.go/build.  (go.string."go/build"þ(go.string."go/token"@2go/token (go.string."go/token"þ.go.importpath.go/token.  (go.string."go/token"þ:type..hash.[1]interface {}·f4type..hash.[1]interface {}þ.runtime.nilinterhash·f(runtime.nilinterhashþ6type..eq.[1]interface {}·f0type..eq.[1]interface {}þ$runtime.efaceeq·fruntime.efaceeqþ.type..hash.[2]string·f(type..hash.[2]stringþ$runtime.strhash·fruntime.strhashþ*type..eq.[2]string·f$type..eq.[2]stringþ.type..hash.[4]string·f(type..hash.[4]stringþ*type..eq.[4]string·f$type..eq.[4]stringþ.type..hash.[8]string·f(type..hash.[8]stringþ*type..eq.[8]string·f$type..eq.[8]stringþ:type..hash.[3]interface {}·f4type..hash.[3]interface {}þ6type..eq.[3]interface {}·f0type..eq.[3]interface {}þftype..hash.[8]golang.org/x/tools/go/types.Object·f`type..hash.[8]golang.org/x/tools/go/types.Objectþ(runtime.interhash·f"runtime.interhashþbtype..eq.[8]golang.org/x/tools/go/types.Object·f\type..eq.[8]golang.org/x/tools/go/types.Objectþ$runtime.ifaceeq·fruntime.ifaceeqþ8type..hash."".importError·f2type..hash."".importErrorþFtype..hash.text/scanner.Position·f@type..hash.text/scanner.Positionþ4type..eq."".importError·f.type..eq."".importErrorþ4"".(*importError).Error·f."".(*importError).Errorþ(runtime.panicwrap·f"runtime.panicwrapþ:type..hash.[2]interface {}·f4type..hash.[2]interface {}Line truncated
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,7 @@
language: go
install:
- go get -t -v ./...
script:
- go test -v ./...
@@ -0,0 +1,15 @@
# Contributing to Golint
## Before filing an issue:
### Are you having trouble building golint?
Check you have the latest version of its dependencies. Run
```
go get -u github.com/golang/lint
```
If you still have problems, consider searching for existing issues before filing a new issue.
## Before sending a pull request:
Have you understood the purpose of golint? Make sure to carefully read `README`.
@@ -0,0 +1,27 @@
Copyright (c) 2013 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,67 @@
Golint is a linter for Go source code.
[![Build Status](https://travis-ci.org/golang/lint.svg?branch=master)](https://travis-ci.org/golang/lint)
To install, run
go get -u github.com/golang/lint/golint
Invoke golint with one or more filenames, a directory, or a package named
by its import path. Golint uses the same import path syntax as the go
command (https://golang.org/cmd/go/#hdr-Import_path_syntax) and therefore
also supports relative import paths like "./...". Additionally the "..."
wildcard can be used as suffix on relative and absolute file paths to recurse
into them.
The output of this tool is a list of suggestions in Vim quickfix format,
which is accepted by lots of different editors.
Golint differs from gofmt. Gofmt reformats Go source code, whereas
golint prints out style mistakes.
Golint differs from govet. Govet is concerned with correctness, whereas
golint is concerned with coding style. Golint is in use at Google, and it
seeks to match the accepted style of the open source Go project.
The suggestions made by golint are exactly that: suggestions.
Golint is not perfect, and has both false positives and false negatives.
Do not treat its output as a gold standard. We will not be adding pragmas
or other knobs to suppress specific warnings, so do not expect or require
code to be completely "lint-free".
In short, this tool is not, and will never be, trustworthy enough for its
suggestions to be enforced automatically, for example as part of a build process.
If you find an established style that is frequently violated, and which
you think golint could statically check, file an issue at
https://github.com/golang/lint/issues
Contributions
-------------
Contributions to this project are welcome, though please send mail before
starting work on anything major. Contributors retain their copyright, so we
need you to fill out a short form before we can accept your contribution:
https://developers.google.com/open-source/cla/individual
Vim
---
Add this to your ~/.vimrc:
set rtp+=$GOPATH/src/github.com/golang/lint/misc/vim
If you have multiple entries in your GOPATH, replace $GOPATH with the right value.
Running :Lint will run golint on the current file and populate the quickfix list.
Optionally, add this to your ~/.vimrc to automatically run golint on :w
autocmd BufWritePost,FileWritePost *.go execute 'Lint' | cwindow
Emacs
-----
Add this to your .emacs file:
(add-to-list 'load-path (concat (getenv "GOPATH") "/src/github.com/golang/lint/misc/emacs"))
(require 'golint)
If you have multiple entries in your GOPATH, replace $GOPATH with the right value.
Running M-x golint will run golint on the current file.
For more usage, see Compilation-Mode:
http://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation-Mode.html
@@ -0,0 +1,126 @@
// Copyright (c) 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.
// golint lints the Go source files named on its command line.
package main
import (
"flag"
"fmt"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/golang/lint"
)
var minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it")
func usage() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(os.Stderr, "\tgolint [flags] # runs on package in current directory\n")
fmt.Fprintf(os.Stderr, "\tgolint [flags] package\n")
fmt.Fprintf(os.Stderr, "\tgolint [flags] directory\n")
fmt.Fprintf(os.Stderr, "\tgolint [flags] files... # must be a single package\n")
fmt.Fprintf(os.Stderr, "Flags:\n")
flag.PrintDefaults()
}
func main() {
flag.Usage = usage
flag.Parse()
switch flag.NArg() {
case 0:
lintDir(".")
case 1:
arg := flag.Arg(0)
if strings.HasSuffix(arg, "/...") && isDir(arg[:len(arg)-4]) {
for _, dirname := range allPackagesInFS(arg) {
lintDir(dirname)
}
} else if isDir(arg) {
lintDir(arg)
} else if exists(arg) {
lintFiles(arg)
} else {
for _, pkgname := range importPaths([]string{arg}) {
lintPackage(pkgname)
}
}
default:
lintFiles(flag.Args()...)
}
}
func isDir(filename string) bool {
fi, err := os.Stat(filename)
return err == nil && fi.IsDir()
}
func exists(filename string) bool {
_, err := os.Stat(filename)
return err == nil
}
func lintFiles(filenames ...string) {
files := make(map[string][]byte)
for _, filename := range filenames {
src, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Fprintln(os.Stderr, err)
continue
}
files[filename] = src
}
l := new(lint.Linter)
ps, err := l.LintFiles(files)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
for _, p := range ps {
if p.Confidence >= *minConfidence {
fmt.Printf("%v: %s\n", p.Position, p.Text)
}
}
}
func lintDir(dirname string) {
pkg, err := build.ImportDir(dirname, 0)
lintImportedPackage(pkg, err)
}
func lintPackage(pkgname string) {
pkg, err := build.Import(pkgname, ".", 0)
lintImportedPackage(pkg, err)
}
func lintImportedPackage(pkg *build.Package, err error) {
if err != nil {
if _, nogo := err.(*build.NoGoError); nogo {
// Don't complain if the failure is due to no Go source files.
return
}
fmt.Fprintln(os.Stderr, err)
return
}
var files []string
files = append(files, pkg.GoFiles...)
files = append(files, pkg.TestGoFiles...)
if pkg.Dir != "." {
for i, f := range files {
files[i] = filepath.Join(pkg.Dir, f)
}
}
// TODO(dsymonds): Do foo_test too (pkg.XTestGoFiles)
lintFiles(files...)
}
@@ -0,0 +1,302 @@
package main
/*
This file holds a direct copy of the import path matching code of
https://code.google.com/p/go/source/browse/src/cmd/go/main.go. It can be
replaced when https://code.google.com/p/go/issues/detail?id=8768 is resolved.
*/
import (
"fmt"
"go/build"
"log"
"os"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
)
var buildContext = build.Default
var (
goroot = filepath.Clean(runtime.GOROOT())
gorootSrcPkg = filepath.Join(goroot, "src/pkg")
)
// importPathsNoDotExpansion returns the import paths to use for the given
// command line, but it does no ... expansion.
func importPathsNoDotExpansion(args []string) []string {
if len(args) == 0 {
return []string{"."}
}
var out []string
for _, a := range args {
// Arguments are supposed to be import paths, but
// as a courtesy to Windows developers, rewrite \ to /
// in command-line arguments. Handles .\... and so on.
if filepath.Separator == '\\' {
a = strings.Replace(a, `\`, `/`, -1)
}
// Put argument in canonical form, but preserve leading ./.
if strings.HasPrefix(a, "./") {
a = "./" + path.Clean(a)
if a == "./." {
a = "."
}
} else {
a = path.Clean(a)
}
if a == "all" || a == "std" {
out = append(out, allPackages(a)...)
continue
}
out = append(out, a)
}
return out
}
// importPaths returns the import paths to use for the given command line.
func importPaths(args []string) []string {
args = importPathsNoDotExpansion(args)
var out []string
for _, a := range args {
if strings.Contains(a, "...") {
if build.IsLocalImport(a) {
out = append(out, allPackagesInFS(a)...)
} else {
out = append(out, allPackages(a)...)
}
continue
}
out = append(out, a)
}
return out
}
// matchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
func matchPattern(pattern string) func(name string) bool {
re := regexp.QuoteMeta(pattern)
re = strings.Replace(re, `\.\.\.`, `.*`, -1)
// Special case: foo/... matches foo too.
if strings.HasSuffix(re, `/.*`) {
re = re[:len(re)-len(`/.*`)] + `(/.*)?`
}
reg := regexp.MustCompile(`^` + re + `$`)
return func(name string) bool {
return reg.MatchString(name)
}
}
// hasPathPrefix reports whether the path s begins with the
// elements in prefix.
func hasPathPrefix(s, prefix string) bool {
switch {
default:
return false
case len(s) == len(prefix):
return s == prefix
case len(s) > len(prefix):
if prefix != "" && prefix[len(prefix)-1] == '/' {
return strings.HasPrefix(s, prefix)
}
return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
}
}
// treeCanMatchPattern(pattern)(name) reports whether
// name or children of name can possibly match pattern.
// Pattern is the same limited glob accepted by matchPattern.
func treeCanMatchPattern(pattern string) func(name string) bool {
wildCard := false
if i := strings.Index(pattern, "..."); i >= 0 {
wildCard = true
pattern = pattern[:i]
}
return func(name string) bool {
return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
wildCard && strings.HasPrefix(name, pattern)
}
}
// allPackages returns all the packages that can be found
// under the $GOPATH directories and $GOROOT matching pattern.
// The pattern is either "all" (all packages), "std" (standard packages)
// or a path including "...".
func allPackages(pattern string) []string {
pkgs := matchPackages(pattern)
if len(pkgs) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
}
return pkgs
}
func matchPackages(pattern string) []string {
match := func(string) bool { return true }
treeCanMatch := func(string) bool { return true }
if pattern != "all" && pattern != "std" {
match = matchPattern(pattern)
treeCanMatch = treeCanMatchPattern(pattern)
}
have := map[string]bool{
"builtin": true, // ignore pseudo-package that exists only for documentation
}
if !buildContext.CgoEnabled {
have["runtime/cgo"] = true // ignore during walk
}
var pkgs []string
// Commands
cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() || path == cmd {
return nil
}
name := path[len(cmd):]
if !treeCanMatch(name) {
return filepath.SkipDir
}
// Commands are all in cmd/, not in subdirectories.
if strings.Contains(name, string(filepath.Separator)) {
return filepath.SkipDir
}
// We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
name = "cmd/" + name
if have[name] {
return nil
}
have[name] = true
if !match(name) {
return nil
}
_, err = buildContext.ImportDir(path, 0)
if err != nil {
if _, noGo := err.(*build.NoGoError); !noGo {
log.Print(err)
}
return nil
}
pkgs = append(pkgs, name)
return nil
})
for _, src := range buildContext.SrcDirs() {
if pattern == "std" && src != gorootSrcPkg {
continue
}
src = filepath.Clean(src) + string(filepath.Separator)
filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() || path == src {
return nil
}
// Avoid .foo, _foo, and testdata directory trees.
_, elem := filepath.Split(path)
if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
return filepath.SkipDir
}
name := filepath.ToSlash(path[len(src):])
if pattern == "std" && strings.Contains(name, ".") {
return filepath.SkipDir
}
if !treeCanMatch(name) {
return filepath.SkipDir
}
if have[name] {
return nil
}
have[name] = true
if !match(name) {
return nil
}
_, err = buildContext.ImportDir(path, 0)
if err != nil {
if _, noGo := err.(*build.NoGoError); noGo {
return nil
}
}
pkgs = append(pkgs, name)
return nil
})
}
return pkgs
}
// allPackagesInFS is like allPackages but is passed a pattern
// beginning ./ or ../, meaning it should scan the tree rooted
// at the given directory. There are ... in the pattern too.
func allPackagesInFS(pattern string) []string {
pkgs := matchPackagesInFS(pattern)
if len(pkgs) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
}
return pkgs
}
func matchPackagesInFS(pattern string) []string {
// Find directory to begin the scan.
// Could be smarter but this one optimization
// is enough for now, since ... is usually at the
// end of a path.
i := strings.Index(pattern, "...")
dir, _ := path.Split(pattern[:i])
// pattern begins with ./ or ../.
// path.Clean will discard the ./ but not the ../.
// We need to preserve the ./ for pattern matching
// and in the returned import paths.
prefix := ""
if strings.HasPrefix(pattern, "./") {
prefix = "./"
}
match := matchPattern(pattern)
var pkgs []string
filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() {
return nil
}
if path == dir {
// filepath.Walk starts at dir and recurses. For the recursive case,
// the path is the result of filepath.Join, which calls filepath.Clean.
// The initial case is not Cleaned, though, so we do this explicitly.
//
// This converts a path like "./io/" to "io". Without this step, running
// "cd $GOROOT/src/pkg; go list ./io/..." would incorrectly skip the io
// package, because prepending the prefix "./" to the unclean path would
// result in "././io", and match("././io") returns false.
path = filepath.Clean(path)
}
// Avoid .foo, _foo, and testdata directory trees, but do not avoid "." or "..".
_, elem := filepath.Split(path)
dot := strings.HasPrefix(elem, ".") && elem != "." && elem != ".."
if dot || strings.HasPrefix(elem, "_") || elem == "testdata" {
return filepath.SkipDir
}
name := prefix + filepath.ToSlash(path)
if !match(name) {
return nil
}
if _, err = build.ImportDir(path, 0); err != nil {
if _, noGo := err.(*build.NoGoError); !noGo {
log.Print(err)
}
return nil
}
pkgs = append(pkgs, name)
return nil
})
return pkgs
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,262 @@
// Copyright (c) 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.
package lint
import (
"bytes"
"flag"
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"io/ioutil"
"path"
"regexp"
"strconv"
"strings"
"testing"
"golang.org/x/tools/go/types"
)
var lintMatch = flag.String("lint.match", "", "restrict testdata matches to this pattern")
func TestAll(t *testing.T) {
l := new(Linter)
rx, err := regexp.Compile(*lintMatch)
if err != nil {
t.Fatalf("Bad -lint.match value %q: %v", *lintMatch, err)
}
baseDir := "testdata"
fis, err := ioutil.ReadDir(baseDir)
if err != nil {
t.Fatalf("ioutil.ReadDir: %v", err)
}
if len(fis) == 0 {
t.Fatalf("no files in %v", baseDir)
}
for _, fi := range fis {
if !rx.MatchString(fi.Name()) {
continue
}
//t.Logf("Testing %s", fi.Name())
src, err := ioutil.ReadFile(path.Join(baseDir, fi.Name()))
if err != nil {
t.Fatalf("Failed reading %s: %v", fi.Name(), err)
}
ins := parseInstructions(t, fi.Name(), src)
if ins == nil {
t.Errorf("Test file %v does not have instructions", fi.Name())
continue
}
ps, err := l.Lint(fi.Name(), src)
if err != nil {
t.Errorf("Linting %s: %v", fi.Name(), err)
continue
}
for _, in := range ins {
ok := false
for i, p := range ps {
if p.Position.Line != in.Line {
continue
}
if in.Match.MatchString(p.Text) {
// remove this problem from ps
copy(ps[i:], ps[i+1:])
ps = ps[:len(ps)-1]
//t.Logf("/%v/ matched at %s:%d", in.Match, fi.Name(), in.Line)
ok = true
break
}
}
if !ok {
t.Errorf("Lint failed at %s:%d; /%v/ did not match", fi.Name(), in.Line, in.Match)
}
}
for _, p := range ps {
t.Errorf("Unexpected problem at %s:%d: %v", fi.Name(), p.Position.Line, p.Text)
}
}
}
type instruction struct {
Line int // the line number this applies to
Match *regexp.Regexp // what pattern to match
}
// parseInstructions parses instructions from the comments in a Go source file.
// It returns nil if none were parsed.
func parseInstructions(t *testing.T, filename string, src []byte) []instruction {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filename, src, parser.ParseComments)
if err != nil {
t.Fatalf("Test file %v does not parse: %v", filename, err)
}
var ins []instruction
for _, cg := range f.Comments {
ln := fset.Position(cg.Pos()).Line
raw := cg.Text()
for _, line := range strings.Split(raw, "\n") {
if line == "" || strings.HasPrefix(line, "#") {
continue
}
if line == "OK" && ins == nil {
// so our return value will be non-nil
ins = make([]instruction, 0)
continue
}
if strings.Contains(line, "MATCH") {
rx, err := extractPattern(line)
if err != nil {
t.Fatalf("At %v:%d: %v", filename, ln, err)
}
matchLine := ln
if i := strings.Index(line, "MATCH:"); i >= 0 {
// This is a match for a different line.
lns := strings.TrimPrefix(line[i:], "MATCH:")
lns = lns[:strings.Index(lns, " ")]
matchLine, err = strconv.Atoi(lns)
if err != nil {
t.Fatalf("Bad match line number %q at %v:%d: %v", lns, filename, ln, err)
}
}
ins = append(ins, instruction{
Line: matchLine,
Match: rx,
})
}
}
}
return ins
}
func extractPattern(line string) (*regexp.Regexp, error) {
a, b := strings.Index(line, "/"), strings.LastIndex(line, "/")
if a == -1 || a == b {
return nil, fmt.Errorf("malformed match instruction %q", line)
}
pat := line[a+1 : b]
rx, err := regexp.Compile(pat)
if err != nil {
return nil, fmt.Errorf("bad match pattern %q: %v", pat, err)
}
return rx, nil
}
func render(fset *token.FileSet, x interface{}) string {
var buf bytes.Buffer
if err := printer.Fprint(&buf, fset, x); err != nil {
panic(err)
}
return buf.String()
}
func TestLine(t *testing.T) {
tests := []struct {
src string
offset int
want string
}{
{"single line file", 5, "single line file"},
{"single line file with newline\n", 5, "single line file with newline\n"},
{"first\nsecond\nthird\n", 2, "first\n"},
{"first\nsecond\nthird\n", 9, "second\n"},
{"first\nsecond\nthird\n", 14, "third\n"},
{"first\nsecond\nthird with no newline", 16, "third with no newline"},
{"first byte\n", 0, "first byte\n"},
}
for _, test := range tests {
got := srcLine([]byte(test.src), token.Position{Offset: test.offset})
if got != test.want {
t.Errorf("srcLine(%q, offset=%d) = %q, want %q", test.src, test.offset, got, test.want)
}
}
}
func TestLintName(t *testing.T) {
tests := []struct {
name, want string
}{
{"foo_bar", "fooBar"},
{"foo_bar_baz", "fooBarBaz"},
{"Foo_bar", "FooBar"},
{"foo_WiFi", "fooWiFi"},
{"id", "id"},
{"Id", "ID"},
{"foo_id", "fooID"},
{"fooId", "fooID"},
{"fooUid", "fooUID"},
{"idFoo", "idFoo"},
{"uidFoo", "uidFoo"},
{"midIdDle", "midIDDle"},
{"APIProxy", "APIProxy"},
{"ApiProxy", "APIProxy"},
{"apiProxy", "apiProxy"},
{"_Leading", "_Leading"},
{"___Leading", "_Leading"},
{"trailing_", "trailing"},
{"trailing___", "trailing"},
{"a_b", "aB"},
{"a__b", "aB"},
{"a___b", "aB"},
{"Rpc1150", "RPC1150"},
{"case3_1", "case3_1"},
{"case3__1", "case3_1"},
{"IEEE802_16bit", "IEEE802_16bit"},
{"IEEE802_16Bit", "IEEE802_16Bit"},
}
for _, test := range tests {
got := lintName(test.name)
if got != test.want {
t.Errorf("lintName(%q) = %q, want %q", test.name, got, test.want)
}
}
}
func TestExportedType(t *testing.T) {
tests := []struct {
typString string
exp bool
}{
{"int", true},
{"string", false}, // references the shadowed builtin "string"
{"T", true},
{"t", false},
{"*T", true},
{"*t", false},
{"map[int]complex128", true},
}
for _, test := range tests {
src := `package foo; type T int; type t int; type string struct{}`
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "foo.go", src, 0)
if err != nil {
t.Fatalf("Parsing %q: %v", src, err)
}
// use the package name as package path
pkg, err := types.Check(file.Name.Name, fset, []*ast.File{file})
if err != nil {
t.Fatalf("Type checking %q: %v", src, err)
}
// Use the first child scope of the package, which will be the file scope.
scope := pkg.Scope().Child(0)
tv, err := types.Eval(test.typString, pkg, scope)
if err != nil {
t.Errorf("types.Eval(%q): %v", test.typString, err)
continue
}
if got := exportedType(tv.Type); got != test.exp {
t.Errorf("exportedType(%v) = %t, want %t", tv.Type, got, test.exp)
}
}
}
@@ -0,0 +1,51 @@
;;; golint.el --- lint for the Go source code
;; Copyright 2013 The Go Authors. All rights reserved.
;; Use of this source code is governed by a BSD-style
;; license that can be found in the LICENSE file.
;; URL: https://github.com/golang/lint
;;; Commentary:
;; To install golint, add the following lines to your .emacs file:
;; (add-to-list 'load-path "PATH CONTAINING golint.el" t)
;; (require 'golint)
;;
;; After this, type M-x golint on Go source code.
;;
;; Usage:
;; C-x `
;; Jump directly to the line in your code which caused the first message.
;;
;; For more usage, see Compilation-Mode:
;; http://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation-Mode.html
;;; Code:
(require 'compile)
(defun go-lint-buffer-name (mode)
"*Golint*")
(defun golint-process-setup ()
"Setup compilation variables and buffer for `golint'."
(run-hooks 'golint-setup-hook))
(define-compilation-mode golint-mode "golint"
"Golint is a linter for Go source code."
(set (make-local-variable 'compilation-scroll-output) nil)
(set (make-local-variable 'compilation-disable-input) t)
(set (make-local-variable 'compilation-process-setup-function)
'golint-process-setup)
)
;;;###autoload
(defun golint ()
"Run golint on the current file and populate the fix list. Pressing C-x ` will jump directly to the line in your code which caused the first message."
(interactive)
(compilation-start (concat "golint " buffer-file-name)
'golint-mode))
(provide 'golint)
;;; golint.el ends here
@@ -0,0 +1,31 @@
" Copyright 2013 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" lint.vim: Vim command to lint Go files with golint.
"
" https://github.com/golang/lint
"
" This filetype plugin add a new commands for go buffers:
"
" :Lint
"
" Run golint for the current Go file.
"
if exists("b:did_ftplugin_go_lint")
finish
endif
if !executable("golint")
finish
endif
command! -buffer Lint call s:GoLint()
function! s:GoLint() abort
cexpr system('golint ' . shellescape(expand('%')))
endfunction
let b:did_ftplugin_go_lint = 1
" vim:ts=4:sw=4:et
+34
View File
@@ -0,0 +1,34 @@
// Test that exported names have correct comments.
// Package pkg does something.
package pkg
import "time"
type T int // MATCH /exported type T.*should.*comment.*or.*unexport/
func (T) F() {} // MATCH /exported method T\.F.*should.*comment.*or.*unexport/
// this is a nice type.
// MATCH /comment.*exported type U.*should.*form.*"U ..."/
type U string
// this is a neat function.
// MATCH /comment.*exported method U\.G.*should.*form.*"G ..."/
func (U) G() {}
// A V is a string.
type V string
// V.H has a pointer receiver
func (*V) H() {} // MATCH /exported method V\.H.*should.*comment.*or.*unexport/
var W = "foo" // MATCH /exported var W.*should.*comment.*or.*unexport/
const X = "bar" // MATCH /exported const X.*should.*comment.*or.*unexport/
var Y, Z int // MATCH /exported var Z.*own declaration/
// Location should be okay, since the other var name is an underscore.
var Location, _ = time.LoadLocation("Europe/Istanbul") // not Constantinople
+17
View File
@@ -0,0 +1,17 @@
// This file ends in _test.go, so we should not warn about doc comments.
// OK
package pkg
import "testing"
type H int
func TestSomething(t *testing.T) {
}
func TestSomething_suffix(t *testing.T) {
}
func ExampleBuffer_reader() {
}
@@ -0,0 +1,39 @@
// Test that blank imports in library packages are flagged.
// Package foo ...
package foo
// The instructions need to go before the imports below so they will not be
// mistaken for documentation.
/* MATCH /blank import/ */ import _ "encoding/json"
import (
"fmt"
/* MATCH /blank import/ */ _ "os"
/* MATCH /blank import/ */ _ "net/http"
_ "path"
)
import _ "encoding/base64" // Don't gripe about this
import (
// Don't gripe about these next two lines.
_ "compress/zlib"
_ "syscall"
/* MATCH /blank import/ */ _ "path/filepath"
)
import (
"go/ast"
_ "go/scanner" // Don't gripe about this or the following line.
_ "go/token"
)
var (
_ fmt.Stringer // for "fmt"
_ ast.Node // for "go/ast"
)
@@ -0,0 +1,25 @@
// Test that blank imports in test packages are not flagged.
// OK
// Package foo ...
package foo
// These are essentially the same imports as in the "library" package, but
// these should not trigger the warning because this is a test.
import _ "encoding/json"
import (
"fmt"
"testing"
_ "os"
_ "net/http"
_ "path"
)
var (
_ fmt.Stringer // for "fmt"
_ testing.T // for "testing"
)
@@ -0,0 +1,14 @@
// Test that blank imports in package main are not flagged.
// OK
// Binary foo ...
package main
import _ "fmt"
import (
"os"
_ "path"
)
var _ os.File // for "os"
@@ -0,0 +1,16 @@
// Test that we don't nag for comments on common methods.
// OK
// Package pkg ...
package pkg
import "net/http"
// T is ...
type T int
func (T) Error() string { return "" }
func (T) String() string { return "" }
func (T) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
func (T) Read(p []byte) (n int, err error) { return 0, nil }
func (T) Write(p []byte) (n int, err error) { return 0, nil }
@@ -0,0 +1,36 @@
// Test for docs in const blocks
// Package foo ...
package foo
const (
// Prefix for something.
// MATCH /InlineWhatever.*form/
InlineWhatever = "blah"
Whatsit = "missing_comment" // MATCH /Whatsit.*should have comment.*block/
// We should only warn once per block for missing comments,
// but always complain about malformed comments.
WhosYourDaddy = "another_missing_one"
// Something
// MATCH /WhatDoesHeDo.*form/
WhatDoesHeDo = "it's not a tumor!"
)
// These shouldn't need doc comments.
const (
Alpha = "a"
Beta = "b"
Gamma = "g"
)
// The comment on the previous const block shouldn't flow through to here.
const UndocAgain = 6 // MATCH /UndocAgain.*should have comment/
const (
SomeUndocumented = 7 // MATCH /SomeUndocumented.*should have comment.*block/
)
@@ -0,0 +1,18 @@
// Test of return+else warning; should not trigger on multi-branch if/else.
// OK
// Package pkg ...
package pkg
import "log"
func f(x int) bool {
if x == 0 {
log.Print("x is zero")
} else if x > 0 {
return true
} else {
log.Printf("non-positive x: %d", x)
}
return false
}
+23
View File
@@ -0,0 +1,23 @@
// Test of return+else warning.
// Package pkg ...
package pkg
import "log"
func f(x int) bool {
if x > 0 {
return true
} else { // MATCH /if.*return.*else.*outdent/
log.Printf("non-positive x: %d", x)
}
return false
}
func g(f func() bool) string {
if ok := f(); ok {
return "it's okay"
} else { // MATCH /if.*return.*else.*outdent.*short.*var.*declaration/
return "it's NOT okay!"
}
}
@@ -0,0 +1,43 @@
// Test for returning errors.
// Package foo ...
package foo
// Returns nothing
func f() { // ok
}
// Check for a single error return
func g() error { // ok
return nil
}
// Check for a single other return type
func h() int { // ok
return 0
}
// Check for multiple return but error at end.
func i() (int, error) { // ok
return 0, nil
}
// Check for multiple return but error at end with named variables.
func j() (x int, err error) { // ok
return 0, nil
}
// Check for error in the wrong location on 2 types
func k() (error, int) { // MATCH /error should be the last type/
return nil, 0
}
// Check for error in the wrong location for > 2 types
func l() (int, error, int) { // MATCH /error should be the last type/
return 0, nil, 0
}
// Check for error in the wrong location with named variables.
func m() (x int, err error, y int) { // MATCH /error should be the last type/
return 0, nil, 0
}
+24
View File
@@ -0,0 +1,24 @@
// Test for not using fmt.Errorf.
// Package foo ...
package foo
import (
"errors"
"fmt"
)
func f(x int) error {
if x > 10 {
return errors.New(fmt.Sprintf("something %d", x)) // MATCH /should replace.*errors\.New\(fmt\.Sprintf\(\.\.\.\)\).*fmt\.Errorf\(\.\.\.\)/
}
if x > 5 {
return errors.New(g("blah")) // ok
}
if x > 4 {
return errors.New("something else") // ok
}
return nil
}
func g(s string) string { return "prefix: " + s }
+36
View File
@@ -0,0 +1,36 @@
// Test for naming errors.
// Package foo ...
package foo
import (
"errors"
"fmt"
)
var unexp = errors.New("some unexported error") // MATCH /error var.*unexp.*errFoo/
// Exp ...
var Exp = errors.New("some exported error") // MATCH /error var.*Exp.*ErrFoo/
var (
e1 = fmt.Errorf("blah %d", 4) // MATCH /error var.*e1.*errFoo/
// E2 ...
E2 = fmt.Errorf("blah %d", 5) // MATCH /error var.*E2.*ErrFoo/
)
func f() {
var whatever = errors.New("ok") // ok
_ = whatever
}
// Check for the error strings themselves.
func g(x int) error {
if x < 1 {
return fmt.Errorf("This %d is too low", x) // MATCH /error strings.*not be capitalized/
} else if x == 0 {
return fmt.Errorf("XML time") // ok
}
return errors.New(`too much stuff.`) // MATCH /error strings.*not end with punctuation/
}
@@ -0,0 +1,8 @@
// Test that dot imports are flagged.
// Package pkg ...
package pkg
import . "fmt" // MATCH /dot import/
var _ Stringer // from "fmt"
+14
View File
@@ -0,0 +1,14 @@
// Test for use of x++ and x--.
// Package pkg ...
package pkg
func addOne(x int) int {
x += 1 // MATCH /x\+\+/
return x
}
func subOneInLoop(y int) {
for ; y > 0; y -= 1 { // MATCH /y--/
}
}
+19
View File
@@ -0,0 +1,19 @@
// Test for pointless make() calls.
// Package pkg ...
package pkg
import "net/http"
// T is a test type.
type T int
var z []T
func f() {
x := make([]T, 0) // MATCH /var x \[\]T/
y := make([]http.Request, 0) // MATCH /var y \[\]http\.Request/
z = make([]T, 0) // ok, because we don't know where z is declared
_, _ = x, y
}
+87
View File
@@ -0,0 +1,87 @@
// Test for name linting.
// Package pkg_with_underscores ...
package pkg_with_underscores // MATCH /underscore.*package name/
import (
"io"
"net"
net_http "net/http" // renamed deliberately
"net/url"
)
var var_name int // MATCH /underscore.*var.*var_name/
type t_wow struct { // MATCH /underscore.*type.*t_wow/
x_damn int // MATCH /underscore.*field.*x_damn/
Url *url.URL // MATCH /struct field.*Url.*URL/
}
const fooId = "blah" // MATCH /fooId.*fooID/
func f_it() { // MATCH /underscore.*func.*f_it/
more_underscore := 4 // MATCH /underscore.*var.*more_underscore/
_ = more_underscore
var err error
if isEof := (err == io.EOF); isEof { // MATCH /var.*isEof.*isEOF/
more_underscore = 7 // should be okay
}
x := net_http.Request{} // should be okay
_ = x
var ips []net.IP
for _, theIp := range ips { // MATCH /range var.*theIp.*theIP/
_ = theIp
}
switch myJson := g(); { // MATCH /var.*myJson.*myJSON/
default:
_ = myJson
}
var y net_http.ResponseWriter // an interface
switch tApi := y.(type) { // MATCH /var.*tApi.*tAPI/
default:
_ = tApi
}
var c chan int
select {
case qId := <-c: // MATCH /var.*qId.*qID/
_ = qId
}
}
// Common styles in other languages that don't belong in Go.
const (
CPP_CONST = 1 // MATCH /ALL_CAPS.*CamelCase/
kLeadingKay = 2 // MATCH /k.*leadingKay/
HTML = 3 // okay; no underscore
X509B = 4 // ditto
)
func f(bad_name int) {} // MATCH /underscore.*func parameter.*bad_name/
func g() (no_way int) { return 0 } // MATCH /underscore.*func result.*no_way/
func (t *t_wow) f(more_under string) {} // MATCH /underscore.*method parameter.*more_under/
func (t *t_wow) g() (still_more string) { return "" } // MATCH /underscore.*method result.*still_more/
type i interface {
CheckHtml() string // okay; interface method names are often constrained by the concrete types' method names
F(foo_bar int) // MATCH /foo_bar.*fooBar/
}
// All okay; underscore between digits
const case1_1 = 1
type case2_1 struct {
case2_2 int
}
func case3_1(case3_2 int) (case3_3 string) {
case3_4 := 4
_ = case3_4
return ""
}
@@ -0,0 +1,3 @@
// Test of missing package comment.
package foo // MATCH /should.*package comment.*unless/
@@ -0,0 +1,5 @@
// Test of package comment in an incorrect form.
// Some random package doc that isn't in the right form.
// MATCH /package comment should.*form.*"Package testdata .*"/
package testdata
@@ -0,0 +1,7 @@
// Test of block package comment.
// OK
/*
Package foo is pretty sweet.
*/
package foo
@@ -0,0 +1,7 @@
// Test of block package comment with leading space.
/*
Package foo is pretty sweet.
MATCH /package comment.*leading space/
*/
package foo
@@ -0,0 +1,9 @@
// Test of detached package comment.
/*
Package foo is pretty sweet.
*/
package foo
// MATCH:6 /package comment.*detached/
@@ -0,0 +1,5 @@
// Test of package comment for package main.
// OK
// This binary does something awesome.
package main
+37
View File
@@ -0,0 +1,37 @@
// Test for range construction.
// Package foo ...
package foo
func f() {
var m map[string]int
// with :=
for x, _ := range m { // MATCH /should omit 2nd value.*range.*equivalent.*for x := range/
_ = x
}
// with =
var y string
_ = y
for y, _ = range m { // MATCH /should omit 2nd value.*range.*equivalent.*for y = range/
}
// all OK:
for x := range m {
_ = x
}
for x, y := range m {
_, _ = x, y
}
for _, y := range m {
_ = y
}
var x int
_ = x
for y = range m {
}
for y, x = range m {
}
for _, x = range m {
}
}
@@ -0,0 +1,41 @@
// Test for bad receiver names.
// Package foo ...
package foo
type foo struct{}
func (this foo) f1() { // MATCH /should be a reflection of its identity/
}
func (self foo) f2() { // MATCH /should be a reflection of its identity/
}
func (f foo) f3() {
}
func (foo) f4() {
}
type bar struct{}
func (b bar) f1() {
}
func (b bar) f2() {
}
func (a bar) f3() { // MATCH /receiver name a should be consistent with previous receiver name b for bar/
}
func (a *bar) f4() { // MATCH /receiver name a should be consistent with previous receiver name b for bar/
}
func (b *bar) f5() {
}
func (bar) f6() {
}
func (_ *bar) f7() { // MATCH /receiver name should not be an underscore/
}
+20
View File
@@ -0,0 +1,20 @@
// Test that we don't ask for comments on sort.Interface methods.
// Package pkg ...
package pkg
// T is ...
type T []int
// Len by itself should get documented.
func (t T) Len() int { return len(t) } // MATCH /exported method T\.Len.*should.*comment/
// U is ...
type U []int
func (u U) Len() int { return len(u) }
func (u U) Less(i, j int) bool { return u[i] < u[j] }
func (u U) Swap(i, j int) { u[i], u[j] = u[j], u[i] }
func (u U) Other() {} // MATCH /exported method U\.Other.*should.*comment/
+25
View File
@@ -0,0 +1,25 @@
// Test of stuttery names.
// Package donut ...
package donut
// DonutMaker makes donuts.
type DonutMaker struct{} // MATCH /donut\.DonutMaker.*stutter/
// DonutRank computes the ranking of a donut.
func DonutRank(d Donut) int { // MATCH /donut\.DonutRank.*stutter/
return 0
}
// Donut is a delicious treat.
type Donut struct{} // ok because it is the whole name
// Donuts are great, aren't they?
type Donuts []Donut // ok because it didn't start a new word
type donutGlaze int // ok because it is unexported
// DonutMass reports the mass of a donut.
func (d *Donut) DonutMass() (grams int) { // okay because it is a method
return 38
}
+13
View File
@@ -0,0 +1,13 @@
// Test of time suffixes.
// Package foo ...
package foo
import (
"flag"
"time"
)
var rpcTimeoutMsec = flag.Duration("rpc_timeout", 100*time.Millisecond, "some flag") // MATCH /Msec.*\*time.Duration/
var timeoutSecs = 5 * time.Second // MATCH /Secs.*time.Duration/
@@ -0,0 +1,46 @@
// Test for unexported return types.
// Package foo ...
package foo
import ()
type hidden struct{}
// Exported returns a hidden type, which is annoying.
func Exported() hidden { // MATCH /Exported.*unexported.*hidden/
return hidden{}
}
// ExpErr returns a builtin type.
func ExpErr() error { // ok
}
func (hidden) ExpOnHidden() hidden { // ok
}
// T is another test type.
type T struct{}
// MethodOnT returns a hidden type, which is annoying.
func (T) MethodOnT() hidden { // MATCH /method MethodOnT.*unexported.*hidden/
return hidden{}
}
// ExpT returns a T.
func ExpT() T { // ok
return T{}
}
func unexp() hidden { // ok
return hidden{}
}
// This is slightly sneaky: we shadow the builtin "int" type.
type int struct{}
// ExportedIntReturner returns an unexported type from this package.
func ExportedIntReturner() int { // MATCH /ExportedIntReturner.*unexported.*int/
return int{}
}
+70
View File
@@ -0,0 +1,70 @@
// Test for redundant type declaration.
// Package foo ...
package foo
import "fmt"
import "net/http"
// Q is a test type.
type Q bool
var myInt int = 7 // MATCH /should.*int.*myInt.*inferred/
var mux *http.ServeMux = http.NewServeMux() // MATCH /should.*\*http\.ServeMux.*inferred/
var myZeroInt int = 0 // MATCH /should.*= 0.*myZeroInt.*zero value/
var myZeroFlt float32 = 0. // MATCH /should.*= 0\..*myZeroFlt.*zero value/
var myZeroF64 float64 = 0.0 // MATCH /should.*= 0\..*myZeroF64.*zero value/
var myZeroImg complex64 = 0i // MATCH /should.*= 0i.*myZeroImg.*zero value/
var myZeroStr string = "" // MATCH /should.*= "".*myZeroStr.*zero value/
var myZeroRaw string = `` // MATCH /should.*= ``.*myZeroRaw.*zero value/
var myZeroPtr *Q = nil // MATCH /should.*= nil.*myZeroPtr.*zero value/
var myZeroRune rune = '\x00' // MATCH /should.*= '\\x00'.*myZeroRune.*zero value/
var myZeroRune2 rune = '\000' // MATCH /should.*= '\\000'.*myZeroRune2.*zero value/
// No warning because there's no type on the LHS
var x = 0
// This shouldn't get a warning because there's no initial values.
var str fmt.Stringer
// No warning because this is a const.
const k uint64 = 7
const num = 123
// No warning because the var's RHS is known to be an untyped const.
var flags uint32 = num
// No warnings because the RHS is an ideal int, and the LHS is a different int type.
var userID int64 = 1235
var negID int64 = -1
var parenID int64 = (17)
var crazyID int64 = -(-(-(-9)))
// Same, but for strings and floats.
type stringT string
type floatT float64
var stringV stringT = "abc"
var floatV floatT = 123.45
// No warning because the LHS names an interface type.
var data interface{} = googleIPs
var googleIPs []int
// No warning because it's a common idiom for interface satisfaction.
var _ Server = (*serverImpl)(nil)
// Server is a test type.
type Server interface{}
type serverImpl struct{}
// LHS is a different type than the RHS.
var myStringer fmt.Stringer = q(0)
var y string = q(1).String() // MATCH /should.*string/
type q int
func (q) String() string { return "I'm a q" }
@@ -0,0 +1,10 @@
# Treat all files in this repo as binary, with no git magic updating
# line endings. Windows users contributing to Go will need to use a
# modern version of git and editors capable of LF line endings.
#
# We'll prevent accidental CRLF line endings from entering the repo
# via the git-review gofmt checks.
#
# See golang.org/issue/9281
* -text
@@ -0,0 +1,2 @@
# Add no patterns to .gitignore except for files generated by the build.
last-change
+3
View File
@@ -0,0 +1,3 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.
@@ -0,0 +1,3 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.
+27
View File
@@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+22
View File
@@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.
+10
View File
@@ -0,0 +1,10 @@
This subrepository holds the source for various packages and tools that support
the Go programming language.
Some of the tools, godoc and vet for example, are included in binary Go distributions.
Others, including the Go oracle and the test coverage tool, can be fetched with "go get".
Packages include a type-checker for Go and an implementation of the
Static Single Assignment form (SSA) representation for Go programs.
To submit changes to this repository, see http://golang.org/doc/contribute.html.
@@ -0,0 +1,131 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package parse provides support for parsing benchmark results as
// generated by 'go test -bench'.
package parse // import "golang.org/x/tools/benchmark/parse"
import (
"bufio"
"bytes"
"fmt"
"io"
"strconv"
"strings"
)
// Flags used by Benchmark.Measured to indicate
// which measurements a Benchmark contains.
const (
NsPerOp = 1 << iota
MBPerS
AllocedBytesPerOp
AllocsPerOp
)
// Benchmark is one run of a single benchmark.
type Benchmark struct {
Name string // benchmark name
N int // number of iterations
NsPerOp float64 // nanoseconds per iteration
AllocedBytesPerOp uint64 // bytes allocated per iteration
AllocsPerOp uint64 // allocs per iteration
MBPerS float64 // MB processed per second
Measured int // which measurements were recorded
Ord int // ordinal position within a benchmark run
}
// ParseLine extracts a Benchmark from a single line of testing.B
// output.
func ParseLine(line string) (*Benchmark, error) {
fields := strings.Fields(line)
// Two required, positional fields: Name and iterations.
if len(fields) < 2 {
return nil, fmt.Errorf("two fields required, have %d", len(fields))
}
if !strings.HasPrefix(fields[0], "Benchmark") {
return nil, fmt.Errorf(`first field does not start with "Benchmark"`)
}
n, err := strconv.Atoi(fields[1])
if err != nil {
return nil, err
}
b := &Benchmark{Name: fields[0], N: n}
// Parse any remaining pairs of fields; we've parsed one pair already.
for i := 1; i < len(fields)/2; i++ {
b.parseMeasurement(fields[i*2], fields[i*2+1])
}
return b, nil
}
func (b *Benchmark) parseMeasurement(quant string, unit string) {
switch unit {
case "ns/op":
if f, err := strconv.ParseFloat(quant, 64); err == nil {
b.NsPerOp = f
b.Measured |= NsPerOp
}
case "MB/s":
if f, err := strconv.ParseFloat(quant, 64); err == nil {
b.MBPerS = f
b.Measured |= MBPerS
}
case "B/op":
if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
b.AllocedBytesPerOp = i
b.Measured |= AllocedBytesPerOp
}
case "allocs/op":
if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
b.AllocsPerOp = i
b.Measured |= AllocsPerOp
}
}
}
func (b *Benchmark) String() string {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "%s %d", b.Name, b.N)
if (b.Measured & NsPerOp) != 0 {
fmt.Fprintf(buf, " %.2f ns/op", b.NsPerOp)
}
if (b.Measured & MBPerS) != 0 {
fmt.Fprintf(buf, " %.2f MB/s", b.MBPerS)
}
if (b.Measured & AllocedBytesPerOp) != 0 {
fmt.Fprintf(buf, " %d B/op", b.AllocedBytesPerOp)
}
if (b.Measured & AllocsPerOp) != 0 {
fmt.Fprintf(buf, " %d allocs/op", b.AllocsPerOp)
}
return buf.String()
}
// Set is a collection of benchmarks from one
// testing.B run, keyed by name to facilitate comparison.
type Set map[string][]*Benchmark
// ParseSet extracts a Set from testing.B output.
// ParseSet preserves the order of benchmarks that have identical
// names.
func ParseSet(r io.Reader) (Set, error) {
bb := make(Set)
scan := bufio.NewScanner(r)
ord := 0
for scan.Scan() {
if b, err := ParseLine(scan.Text()); err == nil {
b.Ord = ord
ord++
bb[b.Name] = append(bb[b.Name], b)
}
}
if err := scan.Err(); err != nil {
return nil, err
}
return bb, nil
}
@@ -0,0 +1,154 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package parse
import (
"reflect"
"strings"
"testing"
)
func TestParseLine(t *testing.T) {
cases := []struct {
line string
want *Benchmark
err bool // expect an error
}{
{
line: "BenchmarkEncrypt 100000000 19.6 ns/op",
want: &Benchmark{
Name: "BenchmarkEncrypt",
N: 100000000, NsPerOp: 19.6,
Measured: NsPerOp,
},
},
{
line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77 MB/s",
want: &Benchmark{
Name: "BenchmarkEncrypt",
N: 100000000, NsPerOp: 19.6, MBPerS: 817.77,
Measured: NsPerOp | MBPerS,
},
},
{
line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77",
want: &Benchmark{
Name: "BenchmarkEncrypt",
N: 100000000, NsPerOp: 19.6,
Measured: NsPerOp,
},
},
{
line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77 MB/s 5 allocs/op",
want: &Benchmark{
Name: "BenchmarkEncrypt",
N: 100000000, NsPerOp: 19.6, MBPerS: 817.77, AllocsPerOp: 5,
Measured: NsPerOp | MBPerS | AllocsPerOp,
},
},
{
line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77 MB/s 3 B/op 5 allocs/op",
want: &Benchmark{
Name: "BenchmarkEncrypt",
N: 100000000, NsPerOp: 19.6, MBPerS: 817.77, AllocedBytesPerOp: 3, AllocsPerOp: 5,
Measured: NsPerOp | MBPerS | AllocedBytesPerOp | AllocsPerOp,
},
},
// error handling cases
{
line: "BenchPress 100 19.6 ns/op", // non-benchmark
err: true,
},
{
line: "BenchmarkEncrypt lots 19.6 ns/op", // non-int iterations
err: true,
},
{
line: "BenchmarkBridge 100000000 19.6 smoots", // unknown unit
want: &Benchmark{
Name: "BenchmarkBridge",
N: 100000000,
},
},
{
line: "PASS",
err: true,
},
}
for _, tt := range cases {
have, err := ParseLine(tt.line)
if tt.err && err == nil {
t.Errorf("parsing line %q should have failed", tt.line)
continue
}
if !reflect.DeepEqual(have, tt.want) {
t.Errorf("parsed line %q incorrectly, want %v have %v", tt.line, tt.want, have)
}
}
}
func TestParseSet(t *testing.T) {
// Test two things:
// 1. The noise that can accompany testing.B output gets ignored.
// 2. Benchmarks with the same name have their order preserved.
in := `
? crypto [no test files]
PASS
pem_decrypt_test.go:17: test 4. %!s(x509.PEMCipher=5)
... [output truncated]
BenchmarkEncrypt 100000000 19.6 ns/op
BenchmarkEncrypt 5000000 517 ns/op
=== RUN TestChunk
--- PASS: TestChunk (0.00 seconds)
--- SKIP: TestLinuxSendfile (0.00 seconds)
fs_test.go:716: skipping; linux-only test
BenchmarkReadRequestApachebench 1000000 2960 ns/op 27.70 MB/s 839 B/op 9 allocs/op
BenchmarkClientServerParallel64 50000 59192 ns/op 7028 B/op 60 allocs/op
ok net/http 95.783s
`
want := Set{
"BenchmarkReadRequestApachebench": []*Benchmark{
{
Name: "BenchmarkReadRequestApachebench",
N: 1000000, NsPerOp: 2960, MBPerS: 27.70, AllocedBytesPerOp: 839, AllocsPerOp: 9,
Measured: NsPerOp | MBPerS | AllocedBytesPerOp | AllocsPerOp,
Ord: 2,
},
},
"BenchmarkClientServerParallel64": []*Benchmark{
{
Name: "BenchmarkClientServerParallel64",
N: 50000, NsPerOp: 59192, AllocedBytesPerOp: 7028, AllocsPerOp: 60,
Measured: NsPerOp | AllocedBytesPerOp | AllocsPerOp,
Ord: 3,
},
},
"BenchmarkEncrypt": []*Benchmark{
{
Name: "BenchmarkEncrypt",
N: 100000000, NsPerOp: 19.6,
Measured: NsPerOp,
Ord: 0,
},
{
Name: "BenchmarkEncrypt",
N: 5000000, NsPerOp: 517,
Measured: NsPerOp,
Ord: 1,
},
},
}
have, err := ParseSet(strings.NewReader(in))
if err != nil {
t.Fatalf("unexpected err during ParseSet: %v", err)
}
if !reflect.DeepEqual(want, have) {
t.Errorf("parsed bench set incorrectly, want %v have %v", want, have)
}
}
@@ -0,0 +1,57 @@
// Copyright 2009 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.
// Adapted from encoding/xml/read_test.go.
// Package atom defines XML data structures for an Atom feed.
package atom // import "golang.org/x/tools/blog/atom"
import (
"encoding/xml"
"time"
)
type Feed struct {
XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
Title string `xml:"title"`
ID string `xml:"id"`
Link []Link `xml:"link"`
Updated TimeStr `xml:"updated"`
Author *Person `xml:"author"`
Entry []*Entry `xml:"entry"`
}
type Entry struct {
Title string `xml:"title"`
ID string `xml:"id"`
Link []Link `xml:"link"`
Published TimeStr `xml:"published"`
Updated TimeStr `xml:"updated"`
Author *Person `xml:"author"`
Summary *Text `xml:"summary"`
Content *Text `xml:"content"`
}
type Link struct {
Rel string `xml:"rel,attr"`
Href string `xml:"href,attr"`
}
type Person struct {
Name string `xml:"name"`
URI string `xml:"uri,omitempty"`
Email string `xml:"email,omitempty"`
InnerXML string `xml:",innerxml"`
}
type Text struct {
Type string `xml:"type,attr"`
Body string `xml:",chardata"`
}
type TimeStr string
func Time(t time.Time) TimeStr {
return TimeStr(t.Format("2006-01-02T15:04:05-07:00"))
}
+424
View File
@@ -0,0 +1,424 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package blog implements a web server for articles written in present format.
package blog // import "golang.org/x/tools/blog"
import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"html/template"
"log"
"net/http"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
"golang.org/x/tools/blog/atom"
"golang.org/x/tools/present"
)
var validJSONPFunc = regexp.MustCompile(`(?i)^[a-z_][a-z0-9_.]*$`)
// Config specifies Server configuration values.
type Config struct {
ContentPath string // Relative or absolute location of article files and related content.
TemplatePath string // Relative or absolute location of template files.
BaseURL string // Absolute base URL (for permalinks; no trailing slash).
BasePath string // Base URL path relative to server root (no trailing slash).
GodocURL string // The base URL of godoc (for menu bar; no trailing slash).
Hostname string // Server host name, used for rendering ATOM feeds.
HomeArticles int // Articles to display on the home page.
FeedArticles int // Articles to include in Atom and JSON feeds.
FeedTitle string // The title of the Atom XML feed
PlayEnabled bool
}
// Doc represents an article adorned with presentation data.
type Doc struct {
*present.Doc
Permalink string // Canonical URL for this document.
Path string // Path relative to server root (including base).
HTML template.HTML // rendered article
Related []*Doc
Newer, Older *Doc
}
// Server implements an http.Handler that serves blog articles.
type Server struct {
cfg Config
docs []*Doc
tags []string
docPaths map[string]*Doc // key is path without BasePath.
docTags map[string][]*Doc
template struct {
home, index, article, doc *template.Template
}
atomFeed []byte // pre-rendered Atom feed
jsonFeed []byte // pre-rendered JSON feed
content http.Handler
}
// NewServer constructs a new Server using the specified config.
func NewServer(cfg Config) (*Server, error) {
present.PlayEnabled = cfg.PlayEnabled
root := filepath.Join(cfg.TemplatePath, "root.tmpl")
parse := func(name string) (*template.Template, error) {
t := template.New("").Funcs(funcMap)
return t.ParseFiles(root, filepath.Join(cfg.TemplatePath, name))
}
s := &Server{cfg: cfg}
// Parse templates.
var err error
s.template.home, err = parse("home.tmpl")
if err != nil {
return nil, err
}
s.template.index, err = parse("index.tmpl")
if err != nil {
return nil, err
}
s.template.article, err = parse("article.tmpl")
if err != nil {
return nil, err
}
p := present.Template().Funcs(funcMap)
s.template.doc, err = p.ParseFiles(filepath.Join(cfg.TemplatePath, "doc.tmpl"))
if err != nil {
return nil, err
}
// Load content.
err = s.loadDocs(filepath.Clean(cfg.ContentPath))
if err != nil {
return nil, err
}
err = s.renderAtomFeed()
if err != nil {
return nil, err
}
err = s.renderJSONFeed()
if err != nil {
return nil, err
}
// Set up content file server.
s.content = http.StripPrefix(s.cfg.BasePath, http.FileServer(http.Dir(cfg.ContentPath)))
return s, nil
}
var funcMap = template.FuncMap{
"sectioned": sectioned,
"authors": authors,
}
// sectioned returns true if the provided Doc contains more than one section.
// This is used to control whether to display the table of contents and headings.
func sectioned(d *present.Doc) bool {
return len(d.Sections) > 1
}
// authors returns a comma-separated list of author names.
func authors(authors []present.Author) string {
var b bytes.Buffer
last := len(authors) - 1
for i, a := range authors {
if i > 0 {
if i == last {
b.WriteString(" and ")
} else {
b.WriteString(", ")
}
}
b.WriteString(authorName(a))
}
return b.String()
}
// authorName returns the first line of the Author text: the author's name.
func authorName(a present.Author) string {
el := a.TextElem()
if len(el) == 0 {
return ""
}
text, ok := el[0].(present.Text)
if !ok || len(text.Lines) == 0 {
return ""
}
return text.Lines[0]
}
// loadDocs reads all content from the provided file system root, renders all
// the articles it finds, adds them to the Server's docs field, computes the
// denormalized docPaths, docTags, and tags fields, and populates the various
// helper fields (Next, Previous, Related) for each Doc.
func (s *Server) loadDocs(root string) error {
// Read content into docs field.
const ext = ".article"
fn := func(p string, info os.FileInfo, err error) error {
if filepath.Ext(p) != ext {
return nil
}
f, err := os.Open(p)
if err != nil {
return err
}
defer f.Close()
d, err := present.Parse(f, p, 0)
if err != nil {
return err
}
html := new(bytes.Buffer)
err = d.Render(html, s.template.doc)
if err != nil {
return err
}
p = p[len(root) : len(p)-len(ext)] // trim root and extension
p = filepath.ToSlash(p)
s.docs = append(s.docs, &Doc{
Doc: d,
Path: s.cfg.BasePath + p,
Permalink: s.cfg.BaseURL + p,
HTML: template.HTML(html.String()),
})
return nil
}
err := filepath.Walk(root, fn)
if err != nil {
return err
}
sort.Sort(docsByTime(s.docs))
// Pull out doc paths and tags and put in reverse-associating maps.
s.docPaths = make(map[string]*Doc)
s.docTags = make(map[string][]*Doc)
for _, d := range s.docs {
s.docPaths[strings.TrimPrefix(d.Path, s.cfg.BasePath)] = d
for _, t := range d.Tags {
s.docTags[t] = append(s.docTags[t], d)
}
}
// Pull out unique sorted list of tags.
for t := range s.docTags {
s.tags = append(s.tags, t)
}
sort.Strings(s.tags)
// Set up presentation-related fields, Newer, Older, and Related.
for _, doc := range s.docs {
// Newer, Older: docs adjacent to doc
for i := range s.docs {
if s.docs[i] != doc {
continue
}
if i > 0 {
doc.Newer = s.docs[i-1]
}
if i+1 < len(s.docs) {
doc.Older = s.docs[i+1]
}
break
}
// Related: all docs that share tags with doc.
related := make(map[*Doc]bool)
for _, t := range doc.Tags {
for _, d := range s.docTags[t] {
if d != doc {
related[d] = true
}
}
}
for d := range related {
doc.Related = append(doc.Related, d)
}
sort.Sort(docsByTime(doc.Related))
}
return nil
}
// renderAtomFeed generates an XML Atom feed and stores it in the Server's
// atomFeed field.
func (s *Server) renderAtomFeed() error {
var updated time.Time
if len(s.docs) > 0 {
updated = s.docs[0].Time
}
feed := atom.Feed{
Title: s.cfg.FeedTitle,
ID: "tag:" + s.cfg.Hostname + ",2013:" + s.cfg.Hostname,
Updated: atom.Time(updated),
Link: []atom.Link{{
Rel: "self",
Href: s.cfg.BaseURL + "/feed.atom",
}},
}
for i, doc := range s.docs {
if i >= s.cfg.FeedArticles {
break
}
e := &atom.Entry{
Title: doc.Title,
ID: feed.ID + doc.Path,
Link: []atom.Link{{
Rel: "alternate",
Href: doc.Permalink,
}},
Published: atom.Time(doc.Time),
Updated: atom.Time(doc.Time),
Summary: &atom.Text{
Type: "html",
Body: summary(doc),
},
Content: &atom.Text{
Type: "html",
Body: string(doc.HTML),
},
Author: &atom.Person{
Name: authors(doc.Authors),
},
}
feed.Entry = append(feed.Entry, e)
}
data, err := xml.Marshal(&feed)
if err != nil {
return err
}
s.atomFeed = data
return nil
}
type jsonItem struct {
Title string
Link string
Time time.Time
Summary string
Content string
Author string
}
// renderJSONFeed generates a JSON feed and stores it in the Server's jsonFeed
// field.
func (s *Server) renderJSONFeed() error {
var feed []jsonItem
for i, doc := range s.docs {
if i >= s.cfg.FeedArticles {
break
}
item := jsonItem{
Title: doc.Title,
Link: doc.Permalink,
Time: doc.Time,
Summary: summary(doc),
Content: string(doc.HTML),
Author: authors(doc.Authors),
}
feed = append(feed, item)
}
data, err := json.Marshal(feed)
if err != nil {
return err
}
s.jsonFeed = data
return nil
}
// summary returns the first paragraph of text from the provided Doc.
func summary(d *Doc) string {
if len(d.Sections) == 0 {
return ""
}
for _, elem := range d.Sections[0].Elem {
text, ok := elem.(present.Text)
if !ok || text.Pre {
// skip everything but non-text elements
continue
}
var buf bytes.Buffer
for _, s := range text.Lines {
buf.WriteString(string(present.Style(s)))
buf.WriteByte('\n')
}
return buf.String()
}
return ""
}
// rootData encapsulates data destined for the root template.
type rootData struct {
Doc *Doc
BasePath string
GodocURL string
Data interface{}
}
// ServeHTTP serves the front, index, and article pages
// as well as the ATOM and JSON feeds.
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var (
d = rootData{BasePath: s.cfg.BasePath, GodocURL: s.cfg.GodocURL}
t *template.Template
)
switch p := strings.TrimPrefix(r.URL.Path, s.cfg.BasePath); p {
case "/":
d.Data = s.docs
if len(s.docs) > s.cfg.HomeArticles {
d.Data = s.docs[:s.cfg.HomeArticles]
}
t = s.template.home
case "/index":
d.Data = s.docs
t = s.template.index
case "/feed.atom", "/feeds/posts/default":
w.Header().Set("Content-type", "application/atom+xml; charset=utf-8")
w.Write(s.atomFeed)
return
case "/.json":
if p := r.FormValue("jsonp"); validJSONPFunc.MatchString(p) {
w.Header().Set("Content-type", "application/javascript; charset=utf-8")
fmt.Fprintf(w, "%v(%s)", p, s.jsonFeed)
return
}
w.Header().Set("Content-type", "application/json; charset=utf-8")
w.Write(s.jsonFeed)
return
default:
doc, ok := s.docPaths[p]
if !ok {
// Not a doc; try to just serve static content.
s.content.ServeHTTP(w, r)
return
}
d.Doc = doc
t = s.template.article
}
err := t.ExecuteTemplate(w, "root", d)
if err != nil {
log.Println(err)
}
}
// docsByTime implements sort.Interface, sorting Docs by their Time field.
type docsByTime []*Doc
func (s docsByTime) Len() int { return len(s) }
func (s docsByTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s docsByTime) Less(i, j int) bool { return s[i].Time.After(s[j].Time) }
@@ -0,0 +1,184 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"flag"
"fmt"
"os"
"sort"
"strconv"
"text/tabwriter"
"golang.org/x/tools/benchmark/parse"
)
var (
changedOnly = flag.Bool("changed", false, "show only benchmarks that have changed")
magSort = flag.Bool("mag", false, "sort benchmarks by magnitude of change")
best = flag.Bool("best", false, "compare best times from old and new")
)
const usageFooter = `
Each input file should be from:
go test -run=NONE -bench=. > [old,new].txt
Benchcmp compares old and new for each benchmark.
If -test.benchmem=true is added to the "go test" command
benchcmp will also compare memory allocations.
`
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: %s old.txt new.txt\n\n", os.Args[0])
flag.PrintDefaults()
fmt.Fprint(os.Stderr, usageFooter)
os.Exit(2)
}
flag.Parse()
if flag.NArg() != 2 {
flag.Usage()
}
before := parseFile(flag.Arg(0))
after := parseFile(flag.Arg(1))
cmps, warnings := Correlate(before, after)
for _, warn := range warnings {
fmt.Fprintln(os.Stderr, warn)
}
if len(cmps) == 0 {
fatal("benchcmp: no repeated benchmarks")
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 0, 0, 5, ' ', 0)
defer w.Flush()
var header bool // Has the header has been displayed yet for a given block?
if *magSort {
sort.Sort(ByDeltaNsPerOp(cmps))
} else {
sort.Sort(ByParseOrder(cmps))
}
for _, cmp := range cmps {
if !cmp.Measured(parse.NsPerOp) {
continue
}
if delta := cmp.DeltaNsPerOp(); !*changedOnly || delta.Changed() {
if !header {
fmt.Fprint(w, "benchmark\told ns/op\tnew ns/op\tdelta\n")
header = true
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", cmp.Name(), formatNs(cmp.Before.NsPerOp), formatNs(cmp.After.NsPerOp), delta.Percent())
}
}
header = false
if *magSort {
sort.Sort(ByDeltaMBPerS(cmps))
}
for _, cmp := range cmps {
if !cmp.Measured(parse.MBPerS) {
continue
}
if delta := cmp.DeltaMBPerS(); !*changedOnly || delta.Changed() {
if !header {
fmt.Fprint(w, "\nbenchmark\told MB/s\tnew MB/s\tspeedup\n")
header = true
}
fmt.Fprintf(w, "%s\t%.2f\t%.2f\t%s\n", cmp.Name(), cmp.Before.MBPerS, cmp.After.MBPerS, delta.Multiple())
}
}
header = false
if *magSort {
sort.Sort(ByDeltaAllocsPerOp(cmps))
}
for _, cmp := range cmps {
if !cmp.Measured(parse.AllocsPerOp) {
continue
}
if delta := cmp.DeltaAllocsPerOp(); !*changedOnly || delta.Changed() {
if !header {
fmt.Fprint(w, "\nbenchmark\told allocs\tnew allocs\tdelta\n")
header = true
}
fmt.Fprintf(w, "%s\t%d\t%d\t%s\n", cmp.Name(), cmp.Before.AllocsPerOp, cmp.After.AllocsPerOp, delta.Percent())
}
}
header = false
if *magSort {
sort.Sort(ByDeltaAllocedBytesPerOp(cmps))
}
for _, cmp := range cmps {
if !cmp.Measured(parse.AllocedBytesPerOp) {
continue
}
if delta := cmp.DeltaAllocedBytesPerOp(); !*changedOnly || delta.Changed() {
if !header {
fmt.Fprint(w, "\nbenchmark\told bytes\tnew bytes\tdelta\n")
header = true
}
fmt.Fprintf(w, "%s\t%d\t%d\t%s\n", cmp.Name(), cmp.Before.AllocedBytesPerOp, cmp.After.AllocedBytesPerOp, cmp.DeltaAllocedBytesPerOp().Percent())
}
}
}
func fatal(msg interface{}) {
fmt.Fprintln(os.Stderr, msg)
os.Exit(1)
}
func parseFile(path string) parse.Set {
f, err := os.Open(path)
if err != nil {
fatal(err)
}
defer f.Close()
bb, err := parse.ParseSet(f)
if err != nil {
fatal(err)
}
if *best {
selectBest(bb)
}
return bb
}
func selectBest(bs parse.Set) {
for name, bb := range bs {
if len(bb) < 2 {
continue
}
ord := bb[0].Ord
best := bb[0]
for _, b := range bb {
if b.NsPerOp < best.NsPerOp {
b.Ord = ord
best = b
}
}
bs[name] = []*parse.Benchmark{best}
}
}
// formatNs formats ns measurements to expose a useful amount of
// precision. It mirrors the ns precision logic of testing.B.
func formatNs(ns float64) string {
prec := 0
switch {
case ns < 10:
prec = 2
case ns < 100:
prec = 1
}
return strconv.FormatFloat(ns, 'f', prec, 64)
}
@@ -0,0 +1,59 @@
package main
import (
"reflect"
"testing"
"golang.org/x/tools/benchmark/parse"
)
func TestSelectBest(t *testing.T) {
have := parse.Set{
"Benchmark1": []*parse.Benchmark{
{
Name: "Benchmark1",
N: 10, NsPerOp: 100, Measured: parse.NsPerOp,
Ord: 0,
},
{
Name: "Benchmark1",
N: 10, NsPerOp: 50, Measured: parse.NsPerOp,
Ord: 3,
},
},
"Benchmark2": []*parse.Benchmark{
{
Name: "Benchmark2",
N: 10, NsPerOp: 60, Measured: parse.NsPerOp,
Ord: 1,
},
{
Name: "Benchmark2",
N: 10, NsPerOp: 500, Measured: parse.NsPerOp,
Ord: 2,
},
},
}
want := parse.Set{
"Benchmark1": []*parse.Benchmark{
{
Name: "Benchmark1",
N: 10, NsPerOp: 50, Measured: parse.NsPerOp,
Ord: 0,
},
},
"Benchmark2": []*parse.Benchmark{
{
Name: "Benchmark2",
N: 10, NsPerOp: 60, Measured: parse.NsPerOp,
Ord: 1,
},
},
}
selectBest(have)
if !reflect.DeepEqual(want, have) {
t.Errorf("filtered bench set incorrectly, want %v have %v", want, have)
}
}
@@ -0,0 +1,156 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"math"
"golang.org/x/tools/benchmark/parse"
)
// BenchCmp is a pair of benchmarks.
type BenchCmp struct {
Before *parse.Benchmark
After *parse.Benchmark
}
// Correlate correlates benchmarks from two BenchSets.
func Correlate(before, after parse.Set) (cmps []BenchCmp, warnings []string) {
cmps = make([]BenchCmp, 0, len(after))
for name, beforebb := range before {
afterbb := after[name]
if len(beforebb) != len(afterbb) {
warnings = append(warnings, fmt.Sprintf("ignoring %s: before has %d instances, after has %d", name, len(beforebb), len(afterbb)))
continue
}
for i, beforeb := range beforebb {
afterb := afterbb[i]
cmps = append(cmps, BenchCmp{beforeb, afterb})
}
}
return
}
func (c BenchCmp) Name() string { return c.Before.Name }
func (c BenchCmp) String() string { return fmt.Sprintf("<%s, %s>", c.Before, c.After) }
func (c BenchCmp) Measured(flag int) bool { return (c.Before.Measured & c.After.Measured & flag) != 0 }
func (c BenchCmp) DeltaNsPerOp() Delta { return Delta{c.Before.NsPerOp, c.After.NsPerOp} }
func (c BenchCmp) DeltaMBPerS() Delta { return Delta{c.Before.MBPerS, c.After.MBPerS} }
func (c BenchCmp) DeltaAllocedBytesPerOp() Delta {
return Delta{float64(c.Before.AllocedBytesPerOp), float64(c.After.AllocedBytesPerOp)}
}
func (c BenchCmp) DeltaAllocsPerOp() Delta {
return Delta{float64(c.Before.AllocsPerOp), float64(c.After.AllocsPerOp)}
}
// Delta is the before and after value for a benchmark measurement.
// Both must be non-negative.
type Delta struct {
Before float64
After float64
}
// mag calculates the magnitude of a change, regardless of the direction of
// the change. mag is intended for sorting and has no independent meaning.
func (d Delta) mag() float64 {
switch {
case d.Before != 0 && d.After != 0 && d.Before >= d.After:
return d.After / d.Before
case d.Before != 0 && d.After != 0 && d.Before < d.After:
return d.Before / d.After
case d.Before == 0 && d.After == 0:
return 1
default:
// 0 -> 1 or 1 -> 0
// These are significant changes and worth surfacing.
return math.Inf(1)
}
}
// Changed reports whether the benchmark quantities are different.
func (d Delta) Changed() bool { return d.Before != d.After }
// Float64 returns After / Before. If Before is 0, Float64 returns
// 1 if After is also 0, and +Inf otherwise.
func (d Delta) Float64() float64 {
switch {
case d.Before != 0:
return d.After / d.Before
case d.After == 0:
return 1
default:
return math.Inf(1)
}
}
// Percent formats a Delta as a percent change, ranging from -100% up.
func (d Delta) Percent() string {
return fmt.Sprintf("%+.2f%%", 100*d.Float64()-100)
}
// Multiple formats a Delta as a multiplier, ranging from 0.00x up.
func (d Delta) Multiple() string {
return fmt.Sprintf("%.2fx", d.Float64())
}
func (d Delta) String() string {
return fmt.Sprintf("Δ(%f, %f)", d.Before, d.After)
}
// ByParseOrder sorts BenchCmps to match the order in
// which the Before benchmarks were presented to Parse.
type ByParseOrder []BenchCmp
func (x ByParseOrder) Len() int { return len(x) }
func (x ByParseOrder) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x ByParseOrder) Less(i, j int) bool { return x[i].Before.Ord < x[j].Before.Ord }
// lessByDelta provides lexicographic ordering:
// * largest delta by magnitude
// * alphabetic by name
func lessByDelta(i, j BenchCmp, calcDelta func(BenchCmp) Delta) bool {
iDelta, jDelta := calcDelta(i).mag(), calcDelta(j).mag()
if iDelta != jDelta {
return iDelta < jDelta
}
return i.Name() < j.Name()
}
// ByDeltaNsPerOp sorts BenchCmps lexicographically by change
// in ns/op, descending, then by benchmark name.
type ByDeltaNsPerOp []BenchCmp
func (x ByDeltaNsPerOp) Len() int { return len(x) }
func (x ByDeltaNsPerOp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x ByDeltaNsPerOp) Less(i, j int) bool { return lessByDelta(x[i], x[j], BenchCmp.DeltaNsPerOp) }
// ByDeltaMBPerS sorts BenchCmps lexicographically by change
// in MB/s, descending, then by benchmark name.
type ByDeltaMBPerS []BenchCmp
func (x ByDeltaMBPerS) Len() int { return len(x) }
func (x ByDeltaMBPerS) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x ByDeltaMBPerS) Less(i, j int) bool { return lessByDelta(x[i], x[j], BenchCmp.DeltaMBPerS) }
// ByDeltaAllocedBytesPerOp sorts BenchCmps lexicographically by change
// in B/op, descending, then by benchmark name.
type ByDeltaAllocedBytesPerOp []BenchCmp
func (x ByDeltaAllocedBytesPerOp) Len() int { return len(x) }
func (x ByDeltaAllocedBytesPerOp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x ByDeltaAllocedBytesPerOp) Less(i, j int) bool {
return lessByDelta(x[i], x[j], BenchCmp.DeltaAllocedBytesPerOp)
}
// ByDeltaAllocsPerOp sorts BenchCmps lexicographically by change
// in allocs/op, descending, then by benchmark name.
type ByDeltaAllocsPerOp []BenchCmp
func (x ByDeltaAllocsPerOp) Len() int { return len(x) }
func (x ByDeltaAllocsPerOp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x ByDeltaAllocsPerOp) Less(i, j int) bool {
return lessByDelta(x[i], x[j], BenchCmp.DeltaAllocsPerOp)
}
@@ -0,0 +1,133 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"math"
"reflect"
"sort"
"testing"
"golang.org/x/tools/benchmark/parse"
)
func TestDelta(t *testing.T) {
cases := []struct {
before float64
after float64
mag float64
f float64
changed bool
pct string
mult string
}{
{before: 1, after: 1, mag: 1, f: 1, changed: false, pct: "+0.00%", mult: "1.00x"},
{before: 1, after: 2, mag: 0.5, f: 2, changed: true, pct: "+100.00%", mult: "2.00x"},
{before: 2, after: 1, mag: 0.5, f: 0.5, changed: true, pct: "-50.00%", mult: "0.50x"},
{before: 0, after: 0, mag: 1, f: 1, changed: false, pct: "+0.00%", mult: "1.00x"},
{before: 1, after: 0, mag: math.Inf(1), f: 0, changed: true, pct: "-100.00%", mult: "0.00x"},
{before: 0, after: 1, mag: math.Inf(1), f: math.Inf(1), changed: true, pct: "+Inf%", mult: "+Infx"},
}
for _, tt := range cases {
d := Delta{tt.before, tt.after}
if want, have := tt.mag, d.mag(); want != have {
t.Errorf("%s.mag(): want %f have %f", d, want, have)
}
if want, have := tt.f, d.Float64(); want != have {
t.Errorf("%s.Float64(): want %f have %f", d, want, have)
}
if want, have := tt.changed, d.Changed(); want != have {
t.Errorf("%s.Changed(): want %t have %t", d, want, have)
}
if want, have := tt.pct, d.Percent(); want != have {
t.Errorf("%s.Percent(): want %q have %q", d, want, have)
}
if want, have := tt.mult, d.Multiple(); want != have {
t.Errorf("%s.Multiple(): want %q have %q", d, want, have)
}
}
}
func TestCorrelate(t *testing.T) {
// Benches that are going to be successfully correlated get N thus:
// 0x<counter><num benches><b = before | a = after>
// Read this: "<counter> of <num benches>, from <before|after>".
before := parse.Set{
"BenchmarkOneEach": []*parse.Benchmark{{Name: "BenchmarkOneEach", N: 0x11b}},
"BenchmarkOneToNone": []*parse.Benchmark{{Name: "BenchmarkOneToNone"}},
"BenchmarkOneToTwo": []*parse.Benchmark{{Name: "BenchmarkOneToTwo"}},
"BenchmarkTwoToOne": []*parse.Benchmark{
{Name: "BenchmarkTwoToOne"},
{Name: "BenchmarkTwoToOne"},
},
"BenchmarkTwoEach": []*parse.Benchmark{
{Name: "BenchmarkTwoEach", N: 0x12b},
{Name: "BenchmarkTwoEach", N: 0x22b},
},
}
after := parse.Set{
"BenchmarkOneEach": []*parse.Benchmark{{Name: "BenchmarkOneEach", N: 0x11a}},
"BenchmarkNoneToOne": []*parse.Benchmark{{Name: "BenchmarkNoneToOne"}},
"BenchmarkTwoToOne": []*parse.Benchmark{{Name: "BenchmarkTwoToOne"}},
"BenchmarkOneToTwo": []*parse.Benchmark{
{Name: "BenchmarkOneToTwo"},
{Name: "BenchmarkOneToTwo"},
},
"BenchmarkTwoEach": []*parse.Benchmark{
{Name: "BenchmarkTwoEach", N: 0x12a},
{Name: "BenchmarkTwoEach", N: 0x22a},
},
}
pairs, errs := Correlate(before, after)
// Fail to match: BenchmarkOneToNone, BenchmarkOneToTwo, BenchmarkTwoToOne.
// Correlate does not notice BenchmarkNoneToOne.
if len(errs) != 3 {
t.Errorf("Correlated expected 4 errors, got %d: %v", len(errs), errs)
}
// Want three correlated pairs: one BenchmarkOneEach, two BenchmarkTwoEach.
if len(pairs) != 3 {
t.Fatalf("Correlated expected 3 pairs, got %v", pairs)
}
for _, pair := range pairs {
if pair.Before.N&0xF != 0xb {
t.Errorf("unexpected Before in pair %s", pair)
}
if pair.After.N&0xF != 0xa {
t.Errorf("unexpected After in pair %s", pair)
}
if pair.Before.N>>4 != pair.After.N>>4 {
t.Errorf("mismatched pair %s", pair)
}
}
}
func TestBenchCmpSorting(t *testing.T) {
c := []BenchCmp{
{&parse.Benchmark{Name: "BenchmarkMuchFaster", NsPerOp: 10, Ord: 3}, &parse.Benchmark{Name: "BenchmarkMuchFaster", NsPerOp: 1}},
{&parse.Benchmark{Name: "BenchmarkSameB", NsPerOp: 5, Ord: 1}, &parse.Benchmark{Name: "BenchmarkSameB", NsPerOp: 5}},
{&parse.Benchmark{Name: "BenchmarkSameA", NsPerOp: 5, Ord: 2}, &parse.Benchmark{Name: "BenchmarkSameA", NsPerOp: 5}},
{&parse.Benchmark{Name: "BenchmarkSlower", NsPerOp: 10, Ord: 0}, &parse.Benchmark{Name: "BenchmarkSlower", NsPerOp: 11}},
}
// Test just one magnitude-based sort order; they are symmetric.
sort.Sort(ByDeltaNsPerOp(c))
want := []string{"BenchmarkMuchFaster", "BenchmarkSlower", "BenchmarkSameA", "BenchmarkSameB"}
have := []string{c[0].Name(), c[1].Name(), c[2].Name(), c[3].Name()}
if !reflect.DeepEqual(want, have) {
t.Errorf("ByDeltaNsOp incorrect sorting: want %v have %v", want, have)
}
sort.Sort(ByParseOrder(c))
want = []string{"BenchmarkSlower", "BenchmarkSameB", "BenchmarkSameA", "BenchmarkMuchFaster"}
have = []string{c[0].Name(), c[1].Name(), c[2].Name(), c[3].Name()}
if !reflect.DeepEqual(want, have) {
t.Errorf("ByParseOrder incorrect sorting: want %v have %v", want, have)
}
}
@@ -0,0 +1,37 @@
// Copyright 2014 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.
/*
The benchcmp command displays performance changes between benchmarks.
Benchcmp parses the output of two 'go test' benchmark runs,
correlates the results per benchmark, and displays the deltas.
To measure the performance impact of a change, use 'go test'
to run benchmarks before and after the change:
go test -run=NONE -bench=. ./... > old.txt
# make changes
go test -run=NONE -bench=. ./... > new.txt
Then feed the benchmark results to benchcmp:
benchcmp old.txt new.txt
Benchcmp will summarize and display the performance changes,
in a format like this:
$ benchcmp old.txt new.txt
benchmark old ns/op new ns/op delta
BenchmarkConcat 523 68.6 -86.88%
benchmark old allocs new allocs delta
BenchmarkConcat 3 1 -66.67%
benchmark old bytes new bytes delta
BenchmarkConcat 80 48 -40.00%
*/
package main // import "golang.org/x/tools/cmd/benchcmp"
@@ -0,0 +1,334 @@
// Copyright 2014 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.
// callgraph: a tool for reporting the call graph of a Go program.
// See Usage for details, or run with -help.
package main // import "golang.org/x/tools/cmd/callgraph"
// TODO(adonovan):
//
// Features:
// - restrict graph to a single package
// - output
// - functions reachable from root (use digraph tool?)
// - unreachable functions (use digraph tool?)
// - dynamic (runtime) types
// - indexed output (numbered nodes)
// - JSON output
// - additional template fields:
// callee file/line/col
import (
"bytes"
"flag"
"fmt"
"go/build"
"go/token"
"io"
"os"
"runtime"
"text/template"
"golang.org/x/tools/go/callgraph"
"golang.org/x/tools/go/callgraph/cha"
"golang.org/x/tools/go/callgraph/rta"
"golang.org/x/tools/go/callgraph/static"
"golang.org/x/tools/go/loader"
"golang.org/x/tools/go/pointer"
"golang.org/x/tools/go/ssa"
)
var algoFlag = flag.String("algo", "rta",
`Call graph construction algorithm, one of "rta" or "pta"`)
var testFlag = flag.Bool("test", false,
"Loads test code (*_test.go) for imported packages")
var formatFlag = flag.String("format",
"{{.Caller}}\t--{{.Dynamic}}-{{.Line}}:{{.Column}}-->\t{{.Callee}}",
"A template expression specifying how to format an edge")
const Usage = `callgraph: display the the call graph of a Go program.
Usage:
callgraph [-algo=static|cha|rta|pta] [-test] [-format=...] <args>...
Flags:
-algo Specifies the call-graph construction algorithm, one of:
static static calls only (unsound)
cha Class Hierarchy Analysis
rta Rapid Type Analysis
pta inclusion-based Points-To Analysis
The algorithms are ordered by increasing precision in their
treatment of dynamic calls (and thus also computational cost).
RTA and PTA require a whole program (main or test), and
include only functions reachable from main.
-test Include the package's tests in the analysis.
-format Specifies the format in which each call graph edge is displayed.
One of:
digraph output suitable for input to
golang.org/x/tools/cmd/digraph.
graphviz output in AT&T GraphViz (.dot) format.
All other values are interpreted using text/template syntax.
The default value is:
{{.Caller}}\t--{{.Dynamic}}-{{.Line}}:{{.Column}}-->\t{{.Callee}}
The structure passed to the template is (effectively):
type Edge struct {
Caller *ssa.Function // calling function
Callee *ssa.Function // called function
// Call site:
Filename string // containing file
Offset int // offset within file of '('
Line int // line number
Column int // column number of call
Dynamic string // "static" or "dynamic"
Description string // e.g. "static method call"
}
Caller and Callee are *ssa.Function values, which print as
"(*sync/atomic.Mutex).Lock", but other attributes may be
derived from them, e.g. Caller.Pkg.Object.Path yields the
import path of the enclosing package. Consult the go/ssa
API documentation for details.
` + loader.FromArgsUsage + `
Examples:
Show the call graph of the trivial web server application:
callgraph -format digraph $GOROOT/src/net/http/triv.go
Same, but show only the packages of each function:
callgraph -format '{{.Caller.Pkg.Object.Path}} -> {{.Callee.Pkg.Object.Path}}' \
$GOROOT/src/net/http/triv.go | sort | uniq
Show functions that make dynamic calls into the 'fmt' test package,
using the pointer analysis algorithm:
callgraph -format='{{.Caller}} -{{.Dynamic}}-> {{.Callee}}' -test -algo=pta fmt |
sed -ne 's/-dynamic-/--/p' |
sed -ne 's/-->.*fmt_test.*$//p' | sort | uniq
Show all functions directly called by the callgraph tool's main function:
callgraph -format=digraph golang.org/x/tools/cmd/callgraph |
digraph succs golang.org/x/tools/cmd/callgraph.main
`
func init() {
// If $GOMAXPROCS isn't set, use the full capacity of the machine.
// For small machines, use at least 4 threads.
if os.Getenv("GOMAXPROCS") == "" {
n := runtime.NumCPU()
if n < 4 {
n = 4
}
runtime.GOMAXPROCS(n)
}
}
func main() {
flag.Parse()
if err := doCallgraph(&build.Default, *algoFlag, *formatFlag, *testFlag, flag.Args()); err != nil {
fmt.Fprintf(os.Stderr, "callgraph: %s\n", err)
os.Exit(1)
}
}
var stdout io.Writer = os.Stdout
func doCallgraph(ctxt *build.Context, algo, format string, tests bool, args []string) error {
conf := loader.Config{
Build: ctxt,
SourceImports: true,
}
if len(args) == 0 {
fmt.Fprintln(os.Stderr, Usage)
return nil
}
// Use the initial packages from the command line.
args, err := conf.FromArgs(args, tests)
if err != nil {
return err
}
// Load, parse and type-check the whole program.
iprog, err := conf.Load()
if err != nil {
return err
}
// Create and build SSA-form program representation.
prog := ssa.Create(iprog, 0)
prog.BuildAll()
// -- call graph construction ------------------------------------------
var cg *callgraph.Graph
switch algo {
case "static":
cg = static.CallGraph(prog)
case "cha":
cg = cha.CallGraph(prog)
case "pta":
main, err := mainPackage(prog, tests)
if err != nil {
return err
}
config := &pointer.Config{
Mains: []*ssa.Package{main},
BuildCallGraph: true,
}
ptares, err := pointer.Analyze(config)
if err != nil {
return err // internal error in pointer analysis
}
cg = ptares.CallGraph
case "rta":
main, err := mainPackage(prog, tests)
if err != nil {
return err
}
roots := []*ssa.Function{
main.Func("init"),
main.Func("main"),
}
rtares := rta.Analyze(roots, true)
cg = rtares.CallGraph
// NB: RTA gives us Reachable and RuntimeTypes too.
default:
return fmt.Errorf("unknown algorithm: %s", algo)
}
cg.DeleteSyntheticNodes()
// -- output------------------------------------------------------------
var before, after string
// Pre-canned formats.
switch format {
case "digraph":
format = `{{printf "%q %q" .Caller .Callee}}`
case "graphviz":
before = "digraph callgraph {\n"
after = "}\n"
format = ` {{printf "%q" .Caller}} -> {{printf "%q" .Callee}}`
}
tmpl, err := template.New("-format").Parse(format)
if err != nil {
return fmt.Errorf("invalid -format template: %v", err)
}
// Allocate these once, outside the traversal.
var buf bytes.Buffer
data := Edge{fset: prog.Fset}
fmt.Fprint(stdout, before)
if err := callgraph.GraphVisitEdges(cg, func(edge *callgraph.Edge) error {
data.position.Offset = -1
data.edge = edge
data.Caller = edge.Caller.Func
data.Callee = edge.Callee.Func
buf.Reset()
if err := tmpl.Execute(&buf, &data); err != nil {
return err
}
stdout.Write(buf.Bytes())
if len := buf.Len(); len == 0 || buf.Bytes()[len-1] != '\n' {
fmt.Fprintln(stdout)
}
return nil
}); err != nil {
return err
}
fmt.Fprint(stdout, after)
return nil
}
// mainPackage returns the main package to analyze.
// The resulting package has a main() function.
func mainPackage(prog *ssa.Program, tests bool) (*ssa.Package, error) {
pkgs := prog.AllPackages()
// TODO(adonovan): allow independent control over tests, mains and libraries.
// TODO(adonovan): put this logic in a library; we keep reinventing it.
if tests {
// If -test, use all packages' tests.
if len(pkgs) > 0 {
if main := prog.CreateTestMainPackage(pkgs...); main != nil {
return main, nil
}
}
return nil, fmt.Errorf("no tests")
}
// Otherwise, use the first package named main.
for _, pkg := range pkgs {
if pkg.Object.Name() == "main" {
if pkg.Func("main") == nil {
return nil, fmt.Errorf("no func main() in main package")
}
return pkg, nil
}
}
return nil, fmt.Errorf("no main package")
}
type Edge struct {
Caller *ssa.Function
Callee *ssa.Function
edge *callgraph.Edge
fset *token.FileSet
position token.Position // initialized lazily
}
func (e *Edge) pos() *token.Position {
if e.position.Offset == -1 {
e.position = e.fset.Position(e.edge.Pos()) // called lazily
}
return &e.position
}
func (e *Edge) Filename() string { return e.pos().Filename }
func (e *Edge) Column() int { return e.pos().Column }
func (e *Edge) Line() int { return e.pos().Line }
func (e *Edge) Offset() int { return e.pos().Offset }
func (e *Edge) Dynamic() string {
if e.edge.Site != nil && e.edge.Site.Common().StaticCallee() == nil {
return "dynamic"
}
return "static"
}
func (e *Edge) Description() string { return e.edge.Description() }
@@ -0,0 +1,73 @@
package main
import (
"bytes"
"fmt"
"go/build"
"reflect"
"sort"
"strings"
"testing"
)
func TestCallgraph(t *testing.T) {
ctxt := build.Default // copy
ctxt.GOPATH = "testdata"
const format = "{{.Caller}} --> {{.Callee}}"
for _, test := range []struct {
algo, format string
tests bool
want []string
}{
{"rta", format, false, []string{
// rta imprecisely shows cross product of {main,main2} x {C,D}
`pkg.main --> (pkg.C).f`,
`pkg.main --> (pkg.D).f`,
`pkg.main --> pkg.main2`,
`pkg.main2 --> (pkg.C).f`,
`pkg.main2 --> (pkg.D).f`,
}},
{"pta", format, false, []string{
// pta distinguishes main->C, main2->D. Also has a root node.
`<root> --> pkg.init`,
`<root> --> pkg.main`,
`pkg.main --> (pkg.C).f`,
`pkg.main --> pkg.main2`,
`pkg.main2 --> (pkg.D).f`,
}},
// tests: main is not called.
{"rta", format, true, []string{
`pkg.Example --> (pkg.C).f`,
`test$main.init --> pkg.init`,
}},
{"pta", format, true, []string{
`<root> --> pkg.Example`,
`<root> --> test$main.init`,
`pkg.Example --> (pkg.C).f`,
`test$main.init --> pkg.init`,
}},
} {
stdout = new(bytes.Buffer)
if err := doCallgraph(&ctxt, test.algo, test.format, test.tests, []string{"pkg"}); err != nil {
t.Error(err)
continue
}
got := sortedLines(fmt.Sprint(stdout))
if !reflect.DeepEqual(got, test.want) {
t.Errorf("callgraph(%q, %q, %t):\ngot:\n%s\nwant:\n%s",
test.algo, test.format, test.tests,
strings.Join(got, "\n"),
strings.Join(test.want, "\n"))
}
}
}
func sortedLines(s string) []string {
s = strings.TrimSpace(s)
lines := strings.Split(s, "\n")
sort.Strings(lines)
return lines
}
@@ -0,0 +1,25 @@
package main
type I interface {
f()
}
type C int
func (C) f() {}
type D int
func (D) f() {}
func main() {
var i I = C(0)
i.f() // dynamic call
main2()
}
func main2() {
var i I = D(0)
i.f() // dynamic call
}
@@ -0,0 +1,7 @@
package main
// Don't import "testing", it adds a lot of callgraph edges.
func Example() {
C(0).f()
}
@@ -0,0 +1,652 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"flag"
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"sort"
"strconv"
)
const usageMessage = "" +
`Usage of 'go tool cover':
Given a coverage profile produced by 'go test':
go test -coverprofile=c.out
Open a web browser displaying annotated source code:
go tool cover -html=c.out
Write out an HTML file instead of launching a web browser:
go tool cover -html=c.out -o coverage.html
Display coverage percentages to stdout for each function:
go tool cover -func=c.out
Finally, to generate modified source code with coverage annotations
(what go test -cover does):
go tool cover -mode=set -var=CoverageVariableName program.go
`
func usage() {
fmt.Fprintln(os.Stderr, usageMessage)
fmt.Fprintln(os.Stderr, "Flags:")
flag.PrintDefaults()
fmt.Fprintln(os.Stderr, "\n Only one of -html, -func, or -mode may be set.")
os.Exit(2)
}
var (
mode = flag.String("mode", "", "coverage mode: set, count, atomic")
varVar = flag.String("var", "GoCover", "name of coverage variable to generate")
output = flag.String("o", "", "file for output; default: stdout")
htmlOut = flag.String("html", "", "generate HTML representation of coverage profile")
funcOut = flag.String("func", "", "output coverage profile information for each function")
)
var profile string // The profile to read; the value of -html or -func
var counterStmt func(*File, ast.Expr) ast.Stmt
const (
atomicPackagePath = "sync/atomic"
atomicPackageName = "_cover_atomic_"
)
func main() {
flag.Usage = usage
flag.Parse()
// Usage information when no arguments.
if flag.NFlag() == 0 && flag.NArg() == 0 {
flag.Usage()
}
err := parseFlags()
if err != nil {
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, `For usage information, run "go tool cover -help"`)
os.Exit(2)
}
// Generate coverage-annotated source.
if *mode != "" {
annotate(flag.Arg(0))
return
}
// Output HTML or function coverage information.
if *htmlOut != "" {
err = htmlOutput(profile, *output)
} else {
err = funcOutput(profile, *output)
}
if err != nil {
fmt.Fprintf(os.Stderr, "cover: %v\n", err)
os.Exit(2)
}
}
// parseFlags sets the profile and counterStmt globals and performs validations.
func parseFlags() error {
profile = *htmlOut
if *funcOut != "" {
if profile != "" {
return fmt.Errorf("too many options")
}
profile = *funcOut
}
// Must either display a profile or rewrite Go source.
if (profile == "") == (*mode == "") {
return fmt.Errorf("too many options")
}
if *mode != "" {
switch *mode {
case "set":
counterStmt = setCounterStmt
case "count":
counterStmt = incCounterStmt
case "atomic":
counterStmt = atomicCounterStmt
default:
return fmt.Errorf("unknown -mode %v", *mode)
}
if flag.NArg() == 0 {
return fmt.Errorf("missing source file")
} else if flag.NArg() == 1 {
return nil
}
} else if flag.NArg() == 0 {
return nil
}
return fmt.Errorf("too many arguments")
}
// Block represents the information about a basic block to be recorded in the analysis.
// Note: Our definition of basic block is based on control structures; we don't break
// apart && and ||. We could but it doesn't seem important enough to bother.
type Block struct {
startByte token.Pos
endByte token.Pos
numStmt int
}
// File is a wrapper for the state of a file used in the parser.
// The basic parse tree walker is a method of this type.
type File struct {
fset *token.FileSet
name string // Name of file.
astFile *ast.File
blocks []Block
atomicPkg string // Package name for "sync/atomic" in this file.
}
// Visit implements the ast.Visitor interface.
func (f *File) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
case *ast.BlockStmt:
// If it's a switch or select, the body is a list of case clauses; don't tag the block itself.
if len(n.List) > 0 {
switch n.List[0].(type) {
case *ast.CaseClause: // switch
for _, n := range n.List {
clause := n.(*ast.CaseClause)
clause.Body = f.addCounters(clause.Pos(), clause.End(), clause.Body, false)
}
return f
case *ast.CommClause: // select
for _, n := range n.List {
clause := n.(*ast.CommClause)
clause.Body = f.addCounters(clause.Pos(), clause.End(), clause.Body, false)
}
return f
}
}
n.List = f.addCounters(n.Lbrace, n.Rbrace+1, n.List, true) // +1 to step past closing brace.
case *ast.IfStmt:
ast.Walk(f, n.Body)
if n.Else == nil {
return nil
}
// The elses are special, because if we have
// if x {
// } else if y {
// }
// we want to cover the "if y". To do this, we need a place to drop the counter,
// so we add a hidden block:
// if x {
// } else {
// if y {
// }
// }
switch stmt := n.Else.(type) {
case *ast.IfStmt:
block := &ast.BlockStmt{
Lbrace: n.Body.End(), // Start at end of the "if" block so the covered part looks like it starts at the "else".
List: []ast.Stmt{stmt},
Rbrace: stmt.End(),
}
n.Else = block
case *ast.BlockStmt:
stmt.Lbrace = n.Body.End() // Start at end of the "if" block so the covered part looks like it starts at the "else".
default:
panic("unexpected node type in if")
}
ast.Walk(f, n.Else)
return nil
case *ast.SelectStmt:
// Don't annotate an empty select - creates a syntax error.
if n.Body == nil || len(n.Body.List) == 0 {
return nil
}
case *ast.SwitchStmt:
// Don't annotate an empty switch - creates a syntax error.
if n.Body == nil || len(n.Body.List) == 0 {
return nil
}
}
return f
}
// unquote returns the unquoted string.
func unquote(s string) string {
t, err := strconv.Unquote(s)
if err != nil {
log.Fatalf("cover: improperly quoted string %q\n", s)
}
return t
}
// addImport adds an import for the specified path, if one does not already exist, and returns
// the local package name.
func (f *File) addImport(path string) string {
// Does the package already import it?
for _, s := range f.astFile.Imports {
if unquote(s.Path.Value) == path {
if s.Name != nil {
return s.Name.Name
}
return filepath.Base(path)
}
}
newImport := &ast.ImportSpec{
Name: ast.NewIdent(atomicPackageName),
Path: &ast.BasicLit{
Kind: token.STRING,
Value: fmt.Sprintf("%q", path),
},
}
impDecl := &ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
newImport,
},
}
// Make the new import the first Decl in the file.
astFile := f.astFile
astFile.Decls = append(astFile.Decls, nil)
copy(astFile.Decls[1:], astFile.Decls[0:])
astFile.Decls[0] = impDecl
astFile.Imports = append(astFile.Imports, newImport)
// Now refer to the package, just in case it ends up unused.
// That is, append to the end of the file the declaration
// var _ = _cover_atomic_.AddUint32
reference := &ast.GenDecl{
Tok: token.VAR,
Specs: []ast.Spec{
&ast.ValueSpec{
Names: []*ast.Ident{
ast.NewIdent("_"),
},
Values: []ast.Expr{
&ast.SelectorExpr{
X: ast.NewIdent(atomicPackageName),
Sel: ast.NewIdent("AddUint32"),
},
},
},
},
}
astFile.Decls = append(astFile.Decls, reference)
return atomicPackageName
}
var slashslash = []byte("//")
// initialComments returns the prefix of content containing only
// whitespace and line comments. Any +build directives must appear
// within this region. This approach is more reliable than using
// go/printer to print a modified AST containing comments.
//
func initialComments(content []byte) []byte {
// Derived from go/build.Context.shouldBuild.
end := 0
p := content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if len(line) == 0 { // Blank line.
end = len(content) - len(p)
continue
}
if !bytes.HasPrefix(line, slashslash) { // Not comment line.
break
}
}
return content[:end]
}
func annotate(name string) {
fset := token.NewFileSet()
content, err := ioutil.ReadFile(name)
if err != nil {
log.Fatalf("cover: %s: %s", name, err)
}
parsedFile, err := parser.ParseFile(fset, name, content, 0)
if err != nil {
log.Fatalf("cover: %s: %s", name, err)
}
file := &File{
fset: fset,
name: name,
astFile: parsedFile,
}
if *mode == "atomic" {
file.atomicPkg = file.addImport(atomicPackagePath)
}
ast.Walk(file, file.astFile)
fd := os.Stdout
if *output != "" {
var err error
fd, err = os.Create(*output)
if err != nil {
log.Fatalf("cover: %s", err)
}
}
fd.Write(initialComments(content)) // Retain '// +build' directives.
file.print(fd)
// After printing the source tree, add some declarations for the counters etc.
// We could do this by adding to the tree, but it's easier just to print the text.
file.addVariables(fd)
}
func (f *File) print(w io.Writer) {
printer.Fprint(w, f.fset, f.astFile)
}
// intLiteral returns an ast.BasicLit representing the integer value.
func (f *File) intLiteral(i int) *ast.BasicLit {
node := &ast.BasicLit{
Kind: token.INT,
Value: fmt.Sprint(i),
}
return node
}
// index returns an ast.BasicLit representing the number of counters present.
func (f *File) index() *ast.BasicLit {
return f.intLiteral(len(f.blocks))
}
// setCounterStmt returns the expression: __count[23] = 1.
func setCounterStmt(f *File, counter ast.Expr) ast.Stmt {
return &ast.AssignStmt{
Lhs: []ast.Expr{counter},
Tok: token.ASSIGN,
Rhs: []ast.Expr{f.intLiteral(1)},
}
}
// incCounterStmt returns the expression: __count[23]++.
func incCounterStmt(f *File, counter ast.Expr) ast.Stmt {
return &ast.IncDecStmt{
X: counter,
Tok: token.INC,
}
}
// atomicCounterStmt returns the expression: atomic.AddUint32(&__count[23], 1)
func atomicCounterStmt(f *File, counter ast.Expr) ast.Stmt {
return &ast.ExprStmt{
X: &ast.CallExpr{
Fun: &ast.SelectorExpr{
X: ast.NewIdent(f.atomicPkg),
Sel: ast.NewIdent("AddUint32"),
},
Args: []ast.Expr{&ast.UnaryExpr{
Op: token.AND,
X: counter,
},
f.intLiteral(1),
},
},
}
}
// newCounter creates a new counter expression of the appropriate form.
func (f *File) newCounter(start, end token.Pos, numStmt int) ast.Stmt {
counter := &ast.IndexExpr{
X: &ast.SelectorExpr{
X: ast.NewIdent(*varVar),
Sel: ast.NewIdent("Count"),
},
Index: f.index(),
}
stmt := counterStmt(f, counter)
f.blocks = append(f.blocks, Block{start, end, numStmt})
return stmt
}
// addCounters takes a list of statements and adds counters to the beginning of
// each basic block at the top level of that list. For instance, given
//
// S1
// if cond {
// S2
// }
// S3
//
// counters will be added before S1 and before S3. The block containing S2
// will be visited in a separate call.
// TODO: Nested simple blocks get unnecessary (but correct) counters
func (f *File) addCounters(pos, blockEnd token.Pos, list []ast.Stmt, extendToClosingBrace bool) []ast.Stmt {
// Special case: make sure we add a counter to an empty block. Can't do this below
// or we will add a counter to an empty statement list after, say, a return statement.
if len(list) == 0 {
return []ast.Stmt{f.newCounter(pos, blockEnd, 0)}
}
// We have a block (statement list), but it may have several basic blocks due to the
// appearance of statements that affect the flow of control.
var newList []ast.Stmt
for {
// Find first statement that affects flow of control (break, continue, if, etc.).
// It will be the last statement of this basic block.
var last int
end := blockEnd
for last = 0; last < len(list); last++ {
end = f.statementBoundary(list[last])
if f.endsBasicSourceBlock(list[last]) {
extendToClosingBrace = false // Block is broken up now.
last++
break
}
}
if extendToClosingBrace {
end = blockEnd
}
if pos != end { // Can have no source to cover if e.g. blocks abut.
newList = append(newList, f.newCounter(pos, end, last))
}
newList = append(newList, list[0:last]...)
list = list[last:]
if len(list) == 0 {
break
}
pos = list[0].Pos()
}
return newList
}
// hasFuncLiteral reports the existence and position of the first func literal
// in the node, if any. If a func literal appears, it usually marks the termination
// of a basic block because the function body is itself a block.
// Therefore we draw a line at the start of the body of the first function literal we find.
// TODO: what if there's more than one? Probably doesn't matter much.
func hasFuncLiteral(n ast.Node) (bool, token.Pos) {
var literal funcLitFinder
ast.Walk(&literal, n)
return literal.found(), token.Pos(literal)
}
// statementBoundary finds the location in s that terminates the current basic
// block in the source.
func (f *File) statementBoundary(s ast.Stmt) token.Pos {
// Control flow statements are easy.
switch s := s.(type) {
case *ast.BlockStmt:
// Treat blocks like basic blocks to avoid overlapping counters.
return s.Lbrace
case *ast.IfStmt:
return s.Body.Lbrace
case *ast.ForStmt:
return s.Body.Lbrace
case *ast.LabeledStmt:
return f.statementBoundary(s.Stmt)
case *ast.RangeStmt:
// Ranges might loop over things with function literals.: for _ = range []func(){ ... } {.
// TODO: There are a few other such possibilities, but they're extremely unlikely.
found, pos := hasFuncLiteral(s.X)
if found {
return pos
}
return s.Body.Lbrace
case *ast.SwitchStmt:
return s.Body.Lbrace
case *ast.SelectStmt:
return s.Body.Lbrace
case *ast.TypeSwitchStmt:
return s.Body.Lbrace
}
// If not a control flow statement, it is a declaration, expression, call, etc. and it may have a function literal.
// If it does, that's tricky because we want to exclude the body of the function from this block.
// Draw a line at the start of the body of the first function literal we find.
// TODO: what if there's more than one? Probably doesn't matter much.
found, pos := hasFuncLiteral(s)
if found {
return pos
}
return s.End()
}
// endsBasicSourceBlock reports whether s changes the flow of control: break, if, etc.,
// or if it's just problematic, for instance contains a function literal, which will complicate
// accounting due to the block-within-an expression.
func (f *File) endsBasicSourceBlock(s ast.Stmt) bool {
switch s := s.(type) {
case *ast.BlockStmt:
// Treat blocks like basic blocks to avoid overlapping counters.
return true
case *ast.BranchStmt:
return true
case *ast.ForStmt:
return true
case *ast.IfStmt:
return true
case *ast.LabeledStmt:
return f.endsBasicSourceBlock(s.Stmt)
case *ast.RangeStmt:
return true
case *ast.SwitchStmt:
return true
case *ast.SelectStmt:
return true
case *ast.TypeSwitchStmt:
return true
}
found, _ := hasFuncLiteral(s)
return found
}
// funcLitFinder implements the ast.Visitor pattern to find the location of any
// function literal in a subtree.
type funcLitFinder token.Pos
func (f *funcLitFinder) Visit(node ast.Node) (w ast.Visitor) {
if f.found() {
return nil // Prune search.
}
switch n := node.(type) {
case *ast.FuncLit:
*f = funcLitFinder(n.Body.Lbrace)
return nil // Prune search.
}
return f
}
func (f *funcLitFinder) found() bool {
return token.Pos(*f) != token.NoPos
}
// Sort interface for []block1; used for self-check in addVariables.
type block1 struct {
Block
index int
}
type blockSlice []block1
func (b blockSlice) Len() int { return len(b) }
func (b blockSlice) Less(i, j int) bool { return b[i].startByte < b[j].startByte }
func (b blockSlice) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
// offset translates a token position into a 0-indexed byte offset.
func (f *File) offset(pos token.Pos) int {
return f.fset.Position(pos).Offset
}
// addVariables adds to the end of the file the declarations to set up the counter and position variables.
func (f *File) addVariables(w io.Writer) {
// Self-check: Verify that the instrumented basic blocks are disjoint.
t := make([]block1, len(f.blocks))
for i := range f.blocks {
t[i].Block = f.blocks[i]
t[i].index = i
}
sort.Sort(blockSlice(t))
for i := 1; i < len(t); i++ {
if t[i-1].endByte > t[i].startByte {
fmt.Fprintf(os.Stderr, "cover: internal error: block %d overlaps block %d\n", t[i-1].index, t[i].index)
// Note: error message is in byte positions, not token positions.
fmt.Fprintf(os.Stderr, "\t%s:#%d,#%d %s:#%d,#%d\n",
f.name, f.offset(t[i-1].startByte), f.offset(t[i-1].endByte),
f.name, f.offset(t[i].startByte), f.offset(t[i].endByte))
}
}
// Declare the coverage struct as a package-level variable.
fmt.Fprintf(w, "\nvar %s = struct {\n", *varVar)
fmt.Fprintf(w, "\tCount [%d]uint32\n", len(f.blocks))
fmt.Fprintf(w, "\tPos [3 * %d]uint32\n", len(f.blocks))
fmt.Fprintf(w, "\tNumStmt [%d]uint16\n", len(f.blocks))
fmt.Fprintf(w, "} {\n")
// Initialize the position array field.
fmt.Fprintf(w, "\tPos: [3 * %d]uint32{\n", len(f.blocks))
// A nice long list of positions. Each position is encoded as follows to reduce size:
// - 32-bit starting line number
// - 32-bit ending line number
// - (16 bit ending column number << 16) | (16-bit starting column number).
for i, block := range f.blocks {
start := f.fset.Position(block.startByte)
end := f.fset.Position(block.endByte)
fmt.Fprintf(w, "\t\t%d, %d, %#x, // [%d]\n", start.Line, end.Line, (end.Column&0xFFFF)<<16|(start.Column&0xFFFF), i)
}
// Close the position array.
fmt.Fprintf(w, "\t},\n")
// Initialize the position array field.
fmt.Fprintf(w, "\tNumStmt: [%d]uint16{\n", len(f.blocks))
// A nice long list of statements-per-block, so we can give a conventional
// valuation of "percent covered". To save space, it's a 16-bit number, so we
// clamp it if it overflows - won't matter in practice.
for i, block := range f.blocks {
n := block.numStmt
if n > 1<<16-1 {
n = 1<<16 - 1
}
fmt.Fprintf(w, "\t\t%d, // %d\n", n, i)
}
// Close the statements-per-block array.
fmt.Fprintf(w, "\t},\n")
// Close the struct initialization.
fmt.Fprintf(w, "}\n")
}
@@ -0,0 +1,87 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main_test
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"testing"
)
const (
// Data directory, also the package directory for the test.
testdata = "testdata"
// Binaries we compile.
testcover = "./testcover.exe"
)
var (
// Files we use.
testMain = filepath.Join(testdata, "main.go")
testTest = filepath.Join(testdata, "test.go")
coverInput = filepath.Join(testdata, "test_line.go")
coverOutput = filepath.Join(testdata, "test_cover.go")
)
var debug = false // Keeps the rewritten files around if set.
// Run this shell script, but do it in Go so it can be run by "go test".
//
// replace the word LINE with the line number < testdata/test.go > testdata/test_line.go
// go build -o ./testcover
// ./testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go
// go run ./testdata/main.go ./testdata/test.go
//
func TestCover(t *testing.T) {
// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
file, err := ioutil.ReadFile(testTest)
if err != nil {
t.Fatal(err)
}
lines := bytes.Split(file, []byte("\n"))
for i, line := range lines {
lines[i] = bytes.Replace(line, []byte("LINE"), []byte(fmt.Sprint(i+1)), -1)
}
err = ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666)
// defer removal of test_line.go
if !debug {
defer os.Remove(coverInput)
}
// go build -o testcover
cmd := exec.Command("go", "build", "-o", testcover)
run(cmd, t)
// defer removal of testcover
defer os.Remove(testcover)
// ./testcover -mode=count -var=coverTest -o ./testdata/test_cover.go testdata/test_line.go
cmd = exec.Command(testcover, "-mode=count", "-var=coverTest", "-o", coverOutput, coverInput)
run(cmd, t)
// defer removal of ./testdata/test_cover.go
if !debug {
defer os.Remove(coverOutput)
}
// go run ./testdata/main.go ./testdata/test.go
cmd = exec.Command("go", "run", testMain, coverOutput)
run(cmd, t)
}
func run(c *exec.Cmd, t *testing.T) {
c.Stdout = os.Stdout
c.Stderr = os.Stderr
err := c.Run()
if err != nil {
t.Fatal(err)
}
}
@@ -0,0 +1,21 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Cover is a program for analyzing the coverage profiles generated by
'go test -coverprofile=cover.out'.
Cover is also used by 'go test -cover' to rewrite the source code with
annotations to track which parts of each function are executed.
It operates on one Go source file at a time, computing approximate
basic block information by studying the source. It is thus more portable
than binary-rewriting coverage tools, but also a little less capable.
For instance, it does not probe inside && and || expressions, and can
be mildly confused by single statements with multiple function literals.
For usage information, please see:
go help testflag
go tool cover -help
*/
package main // import "golang.org/x/tools/cmd/cover"
@@ -0,0 +1,166 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements the visitor that computes the (line, column)-(line-column) range for each function.
package main
import (
"bufio"
"fmt"
"go/ast"
"go/build"
"go/parser"
"go/token"
"os"
"path/filepath"
"text/tabwriter"
"golang.org/x/tools/cover"
)
// funcOutput takes two file names as arguments, a coverage profile to read as input and an output
// file to write ("" means to write to standard output). The function reads the profile and produces
// as output the coverage data broken down by function, like this:
//
// fmt/format.go:30: init 100.0%
// fmt/format.go:57: clearflags 100.0%
// ...
// fmt/scan.go:1046: doScan 100.0%
// fmt/scan.go:1075: advance 96.2%
// fmt/scan.go:1119: doScanf 96.8%
// total: (statements) 91.9%
func funcOutput(profile, outputFile string) error {
profiles, err := cover.ParseProfiles(profile)
if err != nil {
return err
}
var out *bufio.Writer
if outputFile == "" {
out = bufio.NewWriter(os.Stdout)
} else {
fd, err := os.Create(outputFile)
if err != nil {
return err
}
defer fd.Close()
out = bufio.NewWriter(fd)
}
defer out.Flush()
tabber := tabwriter.NewWriter(out, 1, 8, 1, '\t', 0)
defer tabber.Flush()
var total, covered int64
for _, profile := range profiles {
fn := profile.FileName
file, err := findFile(fn)
if err != nil {
return err
}
funcs, err := findFuncs(file)
if err != nil {
return err
}
// Now match up functions and profile blocks.
for _, f := range funcs {
c, t := f.coverage(profile)
fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n", fn, f.startLine, f.name, 100.0*float64(c)/float64(t))
total += t
covered += c
}
}
fmt.Fprintf(tabber, "total:\t(statements)\t%.1f%%\n", 100.0*float64(covered)/float64(total))
return nil
}
// findFuncs parses the file and returns a slice of FuncExtent descriptors.
func findFuncs(name string) ([]*FuncExtent, error) {
fset := token.NewFileSet()
parsedFile, err := parser.ParseFile(fset, name, nil, 0)
if err != nil {
return nil, err
}
visitor := &FuncVisitor{
fset: fset,
name: name,
astFile: parsedFile,
}
ast.Walk(visitor, visitor.astFile)
return visitor.funcs, nil
}
// FuncExtent describes a function's extent in the source by file and position.
type FuncExtent struct {
name string
startLine int
startCol int
endLine int
endCol int
}
// FuncVisitor implements the visitor that builds the function position list for a file.
type FuncVisitor struct {
fset *token.FileSet
name string // Name of file.
astFile *ast.File
funcs []*FuncExtent
}
// Visit implements the ast.Visitor interface.
func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
case *ast.FuncDecl:
start := v.fset.Position(n.Pos())
end := v.fset.Position(n.End())
fe := &FuncExtent{
name: n.Name.Name,
startLine: start.Line,
startCol: start.Column,
endLine: end.Line,
endCol: end.Column,
}
v.funcs = append(v.funcs, fe)
}
return v
}
// coverage returns the fraction of the statements in the function that were covered, as a numerator and denominator.
func (f *FuncExtent) coverage(profile *cover.Profile) (num, den int64) {
// We could avoid making this n^2 overall by doing a single scan and annotating the functions,
// but the sizes of the data structures is never very large and the scan is almost instantaneous.
var covered, total int64
// The blocks are sorted, so we can stop counting as soon as we reach the end of the relevant block.
for _, b := range profile.Blocks {
if b.StartLine > f.endLine || (b.StartLine == f.endLine && b.StartCol >= f.endCol) {
// Past the end of the function.
break
}
if b.EndLine < f.startLine || (b.EndLine == f.startLine && b.EndCol <= f.startCol) {
// Before the beginning of the function
continue
}
total += int64(b.NumStmt)
if b.Count > 0 {
covered += int64(b.NumStmt)
}
}
if total == 0 {
total = 1 // Avoid zero denominator.
}
return covered, total
}
// findFile finds the location of the named file in GOROOT, GOPATH etc.
func findFile(file string) (string, error) {
dir, file := filepath.Split(file)
pkg, err := build.Import(dir, ".", build.FindOnly)
if err != nil {
return "", fmt.Errorf("can't find %q: %v", file, err)
}
return filepath.Join(pkg.Dir, file), nil
}
@@ -0,0 +1,281 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bufio"
"bytes"
"fmt"
"html/template"
"io"
"io/ioutil"
"math"
"os"
"os/exec"
"path/filepath"
"runtime"
"golang.org/x/tools/cover"
)
// htmlOutput reads the profile data from profile and generates an HTML
// coverage report, writing it to outfile. If outfile is empty,
// it writes the report to a temporary file and opens it in a web browser.
func htmlOutput(profile, outfile string) error {
profiles, err := cover.ParseProfiles(profile)
if err != nil {
return err
}
var d templateData
for _, profile := range profiles {
fn := profile.FileName
if profile.Mode == "set" {
d.Set = true
}
file, err := findFile(fn)
if err != nil {
return err
}
src, err := ioutil.ReadFile(file)
if err != nil {
return fmt.Errorf("can't read %q: %v", fn, err)
}
var buf bytes.Buffer
err = htmlGen(&buf, src, profile.Boundaries(src))
if err != nil {
return err
}
d.Files = append(d.Files, &templateFile{
Name: fn,
Body: template.HTML(buf.String()),
Coverage: percentCovered(profile),
})
}
var out *os.File
if outfile == "" {
var dir string
dir, err = ioutil.TempDir("", "cover")
if err != nil {
return err
}
out, err = os.Create(filepath.Join(dir, "coverage.html"))
} else {
out, err = os.Create(outfile)
}
err = htmlTemplate.Execute(out, d)
if err == nil {
err = out.Close()
}
if err != nil {
return err
}
if outfile == "" {
if !startBrowser("file://" + out.Name()) {
fmt.Fprintf(os.Stderr, "HTML output written to %s\n", out.Name())
}
}
return nil
}
// percentCovered returns, as a percentage, the fraction of the statements in
// the profile covered by the test run.
// In effect, it reports the coverage of a given source file.
func percentCovered(p *cover.Profile) float64 {
var total, covered int64
for _, b := range p.Blocks {
total += int64(b.NumStmt)
if b.Count > 0 {
covered += int64(b.NumStmt)
}
}
if total == 0 {
return 0
}
return float64(covered) / float64(total) * 100
}
// htmlGen generates an HTML coverage report with the provided filename,
// source code, and tokens, and writes it to the given Writer.
func htmlGen(w io.Writer, src []byte, boundaries []cover.Boundary) error {
dst := bufio.NewWriter(w)
for i := range src {
for len(boundaries) > 0 && boundaries[0].Offset == i {
b := boundaries[0]
if b.Start {
n := 0
if b.Count > 0 {
n = int(math.Floor(b.Norm*9)) + 1
}
fmt.Fprintf(dst, `<span class="cov%v" title="%v">`, n, b.Count)
} else {
dst.WriteString("</span>")
}
boundaries = boundaries[1:]
}
switch b := src[i]; b {
case '>':
dst.WriteString("&gt;")
case '<':
dst.WriteString("&lt;")
case '&':
dst.WriteString("&amp;")
case '\t':
dst.WriteString(" ")
default:
dst.WriteByte(b)
}
}
return dst.Flush()
}
// startBrowser tries to open the URL in a browser
// and reports whether it succeeds.
func startBrowser(url string) bool {
// try to start the browser
var args []string
switch runtime.GOOS {
case "darwin":
args = []string{"open"}
case "windows":
args = []string{"cmd", "/c", "start"}
default:
args = []string{"xdg-open"}
}
cmd := exec.Command(args[0], append(args[1:], url)...)
return cmd.Start() == nil
}
// rgb returns an rgb value for the specified coverage value
// between 0 (no coverage) and 10 (max coverage).
func rgb(n int) string {
if n == 0 {
return "rgb(192, 0, 0)" // Red
}
// Gradient from gray to green.
r := 128 - 12*(n-1)
g := 128 + 12*(n-1)
b := 128 + 3*(n-1)
return fmt.Sprintf("rgb(%v, %v, %v)", r, g, b)
}
// colors generates the CSS rules for coverage colors.
func colors() template.CSS {
var buf bytes.Buffer
for i := 0; i < 11; i++ {
fmt.Fprintf(&buf, ".cov%v { color: %v }\n", i, rgb(i))
}
return template.CSS(buf.String())
}
var htmlTemplate = template.Must(template.New("html").Funcs(template.FuncMap{
"colors": colors,
}).Parse(tmplHTML))
type templateData struct {
Files []*templateFile
Set bool
}
type templateFile struct {
Name string
Body template.HTML
Coverage float64
}
const tmplHTML = `
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body {
background: black;
color: rgb(80, 80, 80);
}
body, pre, #legend span {
font-family: Menlo, monospace;
font-weight: bold;
}
#topbar {
background: black;
position: fixed;
top: 0; left: 0; right: 0;
height: 42px;
border-bottom: 1px solid rgb(80, 80, 80);
}
#content {
margin-top: 50px;
}
#nav, #legend {
float: left;
margin-left: 10px;
}
#legend {
margin-top: 12px;
}
#nav {
margin-top: 10px;
}
#legend span {
margin: 0 5px;
}
{{colors}}
</style>
</head>
<body>
<div id="topbar">
<div id="nav">
<select id="files">
{{range $i, $f := .Files}}
<option value="file{{$i}}">{{$f.Name}} ({{printf "%.1f" $f.Coverage}}%)</option>
{{end}}
</select>
</div>
<div id="legend">
<span>not tracked</span>
{{if .Set}}
<span class="cov0">not covered</span>
<span class="cov8">covered</span>
{{else}}
<span class="cov0">no coverage</span>
<span class="cov1">low coverage</span>
<span class="cov2">*</span>
<span class="cov3">*</span>
<span class="cov4">*</span>
<span class="cov5">*</span>
<span class="cov6">*</span>
<span class="cov7">*</span>
<span class="cov8">*</span>
<span class="cov9">*</span>
<span class="cov10">high coverage</span>
{{end}}
</div>
</div>
<div id="content">
{{range $i, $f := .Files}}
<pre class="file" id="file{{$i}}" {{if $i}}style="display: none"{{end}}>{{$f.Body}}</pre>
{{end}}
</div>
</body>
<script>
(function() {
var files = document.getElementById('files');
var visible = document.getElementById('file0');
files.addEventListener('change', onChange, false);
function onChange() {
visible.style.display = 'none';
visible = document.getElementById(files.value);
visible.style.display = 'block';
window.scrollTo(0, 0);
}
})();
</script>
</html>
`
@@ -0,0 +1,93 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test runner for coverage test. This file is not coverage-annotated; test.go is.
// It knows the coverage counter is called "coverTest".
package main
import (
"fmt"
"os"
)
func main() {
testAll()
verify()
}
type block struct {
count uint32
line uint32
}
var counters = make(map[block]bool)
// check records the location and expected value for a counter.
func check(line, count uint32) {
b := block{
count,
line,
}
counters[b] = true
}
// checkVal is a version of check that returns its extra argument,
// so it can be used in conditionals.
func checkVal(line, count uint32, val int) int {
b := block{
count,
line,
}
counters[b] = true
return val
}
var PASS = true
// verify checks the expected counts against the actual. It runs after the test has completed.
func verify() {
for b := range counters {
got, index := count(b.line)
if b.count == anything && got != 0 {
got = anything
}
if got != b.count {
fmt.Fprintf(os.Stderr, "test_go:%d expected count %d got %d [counter %d]\n", b.line, b.count, got, index)
PASS = false
}
}
if !PASS {
fmt.Fprintf(os.Stderr, "FAIL\n")
os.Exit(2)
}
}
// count returns the count and index for the counter at the specified line.
func count(line uint32) (uint32, int) {
// Linear search is fine. Choose perfect fit over approximate.
// We can have a closing brace for a range on the same line as a condition for an "else if"
// and we don't want that brace to steal the count for the condition on the "if".
// Therefore we test for a perfect (lo==line && hi==line) match, but if we can't
// find that we take the first imperfect match.
index := -1
indexLo := uint32(1e9)
for i := range coverTest.Count {
lo, hi := coverTest.Pos[3*i], coverTest.Pos[3*i+1]
if lo == line && line == hi {
return coverTest.Count[i], i
}
// Choose the earliest match (the counters are in unpredictable order).
if lo <= line && line <= hi && indexLo > lo {
index = i
indexLo = lo
}
}
if index == -1 {
fmt.Fprintln(os.Stderr, "cover_test: no counter for line", line)
PASS = false
return 0, 0
}
return coverTest.Count[index], index
}
@@ -0,0 +1,177 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This program is processed by the cover command, and then testAll is called.
// The test driver in main.go can then compare the coverage statistics with expectation.
// The word LINE is replaced by the line number in this file. When the file is executed,
// the coverage processing has changed the line numbers, so we can't use runtime.Caller.
package main
const anything = 1e9 // Just some unlikely value that means "we got here, don't care how often"
func testAll() {
testSimple()
testBlockRun()
testIf()
testFor()
testRange()
testSwitch()
testTypeSwitch()
testSelect1()
testSelect2()
}
func testSimple() {
check(LINE, 1)
}
func testIf() {
if true {
check(LINE, 1)
} else {
check(LINE, 0)
}
if false {
check(LINE, 0)
} else {
check(LINE, 1)
}
for i := 0; i < 3; i++ {
if checkVal(LINE, 3, i) <= 2 {
check(LINE, 3)
}
if checkVal(LINE, 3, i) <= 1 {
check(LINE, 2)
}
if checkVal(LINE, 3, i) <= 0 {
check(LINE, 1)
}
}
for i := 0; i < 3; i++ {
if checkVal(LINE, 3, i) <= 1 {
check(LINE, 2)
} else {
check(LINE, 1)
}
}
for i := 0; i < 3; i++ {
if checkVal(LINE, 3, i) <= 0 {
check(LINE, 1)
} else if checkVal(LINE, 2, i) <= 1 {
check(LINE, 1)
} else if checkVal(LINE, 1, i) <= 2 {
check(LINE, 1)
} else if checkVal(LINE, 0, i) <= 3 {
check(LINE, 0)
}
}
}
func testFor() {
for i := 0; i < 10; i++ {
check(LINE, 10)
}
}
func testRange() {
for _, f := range []func(){
func() { check(LINE, 1) },
} {
f()
check(LINE, 1)
}
}
func testBlockRun() {
check(LINE, 1)
{
check(LINE, 1)
}
{
check(LINE, 1)
}
check(LINE, 1)
{
check(LINE, 1)
}
{
check(LINE, 1)
}
check(LINE, 1)
}
func testSwitch() {
for i := 0; i < 5; i++ {
switch i {
case 0:
check(LINE, 1)
case 1:
check(LINE, 1)
case 2:
check(LINE, 1)
default:
check(LINE, 2)
}
}
}
func testTypeSwitch() {
var x = []interface{}{1, 2.0, "hi"}
for _, v := range x {
switch v.(type) {
case int:
check(LINE, 1)
case float64:
check(LINE, 1)
case string:
check(LINE, 1)
case complex128:
check(LINE, 0)
default:
check(LINE, 0)
}
}
}
func testSelect1() {
c := make(chan int)
go func() {
for i := 0; i < 1000; i++ {
c <- i
}
}()
for {
select {
case <-c:
check(LINE, anything)
case <-c:
check(LINE, anything)
default:
check(LINE, 1)
return
}
}
}
func testSelect2() {
c1 := make(chan int, 1000)
c2 := make(chan int, 1000)
for i := 0; i < 1000; i++ {
c1 <- i
c2 <- i
}
for {
select {
case <-c1:
check(LINE, 1000)
case <-c2:
check(LINE, 1000)
default:
check(LINE, 1)
return
}
}
}
@@ -0,0 +1,540 @@
// The digraph command performs queries over unlabelled directed graphs
// represented in text form. It is intended to integrate nicely with
// typical UNIX command pipelines.
//
// Since directed graphs (import graphs, reference graphs, call graphs,
// etc) often arise during software tool development and debugging, this
// command is included in the go.tools repository.
//
// TODO(adonovan):
// - support input files other than stdin
// - suport alternative formats (AT&T GraphViz, CSV, etc),
// a comment syntax, etc.
// - allow queries to nest, like Blaze query language.
//
package main // import "golang.org/x/tools/cmd/digraph"
import (
"bufio"
"bytes"
"errors"
"flag"
"fmt"
"io"
"os"
"sort"
"strconv"
"unicode"
"unicode/utf8"
)
const Usage = `digraph: queries over directed graphs in text form.
Graph format:
Each line contains zero or more words. Words are separated by
unquoted whitespace; words may contain Go-style double-quoted portions,
allowing spaces and other characters to be expressed.
Each field declares a node, and if there are more than one,
an edge from the first to each subsequent one.
The graph is provided on the standard input.
For instance, the following (acyclic) graph specifies a partial order
among the subtasks of getting dressed:
% cat clothes.txt
socks shoes
"boxer shorts" pants
pants belt shoes
shirt tie sweater
sweater jacket
hat
The line "shirt tie sweater" indicates the two edges shirt -> tie and
shirt -> sweater, not shirt -> tie -> sweater.
Supported queries:
nodes
the set of all nodes
degree
the in-degree and out-degree of each node.
preds <label> ...
the set of immediate predecessors of the specified nodes
succs <label> ...
the set of immediate successors of the specified nodes
forward <label> ...
the set of nodes transitively reachable from the specified nodes
reverse <label> ...
the set of nodes that transitively reach the specified nodes
somepath <label> <label>
the list of nodes on some arbitrary path from the first node to the second
allpaths <label> <label>
the set of nodes on all paths from the first node to the second
sccs
all strongly connected components (one per line)
scc <label>
the set of nodes nodes strongly connected to the specified one
Example usage:
Show the transitive closure of imports of the digraph tool itself:
% go list -f '{{.ImportPath}}{{.Imports}}' ... | tr '[]' ' ' |
digraph forward golang.org/x/tools/cmd/digraph
Show which clothes (see above) must be donned before a jacket:
% digraph reverse jacket <clothes.txt
`
func main() {
flag.Parse()
args := flag.Args()
if len(args) == 0 {
fmt.Println(Usage)
return
}
if err := digraph(args[0], args[1:]); err != nil {
fmt.Fprintf(os.Stderr, "digraph: %s\n", err)
os.Exit(1)
}
}
type nodelist []string
func (l nodelist) println(sep string) {
for i, label := range l {
if i > 0 {
fmt.Fprint(stdout, sep)
}
fmt.Fprint(stdout, label)
}
fmt.Fprintln(stdout)
}
type nodeset map[string]bool
func (s nodeset) sort() nodelist {
labels := make(nodelist, len(s))
var i int
for label := range s {
labels[i] = label
i++
}
sort.Strings(labels)
return labels
}
func (s nodeset) addAll(x nodeset) {
for label := range x {
s[label] = true
}
}
// A graph maps nodes to the non-nil set of their immediate successors.
type graph map[string]nodeset
func (g graph) addNode(label string) nodeset {
edges := g[label]
if edges == nil {
edges = make(nodeset)
g[label] = edges
}
return edges
}
func (g graph) addEdges(from string, to ...string) {
edges := g.addNode(from)
for _, to := range to {
g.addNode(to)
edges[to] = true
}
}
func (g graph) reachableFrom(roots nodeset) nodeset {
seen := make(nodeset)
var visit func(label string)
visit = func(label string) {
if !seen[label] {
seen[label] = true
for e := range g[label] {
visit(e)
}
}
}
for root := range roots {
visit(root)
}
return seen
}
func (g graph) transpose() graph {
rev := make(graph)
for label, edges := range g {
rev.addNode(label)
for succ := range edges {
rev.addEdges(succ, label)
}
}
return rev
}
func (g graph) sccs() []nodeset {
// Kosaraju's algorithm---Tarjan is overkill here.
// Forward pass.
S := make(nodelist, 0, len(g)) // postorder stack
seen := make(nodeset)
var visit func(label string)
visit = func(label string) {
if !seen[label] {
seen[label] = true
for e := range g[label] {
visit(e)
}
S = append(S, label)
}
}
for label := range g {
visit(label)
}
// Reverse pass.
rev := g.transpose()
var scc nodeset
seen = make(nodeset)
var rvisit func(label string)
rvisit = func(label string) {
if !seen[label] {
seen[label] = true
scc[label] = true
for e := range rev[label] {
rvisit(e)
}
}
}
var sccs []nodeset
for len(S) > 0 {
top := S[len(S)-1]
S = S[:len(S)-1] // pop
if !seen[top] {
scc = make(nodeset)
rvisit(top)
sccs = append(sccs, scc)
}
}
return sccs
}
func parse(rd io.Reader) (graph, error) {
g := make(graph)
var linenum int
in := bufio.NewScanner(rd)
for in.Scan() {
linenum++
// Split into words, honoring double-quotes per Go spec.
words, err := split(in.Text())
if err != nil {
return nil, fmt.Errorf("at line %d: %v", linenum, err)
}
if len(words) > 0 {
g.addEdges(words[0], words[1:]...)
}
}
if err := in.Err(); err != nil {
return nil, err
}
return g, nil
}
var stdin io.Reader = os.Stdin
var stdout io.Writer = os.Stdout
func digraph(cmd string, args []string) error {
// Parse the input graph.
g, err := parse(stdin)
if err != nil {
return err
}
// Parse the command line.
switch cmd {
case "nodes":
if len(args) != 0 {
return fmt.Errorf("usage: digraph nodes")
}
nodes := make(nodeset)
for label := range g {
nodes[label] = true
}
nodes.sort().println("\n")
case "degree":
if len(args) != 0 {
return fmt.Errorf("usage: digraph degree")
}
nodes := make(nodeset)
for label := range g {
nodes[label] = true
}
rev := g.transpose()
for _, label := range nodes.sort() {
fmt.Fprintf(stdout, "%d\t%d\t%s\n", len(rev[label]), len(g[label]), label)
}
case "succs", "preds":
if len(args) == 0 {
return fmt.Errorf("usage: digraph %s <label> ...", cmd)
}
g := g
if cmd == "preds" {
g = g.transpose()
}
result := make(nodeset)
for _, root := range args {
edges := g[root]
if edges == nil {
return fmt.Errorf("no such node %q", root)
}
result.addAll(edges)
}
result.sort().println("\n")
case "forward", "reverse":
if len(args) == 0 {
return fmt.Errorf("usage: digraph %s <label> ...", cmd)
}
roots := make(nodeset)
for _, root := range args {
if g[root] == nil {
return fmt.Errorf("no such node %q", root)
}
roots[root] = true
}
g := g
if cmd == "reverse" {
g = g.transpose()
}
g.reachableFrom(roots).sort().println("\n")
case "somepath":
if len(args) != 2 {
return fmt.Errorf("usage: digraph somepath <from> <to>")
}
from, to := args[0], args[1]
if g[from] == nil {
return fmt.Errorf("no such 'from' node %q", from)
}
if g[to] == nil {
return fmt.Errorf("no such 'to' node %q", to)
}
seen := make(nodeset)
var visit func(path nodelist, label string) bool
visit = func(path nodelist, label string) bool {
if !seen[label] {
seen[label] = true
if label == to {
append(path, label).println("\n")
return true // unwind
}
for e := range g[label] {
if visit(append(path, label), e) {
return true
}
}
}
return false
}
if !visit(make(nodelist, 0, 100), from) {
return fmt.Errorf("no path from %q to %q", args[0], args[1])
}
case "allpaths":
if len(args) != 2 {
return fmt.Errorf("usage: digraph allpaths <from> <to>")
}
from, to := args[0], args[1]
if g[from] == nil {
return fmt.Errorf("no such 'from' node %q", from)
}
if g[to] == nil {
return fmt.Errorf("no such 'to' node %q", to)
}
seen := make(nodeset) // value of seen[x] indicates whether x is on some path to 'to'
var visit func(label string) bool
visit = func(label string) bool {
reachesTo, ok := seen[label]
if !ok {
reachesTo = label == to
seen[label] = reachesTo
for e := range g[label] {
if visit(e) {
reachesTo = true
}
}
seen[label] = reachesTo
}
return reachesTo
}
if !visit(from) {
return fmt.Errorf("no path from %q to %q", from, to)
}
for label, reachesTo := range seen {
if !reachesTo {
delete(seen, label)
}
}
seen.sort().println("\n")
case "sccs":
if len(args) != 0 {
return fmt.Errorf("usage: digraph sccs")
}
for _, scc := range g.sccs() {
scc.sort().println(" ")
}
case "scc":
if len(args) != 1 {
return fmt.Errorf("usage: digraph scc <label>")
}
label := args[0]
if g[label] == nil {
return fmt.Errorf("no such node %q", label)
}
for _, scc := range g.sccs() {
if scc[label] {
scc.sort().println("\n")
break
}
}
default:
return fmt.Errorf("no such command %q", cmd)
}
return nil
}
// -- Utilities --------------------------------------------------------
// split splits a line into words, which are generally separated by
// spaces, but Go-style double-quoted string literals are also supported.
// (This approximates the behaviour of the Bourne shell.)
//
// `one "two three"` -> ["one" "two three"]
// `a"\n"b` -> ["a\nb"]
//
func split(line string) ([]string, error) {
var (
words []string
inWord bool
current bytes.Buffer
)
for len(line) > 0 {
r, size := utf8.DecodeRuneInString(line)
if unicode.IsSpace(r) {
if inWord {
words = append(words, current.String())
current.Reset()
inWord = false
}
} else if r == '"' {
var ok bool
size, ok = quotedLength(line)
if !ok {
return nil, errors.New("invalid quotation")
}
s, err := strconv.Unquote(line[:size])
if err != nil {
return nil, err
}
current.WriteString(s)
inWord = true
} else {
current.WriteRune(r)
inWord = true
}
line = line[size:]
}
if inWord {
words = append(words, current.String())
}
return words, nil
}
// quotedLength returns the length in bytes of the prefix of input that
// contain a possibly-valid double-quoted Go string literal.
//
// On success, n is at least two (""); input[:n] may be passed to
// strconv.Unquote to interpret its value, and input[n:] contains the
// rest of the input.
//
// On failure, quotedLength returns false, and the entire input can be
// passed to strconv.Unquote if an informative error message is desired.
//
// quotedLength does not and need not detect all errors, such as
// invalid hex or octal escape sequences, since it assumes
// strconv.Unquote will be applied to the prefix. It guarantees only
// that if there is a prefix of input containing a valid string literal,
// its length is returned.
//
// TODO(adonovan): move this into a strconv-like utility package.
//
func quotedLength(input string) (n int, ok bool) {
var offset int
// next returns the rune at offset, or -1 on EOF.
// offset advances to just after that rune.
next := func() rune {
if offset < len(input) {
r, size := utf8.DecodeRuneInString(input[offset:])
offset += size
return r
}
return -1
}
if next() != '"' {
return // error: not a quotation
}
for {
r := next()
if r == '\n' || r < 0 {
return // error: string literal not terminated
}
if r == '"' {
return offset, true // success
}
if r == '\\' {
var skip int
switch next() {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"':
skip = 0
case '0', '1', '2', '3', '4', '5', '6', '7':
skip = 2
case 'x':
skip = 2
case 'u':
skip = 4
case 'U':
skip = 8
default:
return // error: invalid escape
}
for i := 0; i < skip; i++ {
next()
}
}
}
}
@@ -0,0 +1,121 @@
package main
import (
"bytes"
"fmt"
"reflect"
"strings"
"testing"
)
func TestDigraph(t *testing.T) {
const g1 = `
socks shoes
shorts pants
pants belt shoes
shirt tie sweater
sweater jacket
hat
`
const g2 = `
a b c
b d
c d
d c
`
for _, test := range []struct {
input string
cmd string
args []string
want string
}{
{g1, "nodes", nil, "belt\nhat\njacket\npants\nshirt\nshoes\nshorts\nsocks\nsweater\ntie\n"},
{g1, "reverse", []string{"jacket"}, "jacket\nshirt\nsweater\n"},
{g1, "forward", []string{"socks"}, "shoes\nsocks\n"},
{g1, "forward", []string{"socks", "sweater"}, "jacket\nshoes\nsocks\nsweater\n"},
{g2, "allpaths", []string{"a", "d"}, "a\nb\nc\nd\n"},
{g2, "sccs", nil, "a\nb\nc d\n"},
{g2, "scc", []string{"d"}, "c\nd\n"},
{g2, "succs", []string{"a"}, "b\nc\n"},
{g2, "preds", []string{"c"}, "a\nd\n"},
{g2, "preds", []string{"c", "d"}, "a\nb\nc\nd\n"},
} {
stdin = strings.NewReader(test.input)
stdout = new(bytes.Buffer)
if err := digraph(test.cmd, test.args); err != nil {
t.Error(err)
continue
}
got := stdout.(fmt.Stringer).String()
if got != test.want {
t.Errorf("digraph(%s, %s) = %q, want %q", test.cmd, test.args, got, test.want)
}
}
// TODO(adonovan):
// - test somepath (it's nondeterministic).
// - test errors
}
func TestSplit(t *testing.T) {
for _, test := range []struct {
line string
want []string
}{
{`one "2a 2b" three`, []string{"one", "2a 2b", "three"}},
{`one tw"\n\x0a\u000a\012"o three`, []string{"one", "tw\n\n\n\no", "three"}},
} {
got, err := split(test.line)
if err != nil {
t.Errorf("split(%s) failed: %v", test.line, err)
}
if !reflect.DeepEqual(got, test.want) {
t.Errorf("split(%s) = %v, want %v", test.line, got, test.want)
}
}
}
func TestQuotedLength(t *testing.T) {
for _, test := range []struct {
input string
want int
}{
{`"abc"`, 5},
{`"abc"def`, 5},
{`"abc\"d"ef`, 8}, // "abc\"d" is consumed, ef is residue
{`"\012\n\x0a\u000a\U0000000a"`, 28},
{"\"\xff\"", 3}, // bad UTF-8 is ok
{`"\xff"`, 6}, // hex escape for bad UTF-8 is ok
} {
got, ok := quotedLength(test.input)
if !ok {
got = 0
}
if got != test.want {
t.Errorf("quotedLength(%s) = %d, want %d", test.input, got, test.want)
}
}
// errors
for _, input := range []string{
``, // not a quotation
`a`, // not a quotation
`'a'`, // not a quotation
`"a`, // not terminated
`"\0"`, // short octal escape
`"\x1"`, // short hex escape
`"\u000"`, // short \u escape
`"\U0000000"`, // short \U escape
`"\k"`, // invalid escape
"\"ab\nc\"", // newline
} {
if n, ok := quotedLength(input); ok {
t.Errorf("quotedLength(%s) = %d, want !ok", input, n)
}
}
}
+140
View File
@@ -0,0 +1,140 @@
// The eg command performs example-based refactoring.
// For documentation, run the command, or see Help in
// golang.org/x/tools/refactor/eg.
package main // import "golang.org/x/tools/cmd/eg"
import (
"flag"
"fmt"
"go/parser"
"go/printer"
"go/token"
"os"
"os/exec"
"strings"
"golang.org/x/tools/go/loader"
"golang.org/x/tools/refactor/eg"
)
var (
beforeeditFlag = flag.String("beforeedit", "", "A command to exec before each file is edited (e.g. chmod, checkout). Whitespace delimits argument words. The string '{}' is replaced by the file name.")
helpFlag = flag.Bool("help", false, "show detailed help message")
templateFlag = flag.String("t", "", "template.go file specifying the refactoring")
transitiveFlag = flag.Bool("transitive", false, "apply refactoring to all dependencies too")
writeFlag = flag.Bool("w", false, "rewrite input files in place (by default, the results are printed to standard output)")
verboseFlag = flag.Bool("v", false, "show verbose matcher diagnostics")
)
const usage = `eg: an example-based refactoring tool.
Usage: eg -t template.go [-w] [-transitive] <args>...
-t template.go specifies the template file (use -help to see explanation)
-w causes files to be re-written in place.
-transitive causes all dependencies to be refactored too.
` + loader.FromArgsUsage
func main() {
if err := doMain(); err != nil {
fmt.Fprintf(os.Stderr, "eg: %s\n", err)
os.Exit(1)
}
}
func doMain() error {
flag.Parse()
args := flag.Args()
if *helpFlag {
fmt.Fprint(os.Stderr, eg.Help)
os.Exit(2)
}
if *templateFlag == "" {
return fmt.Errorf("no -t template.go file specified")
}
conf := loader.Config{
Fset: token.NewFileSet(),
ParserMode: parser.ParseComments,
SourceImports: true,
}
// The first Created package is the template.
conf.CreateFromFilenames("template", *templateFlag)
if len(args) == 0 {
fmt.Fprint(os.Stderr, usage)
os.Exit(1)
}
if _, err := conf.FromArgs(args, true); err != nil {
return err
}
// Load, parse and type-check the whole program.
iprog, err := conf.Load()
if err != nil {
return err
}
// Analyze the template.
template := iprog.Created[0]
xform, err := eg.NewTransformer(iprog.Fset, template, *verboseFlag)
if err != nil {
return err
}
// Apply it to the input packages.
var pkgs []*loader.PackageInfo
if *transitiveFlag {
for _, info := range iprog.AllPackages {
pkgs = append(pkgs, info)
}
} else {
pkgs = iprog.InitialPackages()
}
var hadErrors bool
for _, pkg := range pkgs {
if pkg == template {
continue
}
for _, file := range pkg.Files {
n := xform.Transform(&pkg.Info, pkg.Pkg, file)
if n == 0 {
continue
}
filename := iprog.Fset.File(file.Pos()).Name()
fmt.Fprintf(os.Stderr, "=== %s (%d matches)\n", filename, n)
if *writeFlag {
// Run the before-edit command (e.g. "chmod +w", "checkout") if any.
if *beforeeditFlag != "" {
args := strings.Fields(*beforeeditFlag)
// Replace "{}" with the filename, like find(1).
for i := range args {
if i > 0 {
args[i] = strings.Replace(args[i], "{}", filename, -1)
}
}
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Warning: edit hook %q failed (%s)\n",
args, err)
}
}
if err := eg.WriteAST(iprog.Fset, filename, file); err != nil {
fmt.Fprintf(os.Stderr, "eg: %s\n", err)
hadErrors = true
}
} else {
printer.Fprint(os.Stdout, iprog.Fset, file)
}
}
}
if hadErrors {
os.Exit(1)
}
return nil
}
@@ -0,0 +1,69 @@
// Copyright 2014 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.
// The godex command prints (dumps) exported information of packages
// or selected package objects.
//
// In contrast to godoc, godex extracts this information from compiled
// object files. Hence the exported data is truly what a compiler will
// see, at the cost of missing commentary.
//
// Usage: godex [flags] {path[.name]}
//
// Each argument must be a (possibly partial) package path, optionally
// followed by a dot and the name of a package object:
//
// godex math
// godex math.Sin
// godex math.Sin fmt.Printf
// godex go/types
//
// godex automatically tries all possible package path prefixes if only a
// partial package path is given. For instance, for the path "go/types",
// godex prepends "golang.org/x/tools".
//
// The prefixes are computed by searching the directories specified by
// the GOROOT and GOPATH environment variables (and by excluding the
// build OS- and architecture-specific directory names from the path).
// The search order is depth-first and alphabetic; for a partial path
// "foo", a package "a/foo" is found before "b/foo".
//
// Absolute and relative paths may be provided, which disable automatic
// prefix generation:
//
// godex $GOROOT/pkg/darwin_amd64/sort
// godex ./sort
//
// All but the last path element may contain dots; a dot in the last path
// element separates the package path from the package object name. If the
// last path element contains a dot, terminate the argument with another
// dot (indicating an empty object name). For instance, the path for a
// package foo.bar would be specified as in:
//
// godex foo.bar.
//
// The flags are:
//
// -s=""
// only consider packages from src, where src is one of the supported compilers
// -v=false
// verbose mode
//
// The following sources (-s arguments) are supported:
//
// gc
// gc-generated object files
// gccgo
// gccgo-generated object files
// gccgo-new
// gccgo-generated object files using a condensed format (experimental)
// source
// (uncompiled) source code (not yet implemented)
//
// If no -s argument is provided, godex will try to find a matching source.
//
package main // import "golang.org/x/tools/cmd/godex"
// BUG(gri): support for -s=source is not yet implemented
// BUG(gri): gccgo-importing appears to have occasional problems stalling godex; try -s=gc as work-around
@@ -0,0 +1,15 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements access to gc-generated export data.
package main
import (
"golang.org/x/tools/go/gcimporter"
)
func init() {
register("gc", gcimporter.Import)
}
@@ -0,0 +1,40 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements access to gccgo-generated export data.
package main
import (
"golang.org/x/tools/go/gccgoimporter"
"golang.org/x/tools/go/types"
)
var (
initmap = make(map[*types.Package]gccgoimporter.InitData)
)
func init() {
incpaths := []string{"/"}
// importer for default gccgo
var inst gccgoimporter.GccgoInstallation
inst.InitFromDriver("gccgo")
register("gccgo", inst.GetImporter(incpaths, initmap))
}
// Print the extra gccgo compiler data for this package, if it exists.
func (p *printer) printGccgoExtra(pkg *types.Package) {
if initdata, ok := initmap[pkg]; ok {
p.printf("/*\npriority %d\n", initdata.Priority)
p.printDecl("init", len(initdata.Inits), func() {
for _, init := range initdata.Inits {
p.printf("%s %s %d\n", init.Name, init.InitFunc, init.Priority)
}
})
p.print("*/\n")
}
}
@@ -0,0 +1,207 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"errors"
"flag"
"fmt"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"strings"
"golang.org/x/tools/go/types"
)
var (
source = flag.String("s", "", "only consider packages from src, where src is one of the supported compilers")
verbose = flag.Bool("v", false, "verbose mode")
)
// lists of registered sources and corresponding importers
var (
sources []string
importers []types.Importer
importFailed = errors.New("import failed")
)
// map of imported packages
var packages = make(map[string]*types.Package)
func usage() {
fmt.Fprintln(os.Stderr, "usage: godex [flags] {path|qualifiedIdent}")
flag.PrintDefaults()
os.Exit(2)
}
func report(msg string) {
fmt.Fprintln(os.Stderr, "error: "+msg)
os.Exit(2)
}
func main() {
flag.Usage = usage
flag.Parse()
if flag.NArg() == 0 {
report("no package name, path, or file provided")
}
imp := tryImports
if *source != "" {
imp = lookup(*source)
if imp == nil {
report("source (-s argument) must be one of: " + strings.Join(sources, ", "))
}
}
for _, arg := range flag.Args() {
path, name := splitPathIdent(arg)
logf("\tprocessing %q: path = %q, name = %s\n", arg, path, name)
// generate possible package path prefixes
// (at the moment we do this for each argument - should probably cache the generated prefixes)
prefixes := make(chan string)
go genPrefixes(prefixes, !filepath.IsAbs(path) && !build.IsLocalImport(path))
// import package
pkg, err := tryPrefixes(packages, prefixes, path, imp)
if err != nil {
logf("\t=> ignoring %q: %s\n", path, err)
continue
}
// filter objects if needed
var filter func(types.Object) bool
if name != "" {
filter = func(obj types.Object) bool {
// TODO(gri) perhaps use regular expression matching here?
return obj.Name() == name
}
}
// print contents
print(os.Stdout, pkg, filter)
}
}
func logf(format string, args ...interface{}) {
if *verbose {
fmt.Fprintf(os.Stderr, format, args...)
}
}
// splitPathIdent splits a path.name argument into its components.
// All but the last path element may contain dots.
func splitPathIdent(arg string) (path, name string) {
if i := strings.LastIndex(arg, "."); i >= 0 {
if j := strings.LastIndex(arg, "/"); j < i {
// '.' is not part of path
path = arg[:i]
name = arg[i+1:]
return
}
}
path = arg
return
}
// tryPrefixes tries to import the package given by (the possibly partial) path using the given importer imp
// by prepending all possible prefixes to path. It returns with the first package that it could import, or
// with an error.
func tryPrefixes(packages map[string]*types.Package, prefixes chan string, path string, imp types.Importer) (pkg *types.Package, err error) {
for prefix := range prefixes {
actual := path
if prefix == "" {
// don't use filepath.Join as it will sanitize the path and remove
// a leading dot and then the path is not recognized as a relative
// package path by the importers anymore
logf("\ttrying no prefix\n")
} else {
actual = filepath.Join(prefix, path)
logf("\ttrying prefix %q\n", prefix)
}
pkg, err = imp(packages, actual)
if err == nil {
break
}
logf("\t=> importing %q failed: %s\n", actual, err)
}
return
}
// tryImports is an importer that tries all registered importers
// successively until one of them succeeds or all of them failed.
func tryImports(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
for i, imp := range importers {
logf("\t\ttrying %s import\n", sources[i])
pkg, err = imp(packages, path)
if err == nil {
break
}
logf("\t\t=> %s import failed: %s\n", sources[i], err)
}
return
}
// protect protects an importer imp from panics and returns the protected importer.
func protect(imp types.Importer) types.Importer {
return func(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
defer func() {
if recover() != nil {
pkg = nil
err = importFailed
}
}()
return imp(packages, path)
}
}
// register registers an importer imp for a given source src.
func register(src string, imp types.Importer) {
if lookup(src) != nil {
panic(src + " importer already registered")
}
sources = append(sources, src)
importers = append(importers, protect(imp))
}
// lookup returns the importer imp for a given source src.
func lookup(src string) types.Importer {
for i, s := range sources {
if s == src {
return importers[i]
}
}
return nil
}
func genPrefixes(out chan string, all bool) {
out <- ""
if all {
platform := build.Default.GOOS + "_" + build.Default.GOARCH
dirnames := append([]string{build.Default.GOROOT}, filepath.SplitList(build.Default.GOPATH)...)
for _, dirname := range dirnames {
walkDir(filepath.Join(dirname, "pkg", platform), "", out)
}
}
close(out)
}
func walkDir(dirname, prefix string, out chan string) {
fiList, err := ioutil.ReadDir(dirname)
if err != nil {
return
}
for _, fi := range fiList {
if fi.IsDir() && !strings.HasPrefix(fi.Name(), ".") {
prefix := filepath.Join(prefix, fi.Name())
out <- prefix
walkDir(filepath.Join(dirname, fi.Name()), prefix, out)
}
}
}
@@ -0,0 +1,368 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"fmt"
"go/token"
"io"
"math/big"
"golang.org/x/tools/go/exact"
"golang.org/x/tools/go/types"
)
// TODO(gri) use tabwriter for alignment?
func print(w io.Writer, pkg *types.Package, filter func(types.Object) bool) {
var p printer
p.pkg = pkg
p.printPackage(pkg, filter)
p.printGccgoExtra(pkg)
io.Copy(w, &p.buf)
}
type printer struct {
pkg *types.Package
buf bytes.Buffer
indent int // current indentation level
last byte // last byte written
}
func (p *printer) print(s string) {
// Write the string one byte at a time. We care about the presence of
// newlines for indentation which we will see even in the presence of
// (non-corrupted) Unicode; no need to read one rune at a time.
for i := 0; i < len(s); i++ {
ch := s[i]
if ch != '\n' && p.last == '\n' {
// Note: This could lead to a range overflow for very large
// indentations, but it's extremely unlikely to happen for
// non-pathological code.
p.buf.WriteString("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"[:p.indent])
}
p.buf.WriteByte(ch)
p.last = ch
}
}
func (p *printer) printf(format string, args ...interface{}) {
p.print(fmt.Sprintf(format, args...))
}
// methodsFor returns the named type and corresponding methods if the type
// denoted by obj is not an interface and has methods. Otherwise it returns
// the zero value.
func methodsFor(obj *types.TypeName) (*types.Named, []*types.Selection) {
named, _ := obj.Type().(*types.Named)
if named == nil {
// A type name's type can also be the
// exported basic type unsafe.Pointer.
return nil, nil
}
if _, ok := named.Underlying().(*types.Interface); ok {
// ignore interfaces
return nil, nil
}
methods := combinedMethodSet(named)
if len(methods) == 0 {
return nil, nil
}
return named, methods
}
func (p *printer) printPackage(pkg *types.Package, filter func(types.Object) bool) {
// collect objects by kind
var (
consts []*types.Const
typem []*types.Named // non-interface types with methods
typez []*types.TypeName // interfaces or types without methods
vars []*types.Var
funcs []*types.Func
builtins []*types.Builtin
methods = make(map[*types.Named][]*types.Selection) // method sets for named types
)
scope := pkg.Scope()
for _, name := range scope.Names() {
obj := scope.Lookup(name)
if obj.Exported() {
// collect top-level exported and possibly filtered objects
if filter == nil || filter(obj) {
switch obj := obj.(type) {
case *types.Const:
consts = append(consts, obj)
case *types.TypeName:
// group into types with methods and types without
if named, m := methodsFor(obj); named != nil {
typem = append(typem, named)
methods[named] = m
} else {
typez = append(typez, obj)
}
case *types.Var:
vars = append(vars, obj)
case *types.Func:
funcs = append(funcs, obj)
case *types.Builtin:
// for unsafe.Sizeof, etc.
builtins = append(builtins, obj)
}
}
} else if filter == nil {
// no filtering: collect top-level unexported types with methods
if obj, _ := obj.(*types.TypeName); obj != nil {
// see case *types.TypeName above
if named, m := methodsFor(obj); named != nil {
typem = append(typem, named)
methods[named] = m
}
}
}
}
p.printf("package %s // %q\n", pkg.Name(), pkg.Path())
p.printDecl("const", len(consts), func() {
for _, obj := range consts {
p.printObj(obj)
p.print("\n")
}
})
p.printDecl("var", len(vars), func() {
for _, obj := range vars {
p.printObj(obj)
p.print("\n")
}
})
p.printDecl("type", len(typez), func() {
for _, obj := range typez {
p.printf("%s ", obj.Name())
p.writeType(p.pkg, obj.Type().Underlying())
p.print("\n")
}
})
// non-interface types with methods
for _, named := range typem {
first := true
if obj := named.Obj(); obj.Exported() {
if first {
p.print("\n")
first = false
}
p.printf("type %s ", obj.Name())
p.writeType(p.pkg, named.Underlying())
p.print("\n")
}
for _, m := range methods[named] {
if obj := m.Obj(); obj.Exported() {
if first {
p.print("\n")
first = false
}
p.printFunc(m.Recv(), obj.(*types.Func))
p.print("\n")
}
}
}
if len(funcs) > 0 {
p.print("\n")
for _, obj := range funcs {
p.printFunc(nil, obj)
p.print("\n")
}
}
// TODO(gri) better handling of builtins (package unsafe only)
if len(builtins) > 0 {
p.print("\n")
for _, obj := range builtins {
p.printf("func %s() // builtin\n", obj.Name())
}
}
p.print("\n")
}
func (p *printer) printDecl(keyword string, n int, printGroup func()) {
switch n {
case 0:
// nothing to do
case 1:
p.printf("\n%s ", keyword)
printGroup()
default:
p.printf("\n%s (\n", keyword)
p.indent++
printGroup()
p.indent--
p.print(")\n")
}
}
// absInt returns the absolute value of v as a *big.Int.
// v must be a numeric value.
func absInt(v exact.Value) *big.Int {
// compute big-endian representation of v
b := exact.Bytes(v) // little-endian
for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
b[i], b[j] = b[j], b[i]
}
return new(big.Int).SetBytes(b)
}
var (
one = big.NewRat(1, 1)
ten = big.NewRat(10, 1)
)
// floatString returns the string representation for a
// numeric value v in normalized floating-point format.
func floatString(v exact.Value) string {
if exact.Sign(v) == 0 {
return "0.0"
}
// x != 0
// convert |v| into a big.Rat x
x := new(big.Rat).SetFrac(absInt(exact.Num(v)), absInt(exact.Denom(v)))
// normalize x and determine exponent e
// (This is not very efficient, but also not speed-critical.)
var e int
for x.Cmp(ten) >= 0 {
x.Quo(x, ten)
e++
}
for x.Cmp(one) < 0 {
x.Mul(x, ten)
e--
}
// TODO(gri) Values such as 1/2 are easier to read in form 0.5
// rather than 5.0e-1. Similarly, 1.0e1 is easier to read as
// 10.0. Fine-tune best exponent range for readability.
s := x.FloatString(100) // good-enough precision
// trim trailing 0's
i := len(s)
for i > 0 && s[i-1] == '0' {
i--
}
s = s[:i]
// add a 0 if the number ends in decimal point
if len(s) > 0 && s[len(s)-1] == '.' {
s += "0"
}
// add exponent and sign
if e != 0 {
s += fmt.Sprintf("e%+d", e)
}
if exact.Sign(v) < 0 {
s = "-" + s
}
// TODO(gri) If v is a "small" fraction (i.e., numerator and denominator
// are just a small number of decimal digits), add the exact fraction as
// a comment. For instance: 3.3333...e-1 /* = 1/3 */
return s
}
// valString returns the string representation for the value v.
// Setting floatFmt forces an integer value to be formatted in
// normalized floating-point format.
// TODO(gri) Move this code into package exact.
func valString(v exact.Value, floatFmt bool) string {
switch v.Kind() {
case exact.Int:
if floatFmt {
return floatString(v)
}
case exact.Float:
return floatString(v)
case exact.Complex:
re := exact.Real(v)
im := exact.Imag(v)
var s string
if exact.Sign(re) != 0 {
s = floatString(re)
if exact.Sign(im) >= 0 {
s += " + "
} else {
s += " - "
im = exact.UnaryOp(token.SUB, im, 0) // negate im
}
}
// im != 0, otherwise v would be exact.Int or exact.Float
return s + floatString(im) + "i"
}
return v.String()
}
func (p *printer) printObj(obj types.Object) {
p.print(obj.Name())
typ, basic := obj.Type().Underlying().(*types.Basic)
if basic && typ.Info()&types.IsUntyped != 0 {
// don't write untyped types
} else {
p.print(" ")
p.writeType(p.pkg, obj.Type())
}
if obj, ok := obj.(*types.Const); ok {
floatFmt := basic && typ.Info()&(types.IsFloat|types.IsComplex) != 0
p.print(" = ")
p.print(valString(obj.Val(), floatFmt))
}
}
func (p *printer) printFunc(recvType types.Type, obj *types.Func) {
p.print("func ")
sig := obj.Type().(*types.Signature)
if recvType != nil {
p.print("(")
p.writeType(p.pkg, recvType)
p.print(") ")
}
p.print(obj.Name())
p.writeSignature(p.pkg, sig)
}
// combinedMethodSet returns the method set for a named type T
// merged with all the methods of *T that have different names than
// the methods of T.
//
// combinedMethodSet is analogous to types/typeutil.IntuitiveMethodSet
// but doesn't require a MethodSetCache.
// TODO(gri) If this functionality doesn't change over time, consider
// just calling IntuitiveMethodSet eventually.
func combinedMethodSet(T *types.Named) []*types.Selection {
// method set for T
mset := types.NewMethodSet(T)
var res []*types.Selection
for i, n := 0, mset.Len(); i < n; i++ {
res = append(res, mset.At(i))
}
// add all *T methods with names different from T methods
pmset := types.NewMethodSet(types.NewPointer(T))
for i, n := 0, pmset.Len(); i < n; i++ {
pm := pmset.At(i)
if obj := pm.Obj(); mset.Lookup(obj.Pkg(), obj.Name()) == nil {
res = append(res, pm)
}
}
return res
}
@@ -0,0 +1,19 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements access to export data from source.
package main
import (
"golang.org/x/tools/go/types"
)
func init() {
register("source", sourceImporter)
}
func sourceImporter(packages map[string]*types.Package, path string) (*types.Package, error) {
panic("unimplemented")
}
@@ -0,0 +1,242 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements writing of types. The functionality is lifted
// directly from go/types, but now contains various modifications for
// nicer output.
//
// TODO(gri) back-port once we have a fixed interface and once the
// go/types API is not frozen anymore for the 1.3 release; and remove
// this implementation if possible.
package main
import "golang.org/x/tools/go/types"
func (p *printer) writeType(this *types.Package, typ types.Type) {
p.writeTypeInternal(this, typ, make([]types.Type, 8))
}
// From go/types - leave for now to ease back-porting this code.
const GcCompatibilityMode = false
func (p *printer) writeTypeInternal(this *types.Package, typ types.Type, visited []types.Type) {
// Theoretically, this is a quadratic lookup algorithm, but in
// practice deeply nested composite types with unnamed component
// types are uncommon. This code is likely more efficient than
// using a map.
for _, t := range visited {
if t == typ {
p.printf("○%T", typ) // cycle to typ
return
}
}
visited = append(visited, typ)
switch t := typ.(type) {
case nil:
p.print("<nil>")
case *types.Basic:
if t.Kind() == types.UnsafePointer {
p.print("unsafe.")
}
if GcCompatibilityMode {
// forget the alias names
switch t.Kind() {
case types.Byte:
t = types.Typ[types.Uint8]
case types.Rune:
t = types.Typ[types.Int32]
}
}
p.print(t.Name())
case *types.Array:
p.printf("[%d]", t.Len())
p.writeTypeInternal(this, t.Elem(), visited)
case *types.Slice:
p.print("[]")
p.writeTypeInternal(this, t.Elem(), visited)
case *types.Struct:
n := t.NumFields()
if n == 0 {
p.print("struct{}")
return
}
p.print("struct {\n")
p.indent++
for i := 0; i < n; i++ {
f := t.Field(i)
if !f.Anonymous() {
p.printf("%s ", f.Name())
}
p.writeTypeInternal(this, f.Type(), visited)
if tag := t.Tag(i); tag != "" {
p.printf(" %q", tag)
}
p.print("\n")
}
p.indent--
p.print("}")
case *types.Pointer:
p.print("*")
p.writeTypeInternal(this, t.Elem(), visited)
case *types.Tuple:
p.writeTuple(this, t, false, visited)
case *types.Signature:
p.print("func")
p.writeSignatureInternal(this, t, visited)
case *types.Interface:
// We write the source-level methods and embedded types rather
// than the actual method set since resolved method signatures
// may have non-printable cycles if parameters have anonymous
// interface types that (directly or indirectly) embed the
// current interface. For instance, consider the result type
// of m:
//
// type T interface{
// m() interface{ T }
// }
//
n := t.NumMethods()
if n == 0 {
p.print("interface{}")
return
}
p.print("interface {\n")
p.indent++
if GcCompatibilityMode {
// print flattened interface
// (useful to compare against gc-generated interfaces)
for i := 0; i < n; i++ {
m := t.Method(i)
p.print(m.Name())
p.writeSignatureInternal(this, m.Type().(*types.Signature), visited)
p.print("\n")
}
} else {
// print explicit interface methods and embedded types
for i, n := 0, t.NumExplicitMethods(); i < n; i++ {
m := t.ExplicitMethod(i)
p.print(m.Name())
p.writeSignatureInternal(this, m.Type().(*types.Signature), visited)
p.print("\n")
}
for i, n := 0, t.NumEmbeddeds(); i < n; i++ {
typ := t.Embedded(i)
p.writeTypeInternal(this, typ, visited)
p.print("\n")
}
}
p.indent--
p.print("}")
case *types.Map:
p.print("map[")
p.writeTypeInternal(this, t.Key(), visited)
p.print("]")
p.writeTypeInternal(this, t.Elem(), visited)
case *types.Chan:
var s string
var parens bool
switch t.Dir() {
case types.SendRecv:
s = "chan "
// chan (<-chan T) requires parentheses
if c, _ := t.Elem().(*types.Chan); c != nil && c.Dir() == types.RecvOnly {
parens = true
}
case types.SendOnly:
s = "chan<- "
case types.RecvOnly:
s = "<-chan "
default:
panic("unreachable")
}
p.print(s)
if parens {
p.print("(")
}
p.writeTypeInternal(this, t.Elem(), visited)
if parens {
p.print(")")
}
case *types.Named:
s := "<Named w/o object>"
if obj := t.Obj(); obj != nil {
if pkg := obj.Pkg(); pkg != nil {
if pkg != this {
p.print(pkg.Path())
p.print(".")
}
// TODO(gri): function-local named types should be displayed
// differently from named types at package level to avoid
// ambiguity.
}
s = obj.Name()
}
p.print(s)
default:
// For externally defined implementations of Type.
p.print(t.String())
}
}
func (p *printer) writeTuple(this *types.Package, tup *types.Tuple, variadic bool, visited []types.Type) {
p.print("(")
for i, n := 0, tup.Len(); i < n; i++ {
if i > 0 {
p.print(", ")
}
v := tup.At(i)
if name := v.Name(); name != "" {
p.print(name)
p.print(" ")
}
typ := v.Type()
if variadic && i == n-1 {
p.print("...")
typ = typ.(*types.Slice).Elem()
}
p.writeTypeInternal(this, typ, visited)
}
p.print(")")
}
func (p *printer) writeSignature(this *types.Package, sig *types.Signature) {
p.writeSignatureInternal(this, sig, make([]types.Type, 8))
}
func (p *printer) writeSignatureInternal(this *types.Package, sig *types.Signature, visited []types.Type) {
p.writeTuple(this, sig.Params(), sig.Variadic(), visited)
res := sig.Results()
n := res.Len()
if n == 0 {
// no result
return
}
p.print(" ")
if n == 1 && res.At(0).Name() == "" {
// single unnamed result
p.writeTypeInternal(this, res.At(0).Type(), visited)
return
}
// multiple or named result(s)
p.writeTuple(this, res, false, visited)
}
@@ -0,0 +1,56 @@
godoc on appengine
------------------
Prerequisites
-------------
* Go appengine SDK
https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Go
* Go sources at tip under $GOROOT
* Godoc sources at tip inside $GOPATH
(go get -d golang.org/x/tools/cmd/godoc)
Directory structure
-------------------
* Let $APPDIR be the directory containing the app engine files.
(e.g., $APPDIR=$HOME/godoc-app)
* $APPDIR contains the following entries (this may change depending on
app-engine release and version of godoc):
app.yaml
golang.org/x/tools/cmd/godoc
godoc.zip
index.split.*
* The app.yaml file is set up per app engine documentation.
For instance:
application: godoc-app
version: 1
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
Configuring and running godoc
-----------------------------
To configure godoc, run
bash setup-godoc-app.bash
to prepare an $APPDIR as described above. See the script for details on usage.
To run godoc locally, using the App Engine development server, run
<path to go_appengine>/dev_appserver.py $APPDIR
godoc should come up at http://localhost:8080 .
@@ -0,0 +1,66 @@
// 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.
// +build appengine
package main
// This file replaces main.go when running godoc under app-engine.
// See README.godoc-app for details.
import (
"archive/zip"
"log"
"path"
"regexp"
"golang.org/x/tools/godoc"
"golang.org/x/tools/godoc/static"
"golang.org/x/tools/godoc/vfs"
"golang.org/x/tools/godoc/vfs/mapfs"
"golang.org/x/tools/godoc/vfs/zipfs"
)
func init() {
playEnabled = true
log.Println("initializing godoc ...")
log.Printf(".zip file = %s", zipFilename)
log.Printf(".zip GOROOT = %s", zipGoroot)
log.Printf("index files = %s", indexFilenames)
goroot := path.Join("/", zipGoroot) // fsHttp paths are relative to '/'
// read .zip file and set up file systems
const zipfile = zipFilename
rc, err := zip.OpenReader(zipfile)
if err != nil {
log.Fatalf("%s: %s\n", zipfile, err)
}
// rc is never closed (app running forever)
fs.Bind("/", zipfs.New(rc, zipFilename), goroot, vfs.BindReplace)
fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)
corpus := godoc.NewCorpus(fs)
corpus.Verbose = false
corpus.MaxResults = 10000 // matches flag default in main.go
corpus.IndexEnabled = true
corpus.IndexFiles = indexFilenames
if err := corpus.Init(); err != nil {
log.Fatal(err)
}
go corpus.RunIndexer()
pres = godoc.NewPresentation(corpus)
pres.TabWidth = 8
pres.ShowPlayground = true
pres.ShowExamples = true
pres.DeclLinks = true
pres.NotesRx = regexp.MustCompile("BUG")
readTemplates(pres, true)
registerHandlers(pres)
log.Println("godoc initialization complete")
}
@@ -0,0 +1,81 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"go/build"
"log"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"golang.org/x/tools/blog"
"golang.org/x/tools/godoc/redirect"
)
const (
blogRepo = "golang.org/x/blog"
blogURL = "http://blog.golang.org/"
blogPath = "/blog/"
)
var (
blogServer http.Handler // set by blogInit
blogInitOnce sync.Once
playEnabled bool
)
func init() {
// Initialize blog only when first accessed.
http.HandleFunc(blogPath, func(w http.ResponseWriter, r *http.Request) {
blogInitOnce.Do(blogInit)
blogServer.ServeHTTP(w, r)
})
}
func blogInit() {
// Binary distributions will include the blog content in "/blog".
root := filepath.Join(runtime.GOROOT(), "blog")
// Prefer content from go.blog repository if present.
if pkg, err := build.Import(blogRepo, "", build.FindOnly); err == nil {
root = pkg.Dir
}
// If content is not available fall back to redirect.
if fi, err := os.Stat(root); err != nil || !fi.IsDir() {
fmt.Fprintf(os.Stderr, "Blog content not available locally. "+
"To install, run \n\tgo get %v\n", blogRepo)
blogServer = http.HandlerFunc(blogRedirectHandler)
return
}
s, err := blog.NewServer(blog.Config{
BaseURL: blogPath,
BasePath: strings.TrimSuffix(blogPath, "/"),
ContentPath: filepath.Join(root, "content"),
TemplatePath: filepath.Join(root, "template"),
HomeArticles: 5,
PlayEnabled: playEnabled,
})
if err != nil {
log.Fatal(err)
}
blogServer = s
}
func blogRedirectHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == blogPath {
http.Redirect(w, r, blogURL, http.StatusFound)
return
}
blogPrefixHandler.ServeHTTP(w, r)
}
var blogPrefixHandler = redirect.PrefixHandler(blogPath, blogURL)
@@ -0,0 +1,523 @@
// Copyright 2010 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.
// The /doc/codewalk/ tree is synthesized from codewalk descriptions,
// files named $GOROOT/doc/codewalk/*.xml.
// For an example and a description of the format, see
// http://golang.org/doc/codewalk/codewalk or run godoc -http=:6060
// and see http://localhost:6060/doc/codewalk/codewalk .
// That page is itself a codewalk; the source code for it is
// $GOROOT/doc/codewalk/codewalk.xml.
package main
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"io"
"log"
"net/http"
"os"
pathpkg "path"
"regexp"
"sort"
"strconv"
"strings"
"text/template"
"unicode/utf8"
"golang.org/x/tools/godoc"
"golang.org/x/tools/godoc/vfs"
)
var codewalkHTML, codewalkdirHTML *template.Template
// Handler for /doc/codewalk/ and below.
func codewalk(w http.ResponseWriter, r *http.Request) {
relpath := r.URL.Path[len("/doc/codewalk/"):]
abspath := r.URL.Path
r.ParseForm()
if f := r.FormValue("fileprint"); f != "" {
codewalkFileprint(w, r, f)
return
}
// If directory exists, serve list of code walks.
dir, err := fs.Lstat(abspath)
if err == nil && dir.IsDir() {
codewalkDir(w, r, relpath, abspath)
return
}
// If file exists, serve using standard file server.
if err == nil {
pres.ServeFile(w, r)
return
}
// Otherwise append .xml and hope to find
// a codewalk description, but before trim
// the trailing /.
abspath = strings.TrimRight(abspath, "/")
cw, err := loadCodewalk(abspath + ".xml")
if err != nil {
log.Print(err)
pres.ServeError(w, r, relpath, err)
return
}
// Canonicalize the path and redirect if changed
if redir(w, r) {
return
}
pres.ServePage(w, godoc.Page{
Title: "Codewalk: " + cw.Title,
Tabtitle: cw.Title,
Body: applyTemplate(codewalkHTML, "codewalk", cw),
})
}
func redir(w http.ResponseWriter, r *http.Request) (redirected bool) {
canonical := pathpkg.Clean(r.URL.Path)
if !strings.HasSuffix(canonical, "/") {
canonical += "/"
}
if r.URL.Path != canonical {
url := *r.URL
url.Path = canonical
http.Redirect(w, r, url.String(), http.StatusMovedPermanently)
redirected = true
}
return
}
func applyTemplate(t *template.Template, name string, data interface{}) []byte {
var buf bytes.Buffer
if err := t.Execute(&buf, data); err != nil {
log.Printf("%s.Execute: %s", name, err)
}
return buf.Bytes()
}
// A Codewalk represents a single codewalk read from an XML file.
type Codewalk struct {
Title string `xml:"title,attr"`
File []string `xml:"file"`
Step []*Codestep `xml:"step"`
}
// A Codestep is a single step in a codewalk.
type Codestep struct {
// Filled in from XML
Src string `xml:"src,attr"`
Title string `xml:"title,attr"`
XML string `xml:",innerxml"`
// Derived from Src; not in XML.
Err error
File string
Lo int
LoByte int
Hi int
HiByte int
Data []byte
}
// String method for printing in template.
// Formats file address nicely.
func (st *Codestep) String() string {
s := st.File
if st.Lo != 0 || st.Hi != 0 {
s += fmt.Sprintf(":%d", st.Lo)
if st.Lo != st.Hi {
s += fmt.Sprintf(",%d", st.Hi)
}
}
return s
}
// loadCodewalk reads a codewalk from the named XML file.
func loadCodewalk(filename string) (*Codewalk, error) {
f, err := fs.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
cw := new(Codewalk)
d := xml.NewDecoder(f)
d.Entity = xml.HTMLEntity
err = d.Decode(cw)
if err != nil {
return nil, &os.PathError{Op: "parsing", Path: filename, Err: err}
}
// Compute file list, evaluate line numbers for addresses.
m := make(map[string]bool)
for _, st := range cw.Step {
i := strings.Index(st.Src, ":")
if i < 0 {
i = len(st.Src)
}
filename := st.Src[0:i]
data, err := vfs.ReadFile(fs, filename)
if err != nil {
st.Err = err
continue
}
if i < len(st.Src) {
lo, hi, err := addrToByteRange(st.Src[i+1:], 0, data)
if err != nil {
st.Err = err
continue
}
// Expand match to line boundaries.
for lo > 0 && data[lo-1] != '\n' {
lo--
}
for hi < len(data) && (hi == 0 || data[hi-1] != '\n') {
hi++
}
st.Lo = byteToLine(data, lo)
st.Hi = byteToLine(data, hi-1)
}
st.Data = data
st.File = filename
m[filename] = true
}
// Make list of files
cw.File = make([]string, len(m))
i := 0
for f := range m {
cw.File[i] = f
i++
}
sort.Strings(cw.File)
return cw, nil
}
// codewalkDir serves the codewalk directory listing.
// It scans the directory for subdirectories or files named *.xml
// and prepares a table.
func codewalkDir(w http.ResponseWriter, r *http.Request, relpath, abspath string) {
type elem struct {
Name string
Title string
}
dir, err := fs.ReadDir(abspath)
if err != nil {
log.Print(err)
pres.ServeError(w, r, relpath, err)
return
}
var v []interface{}
for _, fi := range dir {
name := fi.Name()
if fi.IsDir() {
v = append(v, &elem{name + "/", ""})
} else if strings.HasSuffix(name, ".xml") {
cw, err := loadCodewalk(abspath + "/" + name)
if err != nil {
continue
}
v = append(v, &elem{name[0 : len(name)-len(".xml")], cw.Title})
}
}
pres.ServePage(w, godoc.Page{
Title: "Codewalks",
Body: applyTemplate(codewalkdirHTML, "codewalkdir", v),
})
}
// codewalkFileprint serves requests with ?fileprint=f&lo=lo&hi=hi.
// The filename f has already been retrieved and is passed as an argument.
// Lo and hi are the numbers of the first and last line to highlight
// in the response. This format is used for the middle window pane
// of the codewalk pages. It is a separate iframe and does not get
// the usual godoc HTML wrapper.
func codewalkFileprint(w http.ResponseWriter, r *http.Request, f string) {
abspath := f
data, err := vfs.ReadFile(fs, abspath)
if err != nil {
log.Print(err)
pres.ServeError(w, r, f, err)
return
}
lo, _ := strconv.Atoi(r.FormValue("lo"))
hi, _ := strconv.Atoi(r.FormValue("hi"))
if hi < lo {
hi = lo
}
lo = lineToByte(data, lo)
hi = lineToByte(data, hi+1)
// Put the mark 4 lines before lo, so that the iframe
// shows a few lines of context before the highlighted
// section.
n := 4
mark := lo
for ; mark > 0 && n > 0; mark-- {
if data[mark-1] == '\n' {
if n--; n == 0 {
break
}
}
}
io.WriteString(w, `<style type="text/css">@import "/doc/codewalk/codewalk.css";</style><pre>`)
template.HTMLEscape(w, data[0:mark])
io.WriteString(w, "<a name='mark'></a>")
template.HTMLEscape(w, data[mark:lo])
if lo < hi {
io.WriteString(w, "<div class='codewalkhighlight'>")
template.HTMLEscape(w, data[lo:hi])
io.WriteString(w, "</div>")
}
template.HTMLEscape(w, data[hi:])
io.WriteString(w, "</pre>")
}
// addrToByte evaluates the given address starting at offset start in data.
// It returns the lo and hi byte offset of the matched region within data.
// See http://plan9.bell-labs.com/sys/doc/sam/sam.html Table II
// for details on the syntax.
func addrToByteRange(addr string, start int, data []byte) (lo, hi int, err error) {
var (
dir byte
prevc byte
charOffset bool
)
lo = start
hi = start
for addr != "" && err == nil {
c := addr[0]
switch c {
default:
err = errors.New("invalid address syntax near " + string(c))
case ',':
if len(addr) == 1 {
hi = len(data)
} else {
_, hi, err = addrToByteRange(addr[1:], hi, data)
}
return
case '+', '-':
if prevc == '+' || prevc == '-' {
lo, hi, err = addrNumber(data, lo, hi, prevc, 1, charOffset)
}
dir = c
case '$':
lo = len(data)
hi = len(data)
if len(addr) > 1 {
dir = '+'
}
case '#':
charOffset = true
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
var i int
for i = 1; i < len(addr); i++ {
if addr[i] < '0' || addr[i] > '9' {
break
}
}
var n int
n, err = strconv.Atoi(addr[0:i])
if err != nil {
break
}
lo, hi, err = addrNumber(data, lo, hi, dir, n, charOffset)
dir = 0
charOffset = false
prevc = c
addr = addr[i:]
continue
case '/':
var i, j int
Regexp:
for i = 1; i < len(addr); i++ {
switch addr[i] {
case '\\':
i++
case '/':
j = i + 1
break Regexp
}
}
if j == 0 {
j = i
}
pattern := addr[1:i]
lo, hi, err = addrRegexp(data, lo, hi, dir, pattern)
prevc = c
addr = addr[j:]
continue
}
prevc = c
addr = addr[1:]
}
if err == nil && dir != 0 {
lo, hi, err = addrNumber(data, lo, hi, dir, 1, charOffset)
}
if err != nil {
return 0, 0, err
}
return lo, hi, nil
}
// addrNumber applies the given dir, n, and charOffset to the address lo, hi.
// dir is '+' or '-', n is the count, and charOffset is true if the syntax
// used was #n. Applying +n (or +#n) means to advance n lines
// (or characters) after hi. Applying -n (or -#n) means to back up n lines
// (or characters) before lo.
// The return value is the new lo, hi.
func addrNumber(data []byte, lo, hi int, dir byte, n int, charOffset bool) (int, int, error) {
switch dir {
case 0:
lo = 0
hi = 0
fallthrough
case '+':
if charOffset {
pos := hi
for ; n > 0 && pos < len(data); n-- {
_, size := utf8.DecodeRune(data[pos:])
pos += size
}
if n == 0 {
return pos, pos, nil
}
break
}
// find next beginning of line
if hi > 0 {
for hi < len(data) && data[hi-1] != '\n' {
hi++
}
}
lo = hi
if n == 0 {
return lo, hi, nil
}
for ; hi < len(data); hi++ {
if data[hi] != '\n' {
continue
}
switch n--; n {
case 1:
lo = hi + 1
case 0:
return lo, hi + 1, nil
}
}
case '-':
if charOffset {
// Scan backward for bytes that are not UTF-8 continuation bytes.
pos := lo
for ; pos > 0 && n > 0; pos-- {
if data[pos]&0xc0 != 0x80 {
n--
}
}
if n == 0 {
return pos, pos, nil
}
break
}
// find earlier beginning of line
for lo > 0 && data[lo-1] != '\n' {
lo--
}
hi = lo
if n == 0 {
return lo, hi, nil
}
for ; lo >= 0; lo-- {
if lo > 0 && data[lo-1] != '\n' {
continue
}
switch n--; n {
case 1:
hi = lo
case 0:
return lo, hi, nil
}
}
}
return 0, 0, errors.New("address out of range")
}
// addrRegexp searches for pattern in the given direction starting at lo, hi.
// The direction dir is '+' (search forward from hi) or '-' (search backward from lo).
// Backward searches are unimplemented.
func addrRegexp(data []byte, lo, hi int, dir byte, pattern string) (int, int, error) {
re, err := regexp.Compile(pattern)
if err != nil {
return 0, 0, err
}
if dir == '-' {
// Could implement reverse search using binary search
// through file, but that seems like overkill.
return 0, 0, errors.New("reverse search not implemented")
}
m := re.FindIndex(data[hi:])
if len(m) > 0 {
m[0] += hi
m[1] += hi
} else if hi > 0 {
// No match. Wrap to beginning of data.
m = re.FindIndex(data)
}
if len(m) == 0 {
return 0, 0, errors.New("no match for " + pattern)
}
return m[0], m[1], nil
}
// lineToByte returns the byte index of the first byte of line n.
// Line numbers begin at 1.
func lineToByte(data []byte, n int) int {
if n <= 1 {
return 0
}
n--
for i, c := range data {
if c == '\n' {
if n--; n == 0 {
return i + 1
}
}
}
return len(data)
}
// byteToLine returns the number of the line containing the byte at index i.
func byteToLine(data []byte, i int) int {
l := 1
for j, c := range data {
if j == i {
return l
}
if c == '\n' {
l++
}
}
return l
}
@@ -0,0 +1,14 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "net/http"
// Register a redirect handler for /dl/ to the golang.org download page.
// This file will not be included when deploying godoc to golang.org.
func init() {
http.Handle("/dl/", http.RedirectHandler("http://golang.org/dl/", http.StatusFound))
}
@@ -0,0 +1,146 @@
// Copyright 2009 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.
/*
Godoc extracts and generates documentation for Go programs.
It has two modes.
Without the -http flag, it runs in command-line mode and prints plain text
documentation to standard output and exits. If both a library package and
a command with the same name exists, using the prefix cmd/ will force
documentation on the command rather than the library package. If the -src
flag is specified, godoc prints the exported interface of a package in Go
source form, or the implementation of a specific exported language entity:
godoc fmt # documentation for package fmt
godoc fmt Printf # documentation for fmt.Printf
godoc cmd/go # force documentation for the go command
godoc -src fmt # fmt package interface in Go source form
godoc -src fmt Printf # implementation of fmt.Printf
In command-line mode, the -q flag enables search queries against a godoc running
as a webserver. If no explicit server address is specified with the -server flag,
godoc first tries localhost:6060 and then http://golang.org.
godoc -q Reader
godoc -q math.Sin
godoc -server=:6060 -q sin
With the -http flag, it runs as a web server and presents the documentation as a
web page.
godoc -http=:6060
Usage:
godoc [flag] package [name ...]
The flags are:
-v
verbose mode
-q
arguments are considered search queries: a legal query is a
single identifier (such as ToLower) or a qualified identifier
(such as math.Sin)
-src
print (exported) source in command-line mode
-tabwidth=4
width of tabs in units of spaces
-timestamps=true
show timestamps with directory listings
-index
enable identifier and full text search index
(no search box is shown if -index is not set)
-index_files=""
glob pattern specifying index files; if not empty,
the index is read from these files in sorted order
-index_throttle=0.75
index throttle value; a value of 0 means no time is allocated
to the indexer (the indexer will never finish), a value of 1.0
means that index creation is running at full throttle (other
goroutines may get no time while the index is built)
-links=true:
link identifiers to their declarations
-write_index=false
write index to a file; the file name must be specified with
-index_files
-maxresults=10000
maximum number of full text search results shown
(no full text index is built if maxresults <= 0)
-notes="BUG"
regular expression matching note markers to show
(e.g., "BUG|TODO", ".*")
-html
print HTML in command-line mode
-goroot=$GOROOT
Go root directory
-http=addr
HTTP service address (e.g., '127.0.0.1:6060' or just ':6060')
-server=addr
webserver address for command line searches
-analysis=type,pointer
comma-separated list of analyses to perform
"type": display identifier resolution, type info, method sets,
'implements', and static callees
"pointer" display channel peers, callers and dynamic callees
(significantly slower)
See http://golang.org/lib/godoc/analysis/help.html for details.
-templates=""
directory containing alternate template files; if set,
the directory may provide alternative template files
for the files in $GOROOT/lib/godoc
-url=path
print to standard output the data that would be served by
an HTTP request for path
-zip=""
zip file providing the file system to serve; disabled if empty
By default, godoc looks at the packages it finds via $GOROOT and $GOPATH (if set).
This behavior can be altered by providing an alternative $GOROOT with the -goroot
flag.
When godoc runs as a web server and -index is set, a search index is maintained.
The index is created at startup.
The index contains both identifier and full text search information (searchable
via regular expressions). The maximum number of full text search results shown
can be set with the -maxresults flag; if set to 0, no full text results are
shown, and only an identifier index but no full text search index is created.
The presentation mode of web pages served by godoc can be controlled with the
"m" URL parameter; it accepts a comma-separated list of flag names as value:
all show documentation for all declarations, not just the exported ones
methods show all embedded methods, not just those of unexported anonymous fields
src show the original source code rather then the extracted documentation
text present the page in textual (command-line) form rather than HTML
flat present flat (not indented) directory listings using full paths
For instance, http://golang.org/pkg/math/big/?m=all,text shows the documentation
for all (not just the exported) declarations of package big, in textual form (as
it would appear when using godoc from the command line: "godoc -src math/big .*").
By default, godoc serves files from the file system of the underlying OS.
Instead, a .zip file may be provided via the -zip flag, which contains
the file system to serve. The file paths stored in the .zip file must use
slash ('/') as path separator; and they must be unrooted. $GOROOT (or -goroot)
must be set to the .zip file directory path containing the Go root directory.
For instance, for a .zip file created by the command:
zip go.zip $HOME/go
one may run godoc as follows:
godoc -http=:6060 -zip=go.zip -goroot=$HOME/go
Godoc documentation is converted to HTML or to text using the go/doc package;
see http://golang.org/pkg/go/doc/#ToHTML for the exact rules.
Godoc also shows example code that is runnable by the testing package;
see http://golang.org/pkg/testing/#hdr-Examples for the conventions.
See "Godoc: documenting Go code" for how to write good comments for godoc:
http://golang.org/doc/articles/godoc_documenting_go_code.html
*/
package main // import "golang.org/x/tools/cmd/godoc"
@@ -0,0 +1,362 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main_test
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"testing"
"time"
)
var godocTests = []struct {
args []string
matches []string // regular expressions
dontmatch []string // regular expressions
}{
{
args: []string{"fmt"},
matches: []string{
`import "fmt"`,
`Package fmt implements formatted I/O`,
},
},
{
args: []string{"io", "WriteString"},
matches: []string{
`func WriteString\(`,
`WriteString writes the contents of the string s to w`,
},
},
{
args: []string{"nonexistingpkg"},
matches: []string{
`no such file or directory|does not exist|cannot find the file`,
},
},
{
args: []string{"fmt", "NonexistentSymbol"},
matches: []string{
`No match found\.`,
},
},
{
args: []string{"-src", "syscall", "Open"},
matches: []string{
`func Open\(`,
},
dontmatch: []string{
`No match found\.`,
},
},
}
// buildGodoc builds the godoc executable.
// It returns its path, and a cleanup function.
//
// TODO(adonovan): opt: do this at most once, and do the cleanup
// exactly once. How though? There's no atexit.
func buildGodoc(t *testing.T) (bin string, cleanup func()) {
tmp, err := ioutil.TempDir("", "godoc-regtest-")
if err != nil {
t.Fatal(err)
}
defer func() {
if cleanup == nil { // probably, go build failed.
os.RemoveAll(tmp)
}
}()
bin = filepath.Join(tmp, "godoc")
if runtime.GOOS == "windows" {
bin += ".exe"
}
cmd := exec.Command("go", "build", "-o", bin)
if err := cmd.Run(); err != nil {
t.Fatalf("Building godoc: %v", err)
}
return bin, func() { os.RemoveAll(tmp) }
}
// Basic regression test for godoc command-line tool.
func TestCLI(t *testing.T) {
bin, cleanup := buildGodoc(t)
defer cleanup()
for _, test := range godocTests {
cmd := exec.Command(bin, test.args...)
cmd.Args[0] = "godoc"
out, err := cmd.CombinedOutput()
if err != nil {
t.Errorf("Running with args %#v: %v", test.args, err)
continue
}
for _, pat := range test.matches {
re := regexp.MustCompile(pat)
if !re.Match(out) {
t.Errorf("godoc %v =\n%s\nwanted /%v/", strings.Join(test.args, " "), out, pat)
}
}
for _, pat := range test.dontmatch {
re := regexp.MustCompile(pat)
if re.Match(out) {
t.Errorf("godoc %v =\n%s\ndid not want /%v/", strings.Join(test.args, " "), out, pat)
}
}
}
}
func serverAddress(t *testing.T) string {
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
ln, err = net.Listen("tcp6", "[::1]:0")
}
if err != nil {
t.Fatal(err)
}
defer ln.Close()
return ln.Addr().String()
}
func waitForServer(t *testing.T, address string) {
// Poll every 50ms for a total of 5s.
for i := 0; i < 100; i++ {
time.Sleep(50 * time.Millisecond)
conn, err := net.Dial("tcp", address)
if err != nil {
continue
}
conn.Close()
return
}
t.Fatalf("Server %q failed to respond in 5 seconds", address)
}
func killAndWait(cmd *exec.Cmd) {
cmd.Process.Kill()
cmd.Wait()
}
// Basic integration test for godoc HTTP interface.
func TestWeb(t *testing.T) {
bin, cleanup := buildGodoc(t)
defer cleanup()
addr := serverAddress(t)
cmd := exec.Command(bin, fmt.Sprintf("-http=%s", addr))
cmd.Stdout = os.Stderr
cmd.Stderr = os.Stderr
cmd.Args[0] = "godoc"
if err := cmd.Start(); err != nil {
t.Fatalf("failed to start godoc: %s", err)
}
defer killAndWait(cmd)
waitForServer(t, addr)
tests := []struct {
path string
match []string
dontmatch []string
}{
{
path: "/",
match: []string{"Go is an open source programming language"},
},
{
path: "/pkg/fmt/",
match: []string{"Package fmt implements formatted I/O"},
},
{
path: "/src/fmt/",
match: []string{"scan_test.go"},
},
{
path: "/src/fmt/print.go",
match: []string{"// Println formats using"},
},
{
path: "/pkg",
match: []string{
"Standard library",
"Package fmt implements formatted I/O",
},
dontmatch: []string{
"internal/syscall",
"cmd/gc",
},
},
{
path: "/pkg/?m=all",
match: []string{
"Standard library",
"Package fmt implements formatted I/O",
"internal/syscall",
},
dontmatch: []string{
"cmd/gc",
},
},
}
for _, test := range tests {
url := fmt.Sprintf("http://%s%s", addr, test.path)
resp, err := http.Get(url)
if err != nil {
t.Errorf("GET %s failed: %s", url, err)
continue
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
t.Errorf("GET %s: failed to read body: %s (response: %v)", url, err, resp)
}
isErr := false
for _, substr := range test.match {
if !bytes.Contains(body, []byte(substr)) {
t.Errorf("GET %s: wanted substring %q in body", url, substr)
isErr = true
}
}
for _, substr := range test.dontmatch {
if bytes.Contains(body, []byte(substr)) {
t.Errorf("GET %s: didn't want substring %q in body", url, substr)
isErr = true
}
}
if isErr {
t.Errorf("GET %s: got:\n%s", url, body)
}
}
}
// Basic integration test for godoc -analysis=type (via HTTP interface).
func TestTypeAnalysis(t *testing.T) {
// Write a fake GOROOT/GOPATH.
tmpdir, err := ioutil.TempDir("", "godoc-analysis")
if err != nil {
t.Fatalf("ioutil.TempDir failed: %s", err)
}
defer os.RemoveAll(tmpdir)
for _, f := range []struct{ file, content string }{
{"goroot/src/lib/lib.go", `
package lib
type T struct{}
const C = 3
var V T
func (T) F() int { return C }
`},
{"gopath/src/app/main.go", `
package main
import "lib"
func main() { print(lib.V) }
`},
} {
file := filepath.Join(tmpdir, f.file)
if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
t.Fatalf("MkdirAll(%s) failed: %s", filepath.Dir(file), err)
}
if err := ioutil.WriteFile(file, []byte(f.content), 0644); err != nil {
t.Fatal(err)
}
}
// Start the server.
bin, cleanup := buildGodoc(t)
defer cleanup()
addr := serverAddress(t)
cmd := exec.Command(bin, fmt.Sprintf("-http=%s", addr), "-analysis=type")
cmd.Env = append(cmd.Env, fmt.Sprintf("GOROOT=%s", filepath.Join(tmpdir, "goroot")))
cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%s", filepath.Join(tmpdir, "gopath")))
for _, e := range os.Environ() {
if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") {
continue
}
cmd.Env = append(cmd.Env, e)
}
cmd.Stdout = os.Stderr
stderr, err := cmd.StderrPipe()
if err != nil {
t.Fatal(err)
}
cmd.Args[0] = "godoc"
if err := cmd.Start(); err != nil {
t.Fatalf("failed to start godoc: %s", err)
}
defer killAndWait(cmd)
waitForServer(t, addr)
// Wait for type analysis to complete.
reader := bufio.NewReader(stderr)
for {
s, err := reader.ReadString('\n')
if err != nil {
t.Fatal(err)
}
fmt.Fprint(os.Stderr, s)
if strings.Contains(s, "Type analysis complete.") {
break
}
}
go io.Copy(os.Stderr, reader)
t0 := time.Now()
// Make an HTTP request and check for a regular expression match.
// The patterns are very crude checks that basic type information
// has been annotated onto the source view.
tryagain:
for _, test := range []struct{ url, pattern string }{
{"/src/lib/lib.go", "L2.*package .*Package docs for lib.*/lib"},
{"/src/lib/lib.go", "L3.*type .*type info for T.*struct"},
{"/src/lib/lib.go", "L5.*var V .*type T struct"},
{"/src/lib/lib.go", "L6.*func .*type T struct.*T.*return .*const C untyped int.*C"},
{"/src/app/main.go", "L2.*package .*Package docs for app"},
{"/src/app/main.go", "L3.*import .*Package docs for lib.*lib"},
{"/src/app/main.go", "L4.*func main.*package lib.*lib.*var lib.V lib.T.*V"},
} {
url := fmt.Sprintf("http://%s%s", addr, test.url)
resp, err := http.Get(url)
if err != nil {
t.Errorf("GET %s failed: %s", url, err)
continue
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
t.Errorf("GET %s: failed to read body: %s (response: %v)", url, err, resp)
continue
}
if !bytes.Contains(body, []byte("Static analysis features")) {
// Type analysis results usually become available within
// ~4ms after godoc startup (for this input on my machine).
if elapsed := time.Since(t0); elapsed > 500*time.Millisecond {
t.Fatalf("type analysis results still unavailable after %s", elapsed)
}
time.Sleep(10 * time.Millisecond)
goto tryagain
}
match, err := regexp.Match(test.pattern, body)
if err != nil {
t.Errorf("regexp.Match(%q) failed: %s", test.pattern, err)
continue
}
if !match {
// This is a really ugly failure message.
t.Errorf("GET %s: body doesn't match %q, got:\n%s",
url, test.pattern, string(body))
}
}
}
@@ -0,0 +1,83 @@
// Copyright 2010 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.
// The /doc/codewalk/ tree is synthesized from codewalk descriptions,
// files named $GOROOT/doc/codewalk/*.xml.
// For an example and a description of the format, see
// http://golang.org/doc/codewalk/codewalk or run godoc -http=:6060
// and see http://localhost:6060/doc/codewalk/codewalk .
// That page is itself a codewalk; the source code for it is
// $GOROOT/doc/codewalk/codewalk.xml.
package main
import (
"log"
"net/http"
"text/template"
"golang.org/x/tools/godoc"
"golang.org/x/tools/godoc/redirect"
"golang.org/x/tools/godoc/vfs"
)
var (
pres *godoc.Presentation
fs = vfs.NameSpace{}
)
func registerHandlers(pres *godoc.Presentation) {
if pres == nil {
panic("nil Presentation")
}
http.HandleFunc("/doc/codewalk/", codewalk)
http.Handle("/doc/play/", pres.FileServer())
http.Handle("/robots.txt", pres.FileServer())
http.Handle("/", pres)
http.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/"))
redirect.Register(nil)
}
func readTemplate(name string) *template.Template {
if pres == nil {
panic("no global Presentation set yet")
}
path := "lib/godoc/" + name
// use underlying file system fs to read the template file
// (cannot use template ParseFile functions directly)
data, err := vfs.ReadFile(fs, path)
if err != nil {
log.Fatal("readTemplate: ", err)
}
// be explicit with errors (for app engine use)
t, err := template.New(name).Funcs(pres.FuncMap()).Parse(string(data))
if err != nil {
log.Fatal("readTemplate: ", err)
}
return t
}
func readTemplates(p *godoc.Presentation, html bool) {
p.PackageText = readTemplate("package.txt")
p.SearchText = readTemplate("search.txt")
if html || p.HTMLMode {
codewalkHTML = readTemplate("codewalk.html")
codewalkdirHTML = readTemplate("codewalkdir.html")
p.CallGraphHTML = readTemplate("callgraph.html")
p.DirlistHTML = readTemplate("dirlist.html")
p.ErrorHTML = readTemplate("error.html")
p.ExampleHTML = readTemplate("example.html")
p.GodocHTML = readTemplate("godoc.html")
p.ImplementsHTML = readTemplate("implements.html")
p.MethodSetHTML = readTemplate("methodset.html")
p.PackageHTML = readTemplate("package.html")
p.SearchHTML = readTemplate("search.html")
p.SearchDocHTML = readTemplate("searchdoc.html")
p.SearchCodeHTML = readTemplate("searchcode.html")
p.SearchTxtHTML = readTemplate("searchtxt.html")
p.SearchDescXML = readTemplate("opensearch.xml")
}
}
@@ -0,0 +1,326 @@
// Copyright 2009 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.
// godoc: Go Documentation Server
// Web server tree:
//
// http://godoc/ main landing page
// http://godoc/doc/ serve from $GOROOT/doc - spec, mem, etc.
// http://godoc/src/ serve files from $GOROOT/src; .go gets pretty-printed
// http://godoc/cmd/ serve documentation about commands
// http://godoc/pkg/ serve documentation about packages
// (idea is if you say import "compress/zlib", you go to
// http://godoc/pkg/compress/zlib)
//
// Command-line interface:
//
// godoc packagepath [name ...]
//
// godoc compress/zlib
// - prints doc for package compress/zlib
// godoc crypto/block Cipher NewCMAC
// - prints doc for Cipher and NewCMAC in package crypto/block
// +build !appengine
package main
import (
"archive/zip"
_ "expvar" // to serve /debug/vars
"flag"
"fmt"
"go/build"
"log"
"net/http"
"net/http/httptest"
_ "net/http/pprof" // to serve /debug/pprof/*
"net/url"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"golang.org/x/tools/godoc"
"golang.org/x/tools/godoc/analysis"
"golang.org/x/tools/godoc/static"
"golang.org/x/tools/godoc/vfs"
"golang.org/x/tools/godoc/vfs/gatefs"
"golang.org/x/tools/godoc/vfs/mapfs"
"golang.org/x/tools/godoc/vfs/zipfs"
)
const (
defaultAddr = ":6060" // default webserver address
toolsPath = "golang.org/x/tools/cmd/"
)
var (
// file system to serve
// (with e.g.: zip -r go.zip $GOROOT -i \*.go -i \*.html -i \*.css -i \*.js -i \*.txt -i \*.c -i \*.h -i \*.s -i \*.png -i \*.jpg -i \*.sh -i favicon.ico)
zipfile = flag.String("zip", "", "zip file providing the file system to serve; disabled if empty")
// file-based index
writeIndex = flag.Bool("write_index", false, "write index to a file; the file name must be specified with -index_files")
analysisFlag = flag.String("analysis", "", `comma-separated list of analyses to perform (supported: type, pointer). See http://golang.org/lib/godoc/analysis/help.html`)
// network
httpAddr = flag.String("http", "", "HTTP service address (e.g., '"+defaultAddr+"')")
serverAddr = flag.String("server", "", "webserver address for command line searches")
// layout control
html = flag.Bool("html", false, "print HTML in command-line mode")
srcMode = flag.Bool("src", false, "print (exported) source in command-line mode")
urlFlag = flag.String("url", "", "print HTML for named URL")
// command-line searches
query = flag.Bool("q", false, "arguments are considered search queries")
verbose = flag.Bool("v", false, "verbose mode")
// file system roots
// TODO(gri) consider the invariant that goroot always end in '/'
goroot = flag.String("goroot", runtime.GOROOT(), "Go root directory")
// layout control
tabWidth = flag.Int("tabwidth", 4, "tab width")
showTimestamps = flag.Bool("timestamps", false, "show timestamps with directory listings")
templateDir = flag.String("templates", "", "directory containing alternate template files")
showPlayground = flag.Bool("play", false, "enable playground in web interface")
showExamples = flag.Bool("ex", false, "show examples in command line mode")
declLinks = flag.Bool("links", true, "link identifiers to their declarations")
// search index
indexEnabled = flag.Bool("index", false, "enable search index")
indexFiles = flag.String("index_files", "", "glob pattern specifying index files; if not empty, the index is read from these files in sorted order")
maxResults = flag.Int("maxresults", 10000, "maximum number of full text search results shown")
indexThrottle = flag.Float64("index_throttle", 0.75, "index throttle value; 0.0 = no time allocated, 1.0 = full throttle")
// source code notes
notesRx = flag.String("notes", "BUG", "regular expression matching note markers to show")
)
func usage() {
fmt.Fprintf(os.Stderr,
"usage: godoc package [name ...]\n"+
" godoc -http="+defaultAddr+"\n")
flag.PrintDefaults()
os.Exit(2)
}
func loggingHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
log.Printf("%s\t%s", req.RemoteAddr, req.URL)
h.ServeHTTP(w, req)
})
}
func handleURLFlag() {
// Try up to 10 fetches, following redirects.
urlstr := *urlFlag
for i := 0; i < 10; i++ {
// Prepare request.
u, err := url.Parse(urlstr)
if err != nil {
log.Fatal(err)
}
req := &http.Request{
URL: u,
}
// Invoke default HTTP handler to serve request
// to our buffering httpWriter.
w := httptest.NewRecorder()
http.DefaultServeMux.ServeHTTP(w, req)
// Return data, error, or follow redirect.
switch w.Code {
case 200: // ok
os.Stdout.Write(w.Body.Bytes())
return
case 301, 302, 303, 307: // redirect
redirect := w.HeaderMap.Get("Location")
if redirect == "" {
log.Fatalf("HTTP %d without Location header", w.Code)
}
urlstr = redirect
default:
log.Fatalf("HTTP error %d", w.Code)
}
}
log.Fatalf("too many redirects")
}
func main() {
flag.Usage = usage
flag.Parse()
playEnabled = *showPlayground
// Check usage: either server and no args, command line and args, or index creation mode
if (*httpAddr != "" || *urlFlag != "") != (flag.NArg() == 0) && !*writeIndex {
usage()
}
var fsGate chan bool
fsGate = make(chan bool, 20)
// Determine file system to use.
if *zipfile == "" {
// use file system of underlying OS
rootfs := gatefs.New(vfs.OS(*goroot), fsGate)
fs.Bind("/", rootfs, "/", vfs.BindReplace)
} else {
// use file system specified via .zip file (path separator must be '/')
rc, err := zip.OpenReader(*zipfile)
if err != nil {
log.Fatalf("%s: %s\n", *zipfile, err)
}
defer rc.Close() // be nice (e.g., -writeIndex mode)
fs.Bind("/", zipfs.New(rc, *zipfile), *goroot, vfs.BindReplace)
}
if *templateDir != "" {
fs.Bind("/lib/godoc", vfs.OS(*templateDir), "/", vfs.BindBefore)
} else {
fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)
}
// Bind $GOPATH trees into Go root.
for _, p := range filepath.SplitList(build.Default.GOPATH) {
fs.Bind("/src", gatefs.New(vfs.OS(p), fsGate), "/src", vfs.BindAfter)
}
httpMode := *httpAddr != ""
var typeAnalysis, pointerAnalysis bool
if *analysisFlag != "" {
for _, a := range strings.Split(*analysisFlag, ",") {
switch a {
case "type":
typeAnalysis = true
case "pointer":
pointerAnalysis = true
default:
log.Fatalf("unknown analysis: %s", a)
}
}
}
corpus := godoc.NewCorpus(fs)
corpus.Verbose = *verbose
corpus.MaxResults = *maxResults
corpus.IndexEnabled = *indexEnabled && httpMode
if *maxResults == 0 {
corpus.IndexFullText = false
}
corpus.IndexFiles = *indexFiles
corpus.IndexThrottle = *indexThrottle
if *writeIndex {
corpus.IndexThrottle = 1.0
corpus.IndexEnabled = true
}
if *writeIndex || httpMode || *urlFlag != "" {
if err := corpus.Init(); err != nil {
log.Fatal(err)
}
}
pres = godoc.NewPresentation(corpus)
pres.TabWidth = *tabWidth
pres.ShowTimestamps = *showTimestamps
pres.ShowPlayground = *showPlayground
pres.ShowExamples = *showExamples
pres.DeclLinks = *declLinks
pres.SrcMode = *srcMode
pres.HTMLMode = *html
if *notesRx != "" {
pres.NotesRx = regexp.MustCompile(*notesRx)
}
readTemplates(pres, httpMode || *urlFlag != "")
registerHandlers(pres)
if *writeIndex {
// Write search index and exit.
if *indexFiles == "" {
log.Fatal("no index file specified")
}
log.Println("initialize file systems")
*verbose = true // want to see what happens
corpus.UpdateIndex()
log.Println("writing index file", *indexFiles)
f, err := os.Create(*indexFiles)
if err != nil {
log.Fatal(err)
}
index, _ := corpus.CurrentIndex()
_, err = index.WriteTo(f)
if err != nil {
log.Fatal(err)
}
log.Println("done")
return
}
// Print content that would be served at the URL *urlFlag.
if *urlFlag != "" {
handleURLFlag()
return
}
if httpMode {
// HTTP server mode.
var handler http.Handler = http.DefaultServeMux
if *verbose {
log.Printf("Go Documentation Server")
log.Printf("version = %s", runtime.Version())
log.Printf("address = %s", *httpAddr)
log.Printf("goroot = %s", *goroot)
log.Printf("tabwidth = %d", *tabWidth)
switch {
case !*indexEnabled:
log.Print("search index disabled")
case *maxResults > 0:
log.Printf("full text index enabled (maxresults = %d)", *maxResults)
default:
log.Print("identifier search index enabled")
}
fs.Fprint(os.Stderr)
handler = loggingHandler(handler)
}
// Initialize search index.
if *indexEnabled {
go corpus.RunIndexer()
}
// Start type/pointer analysis.
if typeAnalysis || pointerAnalysis {
go analysis.Run(pointerAnalysis, &corpus.Analysis)
}
// Start http server.
if err := http.ListenAndServe(*httpAddr, handler); err != nil {
log.Fatalf("ListenAndServe %s: %v", *httpAddr, err)
}
return
}
if *query {
handleRemoteSearch()
return
}
if err := godoc.CommandLine(os.Stdout, fs, pres, flag.Args()); err != nil {
log.Print(err)
}
}
@@ -0,0 +1,44 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"encoding/json"
"fmt"
"go/format"
"net/http"
// This package registers "/compile" and "/share" handlers
// that redirect to the golang.org playground.
_ "golang.org/x/tools/playground"
)
func init() {
http.HandleFunc("/fmt", fmtHandler)
}
type fmtResponse struct {
Body string
Error string
}
// fmtHandler takes a Go program in its "body" form value, formats it with
// standard gofmt formatting, and writes a fmtResponse as a JSON object.
func fmtHandler(w http.ResponseWriter, r *http.Request) {
resp := new(fmtResponse)
body, err := format.Source([]byte(r.FormValue("body")))
if err != nil {
resp.Error = err.Error()
} else {
resp.Body = string(body)
}
json.NewEncoder(w).Encode(resp)
}
// disabledHandler serves a 501 "Not Implemented" response.
func disabledHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotImplemented)
fmt.Fprint(w, "This functionality is not available via local godoc.")
}
@@ -0,0 +1,72 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !appengine
package main
import (
"errors"
"flag"
"io"
"log"
"net/http"
"net/url"
"os"
)
func handleRemoteSearch() {
// Command-line queries.
for i := 0; i < flag.NArg(); i++ {
res, err := remoteSearch(flag.Arg(i))
if err != nil {
log.Fatalf("remoteSearch: %s", err)
}
io.Copy(os.Stdout, res.Body)
}
return
}
// remoteSearchURL returns the search URL for a given query as needed by
// remoteSearch. If html is set, an html result is requested; otherwise
// the result is in textual form.
// Adjust this function as necessary if modeNames or FormValue parameters
// change.
func remoteSearchURL(query string, html bool) string {
s := "/search?m=text&q="
if html {
s = "/search?q="
}
return s + url.QueryEscape(query)
}
func remoteSearch(query string) (res *http.Response, err error) {
// list of addresses to try
var addrs []string
if *serverAddr != "" {
// explicit server address - only try this one
addrs = []string{*serverAddr}
} else {
addrs = []string{
defaultAddr,
"golang.org",
}
}
// remote search
search := remoteSearchURL(query, *html)
for _, addr := range addrs {
url := "http://" + addr + search
res, err = http.Get(url)
if err == nil && res.StatusCode == http.StatusOK {
break
}
}
if err == nil && res.StatusCode != http.StatusOK {
err = errors.New(res.Status)
}
return
}
@@ -0,0 +1,134 @@
#!/usr/bin/env bash
# Copyright 2011 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# This script creates a complete godoc app in $APPDIR.
# It copies the cmd/godoc and src/go/... sources from GOROOT,
# synthesizes an app.yaml file, and creates the .zip, index, and
# configuration files.
#
# If an argument is provided it is assumed to be the app-engine godoc directory.
# Without an argument, $APPDIR is used instead. If GOROOT is not set, "go env"
# is consulted to find the $GOROOT.
#
# The script creates a .zip file representing the $GOROOT file system
# and computes the correspondig search index files. These files are then
# copied to $APPDIR. A corresponding godoc configuration file is created
# in $APPDIR/appconfig.go.
ZIPFILE=godoc.zip
INDEXFILE=godoc.index
SPLITFILES=index.split.
GODOC=golang.org/x/tools/cmd/godoc
CONFIGFILE=$GODOC/appconfig.go
error() {
echo "error: $1"
exit 2
}
getArgs() {
if [ -z $APPENGINE_SDK ]; then
error "APPENGINE_SDK environment variable not set"
fi
if [ ! -x $APPENGINE_SDK/goapp ]; then
error "couldn't find goapp command in $APPENGINE_SDK"
fi
if [ -z $GOROOT ]; then
GOROOT=$(go env GOROOT)
echo "GOROOT not set explicitly, using go env value instead"
fi
if [ -z $APPDIR ]; then
if [ $# == 0 ]; then
error "APPDIR not set, and no argument provided"
fi
APPDIR=$1
echo "APPDIR not set, using argument instead"
fi
# safety checks
if [ ! -d $GOROOT ]; then
error "$GOROOT is not a directory"
fi
if [ -e $APPDIR ]; then
error "$APPDIR exists; check and remove it before trying again"
fi
# reporting
echo "GOROOT = $GOROOT"
echo "APPDIR = $APPDIR"
}
fetchGodoc() {
echo "*** Fetching godoc (if not already in GOPATH)"
unset GOBIN
go=$APPENGINE_SDK/goapp
$go get -d -tags appengine $GODOC
mkdir -p $APPDIR/$GODOC
cp $(find $($go list -f '{{.Dir}}' $GODOC) -type f -depth 1) $APPDIR/$GODOC/
}
makeAppYaml() {
echo "*** make $APPDIR/app.yaml"
cat > $APPDIR/app.yaml <<EOF
application: godoc
version: 1
runtime: go
api_version: go1.4beta
handlers:
- url: /.*
script: _go_app
EOF
}
makeZipfile() {
echo "*** make $APPDIR/$ZIPFILE"
zip -q -r $APPDIR/$ZIPFILE $GOROOT/*
}
makeIndexfile() {
echo "*** make $APPDIR/$INDEXFILE"
GOPATH= godoc -write_index -index_files=$APPDIR/$INDEXFILE -zip=$APPDIR/$ZIPFILE
}
splitIndexfile() {
echo "*** split $APPDIR/$INDEXFILE"
split -b8m $APPDIR/$INDEXFILE $APPDIR/$SPLITFILES
}
makeConfigfile() {
echo "*** make $APPDIR/$CONFIGFILE"
cat > $APPDIR/$CONFIGFILE <<EOF
package main
// GENERATED FILE - DO NOT MODIFY BY HAND.
// (generated by golang.org/x/tools/cmd/godoc/setup-godoc-app.bash)
const (
// .zip filename
zipFilename = "$ZIPFILE"
// goroot directory in .zip file
zipGoroot = "$GOROOT"
// glob pattern describing search index files
// (if empty, the index is built at run-time)
indexFilenames = "$SPLITFILES*"
)
EOF
}
getArgs "$@"
set -e
mkdir $APPDIR
fetchGodoc
makeAppYaml
makeZipfile
makeIndexfile
splitIndexfile
makeConfigfile
echo "*** setup complete"
@@ -0,0 +1,81 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file contains the handlers that serve go-import redirects for Go
// sub-repositories. It specifies the mapping from import paths like
// "golang.org/x/tools" to the actual repository locations.
package main
import (
"html/template"
"log"
"net/http"
"strings"
)
const xPrefix = "/x/"
type xRepo struct {
URL, VCS string
}
var xMap = map[string]xRepo{
"codereview": {"https://code.google.com/p/go.codereview", "hg"},
"benchmarks": {"https://go.googlesource.com/benchmarks", "git"},
"blog": {"https://go.googlesource.com/blog", "git"},
"build": {"https://go.googlesource.com/build", "git"},
"crypto": {"https://go.googlesource.com/crypto", "git"},
"debug": {"https://go.googlesource.com/debug", "git"},
"exp": {"https://go.googlesource.com/exp", "git"},
"image": {"https://go.googlesource.com/image", "git"},
"mobile": {"https://go.googlesource.com/mobile", "git"},
"net": {"https://go.googlesource.com/net", "git"},
"oauth2": {"https://go.googlesource.com/oauth2", "git"},
"playground": {"https://go.googlesource.com/playground", "git"},
"review": {"https://go.googlesource.com/review", "git"},
"sys": {"https://go.googlesource.com/sys", "git"},
"talks": {"https://go.googlesource.com/talks", "git"},
"text": {"https://go.googlesource.com/text", "git"},
"tools": {"https://go.googlesource.com/tools", "git"},
"tour": {"https://go.googlesource.com/tour", "git"},
}
func init() {
http.HandleFunc(xPrefix, xHandler)
}
func xHandler(w http.ResponseWriter, r *http.Request) {
head, tail := strings.TrimPrefix(r.URL.Path, xPrefix), ""
if i := strings.Index(head, "/"); i != -1 {
head, tail = head[:i], head[i:]
}
repo, ok := xMap[head]
if !ok {
http.NotFound(w, r)
return
}
data := struct {
Prefix, Head, Tail string
Repo xRepo
}{xPrefix, head, tail, repo}
if err := xTemplate.Execute(w, data); err != nil {
log.Println("xHandler:", err)
}
}
var xTemplate = template.Must(template.New("x").Parse(`<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="go-import" content="golang.org{{.Prefix}}{{.Head}} {{.Repo.VCS}} {{.Repo.URL}}">
<meta name="go-source" content="golang.org{{.Prefix}}{{.Head}} https://github.com/golang/{{.Head}}/ https://github.com/golang/{{.Head}}/tree/master{/dir} https://github.com/golang/{{.Head}}/blob/master{/dir}/{file}#L{line}">
<meta http-equiv="refresh" content="0; url=https://godoc.org/golang.org{{.Prefix}}{{.Head}}{{.Tail}}">
</head>
<body>
Nothing to see here; <a href="https://godoc.org/golang.org{{.Prefix}}{{.Head}}{{.Tail}}">move along</a>.
</body>
</html>
`))
@@ -0,0 +1,33 @@
/*
Command goimports updates your Go import lines,
adding missing ones and removing unreferenced ones.
$ go get golang.org/x/tools/cmd/goimports
It's a drop-in replacement for your editor's gofmt-on-save hook.
It has the same command-line interface as gofmt and formats
your code in the same way.
For emacs, make sure you have the latest go-mode.el:
https://github.com/dominikh/go-mode.el
Then in your .emacs file:
(setq gofmt-command "goimports")
(add-to-list 'load-path "/home/you/somewhere/emacs/")
(require 'go-mode-load)
(add-hook 'before-save-hook 'gofmt-before-save)
For vim, set "gofmt_command" to "goimports":
https://golang.org/change/39c724dd7f252
https://golang.org/wiki/IDEsAndTextEditorPlugins
etc
For GoSublime, follow the steps described here:
http://michaelwhatcott.com/gosublime-goimports/
For other editors, you probably know what to do.
Happy hacking!
*/
package main // import "golang.org/x/tools/cmd/goimports"
@@ -0,0 +1,195 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"flag"
"fmt"
"go/scanner"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"golang.org/x/tools/imports"
)
var (
// main operation modes
list = flag.Bool("l", false, "list files whose formatting differs from goimport's")
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
options = &imports.Options{
TabWidth: 8,
TabIndent: true,
Comments: true,
Fragment: true,
}
exitCode = 0
)
func init() {
flag.BoolVar(&options.AllErrors, "e", false, "report all errors (not just the first 10 on different lines)")
}
func report(err error) {
scanner.PrintError(os.Stderr, err)
exitCode = 2
}
func usage() {
fmt.Fprintf(os.Stderr, "usage: goimports [flags] [path ...]\n")
flag.PrintDefaults()
os.Exit(2)
}
func isGoFile(f os.FileInfo) bool {
// ignore non-Go files
name := f.Name()
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
}
func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error {
opt := options
if stdin {
nopt := *options
nopt.Fragment = true
opt = &nopt
}
if in == nil {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
in = f
}
src, err := ioutil.ReadAll(in)
if err != nil {
return err
}
res, err := imports.Process(filename, src, opt)
if err != nil {
return err
}
if !bytes.Equal(src, res) {
// formatting has changed
if *list {
fmt.Fprintln(out, filename)
}
if *write {
err = ioutil.WriteFile(filename, res, 0)
if err != nil {
return err
}
}
if *doDiff {
data, err := diff(src, res)
if err != nil {
return fmt.Errorf("computing diff: %s", err)
}
fmt.Printf("diff %s gofmt/%s\n", filename, filename)
out.Write(data)
}
}
if !*list && !*write && !*doDiff {
_, err = out.Write(res)
}
return err
}
func visitFile(path string, f os.FileInfo, err error) error {
if err == nil && isGoFile(f) {
err = processFile(path, nil, os.Stdout, false)
}
if err != nil {
report(err)
}
return nil
}
func walkDir(path string) {
filepath.Walk(path, visitFile)
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
// call gofmtMain in a separate function
// so that it can use defer and have them
// run before the exit.
gofmtMain()
os.Exit(exitCode)
}
func gofmtMain() {
flag.Usage = usage
flag.Parse()
if options.TabWidth < 0 {
fmt.Fprintf(os.Stderr, "negative tabwidth %d\n", options.TabWidth)
exitCode = 2
return
}
if flag.NArg() == 0 {
if err := processFile("<standard input>", os.Stdin, os.Stdout, true); err != nil {
report(err)
}
return
}
for i := 0; i < flag.NArg(); i++ {
path := flag.Arg(i)
switch dir, err := os.Stat(path); {
case err != nil:
report(err)
case dir.IsDir():
walkDir(path)
default:
if err := processFile(path, nil, os.Stdout, false); err != nil {
report(err)
}
}
}
}
func diff(b1, b2 []byte) (data []byte, err error) {
f1, err := ioutil.TempFile("", "gofmt")
if err != nil {
return
}
defer os.Remove(f1.Name())
defer f1.Close()
f2, err := ioutil.TempFile("", "gofmt")
if err != nil {
return
}
defer os.Remove(f2.Name())
defer f2.Close()
f1.Write(b1)
f2.Write(b2)
data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
if len(data) > 0 {
// diff exits with a non-zero status when the files don't match.
// Ignore that failure as long as we get output.
err = nil
}
return
}
@@ -0,0 +1,89 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// licence that can be found in the LICENSE file.
// The gomvpkg command moves go packages, updating import declarations.
// See the -help message or Usage constant for details.
package main
import (
"flag"
"fmt"
"go/build"
"os"
"golang.org/x/tools/refactor/rename"
)
var (
fromFlag = flag.String("from", "", "Import path of package to be moved")
toFlag = flag.String("to", "", "Destination import path for package")
vcsMvCmdFlag = flag.String("vcs_mv_cmd", "", `A template for the version control system's "move directory" command, e.g. "git mv {{.Src}} {{.Dst}}`)
helpFlag = flag.Bool("help", false, "show usage message")
)
const Usage = `gomvpkg: moves a package, updating import declarations
Usage:
gomvpkg -from <path> -to <path> [-vcs_mv_cmd <template>]
Flags:
-from specifies the import path of the package to be moved
-to specifies the destination import path
-vcs_mv_cmd specifies a shell command to inform the version control system of a
directory move. The argument is a template using the syntax of the
text/template package. It has two fields: Src and Dst, the absolute
paths of the directories.
For example: "git mv {{.Src}} {{.Dst}}"
gomvpkg determines the set of packages that might be affected, including all
packages importing the 'from' package and any of its subpackages. It will move
the 'from' package and all its subpackages to the destination path and update all
imports of those packages to point to its new import path.
gomvpkg rejects moves in which a package already exists at the destination import
path, or in which a directory already exists at the location the package would be
moved to.
gomvpkg will not always be able to rename imports when a package's name is changed.
Import statements may want further cleanup.
gomvpkg's behavior is not defined if any of the packages to be moved are
imported using dot imports.
Examples:
% gomvpkg -from myproject/foo -to myproject/bar
Move the package with import path "myproject/foo" to the new path
"myproject/bar".
% gomvpkg -from myproject/foo -to myproject/bar -vcs_mv_cmd "git mv {{.Src}} {{.Dst}}"
Move the package with import path "myproject/foo" to the new path
"myproject/bar" using "git mv" to execute the directory move.
`
func main() {
flag.Parse()
if len(flag.Args()) > 0 {
fmt.Fprintln(os.Stderr, "gomvpkg: surplus arguments.")
os.Exit(1)
}
if *helpFlag || *fromFlag == "" || *toFlag == "" {
fmt.Println(Usage)
return
}
if err := rename.Move(&build.Default, *fromFlag, *toFlag, *vcsMvCmdFlag); err != nil {
fmt.Fprintf(os.Stderr, "gomvpkg: %s.\n", err)
os.Exit(1)
}
}
@@ -0,0 +1,61 @@
// The gorename command performs precise type-safe renaming of
// identifiers in Go source code.
//
// Run with -help for usage information, or view the Usage constant in
// package golang.org/x/tools/refactor/rename, which contains most of
// the implementation.
//
package main // import "golang.org/x/tools/cmd/gorename"
import (
"flag"
"fmt"
"go/build"
"os"
"runtime"
"golang.org/x/tools/refactor/rename"
)
var (
offsetFlag = flag.String("offset", "", "file and byte offset of identifier to be renamed, e.g. 'file.go:#123'. For use by editors.")
fromFlag = flag.String("from", "", "identifier to be renamed; see -help for formats")
toFlag = flag.String("to", "", "new name for identifier")
helpFlag = flag.Bool("help", false, "show usage message")
)
func init() {
flag.BoolVar(&rename.Force, "force", false, "proceed, even if conflicts were reported")
flag.BoolVar(&rename.DryRun, "dryrun", false, "show the change, but do not apply it")
flag.BoolVar(&rename.Verbose, "v", false, "print verbose information")
// If $GOMAXPROCS isn't set, use the full capacity of the machine.
// For small machines, use at least 4 threads.
if os.Getenv("GOMAXPROCS") == "" {
n := runtime.NumCPU()
if n < 4 {
n = 4
}
runtime.GOMAXPROCS(n)
}
}
func main() {
flag.Parse()
if len(flag.Args()) > 0 {
fmt.Fprintln(os.Stderr, "gorename: surplus arguments.")
os.Exit(1)
}
if *helpFlag || (*offsetFlag == "" && *fromFlag == "" && *toFlag == "") {
fmt.Println(rename.Usage)
return
}
if err := rename.Main(&build.Default, *offsetFlag, *fromFlag, *toFlag); err != nil {
if err != rename.ConflictError {
fmt.Fprintf(os.Stderr, "gorename: %s\n", err)
}
os.Exit(1)
}
}
@@ -0,0 +1,62 @@
// 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.
/*
The gotype command does syntactic and semantic analysis of Go files
and packages like the front-end of a Go compiler. Errors are reported
if the analysis fails; otherwise gotype is quiet (unless -v is set).
Without a list of paths, gotype reads from standard input, which
must provide a single Go source file defining a complete package.
If a single path is specified that is a directory, gotype checks
the Go files in that directory; they must all belong to the same
package.
Otherwise, each path must be the filename of Go file belonging to
the same package.
Usage:
gotype [flags] [path...]
The flags are:
-a
use all (incl. _test.go) files when processing a directory
-e
report all errors (not just the first 10)
-v
verbose mode
-gccgo
use gccimporter instead of gcimporter
Debugging flags:
-seq
parse sequentially, rather than in parallel
-ast
print AST (forces -seq)
-trace
print parse trace (forces -seq)
-comments
parse comments (ignored unless -ast or -trace is provided)
Examples:
To check the files a.go, b.go, and c.go:
gotype a.go b.go c.go
To check an entire package in the directory dir and print the processed files:
gotype -v dir
To check an entire package including tests in the local directory:
gotype -a .
To verify the output of a pipe:
echo "package foo" | gotype
*/
package main // import "golang.org/x/tools/cmd/gotype"
Loaded 100 of 660 files, more files were not shown because too many files have changed in this diff. Show more