mirror of
https://github.com/golang/go
synced 2024-11-12 01:50:22 -07:00
cmd/gofmt: normalize integer imaginary literals starting with 0
An 'i' suffix on an integer literal marks the integer literal as a decimal integer imaginary value, even if the literal without the suffix starts with a 0 and thus looks like an octal value: 0123i == 123i // != 0123 * 1i This is at best confusing, and at worst a potential source of bugs. It is always safe to rewrite such literals into the equivalent literal without the leading 0. This CL implements this normalization. Change-Id: Ib77ad535f98b5be912ecbdec20ca1b472c1b4973 Reviewed-on: https://go-review.googlesource.com/c/162538 Run-TryBot: Robert Griesemer <gri@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
613f0a3144
commit
f8abdd6c8a
@ -330,7 +330,9 @@ func backupFile(filename string, data []byte, perm os.FileMode) (string, error)
|
||||
}
|
||||
|
||||
// normalizeNumbers rewrites base prefixes and exponents to
|
||||
// use lower-case letters. It leaves hexadecimal digits alone.
|
||||
// use lower-case letters, and removes leading 0's from
|
||||
// integer imaginary literals. It leaves hexadecimal digits
|
||||
// alone.
|
||||
func normalizeNumbers(n ast.Node) bool {
|
||||
lit, _ := n.(*ast.BasicLit)
|
||||
if lit == nil {
|
||||
@ -339,37 +341,60 @@ func normalizeNumbers(n ast.Node) bool {
|
||||
if len(lit.Value) < 2 {
|
||||
return false // only one digit - nothing to do
|
||||
}
|
||||
// lit.Value >= 2
|
||||
// len(lit.Value) >= 2
|
||||
|
||||
x := lit.Value
|
||||
switch lit.Kind {
|
||||
case token.INT:
|
||||
switch lit.Value[:2] {
|
||||
switch x[:2] {
|
||||
case "0X":
|
||||
lit.Value = "0x" + lit.Value[2:]
|
||||
lit.Value = "0x" + x[2:]
|
||||
case "0O":
|
||||
lit.Value = "0o" + lit.Value[2:]
|
||||
lit.Value = "0o" + x[2:]
|
||||
case "0B":
|
||||
lit.Value = "0b" + lit.Value[2:]
|
||||
lit.Value = "0b" + x[2:]
|
||||
}
|
||||
|
||||
case token.FLOAT:
|
||||
switch lit.Value[:2] {
|
||||
default:
|
||||
if i := strings.LastIndexByte(lit.Value, 'E'); i >= 0 {
|
||||
lit.Value = lit.Value[:i] + "e" + lit.Value[i+1:]
|
||||
if i := strings.LastIndexByte(x, 'E'); i >= 0 {
|
||||
lit.Value = x[:i] + "e" + x[i+1:]
|
||||
}
|
||||
case "0x":
|
||||
if i := strings.LastIndexByte(lit.Value, 'P'); i >= 0 {
|
||||
lit.Value = lit.Value[:i] + "p" + lit.Value[i+1:]
|
||||
if i := strings.LastIndexByte(x, 'P'); i >= 0 {
|
||||
lit.Value = x[:i] + "p" + x[i+1:]
|
||||
}
|
||||
case "0X":
|
||||
if i := strings.LastIndexByte(lit.Value, 'P'); i >= 0 {
|
||||
lit.Value = "0x" + lit.Value[2:i] + "p" + lit.Value[i+1:]
|
||||
if i := strings.LastIndexByte(x, 'P'); i >= 0 {
|
||||
lit.Value = "0x" + x[2:i] + "p" + x[i+1:]
|
||||
} else {
|
||||
lit.Value = "0x" + lit.Value[2:]
|
||||
lit.Value = "0x" + x[2:]
|
||||
}
|
||||
}
|
||||
|
||||
case token.IMAG:
|
||||
// Note that integer imaginary literals may contain
|
||||
// any decimal digit even if they start with zero.
|
||||
// Imaginary literals should always end in 'i' but be
|
||||
// conservative and check anyway before proceeding.
|
||||
if x[0] == '0' && x[len(x)-1] == 'i' && isDecimals(x[1:len(x)-1]) {
|
||||
x = strings.TrimLeft(x, "0_")
|
||||
if x == "i" {
|
||||
x = "0i"
|
||||
}
|
||||
lit.Value = x
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// isDecimals reports whether x consists entirely of decimal digits and underscores.
|
||||
func isDecimals(x string) bool {
|
||||
i := 0
|
||||
for i < len(x) && ('0' <= x[i] && x[i] <= '9' || x[i] == '_') {
|
||||
i++
|
||||
}
|
||||
return i == len(x)
|
||||
}
|
||||
|
14
src/cmd/gofmt/testdata/go2numbers.golden
vendored
14
src/cmd/gofmt/testdata/go2numbers.golden
vendored
@ -141,10 +141,22 @@ const (
|
||||
|
||||
// imaginaries
|
||||
_ = 0i
|
||||
_ = 00i
|
||||
_ = 0i
|
||||
_ = 8i
|
||||
_ = 0i
|
||||
_ = 123i
|
||||
_ = 123i
|
||||
_ = 56789i
|
||||
_ = 1234i
|
||||
_ = 1234567i
|
||||
|
||||
_ = 0i
|
||||
_ = 0i
|
||||
_ = 8i
|
||||
_ = 0i
|
||||
_ = 123i
|
||||
_ = 123i
|
||||
_ = 56_789i
|
||||
_ = 1_234i
|
||||
_ = 1_234_567i
|
||||
|
||||
|
12
src/cmd/gofmt/testdata/go2numbers.input
vendored
12
src/cmd/gofmt/testdata/go2numbers.input
vendored
@ -142,9 +142,21 @@ const (
|
||||
// imaginaries
|
||||
_ = 0i
|
||||
_ = 00i
|
||||
_ = 08i
|
||||
_ = 0000000000i
|
||||
_ = 0123i
|
||||
_ = 0000000123i
|
||||
_ = 0000056789i
|
||||
_ = 1234i
|
||||
_ = 1234567i
|
||||
|
||||
_ = 0i
|
||||
_ = 0_0i
|
||||
_ = 0_8i
|
||||
_ = 0_000_000_000i
|
||||
_ = 0_123i
|
||||
_ = 0_000_000_123i
|
||||
_ = 0_000_056_789i
|
||||
_ = 1_234i
|
||||
_ = 1_234_567i
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user