This test checks the behavior of the 'Add methods to TYPE to implement an
interface...' code action.

-- capabilities.json --
{
	"experimental":{"interactiveResolve":{"inputTypes":["string"]}}
}

-- flags --
-ignore_extra_diags
-errors_ok

-- go.mod --
module golang.org/lsptests/implementinterface

go 1.18

-- bad/bad.go --
package bad

type foo struct{}

// Named
type namedOfPointer *foo //@codeaction("Pointer", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

type namedOfInterface error //@codeaction("Interface", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

// Alias
type aliasOfBasic = int //@codeaction("Basic", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

type aliasOfInterface = error //@codeaction("Interface", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

type aliasOfPointer = *foo //@codeaction("Pointer", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

type aliasOfNamedPointer namedOfPointer //@codeaction("Pointer", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

type aliasOfNameInterface namedOfInterface //@codeaction("Interface", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

// Interface
type iface interface {} //@codeaction("iface", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

// Not package level
func _ () {
    type NamedOfBasic int //@codeaction("Basic", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)

    type NamedOfStruct foo //@codeaction("Struct", "refactor.rewrite.implementInterface", err=re"found 0 CodeActions", answers=`{"interface":"error"}`)
}

-- good/good.go --
package good

type foo struct{}

// Named
type namedOfBasic int //@codeaction("Basic", "refactor.rewrite.implementInterface", edit=namedBasic, answers=`{"interface":"error"}`)

type namedOfStruct foo //@codeaction("Struct", "refactor.rewrite.implementInterface", edit=namedStruct, answers=`{"interface":"error"}`)

type namedOfFunc func(string) bool //@codeaction("Func", "refactor.rewrite.implementInterface", edit=namedFunc, answers=`{"interface":"error"}`)

type namedOfChannel chan struct{} //@codeaction("Channel", "refactor.rewrite.implementInterface", edit=namedChannel, answers=`{"interface":"error"}`)

// Struct
type structType struct{} //@codeaction("Type", "refactor.rewrite.implementInterface", edit=struct, answers=`{"interface":"error"}`)

type genericStructType[T any] struct{} //@codeaction("Type", "refactor.rewrite.implementInterface", edit=genericStruct, answers=`{"interface":"error"}`)

// Alias
type aliasOfNamedBasic namedOfBasic //@codeaction("Basic", "refactor.rewrite.implementInterface", edit=aliasNamedBasic, answers=`{"interface":"error"}`)

type aliasOfNamedStruct namedOfStruct //@codeaction("Struct", "refactor.rewrite.implementInterface", edit=aliasNamedStruct, answers=`{"interface":"error"}`)

-- @aliasNamedBasic/good/good.go --
@@ -20 +20,8 @@
-type aliasOfNamedBasic namedOfBasic //@codeaction("Basic", "refactor.rewrite.implementInterface", edit=aliasNamedBasic, answers=`{"interface":"error"}`)
+type aliasOfNamedBasic namedOfBasic
+
+// Error implements [error].
+func (a *aliasOfNamedBasic) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Basic", "refactor.rewrite.implementInterface", edit=aliasNamedBasic, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- @aliasNamedStruct/good/good.go --
@@ -22 +22,6 @@
-type aliasOfNamedStruct namedOfStruct //@codeaction("Struct", "refactor.rewrite.implementInterface", edit=aliasNamedStruct, answers=`{"interface":"error"}`)
+type aliasOfNamedStruct namedOfStruct
+
+// Error implements [error].
+func (a *aliasOfNamedStruct) Error() string {
+	panic("unimplemented")
+}
@@ -24 +29 @@
+//@codeaction("Struct", "refactor.rewrite.implementInterface", edit=aliasNamedStruct, answers=`{"interface":"error"}`)
-- @genericStruct/good/good.go --
@@ -17 +17,8 @@
-type genericStructType[T any] struct{} //@codeaction("Type", "refactor.rewrite.implementInterface", edit=genericStruct, answers=`{"interface":"error"}`)
+type genericStructType[T any] struct{}
+
+// Error implements [error].
+func (g *genericStructType[T]) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Type", "refactor.rewrite.implementInterface", edit=genericStruct, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- @namedBasic/good/good.go --
@@ -6 +6,8 @@
-type namedOfBasic int //@codeaction("Basic", "refactor.rewrite.implementInterface", edit=namedBasic, answers=`{"interface":"error"}`)
+type namedOfBasic int
+
+// Error implements [error].
+func (n *namedOfBasic) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Basic", "refactor.rewrite.implementInterface", edit=namedBasic, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- @namedChannel/good/good.go --
@@ -12 +12,8 @@
-type namedOfChannel chan struct{} //@codeaction("Channel", "refactor.rewrite.implementInterface", edit=namedChannel, answers=`{"interface":"error"}`)
+type namedOfChannel chan struct{}
+
+// Error implements [error].
+func (n *namedOfChannel) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Channel", "refactor.rewrite.implementInterface", edit=namedChannel, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- @namedFunc/good/good.go --
@@ -10 +10,8 @@
-type namedOfFunc func(string) bool //@codeaction("Func", "refactor.rewrite.implementInterface", edit=namedFunc, answers=`{"interface":"error"}`)
+type namedOfFunc func(string) bool
+
+// Error implements [error].
+func (n *namedOfFunc) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Func", "refactor.rewrite.implementInterface", edit=namedFunc, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- @namedStruct/good/good.go --
@@ -8 +8,8 @@
-type namedOfStruct foo //@codeaction("Struct", "refactor.rewrite.implementInterface", edit=namedStruct, answers=`{"interface":"error"}`)
+type namedOfStruct foo
+
+// Error implements [error].
+func (n *namedOfStruct) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Struct", "refactor.rewrite.implementInterface", edit=namedStruct, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- @struct/good/good.go --
@@ -15 +15,8 @@
-type structType struct{} //@codeaction("Type", "refactor.rewrite.implementInterface", edit=struct, answers=`{"interface":"error"}`)
+type structType struct{}
+
+// Error implements [error].
+func (s *structType) Error() string {
+	panic("unimplemented")
+}
+
+//@codeaction("Type", "refactor.rewrite.implementInterface", edit=struct, answers=`{"interface":"error"}`)
@@ -23 +30 @@
-
-- cycle/a/a.go --
package a

