~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/go/printer/printer.go

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-11-18 15:12:26 UTC
  • mfrom: (14.2.12 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20141118151226-zug7vn93mn3dtiz3
Tags: 2:1.3.2-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - Support co-installability with gccgo-go tool:
    - d/rules,golang-go.install: Rename bin/go -> bin/golang-go
    - d/golang-go.{postinst,prerm}: Install/remove /usr/bin/go using
      alternatives.
  - d/copyright: Amendments for full compiliance with copyright format.
  - d/control: Demote golang-go.tools to Suggests to support Ubuntu MIR.
  - dropped patches (now upstream):
    - d/p/issue27650045_40001_50001.diff
    - d/p/issue28050043_60001_70001.diff
    - d/p/issue54790044_100001_110001.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
type pmode int
40
40
 
41
41
const (
42
 
        noExtraLinebreak pmode = 1 << iota
 
42
        noExtraBlank     pmode = 1 << iota // disables extra blank after /*-style comment
 
43
        noExtraLinebreak                   // disables extra line break after /*-style comment
43
44
)
44
45
 
 
46
type commentInfo struct {
 
47
        cindex         int               // current comment index
 
48
        comment        *ast.CommentGroup // = printer.comments[cindex]; or nil
 
49
        commentOffset  int               // = printer.posFor(printer.comments[cindex].List[0].Pos()).Offset; or infinity
 
50
        commentNewline bool              // true if the comment group contains newlines
 
51
}
 
52
 
45
53
type printer struct {
46
54
        // Configuration (does not change after initialization)
47
55
        Config
52
60
        indent      int          // current indentation
53
61
        mode        pmode        // current printer mode
54
62
        impliedSemi bool         // if set, a linebreak implies a semicolon
55
 
        lastTok     token.Token  // the last token printed (token.ILLEGAL if it's whitespace)
 
63
        lastTok     token.Token  // last token printed (token.ILLEGAL if it's whitespace)
 
64
        prevOpen    token.Token  // previous non-brace "open" token (, [, or token.ILLEGAL
56
65
        wsbuf       []whiteSpace // delayed white space
57
66
 
58
67
        // Positions
61
70
        // white space). If there's a difference and SourcePos is set in
62
71
        // ConfigMode, //line comments are used in the output to restore
63
72
        // original source positions for a reader.
64
 
        pos  token.Position // current position in AST (source) space
65
 
        out  token.Position // current position in output space
66
 
        last token.Position // value of pos after calling writeString
 
73
        pos     token.Position // current position in AST (source) space
 
74
        out     token.Position // current position in output space
 
75
        last    token.Position // value of pos after calling writeString
 
76
        linePtr *int           // if set, record out.Line for the next token in *linePtr
67
77
 
68
78
        // The list of all source comments, in order of appearance.
69
79
        comments        []*ast.CommentGroup // may be nil
70
 
        cindex          int                 // current comment index
71
80
        useNodeComments bool                // if not set, ignore lead and line comments of nodes
72
81
 
73
82
        // Information about p.comments[p.cindex]; set up by nextComment.
74
 
        comment        *ast.CommentGroup // = p.comments[p.cindex]; or nil
75
 
        commentOffset  int               // = p.posFor(p.comments[p.cindex].List[0].Pos()).Offset; or infinity
76
 
        commentNewline bool              // true if the comment group contains newlines
 
83
        commentInfo
77
84
 
78
85
        // Cache of already computed node sizes.
79
86
        nodeSizes map[ast.Node]int
93
100
        p.cachedPos = -1
94
101
}
95
102
 
 
103
func (p *printer) internalError(msg ...interface{}) {
 
104
        if debug {
 
105
                fmt.Print(p.pos.String() + ": ")
 
106
                fmt.Println(msg...)
 
107
                panic("go/printer")
 
108
        }
 
109
}
 
110
 
96
111
// commentsHaveNewline reports whether a list of comments belonging to
97
112
// an *ast.CommentGroup contains newlines. Because the position information
98
113
// may only be partially correct, we also have to read the comment text.
129
144
        p.commentOffset = infinity
130
145
}
131
146
 
132
 
func (p *printer) internalError(msg ...interface{}) {
133
 
        if debug {
134
 
                fmt.Print(p.pos.String() + ": ")
135
 
                fmt.Println(msg...)
136
 
                panic("go/printer")
 
147
// commentBefore returns true iff the current comment group occurs
 
148
// before the next position in the source code and printing it does
 
149
// not introduce implicit semicolons.
 
150
//
 
151
func (p *printer) commentBefore(next token.Position) bool {
 
152
        return p.commentOffset < next.Offset && (!p.impliedSemi || !p.commentNewline)
 
153
}
 
154
 
 
155
// commentSizeBefore returns the estimated size of the
 
156
// comments on the same line before the next position.
 
157
//
 
158
func (p *printer) commentSizeBefore(next token.Position) int {
 
159
        // save/restore current p.commentInfo (p.nextComment() modifies it)
 
160
        defer func(info commentInfo) {
 
161
                p.commentInfo = info
 
162
        }(p.commentInfo)
 
163
 
 
164
        size := 0
 
165
        for p.commentBefore(next) {
 
166
                for _, c := range p.comment.List {
 
167
                        size += len(c.Text)
 
168
                }
 
169
                p.nextComment()
137
170
        }
 
171
        return size
 
172
}
 
173
 
 
174
// recordLine records the output line number for the next non-whitespace
 
175
// token in *linePtr. It is used to compute an accurate line number for a
 
176
// formatted construct, independent of pending (not yet emitted) whitespace
 
177
// or comments.
 
178
//
 
179
func (p *printer) recordLine(linePtr *int) {
 
180
        p.linePtr = linePtr
 
181
}
 
182
 
 
183
// linesFrom returns the number of output lines between the current
 
184
// output line and the line argument, ignoring any pending (not yet
 
185
// emitted) whitespace or comments. It is used to compute an accurate
 
186
// size (in number of lines) for a formatted construct.
 
187
//
 
188
func (p *printer) linesFrom(line int) int {
 
189
        return p.out.Line - line
138
190
}
139
191
 
140
192
func (p *printer) posFor(pos token.Pos) token.Position {
675
727
 
676
728
        if last != nil {
677
729
                // if the last comment is a /*-style comment and the next item
678
 
                // follows on the same line but is not a comma or a "closing"
679
 
                // token, add an extra blank for separation
680
 
                if last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line && tok != token.COMMA &&
681
 
                        tok != token.RPAREN && tok != token.RBRACK && tok != token.RBRACE {
 
730
                // follows on the same line but is not a comma, and not a "closing"
 
731
                // token immediately following its corresponding "opening" token,
 
732
                // add an extra blank for separation unless explicitly disabled
 
733
                if p.mode&noExtraBlank == 0 &&
 
734
                        last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line &&
 
735
                        tok != token.COMMA &&
 
736
                        (tok != token.RPAREN || p.prevOpen == token.LPAREN) &&
 
737
                        (tok != token.RBRACK || p.prevOpen == token.LBRACK) {
682
738
                        p.writeByte(' ', 1)
683
739
                }
684
740
                // ensure that there is a line break after a //-style comment,
735
791
        }
736
792
 
737
793
        // shift remaining entries down
738
 
        i := 0
739
 
        for ; n < len(p.wsbuf); n++ {
740
 
                p.wsbuf[i] = p.wsbuf[n]
741
 
                i++
742
 
        }
743
 
        p.wsbuf = p.wsbuf[0:i]
 
794
        l := copy(p.wsbuf, p.wsbuf[n:])
 
795
        p.wsbuf = p.wsbuf[:l]
744
796
}
745
797
 
746
798
// ----------------------------------------------------------------------------
790
842
                var isLit bool
791
843
                var impliedSemi bool // value for p.impliedSemi after this arg
792
844
 
 
845
                // record previous opening token, if any
 
846
                switch p.lastTok {
 
847
                case token.ILLEGAL:
 
848
                        // ignore (white space)
 
849
                case token.LPAREN, token.LBRACK:
 
850
                        p.prevOpen = p.lastTok
 
851
                default:
 
852
                        // other tokens followed any opening token
 
853
                        p.prevOpen = token.ILLEGAL
 
854
                }
 
855
 
793
856
                switch x := arg.(type) {
794
857
                case pmode:
795
858
                        // toggle printer mode
899
962
                        }
900
963
                }
901
964
 
 
965
                // the next token starts now - record its line number if requested
 
966
                if p.linePtr != nil {
 
967
                        *p.linePtr = p.out.Line
 
968
                        p.linePtr = nil
 
969
                }
 
970
 
902
971
                p.writeString(next, data, isLit)
903
972
                p.impliedSemi = impliedSemi
904
973
        }
905
974
}
906
975
 
907
 
// commentBefore returns true iff the current comment group occurs
908
 
// before the next position in the source code and printing it does
909
 
// not introduce implicit semicolons.
910
 
//
911
 
func (p *printer) commentBefore(next token.Position) (result bool) {
912
 
        return p.commentOffset < next.Offset && (!p.impliedSemi || !p.commentNewline)
913
 
}
914
 
 
915
976
// flush prints any pending comments and whitespace occurring textually
916
977
// before the position of the next token tok. The flush result indicates
917
978
// if a newline was written or if a formfeed was dropped from the whitespace