blob: 48f059396ad0db0c5a78096688353d6e9cbc7308 [file]
//go:build go1.27
package embedlit
type A struct {
a int
B
}
type B struct {
b int
C
}
type C struct {
c int
D
}
type D struct {
d int
E
}
type E struct {
e int
F
}
type F struct {
f int
}
type G struct {
f int
}
type H struct {
F
G
}
type I struct {
i int
}
type J struct {
F
G
I
}
const zero = 0
type K struct{ L }
type L []int
type T struct {
a int
b int
U
}
type U struct {
x int
V
}
type V struct {
x, y int
}
var (
_ = A{b: 1} // want "embedded field type can be removed from struct literal"
_ = A{a: 1, b: 1, c: 1} // want "embedded field type can be removed from struct literal"
_ = E{F: F{1}} // nope: cannot promote unkeyed fields
_ = D{F: F{1}, d: 1} // want "embedded field type can be removed from struct literal"
_ = D{e: 2, F: F{1}} // want "embedded field type can be removed from struct literal"
_ = A{a: 10, C: C{1, D{d: 1}}} // want "embedded field type can be removed from struct literal"
_ = H{F: F{f: 1}} // nope: cannot promote ambiguous fields
_ = J{i: 1, F: F{f: 1}, G: G{f: 1}} // want "embedded field type can be removed from struct literal"
// multi-line with commas
_ = A{ // want "embedded field type can be removed from struct literal"
b: 1,
}
_ = A{a: 1, B: B{}} // nope: empty composite lit
// don't suggest a fix if it's too tricky to preserve comments
_ = A{ // nope: comments within range to delete
B: B{ // one
C: C{ // two
c: 1, // three
}, // four
}, // five
}
_ = A{ // nope: comments within range to delete
B: B{b: 1 /* comment, with comma */},
a: 2,
}
_ = A{ // nope: comments within range to delete
B: B{
b: 1, // comment, with comma
},
a: 2,
}
_ = A{B: /* comment */ B{b: 1}} // nope: comment in range to delete
_ = A{b: 1 /* comment */, a: 2} // want "embedded field type can be removed from struct literal"
_ = K{L: L{zero: 0}} // nope: cannot promote slice elements
_ = K{L: L{0: 100}} // nope: cannot promote slice elements
_ = A{ // want "embedded field type can be removed from struct literal"
c: 1,
b: 2,
a: 3,
}
_ = A{c: 1} // want "embedded field type can be removed from struct literal"
_ = A{ // want "embedded field type can be removed from struct literal"
c: 1}
_ = A{ // want "embedded field type can be removed from struct literal"
c: 1,
}
_ = A{ // want "embedded field type can be removed from struct literal"
// comment here
c: 1,
}
_ = E{ // want "embedded field type can be removed from struct literal"
e: 2,
f: 1,
}
)
func _() {
t1 := A{a: 1, // want "embedded field assignment can be moved to struct literal"
b: 2}
var t2 A
t2 = A{a: 1, // want "embedded field assignment can be moved to struct literal"
b: 2}
var t3 = A{a: 1, // want "embedded field assignment can be moved to struct literal"
b: 2}
t4 := T{1, 2, U{x: 3}} // nope: can't mix keyed and unkeyed elements
t4.x = 4
t5 := A{a: 1}
_ = t5 // nope: intervening statement
t5.b = 2
t6 := A{a: 1} // nope: value assigned depends on t6 itself
t6.b = t6.a + 1
t7 := A{a: 1, // want "embedded field assignment can be moved to struct literal"
b: foo()}
// Only apply edits from pattern A first even though both patterns apply.
t8 := A{ // want "embedded field type can be removed from struct literal"
b: 1,
}
t8.a = 2
t9 := A{} // nope: multiple assignments not yet supported
t9.a, t9.b = 1, 2
t10 := A{ // want "embedded field assignment can be moved to struct literal"
a: 1, // this comment is preserved
b: 2} // this one too
t11 := A{a: 1, // want "embedded field assignment can be moved to struct literal"
b: 2,
c: 3}
t12 := A{ // want "embedded field assignment can be moved to struct literal"
B: B{
b: 1, // this comment is preserved
}}
t13 := A{ // want "embedded field assignment can be moved to struct literal"
a: 1,
// comment between assignments
b: 2}
t14 := A{ // want "embedded field assignment can be moved to struct literal"
a: 1,
b: foo() +
1}
t15 := A{a: 1} // nope: += in field assignment
t15.b += 2
t16 := A{ // want "embedded field assignment can be moved to struct literal"
a: 1, // comment, with a comma
b: 2}
assgn1, assgn2 := A{}, A{} // nope, multi-assign
assgn1.e = 1
assgn2.e = 1
var (
v = A{} // nope, multi-declaration
othervar = 2
)
v.e = 1
_ = othervar
var v1, v2 = A{}, A{} // nope, multi-declaration
v2.e = 1
_ = v1
t17 := U{}
t17.x = 1 // nope: not embedded
t18 := V{}
t18.x = 1
t18.y = 2 // nope: not embedded
t19 := U{ // want "embedded field assignment can be moved to struct literal"
y: 2,
x: 1}
}
func foo() int {
return 0
}