import "golang.org/lsptests/implementinterface/cycle/b"

var _ int = b.B

type Bar struct{}

type A interface {
    Foo(b Bar)
}

-- cycle/b/b.go --
package b

import "golang.org/lsptests/implementinterface/cycle/named"

var _ int = named.C

const B = 1

-- cycle/named/named.go --
package named

const C = 1

// Package a -> b -> named -x-> a.
type Named struct {} //@codeaction("Named", "refactor.rewrite.implementInterface", err=re"import cycle", answers=`{"interface":"golang.org/lsptests/implementinterface/cycle/a.A"}`)

-- cycle/alias/alias.go --
package alias

import "golang.org/lsptests/implementinterface/cycle/named"

var _ int = named.C

// Method should be added to the named type [named.Named].
// Package  a -> b -> named -x-> a.
type Alias = named.Named //@codeaction("Alias", "refactor.rewrite.implementInterface", err=re"import cycle", answers=`{"interface":"golang.org/lsptests/implementinterface/cycle/a.A"}`)

-- visibility/foo/ok.go --
package foo

// We can implement an internal interface without importing its package, as long
// as its methods only use built-in or accessible types.
type Ok struct{} //@codeaction("Ok", "refactor.rewrite.implementInterface", edit=visible, answers=`{"interface":"golang.org/lsptests/implementinterface/visibility/bar/internal/bar.VisibleTypes"}`)

-- visibility/foo/notok.go --
package foo

// We cannot implement this interface because its method signature requires
// importing the internal, inaccessible type bar.Bar.
type NotOk struct{} //@codeaction("NotOk", "refactor.rewrite.implementInterface", err=re"inaccessible package", answers=`{"interface":"golang.org/lsptests/implementinterface/visibility/bar/internal/bar.InvisibleTypes"}`)

-- visibility/bar/internal/bar/bar.go --
package bar

type VisibleTypes interface {
    Bar(string) error
}

type Bar struct{}

type InvisibleTypes interface {
    Bar(Bar) error
}

-- @visible/visibility/foo/ok.go --
@@ -5 +5,6 @@
-type Ok struct{} //@codeaction("Ok", "refactor.rewrite.implementInterface", edit=visible, answers=`{"interface":"golang.org/lsptests/implementinterface/visibility/bar/internal/bar.VisibleTypes"}`)
+type Ok struct{}
+
+// Bar implements [bar.VisibleTypes].
+func (o *Ok) Bar(string) error {
+	panic("unimplemented")
+}
@@ -7 +12 @@
+//@codeaction("Ok", "refactor.rewrite.implementInterface", edit=visible, answers=`{"interface":"golang.org/lsptests/implementinterface/visibility/bar/internal/bar.VisibleTypes"}`)
