OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [go/] [ast/] [import.go] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package ast
6
 
7
import (
8
        "go/token"
9
        "sort"
10
        "strconv"
11
)
12
 
13
// SortImports sorts runs of consecutive import lines in import blocks in f.
14
func SortImports(fset *token.FileSet, f *File) {
15
        for _, d := range f.Decls {
16
                d, ok := d.(*GenDecl)
17
                if !ok || d.Tok != token.IMPORT {
18
                        // Not an import declaration, so we're done.
19
                        // Imports are always first.
20
                        break
21
                }
22
 
23
                if d.Lparen == token.NoPos {
24
                        // Not a block: sorted by default.
25
                        continue
26
                }
27
 
28
                // Identify and sort runs of specs on successive lines.
29
                i := 0
30
                for j, s := range d.Specs {
31
                        if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line {
32
                                // j begins a new run.  End this one.
33
                                sortSpecs(fset, f, d.Specs[i:j])
34
                                i = j
35
                        }
36
                }
37
                sortSpecs(fset, f, d.Specs[i:])
38
        }
39
}
40
 
41
func importPath(s Spec) string {
42
        t, err := strconv.Unquote(s.(*ImportSpec).Path.Value)
43
        if err == nil {
44
                return t
45
        }
46
        return ""
47
}
48
 
49
type posSpan struct {
50
        Start token.Pos
51
        End   token.Pos
52
}
53
 
54
func sortSpecs(fset *token.FileSet, f *File, specs []Spec) {
55
        // Avoid work if already sorted (also catches < 2 entries).
56
        sorted := true
57
        for i, s := range specs {
58
                if i > 0 && importPath(specs[i-1]) > importPath(s) {
59
                        sorted = false
60
                        break
61
                }
62
        }
63
        if sorted {
64
                return
65
        }
66
 
67
        // Record positions for specs.
68
        pos := make([]posSpan, len(specs))
69
        for i, s := range specs {
70
                pos[i] = posSpan{s.Pos(), s.End()}
71
        }
72
 
73
        // Identify comments in this range.
74
        // Any comment from pos[0].Start to the final line counts.
75
        lastLine := fset.Position(pos[len(pos)-1].End).Line
76
        cstart := len(f.Comments)
77
        cend := len(f.Comments)
78
        for i, g := range f.Comments {
79
                if g.Pos() < pos[0].Start {
80
                        continue
81
                }
82
                if i < cstart {
83
                        cstart = i
84
                }
85
                if fset.Position(g.End()).Line > lastLine {
86
                        cend = i
87
                        break
88
                }
89
        }
90
        comments := f.Comments[cstart:cend]
91
 
92
        // Assign each comment to the import spec preceding it.
93
        importComment := map[*ImportSpec][]*CommentGroup{}
94
        specIndex := 0
95
        for _, g := range comments {
96
                for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() {
97
                        specIndex++
98
                }
99
                s := specs[specIndex].(*ImportSpec)
100
                importComment[s] = append(importComment[s], g)
101
        }
102
 
103
        // Sort the import specs by import path.
104
        // Reassign the import paths to have the same position sequence.
105
        // Reassign each comment to abut the end of its spec.
106
        // Sort the comments by new position.
107
        sort.Sort(byImportPath(specs))
108
        for i, s := range specs {
109
                s := s.(*ImportSpec)
110
                if s.Name != nil {
111
                        s.Name.NamePos = pos[i].Start
112
                }
113
                s.Path.ValuePos = pos[i].Start
114
                s.EndPos = pos[i].End
115
                for _, g := range importComment[s] {
116
                        for _, c := range g.List {
117
                                c.Slash = pos[i].End
118
                        }
119
                }
120
        }
121
        sort.Sort(byCommentPos(comments))
122
}
123
 
124
type byImportPath []Spec // slice of *ImportSpec
125
 
126
func (x byImportPath) Len() int           { return len(x) }
127
func (x byImportPath) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
128
func (x byImportPath) Less(i, j int) bool { return importPath(x[i]) < importPath(x[j]) }
129
 
130
type byCommentPos []*CommentGroup
131
 
132
func (x byCommentPos) Len() int           { return len(x) }
133
func (x byCommentPos) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
134
func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.