Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(310)

Side by Side Diff: src/pkg/go/build/build.go

Issue 160200044: [dev.power64] code review 160200044: build: merge default into dev.power64 (Closed)
Patch Set: diff -r be0c14f62257b42485019e9e1db23cf40d2e249f https://code.google.com/p/go Created 10 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/fmt/scan_test.go ('k') | src/pkg/go/build/build_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package build 5 package build
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
11 "go/ast" 11 "go/ast"
12 "go/doc" 12 "go/doc"
13 "go/parser" 13 "go/parser"
14 "go/token" 14 "go/token"
15 "io" 15 "io"
16 "io/ioutil" 16 "io/ioutil"
17 "log" 17 "log"
18 "os" 18 "os"
19 pathpkg "path" 19 pathpkg "path"
20 "path/filepath" 20 "path/filepath"
21 "runtime" 21 "runtime"
22 "sort" 22 "sort"
23 "strconv" 23 "strconv"
24 "strings" 24 "strings"
25 "unicode" 25 "unicode"
26 "unicode/utf8"
26 ) 27 )
27 28
28 // A Context specifies the supporting context for a build. 29 // A Context specifies the supporting context for a build.
29 type Context struct { 30 type Context struct {
30 GOARCH string // target architecture 31 GOARCH string // target architecture
31 GOOS string // target operating system 32 GOOS string // target operating system
32 GOROOT string // Go root 33 GOROOT string // Go root
33 GOPATH string // Go path 34 GOPATH string // Go path
34 CgoEnabled bool // whether cgo can be used 35 CgoEnabled bool // whether cgo can be used
35 UseAllFiles bool // use files regardless of +build lines, file names 36 UseAllFiles bool // use files regardless of +build lines, file names
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 331
331 const ( 332 const (
332 // If FindOnly is set, Import stops after locating the directory 333 // If FindOnly is set, Import stops after locating the directory
333 // that should contain the sources for a package. It does not 334 // that should contain the sources for a package. It does not
334 // read any files in the directory. 335 // read any files in the directory.
335 FindOnly ImportMode = 1 << iota 336 FindOnly ImportMode = 1 << iota
336 337
337 // If AllowBinary is set, Import can be satisfied by a compiled 338 // If AllowBinary is set, Import can be satisfied by a compiled
338 // package object without corresponding sources. 339 // package object without corresponding sources.
339 AllowBinary 340 AllowBinary
341
342 // If ImportComment is set, parse import comments on package statements.
343 // Import returns an error if it finds a comment it cannot understand
344 // or finds conflicting comments in multiple source files.
345 // See golang.org/s/go14customimport for more information.
346 ImportComment
340 ) 347 )
341 348
342 // A Package describes the Go package found in a directory. 349 // A Package describes the Go package found in a directory.
343 type Package struct { 350 type Package struct {
344 » Dir string // directory containing package sources 351 » Dir string // directory containing package sources
345 » Name string // package name 352 » Name string // package name
346 » Doc string // documentation synopsis 353 » ImportComment string // path in import comment on package statement
347 » ImportPath string // import path of package ("" if unknown) 354 » Doc string // documentation synopsis
348 » Root string // root of Go tree where this package lives 355 » ImportPath string // import path of package ("" if unknown)
349 » SrcRoot string // package source root directory ("" if unknown) 356 » Root string // root of Go tree where this package lives
350 » PkgRoot string // package install root directory ("" if unknown) 357 » SrcRoot string // package source root directory ("" if unknown)
351 » BinDir string // command install directory ("" if unknown) 358 » PkgRoot string // package install root directory ("" if unknown)
352 » Goroot bool // package found in Go root 359 » BinDir string // command install directory ("" if unknown)
353 » PkgObj string // installed .a file 360 » Goroot bool // package found in Go root
354 » AllTags []string // tags that can influence file selection in this d irectory 361 » PkgObj string // installed .a file
355 » ConflictDir string // this directory shadows Dir in $GOPATH 362 » AllTags []string // tags that can influence file selection in this directory
363 » ConflictDir string // this directory shadows Dir in $GOPATH
356 364
357 // Source files 365 // Source files
358 GoFiles []string // .go source files (excluding CgoFiles, TestGoF iles, XTestGoFiles) 366 GoFiles []string // .go source files (excluding CgoFiles, TestGoF iles, XTestGoFiles)
359 CgoFiles []string // .go source files that import "C" 367 CgoFiles []string // .go source files that import "C"
360 IgnoredGoFiles []string // .go source files ignored for this build 368 IgnoredGoFiles []string // .go source files ignored for this build
361 CFiles []string // .c source files 369 CFiles []string // .c source files
362 CXXFiles []string // .cc, .cpp and .cxx source files 370 CXXFiles []string // .cc, .cpp and .cxx source files
363 MFiles []string // .m (Objective-C) source files 371 MFiles []string // .m (Objective-C) source files
364 HFiles []string // .h, .hh, .hpp and .hxx source files 372 HFiles []string // .h, .hh, .hpp and .hxx source files
365 SFiles []string // .s source files 373 SFiles []string // .s source files
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 } 522 }
515 523
516 // tried records the location of unsuccessful package lookups 524 // tried records the location of unsuccessful package lookups
517 var tried struct { 525 var tried struct {
518 goroot string 526 goroot string
519 gopath []string 527 gopath []string
520 } 528 }
521 529
522 // Determine directory from import path. 530 // Determine directory from import path.
523 if ctxt.GOROOT != "" { 531 if ctxt.GOROOT != "" {
524 » » » dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path) 532 » » » var dir string
533 » » » if strings.HasPrefix(path, "cmd/") {
534 » » » » dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
535 » » » } else {
536 » » » » dir = ctxt.joinPath(ctxt.GOROOT, "src", "pkg", p ath)
537 » » » }
525 isDir := ctxt.isDir(dir) 538 isDir := ctxt.isDir(dir)
526 binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) 539 binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
527 if isDir || binaryOnly { 540 if isDir || binaryOnly {
528 p.Dir = dir 541 p.Dir = dir
529 p.Goroot = true 542 p.Goroot = true
530 p.Root = ctxt.GOROOT 543 p.Root = ctxt.GOROOT
531 goto Found 544 goto Found
532 } 545 }
533 tried.goroot = dir 546 tried.goroot = dir
534 } 547 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 if binaryOnly && (mode&AllowBinary) != 0 { 598 if binaryOnly && (mode&AllowBinary) != 0 {
586 return p, pkgerr 599 return p, pkgerr
587 } 600 }
588 601
589 dirs, err := ctxt.readDir(p.Dir) 602 dirs, err := ctxt.readDir(p.Dir)
590 if err != nil { 603 if err != nil {
591 return p, err 604 return p, err
592 } 605 }
593 606
594 var Sfiles []string // files with ".S" (capital S) 607 var Sfiles []string // files with ".S" (capital S)
595 » var firstFile string 608 » var firstFile, firstCommentFile string
596 imported := make(map[string][]token.Position) 609 imported := make(map[string][]token.Position)
597 testImported := make(map[string][]token.Position) 610 testImported := make(map[string][]token.Position)
598 xTestImported := make(map[string][]token.Position) 611 xTestImported := make(map[string][]token.Position)
599 allTags := make(map[string]bool) 612 allTags := make(map[string]bool)
600 fset := token.NewFileSet() 613 fset := token.NewFileSet()
601 for _, d := range dirs { 614 for _, d := range dirs {
602 if d.IsDir() { 615 if d.IsDir() {
603 continue 616 continue
604 } 617 }
605 618
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 if p.Name == "" { 685 if p.Name == "" {
673 p.Name = pkg 686 p.Name = pkg
674 firstFile = name 687 firstFile = name
675 } else if pkg != p.Name { 688 } else if pkg != p.Name {
676 return p, fmt.Errorf("found packages %s (%s) and %s (%s) in %s", p.Name, firstFile, pkg, name, p.Dir) 689 return p, fmt.Errorf("found packages %s (%s) and %s (%s) in %s", p.Name, firstFile, pkg, name, p.Dir)
677 } 690 }
678 if pf.Doc != nil && p.Doc == "" { 691 if pf.Doc != nil && p.Doc == "" {
679 p.Doc = doc.Synopsis(pf.Doc.Text()) 692 p.Doc = doc.Synopsis(pf.Doc.Text())
680 } 693 }
681 694
695 if mode&ImportComment != 0 {
696 qcom, line := findImportComment(data)
697 if line != 0 {
698 com, err := strconv.Unquote(qcom)
699 if err != nil {
700 return p, fmt.Errorf("%s:%d: cannot pars e import comment", filename, line)
701 }
702 if p.ImportComment == "" {
703 p.ImportComment = com
704 firstCommentFile = name
705 } else if p.ImportComment != com {
706 return p, fmt.Errorf("found import comme nts %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p. Dir)
707 }
708 }
709 }
710
682 // Record imports and information about cgo. 711 // Record imports and information about cgo.
683 isCgo := false 712 isCgo := false
684 for _, decl := range pf.Decls { 713 for _, decl := range pf.Decls {
685 d, ok := decl.(*ast.GenDecl) 714 d, ok := decl.(*ast.GenDecl)
686 if !ok { 715 if !ok {
687 continue 716 continue
688 } 717 }
689 for _, dspec := range d.Specs { 718 for _, dspec := range d.Specs {
690 spec, ok := dspec.(*ast.ImportSpec) 719 spec, ok := dspec.(*ast.ImportSpec)
691 if !ok { 720 if !ok {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 // (which means gcc will compile them). 781 // (which means gcc will compile them).
753 // The standard assemblers expect .s files. 782 // The standard assemblers expect .s files.
754 if len(p.CgoFiles) > 0 { 783 if len(p.CgoFiles) > 0 {
755 p.SFiles = append(p.SFiles, Sfiles...) 784 p.SFiles = append(p.SFiles, Sfiles...)
756 sort.Strings(p.SFiles) 785 sort.Strings(p.SFiles)
757 } 786 }
758 787
759 return p, pkgerr 788 return p, pkgerr
760 } 789 }
761 790
791 func findImportComment(data []byte) (s string, line int) {
792 // expect keyword package
793 word, data := parseWord(data)
794 if string(word) != "package" {
795 return "", 0
796 }
797
798 // expect package name
799 _, data = parseWord(data)
800
801 // now ready for import comment, a // or /* */ comment
802 // beginning and ending on the current line.
803 for len(data) > 0 && (data[0] == ' ' || data[0] == '\t' || data[0] == '\ r') {
804 data = data[1:]
805 }
806
807 var comment []byte
808 switch {
809 case bytes.HasPrefix(data, slashSlash):
810 i := bytes.Index(data, newline)
811 if i < 0 {
812 i = len(data)
813 }
814 comment = data[2:i]
815 case bytes.HasPrefix(data, slashStar):
816 data = data[2:]
817 i := bytes.Index(data, starSlash)
818 if i < 0 {
819 // malformed comment
820 return "", 0
821 }
822 comment = data[:i]
823 if bytes.Contains(comment, newline) {
824 return "", 0
825 }
826 }
827 comment = bytes.TrimSpace(comment)
828
829 // split comment into `import`, `"pkg"`
830 word, arg := parseWord(comment)
831 if string(word) != "import" {
832 return "", 0
833 }
834
835 line = 1 + bytes.Count(data[:cap(data)-cap(arg)], newline)
836 return strings.TrimSpace(string(arg)), line
837 }
838
839 var (
840 slashSlash = []byte("//")
841 slashStar = []byte("/*")
842 starSlash = []byte("*/")
843 newline = []byte("\n")
844 )
845
846 // skipSpaceOrComment returns data with any leading spaces or comments removed.
847 func skipSpaceOrComment(data []byte) []byte {
848 for len(data) > 0 {
849 switch data[0] {
850 case ' ', '\t', '\r', '\n':
851 data = data[1:]
852 continue
853 case '/':
854 if bytes.HasPrefix(data, slashSlash) {
855 i := bytes.Index(data, newline)
856 if i < 0 {
857 return nil
858 }
859 data = data[i+1:]
860 continue
861 }
862 if bytes.HasPrefix(data, slashStar) {
863 data = data[2:]
864 i := bytes.Index(data, starSlash)
865 if i < 0 {
866 return nil
867 }
868 data = data[i+2:]
869 continue
870 }
871 }
872 break
873 }
874 return data
875 }
876
877 // parseWord skips any leading spaces or comments in data
878 // and then parses the beginning of data as an identifier or keyword,
879 // returning that word and what remains after the word.
880 func parseWord(data []byte) (word, rest []byte) {
881 data = skipSpaceOrComment(data)
882
883 // Parse past leading word characters.
884 rest = data
885 for {
886 r, size := utf8.DecodeRune(rest)
887 if unicode.IsLetter(r) || '0' <= r && r <= '9' || r == '_' {
888 rest = rest[size:]
889 continue
890 }
891 break
892 }
893
894 word = data[:len(data)-len(rest)]
895 if len(word) == 0 {
896 return nil, nil
897 }
898
899 return word, rest
900 }
901
762 // MatchFile reports whether the file with the given name in the given directory 902 // MatchFile reports whether the file with the given name in the given directory
763 // matches the context and would be included in a Package created by ImportDir 903 // matches the context and would be included in a Package created by ImportDir
764 // of that directory. 904 // of that directory.
765 // 905 //
766 // MatchFile considers the name of the file and may use ctxt.OpenFile to 906 // MatchFile considers the name of the file and may use ctxt.OpenFile to
767 // read some or all of the file's content. 907 // read some or all of the file's content.
768 func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) { 908 func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
769 match, _, _, err = ctxt.matchFile(dir, name, false, nil) 909 match, _, _, err = ctxt.matchFile(dir, name, false, nil)
770 return 910 return
771 } 911 }
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 return "8", nil 1368 return "8", nil
1229 case "amd64", "amd64p32": 1369 case "amd64", "amd64p32":
1230 return "6", nil 1370 return "6", nil
1231 case "arm": 1371 case "arm":
1232 return "5", nil 1372 return "5", nil
1233 case "power64", "power64le": 1373 case "power64", "power64le":
1234 return "9", nil 1374 return "9", nil
1235 } 1375 }
1236 return "", errors.New("unsupported GOARCH " + goarch) 1376 return "", errors.New("unsupported GOARCH " + goarch)
1237 } 1377 }
OLDNEW
« no previous file with comments | « src/pkg/fmt/scan_test.go ('k') | src/pkg/go/build/build_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b