@@ -288,4 +288,161 @@ class CompletionTest {
288288 |import Foo.b $m1""" .withSource
289289 .completion(m1, Set ((" bar" , Field , " type and lazy value bar" )))
290290 }
291+
292+ @ Test def completeExtensionMethodWithoutParameter : Unit = {
293+ code """ object Foo
294+ |extension (foo: Foo.type) def xxxx = 1
295+ |object Main { Foo.xx ${m1} } """ .withSource
296+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
297+ }
298+
299+ @ Test def completeExtensionMethodWithParameter : Unit = {
300+ code """ object Foo
301+ |extension (foo: Foo.type) def xxxx(i: Int) = i
302+ |object Main { Foo.xx ${m1} } """ .withSource
303+ .completion(m1, Set ((" xxxx" , Method , " (i: Int): Int" )))
304+ }
305+
306+ @ Test def completeExtensionMethodWithTypeParameter : Unit = {
307+ code """ object Foo
308+ |extension [A](foo: Foo.type) def xxxx: Int = 1
309+ |object Main { Foo.xx ${m1} } """ .withSource
310+ .completion(m1, Set ((" xxxx" , Method , " [A] => Int" )))
311+ }
312+
313+ @ Test def completeExtensionMethodWithParameterAndTypeParameter : Unit = {
314+ code """ object Foo
315+ |extension [A](foo: Foo.type) def xxxx(a: A) = a
316+ |object Main { Foo.xx ${m1} } """ .withSource
317+ .completion(m1, Set ((" xxxx" , Method , " [A](a: A): A" )))
318+ }
319+
320+ @ Test def completeExtensionMethodFromExtenionWithAUsingSection : Unit = {
321+ code """ object Foo
322+ |trait Bar
323+ |trait Baz
324+ |given Bar = new Bar {}
325+ |given Baz = new Baz {}
326+ |extension (foo: Foo.type)(using Bar, Baz) def xxxx = 1
327+ |object Main { Foo.xx ${m1} } """ .withSource
328+ .completion(m1, Set ((" xxxx" , Method , " (using x$1: Bar, x$2: Baz): Int" )))
329+ }
330+
331+ @ Test def completeExtensionMethodFromExtenionWithMultipleUsingSections : Unit = {
332+ code """ object Foo
333+ |trait Bar
334+ |trait Baz
335+ |given Bar = new Bar {}
336+ |given Baz = new Baz {}
337+ |extension (foo: Foo.type)(using Bar)(using Baz) def xxxx = 1
338+ |object Main { Foo.xx ${m1} } """ .withSource
339+ .completion(m1, Set ((" xxxx" , Method , " (using x$1: Bar)(using x$2: Baz): Int" )))
340+ }
341+
342+ @ Test def completeInheritedExtensionMethod : Unit = {
343+ code """ object Foo
344+ |trait FooOps {
345+ | extension (foo: Foo.type) def xxxx = 1
346+ |}
347+ |object Main extends FooOps { Foo.xx ${m1} } """ .withSource
348+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
349+ }
350+
351+ @ Test def completeRenamedExtensionMethod : Unit = {
352+ code """ object Foo
353+ |object FooOps {
354+ | extension (foo: Foo.type) def xxxx = 1
355+ |}
356+ |import FooOps.{xxxx => yyyy}
357+ |object Main { Foo.yy ${m1} } """ .withSource
358+ .completion(m1, Set ((" yyyy" , Method , " => Int" )))
359+ }
360+
361+ @ Test def completeExtensionMethodFromGivenInstanceDefinedInScope : Unit = {
362+ code """ object Foo
363+ |trait FooOps
364+ |given FooOps {
365+ | extension (foo: Foo.type) def xxxx = 1
366+ |}
367+ |object Main { Foo.xx ${m1} } """ .withSource
368+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
369+ }
370+
371+ @ Test def completeExtensionMethodFromImportedGivenInstance : Unit = {
372+ code """ object Foo
373+ |trait FooOps
374+ |object Bar {
375+ | given FooOps {
376+ | extension (foo: Foo.type) def xxxx = 1
377+ | }
378+ |}
379+ |import Bar.given
380+ |object Main { Foo.xx ${m1} } """ .withSource
381+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
382+ }
383+
384+ @ Test def completeExtensionMethodFromImplicitScope : Unit = {
385+ code """ case class Foo(i: Int)
386+ |object Foo {
387+ | extension (foo: Foo) def xxxx = foo.i
388+ |}
389+ |object Main { Foo(123).xx ${m1} } """ .withSource
390+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
391+ }
392+
393+ @ Test def completeExtensionMethodFromGivenInImplicitScope : Unit = {
394+ code """ trait Bar
395+ |case class Foo(i: Int)
396+ |object Foo {
397+ | given Bar {
398+ | extension (foo: Foo) def xxxx = foo.i
399+ | }
400+ |}
401+ |object Main { Foo(123).xx ${m1} } """ .withSource
402+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
403+ }
404+
405+ @ Test def completeExtensionMethodOnResultOfImplicitConversion : Unit = {
406+ code """ import scala.language.implicitConversions
407+ |case class Foo(i: Int)
408+ |extension (foo: Foo) def xxxx = foo.i
409+ |given Conversion[Int, Foo] = Foo(_)
410+ |object Main { 123.xx ${m1} } """ .withSource
411+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
412+ }
413+
414+ @ Test def dontCompleteExtensionMethodWithMismatchedName : Unit = {
415+ code """ object Foo
416+ |extension (foo: Foo.type) def xxxx = 1
417+ |object Main { Foo.yy ${m1} } """ .withSource
418+ .completion(m1, Set ())
419+ }
420+
421+ @ Test def preferNormalMethodToExtensionMethod : Unit = {
422+ code """ object Foo {
423+ | def xxxx = "abcd"
424+ |}
425+ |object FooOps {
426+ | extension (foo: Foo.type) def xxxx = 1
427+ |}
428+ |object Main { Foo.xx ${m1} } """ .withSource
429+ .completion(m1, Set ((" xxxx" , Method , " => String" )))
430+ }
431+
432+ @ Test def preferExtensionMethodFromExplicitScope : Unit = {
433+ code """ object Foo
434+ |extension (foo: Foo.type) def xxxx = 1
435+ |object FooOps {
436+ | extension (foo: Foo.type) def xxxx = "abcd"
437+ |}
438+ |object Main { Foo.xx ${m1} } """ .withSource
439+ .completion(m1, Set ((" xxxx" , Method , " => Int" )))
440+ }
441+
442+ @ Test def dontCompleteInapplicableExtensionMethod : Unit = {
443+ code """ case class Foo[A](a: A)
444+ |extension (foo: Foo[Int]) def xxxx = foo.a
445+ |object Main { Foo("abc").xx ${m1} } """ .withSource
446+ .completion(m1, Set ())
447+ }
291448}
0 commit comments