@@ -288,4 +288,161 @@ class CompletionTest {
288
288
|import Foo.b $m1""" .withSource
289
289
.completion(m1, Set ((" bar" , Field , " type and lazy value bar" )))
290
290
}
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
+ }
291
448
}
0 commit comments