URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [go/] [ast/] [import.go] - Rev 747
Compare with Previous | Blame | View Log
// 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.package astimport ("go/token""sort""strconv")// SortImports sorts runs of consecutive import lines in import blocks in f.func SortImports(fset *token.FileSet, f *File) {for _, d := range f.Decls {d, ok := d.(*GenDecl)if !ok || d.Tok != token.IMPORT {// Not an import declaration, so we're done.// Imports are always first.break}if d.Lparen == token.NoPos {// Not a block: sorted by default.continue}// Identify and sort runs of specs on successive lines.i := 0for j, s := range d.Specs {if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line {// j begins a new run. End this one.sortSpecs(fset, f, d.Specs[i:j])i = j}}sortSpecs(fset, f, d.Specs[i:])}}func importPath(s Spec) string {t, err := strconv.Unquote(s.(*ImportSpec).Path.Value)if err == nil {return t}return ""}type posSpan struct {Start token.PosEnd token.Pos}func sortSpecs(fset *token.FileSet, f *File, specs []Spec) {// Avoid work if already sorted (also catches < 2 entries).sorted := truefor i, s := range specs {if i > 0 && importPath(specs[i-1]) > importPath(s) {sorted = falsebreak}}if sorted {return}// Record positions for specs.pos := make([]posSpan, len(specs))for i, s := range specs {pos[i] = posSpan{s.Pos(), s.End()}}// Identify comments in this range.// Any comment from pos[0].Start to the final line counts.lastLine := fset.Position(pos[len(pos)-1].End).Linecstart := len(f.Comments)cend := len(f.Comments)for i, g := range f.Comments {if g.Pos() < pos[0].Start {continue}if i < cstart {cstart = i}if fset.Position(g.End()).Line > lastLine {cend = ibreak}}comments := f.Comments[cstart:cend]// Assign each comment to the import spec preceding it.importComment := map[*ImportSpec][]*CommentGroup{}specIndex := 0for _, g := range comments {for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() {specIndex++}s := specs[specIndex].(*ImportSpec)importComment[s] = append(importComment[s], g)}// Sort the import specs by import path.// Reassign the import paths to have the same position sequence.// Reassign each comment to abut the end of its spec.// Sort the comments by new position.sort.Sort(byImportPath(specs))for i, s := range specs {s := s.(*ImportSpec)if s.Name != nil {s.Name.NamePos = pos[i].Start}s.Path.ValuePos = pos[i].Starts.EndPos = pos[i].Endfor _, g := range importComment[s] {for _, c := range g.List {c.Slash = pos[i].End}}}sort.Sort(byCommentPos(comments))}type byImportPath []Spec // slice of *ImportSpecfunc (x byImportPath) Len() int { return len(x) }func (x byImportPath) Swap(i, j int) { x[i], x[j] = x[j], x[i] }func (x byImportPath) Less(i, j int) bool { return importPath(x[i]) < importPath(x[j]) }type byCommentPos []*CommentGroupfunc (x byCommentPos) Len() int { return len(x) }func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] }func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }
