Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
10242e80
Commit
10242e80
authored
Nov 05, 2009
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gofmt'ed parts of go
R=rsc
http://go/go-review/1023001
parent
65063bc6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
137 additions
and
127 deletions
+137
-127
nodes.go
src/pkg/go/printer/nodes.go
+37
-33
printer.go
src/pkg/go/printer/printer.go
+80
-75
printer_test.go
src/pkg/go/printer/printer_test.go
+20
-19
No files found.
src/pkg/go/printer/nodes.go
View file @
10242e80
...
@@ -18,9 +18,9 @@ import (
...
@@ -18,9 +18,9 @@ import (
// Disabled formatting - enable eventually and remove the flag.
// Disabled formatting - enable eventually and remove the flag.
const
(
const
(
oneLineFuncDecls
=
false
;
oneLineFuncDecls
=
false
;
compositeLitBlank
=
false
;
compositeLitBlank
=
false
;
stringListMode
=
exprListMode
(
0
);
// previously: noIndent
stringListMode
=
exprListMode
(
0
);
// previously: noIndent
)
)
...
@@ -37,8 +37,10 @@ const (
...
@@ -37,8 +37,10 @@ const (
func
(
p
*
printer
)
linebreak
(
line
,
min
,
max
int
,
ws
whiteSpace
,
newSection
bool
)
(
printedBreak
bool
)
{
func
(
p
*
printer
)
linebreak
(
line
,
min
,
max
int
,
ws
whiteSpace
,
newSection
bool
)
(
printedBreak
bool
)
{
n
:=
line
-
p
.
pos
.
Line
;
n
:=
line
-
p
.
pos
.
Line
;
switch
{
switch
{
case
n
<
min
:
n
=
min
;
case
n
<
min
:
case
n
>
max
:
n
=
max
;
n
=
min
;
case
n
>
max
:
n
=
max
;
}
}
if
n
>
0
{
if
n
>
0
{
p
.
print
(
ws
);
p
.
print
(
ws
);
...
@@ -118,12 +120,13 @@ func (p *printer) stringList(list []*ast.BasicLit, multiLine *bool) {
...
@@ -118,12 +120,13 @@ func (p *printer) stringList(list []*ast.BasicLit, multiLine *bool) {
}
}
type
exprListMode
uint
;
type
exprListMode
uint
const
(
const
(
blankStart
exprListMode
=
1
<<
iota
;
// print a blank before the list
blankStart
exprListMode
=
1
<<
iota
;
// print a blank before the list
commaSep
;
// elements are separated by commas
commaSep
;
// elements are separated by commas
commaTerm
;
// elements are terminated by comma
commaTerm
;
// elements are terminated by comma
noIndent
;
// no extra indentation in multi-line lists
noIndent
;
// no extra indentation in multi-line lists
)
)
...
@@ -150,7 +153,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, mode exprListMo
...
@@ -150,7 +153,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, mode exprListMo
// all list entries on a single line
// all list entries on a single line
for
i
,
x
:=
range
list
{
for
i
,
x
:=
range
list
{
if
i
>
0
{
if
i
>
0
{
if
mode
&
commaSep
!=
0
{
if
mode
&
commaSep
!=
0
{
p
.
print
(
token
.
COMMA
);
p
.
print
(
token
.
COMMA
);
}
}
p
.
print
(
blank
);
p
.
print
(
blank
);
...
@@ -179,7 +182,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, mode exprListMo
...
@@ -179,7 +182,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, mode exprListMo
prev
:=
line
;
prev
:=
line
;
line
=
x
.
Pos
()
.
Line
;
line
=
x
.
Pos
()
.
Line
;
if
i
>
0
{
if
i
>
0
{
if
mode
&
commaSep
!=
0
{
if
mode
&
commaSep
!=
0
{
p
.
print
(
token
.
COMMA
);
p
.
print
(
token
.
COMMA
);
}
}
if
prev
<
line
{
if
prev
<
line
{
...
@@ -200,7 +203,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, mode exprListMo
...
@@ -200,7 +203,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, mode exprListMo
// expression list - be conservative and check anyway
// expression list - be conservative and check anyway
p
.
print
(
unindent
);
p
.
print
(
unindent
);
}
}
p
.
print
(
formfeed
);
// terminating comma needs a line break to look good
p
.
print
(
formfeed
);
// terminating comma needs a line break to look good
}
else
if
ws
==
ignore
&&
mode
&
noIndent
==
0
{
}
else
if
ws
==
ignore
&&
mode
&
noIndent
==
0
{
p
.
print
(
unindent
);
p
.
print
(
unindent
);
}
}
...
@@ -304,7 +307,7 @@ func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace tok
...
@@ -304,7 +307,7 @@ func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace tok
p
.
print
(
"// contains unexported fields"
);
p
.
print
(
"// contains unexported fields"
);
}
}
}
else
{
// interface
}
else
{
// interface
var
ml
bool
;
var
ml
bool
;
for
i
,
f
:=
range
list
{
for
i
,
f
:=
range
list
{
...
@@ -353,7 +356,7 @@ func needsBlanks(expr ast.Expr) bool {
...
@@ -353,7 +356,7 @@ func needsBlanks(expr ast.Expr) bool {
return
false
;
return
false
;
case
*
ast
.
IndexExpr
:
case
*
ast
.
IndexExpr
:
// index expressions don't need blanks if the indexed expressions are simple
// index expressions don't need blanks if the indexed expressions are simple
return
needsBlanks
(
x
.
X
)
return
needsBlanks
(
x
.
X
)
;
case
*
ast
.
CallExpr
:
case
*
ast
.
CallExpr
:
// call expressions need blanks if they have more than one
// call expressions need blanks if they have more than one
// argument or if the function expression needs blanks
// argument or if the function expression needs blanks
...
@@ -539,7 +542,7 @@ func (p *printer) expr1(expr ast.Expr, prec1 int, multiLine *bool) (optSemi bool
...
@@ -539,7 +542,7 @@ func (p *printer) expr1(expr ast.Expr, prec1 int, multiLine *bool) (optSemi bool
p
.
print
(
blank
);
p
.
print
(
blank
);
}
}
p
.
print
(
x
.
Lbrace
,
token
.
LBRACE
);
p
.
print
(
x
.
Lbrace
,
token
.
LBRACE
);
p
.
exprList
(
x
.
Lbrace
,
x
.
Elts
,
commaSep
|
commaTerm
,
multiLine
);
p
.
exprList
(
x
.
Lbrace
,
x
.
Elts
,
commaSep
|
commaTerm
,
multiLine
);
p
.
print
(
x
.
Rbrace
,
token
.
RBRACE
);
p
.
print
(
x
.
Rbrace
,
token
.
RBRACE
);
case
*
ast
.
Ellipsis
:
case
*
ast
.
Ellipsis
:
...
@@ -603,7 +606,7 @@ func (p *printer) expr(x ast.Expr, multiLine *bool) (optSemi bool) {
...
@@ -603,7 +606,7 @@ func (p *printer) expr(x ast.Expr, multiLine *bool) (optSemi bool) {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Statements
// Statements
const
maxStmtNewlines
=
2
// maximum number of newlines between statements
const
maxStmtNewlines
=
2
// maximum number of newlines between statements
// Print the statement list indented, but without a newline after the last statement.
// Print the statement list indented, but without a newline after the last statement.
// Extra line breaks between statements in the source are respected but at most one
// Extra line breaks between statements in the source are respected but at most one
...
@@ -695,7 +698,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
...
@@ -695,7 +698,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
case
*
ast
.
DeclStmt
:
case
*
ast
.
DeclStmt
:
p
.
decl
(
s
.
Decl
,
inStmtList
,
multiLine
);
p
.
decl
(
s
.
Decl
,
inStmtList
,
multiLine
);
optSemi
=
true
;
// decl prints terminating semicolon if necessary
optSemi
=
true
;
// decl prints terminating semicolon if necessary
case
*
ast
.
EmptyStmt
:
case
*
ast
.
EmptyStmt
:
// nothing to do
// nothing to do
...
@@ -775,7 +778,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
...
@@ -775,7 +778,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
}
}
p
.
print
(
s
.
Colon
,
token
.
COLON
);
p
.
print
(
s
.
Colon
,
token
.
COLON
);
p
.
stmtList
(
s
.
Body
,
1
);
p
.
stmtList
(
s
.
Body
,
1
);
optSemi
=
true
;
// "block" without {}'s
optSemi
=
true
;
// "block" without {}'s
case
*
ast
.
SwitchStmt
:
case
*
ast
.
SwitchStmt
:
p
.
print
(
token
.
SWITCH
);
p
.
print
(
token
.
SWITCH
);
...
@@ -793,7 +796,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
...
@@ -793,7 +796,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
}
}
p
.
print
(
s
.
Colon
,
token
.
COLON
);
p
.
print
(
s
.
Colon
,
token
.
COLON
);
p
.
stmtList
(
s
.
Body
,
1
);
p
.
stmtList
(
s
.
Body
,
1
);
optSemi
=
true
;
// "block" without {}'s
optSemi
=
true
;
// "block" without {}'s
case
*
ast
.
TypeSwitchStmt
:
case
*
ast
.
TypeSwitchStmt
:
p
.
print
(
token
.
SWITCH
);
p
.
print
(
token
.
SWITCH
);
...
@@ -822,7 +825,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
...
@@ -822,7 +825,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
}
}
p
.
print
(
s
.
Colon
,
token
.
COLON
);
p
.
print
(
s
.
Colon
,
token
.
COLON
);
p
.
stmtList
(
s
.
Body
,
1
);
p
.
stmtList
(
s
.
Body
,
1
);
optSemi
=
true
;
// "block" without {}'s
optSemi
=
true
;
// "block" without {}'s
case
*
ast
.
SelectStmt
:
case
*
ast
.
SelectStmt
:
p
.
print
(
token
.
SELECT
,
blank
);
p
.
print
(
token
.
SELECT
,
blank
);
...
@@ -862,9 +865,10 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
...
@@ -862,9 +865,10 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) (optSemi bool) {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Declarations
// Declarations
type
declContext
uint
;
type
declContext
uint
const
(
const
(
atTop
declContext
=
iota
;
atTop
declContext
=
iota
;
inGroup
;
inGroup
;
inStmtList
;
inStmtList
;
)
)
...
@@ -876,9 +880,9 @@ const (
...
@@ -876,9 +880,9 @@ const (
//
//
func
(
p
*
printer
)
spec
(
spec
ast
.
Spec
,
n
int
,
context
declContext
,
multiLine
*
bool
)
{
func
(
p
*
printer
)
spec
(
spec
ast
.
Spec
,
n
int
,
context
declContext
,
multiLine
*
bool
)
{
var
(
var
(
optSemi
bool
;
// true if a semicolon is optional
optSemi
bool
;
// true if a semicolon is optional
comment
*
ast
.
CommentGroup
;
// a line comment, if any
comment
*
ast
.
CommentGroup
;
// a line comment, if any
extraTabs
int
;
// number of extra tabs before comment, if any
extraTabs
int
;
// number of extra tabs before comment, if any
)
)
switch
s
:=
spec
.
(
type
)
{
switch
s
:=
spec
.
(
type
)
{
...
@@ -893,7 +897,7 @@ func (p *printer) spec(spec ast.Spec, n int, context declContext, multiLine *boo
...
@@ -893,7 +897,7 @@ func (p *printer) spec(spec ast.Spec, n int, context declContext, multiLine *boo
case
*
ast
.
ValueSpec
:
case
*
ast
.
ValueSpec
:
p
.
leadComment
(
s
.
Doc
);
p
.
leadComment
(
s
.
Doc
);
p
.
identList
(
s
.
Names
,
multiLine
);
// always present
p
.
identList
(
s
.
Names
,
multiLine
);
// always present
if
n
==
1
{
if
n
==
1
{
if
s
.
Type
!=
nil
{
if
s
.
Type
!=
nil
{
p
.
print
(
blank
);
p
.
print
(
blank
);
...
@@ -984,25 +988,25 @@ func (p *printer) genDecl(d *ast.GenDecl, context declContext, multiLine *bool)
...
@@ -984,25 +988,25 @@ func (p *printer) genDecl(d *ast.GenDecl, context declContext, multiLine *bool)
func
(
p
*
printer
)
isOneLiner
(
b
*
ast
.
BlockStmt
)
bool
{
func
(
p
*
printer
)
isOneLiner
(
b
*
ast
.
BlockStmt
)
bool
{
switch
{
switch
{
case
len
(
b
.
List
)
>
1
||
p
.
commentBefore
(
b
.
Rbrace
)
:
case
len
(
b
.
List
)
>
1
||
p
.
commentBefore
(
b
.
Rbrace
)
:
return
false
;
// too many statements or there is a comment - all bets are off
return
false
;
// too many statements or there is a comment - all bets are off
case
len
(
b
.
List
)
==
0
:
case
len
(
b
.
List
)
==
0
:
return
true
;
// empty block and no comments
return
true
;
// empty block and no comments
}
}
// test-print the statement and see if it would fit
// test-print the statement and see if it would fit
var
buf
bytes
.
Buffer
;
var
buf
bytes
.
Buffer
;
_
,
err
:=
p
.
Config
.
Fprint
(
&
buf
,
b
.
List
[
0
]);
_
,
err
:=
p
.
Config
.
Fprint
(
&
buf
,
b
.
List
[
0
]);
if
err
!=
nil
{
if
err
!=
nil
{
return
false
;
// don't try
return
false
;
// don't try
}
}
if
buf
.
Len
()
>
40
{
if
buf
.
Len
()
>
40
{
return
false
;
// too long
return
false
;
// too long
}
}
for
_
,
ch
:=
range
buf
.
Bytes
()
{
for
_
,
ch
:=
range
buf
.
Bytes
()
{
if
ch
<
' '
{
if
ch
<
' '
{
return
false
;
// contains control chars (tabs, newlines)
return
false
;
// contains control chars (tabs, newlines)
}
}
}
}
...
@@ -1075,7 +1079,7 @@ func (p *printer) decl(decl ast.Decl, context declContext, multiLine *bool) {
...
@@ -1075,7 +1079,7 @@ func (p *printer) decl(decl ast.Decl, context declContext, multiLine *bool) {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Files
// Files
const
maxDeclNewlines
=
3
// maximum number of newlines between declarations
const
maxDeclNewlines
=
3
// maximum number of newlines between declarations
func
declToken
(
decl
ast
.
Decl
)
(
tok
token
.
Token
)
{
func
declToken
(
decl
ast
.
Decl
)
(
tok
token
.
Token
)
{
tok
=
token
.
ILLEGAL
;
tok
=
token
.
ILLEGAL
;
...
...
src/pkg/go/printer/printer.go
View file @
10242e80
...
@@ -20,35 +20,35 @@ import (
...
@@ -20,35 +20,35 @@ import (
const
(
const
(
debug
=
false
;
// enable for debugging
debug
=
false
;
// enable for debugging
maxNewlines
=
3
;
// maximum vertical white space
maxNewlines
=
3
;
// maximum vertical white space
)
)
type
whiteSpace
int
type
whiteSpace
int
const
(
const
(
ignore
=
whiteSpace
(
0
);
ignore
=
whiteSpace
(
0
);
blank
=
whiteSpace
(
' '
);
blank
=
whiteSpace
(
' '
);
vtab
=
whiteSpace
(
'\v'
);
vtab
=
whiteSpace
(
'\v'
);
newline
=
whiteSpace
(
'\n'
);
newline
=
whiteSpace
(
'\n'
);
formfeed
=
whiteSpace
(
'\f'
);
formfeed
=
whiteSpace
(
'\f'
);
indent
=
whiteSpace
(
'>'
);
indent
=
whiteSpace
(
'>'
);
unindent
=
whiteSpace
(
'<'
);
unindent
=
whiteSpace
(
'<'
);
)
)
var
(
var
(
esc
=
[]
byte
{
tabwriter
.
Escape
};
esc
=
[]
byte
{
tabwriter
.
Escape
};
htab
=
[]
byte
{
'\t'
};
htab
=
[]
byte
{
'\t'
};
htabs
=
[
...
]
byte
{
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
};
htabs
=
[
...
]
byte
{
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
};
newlines
=
[
...
]
byte
{
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
};
// more than maxNewlines
newlines
=
[
...
]
byte
{
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
,
'\n'
};
// more than maxNewlines
esc_quot
=
strings
.
Bytes
(
"""
);
// shorter than """
esc_quot
=
strings
.
Bytes
(
"""
);
// shorter than """
esc_apos
=
strings
.
Bytes
(
"'"
);
// shorter than "'"
esc_apos
=
strings
.
Bytes
(
"'"
);
// shorter than "'"
esc_amp
=
strings
.
Bytes
(
"&"
);
esc_amp
=
strings
.
Bytes
(
"&"
);
esc_lt
=
strings
.
Bytes
(
"<"
);
esc_lt
=
strings
.
Bytes
(
"<"
);
esc_gt
=
strings
.
Bytes
(
">"
);
esc_gt
=
strings
.
Bytes
(
">"
);
)
)
...
@@ -57,38 +57,38 @@ var noPos token.Position
...
@@ -57,38 +57,38 @@ var noPos token.Position
// Use ignoreMultiLine if the multiLine information is not important.
// Use ignoreMultiLine if the multiLine information is not important.
var
ignoreMultiLine
=
new
(
bool
)
;
var
ignoreMultiLine
=
new
(
bool
)
type
printer
struct
{
type
printer
struct
{
// Configuration (does not change after initialization)
// Configuration (does not change after initialization)
output
io
.
Writer
;
output
io
.
Writer
;
Config
;
Config
;
errors
chan
os
.
Error
;
errors
chan
os
.
Error
;
// Current state
// Current state
written
int
;
// number of bytes written
written
int
;
// number of bytes written
indent
int
;
// current indentation
indent
int
;
// current indentation
escape
bool
;
// true if in escape sequence
escape
bool
;
// true if in escape sequence
// Buffered whitespace
// Buffered whitespace
buffer
[]
whiteSpace
;
buffer
[]
whiteSpace
;
// The (possibly estimated) position in the generated output;
// The (possibly estimated) position in the generated output;
// in AST space (i.e., pos is set whenever a token position is
// in AST space (i.e., pos is set whenever a token position is
// known accurately, and updated dependending on what has been
// known accurately, and updated dependending on what has been
// written)
// written)
pos
token
.
Position
;
pos
token
.
Position
;
// The value of pos immediately after the last item has been
// The value of pos immediately after the last item has been
// written using writeItem.
// written using writeItem.
last
token
.
Position
;
last
token
.
Position
;
// HTML support
// HTML support
lastTaggedLine
int
;
// last line for which a line tag was written
lastTaggedLine
int
;
// last line for which a line tag was written
// The list of comments; or nil.
// The list of comments; or nil.
comment
*
ast
.
CommentGroup
;
comment
*
ast
.
CommentGroup
;
}
}
...
@@ -96,7 +96,7 @@ func (p *printer) init(output io.Writer, cfg *Config) {
...
@@ -96,7 +96,7 @@ func (p *printer) init(output io.Writer, cfg *Config) {
p
.
output
=
output
;
p
.
output
=
output
;
p
.
Config
=
*
cfg
;
p
.
Config
=
*
cfg
;
p
.
errors
=
make
(
chan
os
.
Error
);
p
.
errors
=
make
(
chan
os
.
Error
);
p
.
buffer
=
make
([]
whiteSpace
,
0
,
16
);
// whitespace sequences are short
p
.
buffer
=
make
([]
whiteSpace
,
0
,
16
);
// whitespace sequences are short
}
}
...
@@ -126,7 +126,7 @@ func (p *printer) write(data []byte) {
...
@@ -126,7 +126,7 @@ func (p *printer) write(data []byte) {
p
.
write0
(
data
[
i0
:
i
+
1
]);
p
.
write0
(
data
[
i0
:
i
+
1
]);
// update p.pos
// update p.pos
p
.
pos
.
Offset
+=
i
+
1
-
i0
;
p
.
pos
.
Offset
+=
i
+
1
-
i0
;
p
.
pos
.
Line
++
;
p
.
pos
.
Line
++
;
p
.
pos
.
Column
=
1
;
p
.
pos
.
Column
=
1
;
...
@@ -151,21 +151,26 @@ func (p *printer) write(data []byte) {
...
@@ -151,21 +151,26 @@ func (p *printer) write(data []byte) {
case
'"'
,
'\'
'
,
'&'
,
'<'
,
'>'
:
case
'"'
,
'\'
'
,
'&'
,
'<'
,
'>'
:
if
p
.
Mode
&
GenHTML
!=
0
{
if
p
.
Mode
&
GenHTML
!=
0
{
// write segment ending in b
// write segment ending in b
p
.
write0
(
data
[
i0
:
i
]);
p
.
write0
(
data
[
i0
:
i
]);
// write HTML-escaped b
// write HTML-escaped b
var
esc
[]
byte
;
var
esc
[]
byte
;
switch
b
{
switch
b
{
case
'"'
:
esc
=
esc_quot
;
case
'"'
:
case
'\'
'
:
esc
=
esc_apos
;
esc
=
esc_quot
;
case
'&'
:
esc
=
esc_amp
;
case
'\'
'
:
case
'<'
:
esc
=
esc_lt
;
esc
=
esc_apos
;
case
'>'
:
esc
=
esc_gt
;
case
'&'
:
esc
=
esc_amp
;
case
'<'
:
esc
=
esc_lt
;
case
'>'
:
esc
=
esc_gt
;
}
}
p
.
write0
(
esc
);
p
.
write0
(
esc
);
// update p.pos
// update p.pos
d
:=
i
+
1
-
i0
;
d
:=
i
+
1
-
i0
;
p
.
pos
.
Offset
+=
d
;
p
.
pos
.
Offset
+=
d
;
p
.
pos
.
Column
+=
d
;
p
.
pos
.
Column
+=
d
;
...
@@ -179,10 +184,10 @@ func (p *printer) write(data []byte) {
...
@@ -179,10 +184,10 @@ func (p *printer) write(data []byte) {
}
}
// write remaining segment
// write remaining segment
p
.
write0
(
data
[
i0
:
len
(
data
)]);
p
.
write0
(
data
[
i0
:
len
(
data
)]);
// update p.pos
// update p.pos
d
:=
len
(
data
)
-
i0
;
d
:=
len
(
data
)
-
i0
;
p
.
pos
.
Offset
+=
d
;
p
.
pos
.
Offset
+=
d
;
p
.
pos
.
Column
+=
d
;
p
.
pos
.
Column
+=
d
;
}
}
...
@@ -193,7 +198,7 @@ func (p *printer) writeNewlines(n int) {
...
@@ -193,7 +198,7 @@ func (p *printer) writeNewlines(n int) {
if
n
>
maxNewlines
{
if
n
>
maxNewlines
{
n
=
maxNewlines
;
n
=
maxNewlines
;
}
}
p
.
write
(
newlines
[
0
:
n
]);
p
.
write
(
newlines
[
0
:
n
]);
}
}
}
}
...
@@ -367,8 +372,8 @@ func split(text []byte) [][]byte {
...
@@ -367,8 +372,8 @@ func split(text []byte) [][]byte {
i
:=
0
;
i
:=
0
;
for
j
,
c
:=
range
text
{
for
j
,
c
:=
range
text
{
if
c
==
'\n'
{
if
c
==
'\n'
{
lines
[
n
]
=
text
[
i
:
j
];
// exclude newline
lines
[
n
]
=
text
[
i
:
j
];
// exclude newline
i
=
j
+
1
;
// discard newline
i
=
j
+
1
;
// discard newline
n
++
;
n
++
;
}
}
}
}
...
@@ -393,15 +398,15 @@ func commonPrefix(a, b []byte) []byte {
...
@@ -393,15 +398,15 @@ func commonPrefix(a, b []byte) []byte {
for
i
<
len
(
a
)
&&
i
<
len
(
b
)
&&
a
[
i
]
==
b
[
i
]
&&
(
a
[
i
]
<=
' '
||
a
[
i
]
==
'*'
)
{
for
i
<
len
(
a
)
&&
i
<
len
(
b
)
&&
a
[
i
]
==
b
[
i
]
&&
(
a
[
i
]
<=
' '
||
a
[
i
]
==
'*'
)
{
i
++
;
i
++
;
}
}
return
a
[
0
:
i
];
return
a
[
0
:
i
];
}
}
func
stripCommonPrefix
(
lines
[][]
byte
)
{
func
stripCommonPrefix
(
lines
[][]
byte
)
{
if
len
(
lines
)
<
2
{
if
len
(
lines
)
<
2
{
return
;
// at most one line - nothing to do
return
;
// at most one line - nothing to do
}
}
// The heuristic in this function tries to handle a few
// The heuristic in this function tries to handle a few
// common patterns of /*-style comments: Comments where
// common patterns of /*-style comments: Comments where
// the opening /* and closing */ are aligned and the
// the opening /* and closing */ are aligned and the
...
@@ -434,7 +439,7 @@ func stripCommonPrefix(lines [][]byte) {
...
@@ -434,7 +439,7 @@ func stripCommonPrefix(lines [][]byte) {
if
i
:=
bytes
.
Index
(
prefix
,
[]
byte
{
'*'
});
i
>=
0
{
if
i
:=
bytes
.
Index
(
prefix
,
[]
byte
{
'*'
});
i
>=
0
{
// Line of stars present.
// Line of stars present.
if
i
>
0
&&
prefix
[
i
-
1
]
==
' '
{
if
i
>
0
&&
prefix
[
i
-
1
]
==
' '
{
i
--
;
// remove trailing blank from prefix so stars remain aligned
i
--
;
// remove trailing blank from prefix so stars remain aligned
}
}
prefix
=
prefix
[
0
:
i
];
prefix
=
prefix
[
0
:
i
];
lineOfStars
=
true
;
lineOfStars
=
true
;
...
@@ -447,7 +452,7 @@ func stripCommonPrefix(lines [][]byte) {
...
@@ -447,7 +452,7 @@ func stripCommonPrefix(lines [][]byte) {
// for the opening /*, assume up to 3 blanks or a tab. This
// for the opening /*, assume up to 3 blanks or a tab. This
// whitespace may be found as suffix in the common prefix.
// whitespace may be found as suffix in the common prefix.
first
:=
lines
[
0
];
first
:=
lines
[
0
];
if
isBlank
(
first
[
2
:
len
(
first
)])
{
if
isBlank
(
first
[
2
:
len
(
first
)])
{
// no comment text on the first line:
// no comment text on the first line:
// reduce prefix by up to 3 blanks or a tab
// reduce prefix by up to 3 blanks or a tab
// if present - this keeps comment text indented
// if present - this keeps comment text indented
...
@@ -480,7 +485,7 @@ func stripCommonPrefix(lines [][]byte) {
...
@@ -480,7 +485,7 @@ func stripCommonPrefix(lines [][]byte) {
// Shorten the computed common prefix by the length of
// Shorten the computed common prefix by the length of
// suffix, if it is found as suffix of the prefix.
// suffix, if it is found as suffix of the prefix.
if
bytes
.
HasSuffix
(
prefix
,
suffix
)
{
if
bytes
.
HasSuffix
(
prefix
,
suffix
)
{
prefix
=
prefix
[
0
:
len
(
prefix
)
-
len
(
suffix
)];
prefix
=
prefix
[
0
:
len
(
prefix
)
-
len
(
suffix
)];
}
}
}
}
}
}
...
@@ -508,7 +513,7 @@ func stripCommonPrefix(lines [][]byte) {
...
@@ -508,7 +513,7 @@ func stripCommonPrefix(lines [][]byte) {
// Remove the common prefix from all but the first and empty lines.
// Remove the common prefix from all but the first and empty lines.
for
i
,
line
:=
range
lines
{
for
i
,
line
:=
range
lines
{
if
i
>
0
&&
len
(
line
)
!=
0
{
if
i
>
0
&&
len
(
line
)
!=
0
{
lines
[
i
]
=
line
[
len
(
prefix
)
:
len
(
line
)];
lines
[
i
]
=
line
[
len
(
prefix
)
:
len
(
line
)];
}
}
}
}
}
}
...
@@ -636,7 +641,7 @@ func (p *printer) writeWhitespace(n int) {
...
@@ -636,7 +641,7 @@ func (p *printer) writeWhitespace(n int) {
// of lines before the label; effectively leading to wrong
// of lines before the label; effectively leading to wrong
// indentation.
// indentation.
p
.
buffer
[
i
],
p
.
buffer
[
i
+
1
]
=
unindent
,
formfeed
;
p
.
buffer
[
i
],
p
.
buffer
[
i
+
1
]
=
unindent
,
formfeed
;
i
--
;
// do it again
i
--
;
// do it again
continue
;
continue
;
}
}
fallthrough
;
fallthrough
;
...
@@ -675,7 +680,7 @@ func (p *printer) print(args ...) {
...
@@ -675,7 +680,7 @@ func (p *printer) print(args ...) {
for
i
:=
0
;
i
<
v
.
NumField
();
i
++
{
for
i
:=
0
;
i
<
v
.
NumField
();
i
++
{
f
:=
v
.
Field
(
i
);
f
:=
v
.
Field
(
i
);
next
:=
p
.
pos
;
// estimated position of next item
next
:=
p
.
pos
;
// estimated position of next item
var
data
[]
byte
;
var
data
[]
byte
;
var
tag
HtmlTag
;
var
tag
HtmlTag
;
isKeyword
:=
false
;
isKeyword
:=
false
;
...
@@ -721,7 +726,7 @@ func (p *printer) print(args ...) {
...
@@ -721,7 +726,7 @@ func (p *printer) print(args ...) {
// (note that valid Go programs cannot contain esc ('\xff')
// (note that valid Go programs cannot contain esc ('\xff')
// bytes since they do not appear in legal UTF-8 sequences)
// bytes since they do not appear in legal UTF-8 sequences)
// TODO(gri): this this more efficiently.
// TODO(gri): this this more efficiently.
data
=
strings
.
Bytes
(
"
\xff
"
+
string
(
data
)
+
"
\xff
"
);
data
=
strings
.
Bytes
(
"
\xff
"
+
string
(
data
)
+
"
\xff
"
);
case
token
.
Token
:
case
token
.
Token
:
if
p
.
Styler
!=
nil
{
if
p
.
Styler
!=
nil
{
data
,
tag
=
p
.
Styler
.
Token
(
x
);
data
,
tag
=
p
.
Styler
.
Token
(
x
);
...
@@ -731,7 +736,7 @@ func (p *printer) print(args ...) {
...
@@ -731,7 +736,7 @@ func (p *printer) print(args ...) {
isKeyword
=
x
.
IsKeyword
();
isKeyword
=
x
.
IsKeyword
();
case
token
.
Position
:
case
token
.
Position
:
if
x
.
IsValid
()
{
if
x
.
IsValid
()
{
next
=
x
;
// accurate position of next item
next
=
x
;
// accurate position of next item
}
}
default
:
default
:
panicln
(
"print: unsupported argument type"
,
f
.
Type
()
.
String
());
panicln
(
"print: unsupported argument type"
,
f
.
Type
()
.
String
());
...
@@ -782,8 +787,8 @@ func (p *printer) flush(next token.Position, isKeyword bool) {
...
@@ -782,8 +787,8 @@ func (p *printer) flush(next token.Position, isKeyword bool) {
// is used).
// is used).
//
//
type
trimmer
struct
{
type
trimmer
struct
{
output
io
.
Writer
;
output
io
.
Writer
;
buf
bytes
.
Buffer
;
buf
bytes
.
Buffer
;
}
}
...
@@ -815,7 +820,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
...
@@ -815,7 +820,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
}
}
case
'\v'
:
case
'\v'
:
b
=
'\t'
;
// convert to htab
b
=
'\t'
;
// convert to htab
fallthrough
;
fallthrough
;
case
'\t'
,
' '
,
tabwriter
.
Escape
:
case
'\t'
,
' '
,
tabwriter
.
Escape
:
...
@@ -828,7 +833,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
...
@@ -828,7 +833,7 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
}
}
// collect whitespace but discard tabrwiter.Escapes.
// collect whitespace but discard tabrwiter.Escapes.
if
b
!=
tabwriter
.
Escape
{
if
b
!=
tabwriter
.
Escape
{
p
.
buf
.
WriteByte
(
b
);
// WriteByte returns no errors
p
.
buf
.
WriteByte
(
b
);
// WriteByte returns no errors
}
}
case
'\f'
,
'\n'
:
case
'\f'
,
'\n'
:
...
@@ -865,15 +870,15 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
...
@@ -865,15 +870,15 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
// General printing is controlled with these Config.Mode flags.
// General printing is controlled with these Config.Mode flags.
const
(
const
(
GenHTML
uint
=
1
<<
iota
;
// generate HTML
GenHTML
uint
=
1
<<
iota
;
// generate HTML
RawFormat
;
// do not use a tabwriter; if set, UseSpaces is ignored
RawFormat
;
// do not use a tabwriter; if set, UseSpaces is ignored
UseSpaces
;
// use spaces instead of tabs for indentation and alignment
UseSpaces
;
// use spaces instead of tabs for indentation and alignment
)
)
// An HtmlTag specifies a start and end tag.
// An HtmlTag specifies a start and end tag.
type
HtmlTag
struct
{
type
HtmlTag
struct
{
Start
,
End
string
;
// empty if tags are absent
Start
,
End
string
;
// empty if tags are absent
}
}
...
@@ -882,18 +887,18 @@ type HtmlTag struct {
...
@@ -882,18 +887,18 @@ type HtmlTag struct {
//
//
type
Styler
interface
{
type
Styler
interface
{
LineTag
(
line
int
)
([]
byte
,
HtmlTag
);
LineTag
(
line
int
)
([]
byte
,
HtmlTag
);
Comment
(
c
*
ast
.
Comment
,
line
[]
byte
)
([]
byte
,
HtmlTag
);
Comment
(
c
*
ast
.
Comment
,
line
[]
byte
)
([]
byte
,
HtmlTag
);
BasicLit
(
x
*
ast
.
BasicLit
)
([]
byte
,
HtmlTag
);
BasicLit
(
x
*
ast
.
BasicLit
)
([]
byte
,
HtmlTag
);
Ident
(
id
*
ast
.
Ident
)
([]
byte
,
HtmlTag
);
Ident
(
id
*
ast
.
Ident
)
([]
byte
,
HtmlTag
);
Token
(
tok
token
.
Token
)
([]
byte
,
HtmlTag
);
Token
(
tok
token
.
Token
)
([]
byte
,
HtmlTag
);
}
}
// A Config node controls the output of Fprint.
// A Config node controls the output of Fprint.
type
Config
struct
{
type
Config
struct
{
Mode
uint
;
// default: 0
Mode
uint
;
// default: 0
Tabwidth
int
;
// default: 8
Tabwidth
int
;
// default: 8
Styler
Styler
;
// default: nil
Styler
Styler
;
// default: nil
}
}
...
@@ -942,14 +947,14 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
...
@@ -942,14 +947,14 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
p
.
errors
<-
os
.
NewError
(
fmt
.
Sprintf
(
"printer.Fprint: unsupported node type %T"
,
n
));
p
.
errors
<-
os
.
NewError
(
fmt
.
Sprintf
(
"printer.Fprint: unsupported node type %T"
,
n
));
runtime
.
Goexit
();
runtime
.
Goexit
();
}
}
p
.
flush
(
token
.
Position
{
Offset
:
1
<<
30
,
Line
:
1
<<
30
},
false
);
// flush to "infinity"
p
.
flush
(
token
.
Position
{
Offset
:
1
<<
30
,
Line
:
1
<<
30
},
false
);
// flush to "infinity"
p
.
errors
<-
nil
;
// no errors
p
.
errors
<-
nil
;
// no errors
}();
}();
err
:=
<-
p
.
errors
;
// wait for completion of goroutine
err
:=
<-
p
.
errors
;
// wait for completion of goroutine
// flush tabwriter, if any
// flush tabwriter, if any
if
tw
!=
nil
{
if
tw
!=
nil
{
tw
.
Flush
();
// ignore errors
tw
.
Flush
();
// ignore errors
}
}
return
p
.
written
,
err
;
return
p
.
written
,
err
;
...
@@ -960,6 +965,6 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
...
@@ -960,6 +965,6 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
// It calls Config.Fprint with default settings.
// It calls Config.Fprint with default settings.
//
//
func
Fprint
(
output
io
.
Writer
,
node
interface
{})
os
.
Error
{
func
Fprint
(
output
io
.
Writer
,
node
interface
{})
os
.
Error
{
_
,
err
:=
(
&
Config
{
Tabwidth
:
8
})
.
Fprint
(
output
,
node
);
// don't care about number of bytes written
_
,
err
:=
(
&
Config
{
Tabwidth
:
8
})
.
Fprint
(
output
,
node
);
// don't care about number of bytes written
return
err
;
return
err
;
}
}
src/pkg/go/printer/printer_test.go
View file @
10242e80
...
@@ -16,12 +16,12 @@ import (
...
@@ -16,12 +16,12 @@ import (
const
(
const
(
dataDir
=
"testdata"
;
dataDir
=
"testdata"
;
tabwidth
=
8
;
tabwidth
=
8
;
)
)
var
update
=
flag
.
Bool
(
"update"
,
false
,
"update golden files"
)
;
var
update
=
flag
.
Bool
(
"update"
,
false
,
"update golden files"
)
func
lineString
(
text
[]
byte
,
i
int
)
string
{
func
lineString
(
text
[]
byte
,
i
int
)
string
{
...
@@ -29,13 +29,14 @@ func lineString(text []byte, i int) string {
...
@@ -29,13 +29,14 @@ func lineString(text []byte, i int) string {
for
i
<
len
(
text
)
&&
text
[
i
]
!=
'\n'
{
for
i
<
len
(
text
)
&&
text
[
i
]
!=
'\n'
{
i
++
;
i
++
;
}
}
return
string
(
text
[
i0
:
i
]);
return
string
(
text
[
i0
:
i
]);
}
}
type
checkMode
uint
;
type
checkMode
uint
const
(
const
(
export
checkMode
=
1
<<
iota
;
export
checkMode
=
1
<<
iota
;
rawFormat
;
rawFormat
;
)
)
...
@@ -50,13 +51,13 @@ func check(t *testing.T, source, golden string, mode checkMode) {
...
@@ -50,13 +51,13 @@ func check(t *testing.T, source, golden string, mode checkMode) {
// filter exports if necessary
// filter exports if necessary
if
mode
&
export
!=
0
{
if
mode
&
export
!=
0
{
ast
.
FileExports
(
prog
);
// ignore result
ast
.
FileExports
(
prog
);
// ignore result
prog
.
Comments
=
nil
;
// don't print comments that are not in AST
prog
.
Comments
=
nil
;
// don't print comments that are not in AST
}
}
// determine printer configuration
// determine printer configuration
cfg
:=
Config
{
Tabwidth
:
tabwidth
};
cfg
:=
Config
{
Tabwidth
:
tabwidth
};
if
mode
&
rawFormat
!=
0
{
if
mode
&
rawFormat
!=
0
{
cfg
.
Mode
|=
RawFormat
;
cfg
.
Mode
|=
RawFormat
;
}
}
...
@@ -105,20 +106,20 @@ func check(t *testing.T, source, golden string, mode checkMode) {
...
@@ -105,20 +106,20 @@ func check(t *testing.T, source, golden string, mode checkMode) {
type
entry
struct
{
type
entry
struct
{
source
,
golden
string
;
source
,
golden
string
;
mode
checkMode
;
mode
checkMode
;
}
}
// Use gotest -update to create/update the respective golden files.
// Use gotest -update to create/update the respective golden files.
var
data
=
[]
entry
{
var
data
=
[]
entry
{
entry
{
"empty.input"
,
"empty.golden"
,
0
},
entry
{
"empty.input"
,
"empty.golden"
,
0
},
entry
{
"comments.input"
,
"comments.golden"
,
0
},
entry
{
"comments.input"
,
"comments.golden"
,
0
},
entry
{
"comments.input"
,
"comments.x"
,
export
},
entry
{
"comments.input"
,
"comments.x"
,
export
},
entry
{
"linebreaks.input"
,
"linebreaks.golden"
,
0
},
entry
{
"linebreaks.input"
,
"linebreaks.golden"
,
0
},
entry
{
"expressions.input"
,
"expressions.golden"
,
0
},
entry
{
"expressions.input"
,
"expressions.golden"
,
0
},
entry
{
"expressions.input"
,
"expressions.raw"
,
rawFormat
},
entry
{
"expressions.input"
,
"expressions.raw"
,
rawFormat
},
entry
{
"declarations.input"
,
"declarations.golden"
,
0
},
entry
{
"declarations.input"
,
"declarations.golden"
,
0
},
entry
{
"statements.input"
,
"statements.golden"
,
0
},
entry
{
"statements.input"
,
"statements.golden"
,
0
},
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment