diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 44407daf600c..2ff8ad1c6535 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -71,10 +71,11 @@ object Completion: mode: Mode, rawPrefix: String, tpdPath: List[tpd.Tree], - untpdPath: List[untpd.Tree] + untpdPath: List[untpd.Tree], + customMatcher: Option[Name => Boolean] = None )(using Context): CompletionMap = val adjustedPath = typeCheckExtensionConstructPath(untpdPath, tpdPath, pos) - computeCompletions(pos, mode, rawPrefix, adjustedPath) + computeCompletions(pos, mode, rawPrefix, adjustedPath, customMatcher) /** * Inspect `path` to determine what kinds of symbols should be considered. @@ -193,11 +194,12 @@ object Completion: .flatten.getOrElse(tpdPath) private def computeCompletions( - pos: SourcePosition, mode: Mode, rawPrefix: String, adjustedPath: List[tpd.Tree] + pos: SourcePosition, mode: Mode, rawPrefix: String, adjustedPath: List[tpd.Tree], matches: Option[Name => Boolean] )(using Context): CompletionMap = val hasBackTick = rawPrefix.headOption.contains('`') val prefix = if hasBackTick then rawPrefix.drop(1) else rawPrefix - val completer = new Completer(mode, prefix, pos) + val matches0 = matches.getOrElse(_.startsWith(prefix)) + val completer = new Completer(mode, pos, matches0) val result = adjustedPath match // Ignore synthetic select from `This` because in code it was `Ident` @@ -209,7 +211,6 @@ object Completion: case _ => completer.scopeCompletions interactiv.println(i"""completion info with pos = $pos, - | prefix = ${completer.prefix}, | term = ${completer.mode.is(Mode.Term)}, | type = ${completer.mode.is(Mode.Type)}, | scope = ${completer.mode.is(Mode.Scope)}, @@ -311,13 +312,13 @@ object Completion: /** Computes code completions depending on the context in which completion is requested * @param mode Should complete names of terms, types or both - * @param prefix The prefix that all suggested completions should start with * @param pos Cursor position where completion was requested + * @param matches Function taking name used to filter completions * * For the results of all `xyzCompletions` methods term names and type names are always treated as different keys in the same map * and they never conflict with each other. */ - class Completer(val mode: Mode, val prefix: String, pos: SourcePosition): + class Completer(val mode: Mode, pos: SourcePosition, matches: Name => Boolean): /** Completions for terms and types that are currently in scope: * the members of the current class, local definitions and the symbols that have been imported, * recursively adding completions from outer scopes. @@ -524,7 +525,7 @@ object Completion: // There are four possible ways for an extension method to be applicable // 1. The extension method is visible under a simple name, by being defined or inherited or imported in a scope enclosing the reference. - val termCompleter = new Completer(Mode.Term, prefix, pos) + val termCompleter = new Completer(Mode.Term, pos, matches) val extMethodsInScope = termCompleter.scopeCompletions.toList.flatMap: case (name, denots) => denots.collect: case d: SymDenotation if d.isTerm && d.termRef.symbol.is(Extension) => (d.termRef, name.asTermName) @@ -556,7 +557,7 @@ object Completion: * 2. satisfy [[Completion.isValidCompletionSymbol]] */ private def include(denot: SingleDenotation, nameInScope: Name)(using Context): Boolean = - nameInScope.startsWith(prefix) && + matches(nameInScope) && completionsFilter(NoType, nameInScope) && isValidCompletionSymbol(denot.symbol, mode) @@ -605,7 +606,6 @@ object Completion: private def implicitConversionTargets(qual: tpd.Tree)(using Context): Set[SearchSuccess] = { val typer = ctx.typer val conversions = new typer.ImplicitSearch(defn.AnyType, qual, pos.span).allImplicits - conversions.map(_.tree.typeOpt) interactiv.println(i"implicit conversion targets considered: ${conversions.toList}%, %") conversions diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index cfda041745e4..92d077c9199e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -509,7 +509,8 @@ object Implicits: |must be more specific than $target""" override def msg(using Context) = - super.msg.append("\nThe expected type $target is not specific enough, so no search was attempted") + super.msg.append(i"\nThe expected type $target is not specific enough, so no search was attempted") + override def toString = s"TooUnspecific" /** An ambiguous implicits failure */ diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala index a928734ae752..db9959dc1a9f 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala @@ -16,6 +16,7 @@ import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.core.Comments.Comment import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.* +import dotty.tools.dotc.core.Denotations.SingleDenotation import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.NameOps.* @@ -26,14 +27,13 @@ import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.interactive.Completion import dotty.tools.dotc.interactive.Completion.Mode +import dotty.tools.dotc.interactive.Interactive import dotty.tools.dotc.util.SourcePosition import dotty.tools.dotc.util.SrcPos import dotty.tools.pc.AutoImports.AutoImportsGenerator -import dotty.tools.pc.completions.OverrideCompletions.OverrideExtractor import dotty.tools.pc.buildinfo.BuildInfo +import dotty.tools.pc.completions.OverrideCompletions.OverrideExtractor import dotty.tools.pc.utils.MtagsEnrichments.* -import dotty.tools.dotc.core.Denotations.SingleDenotation - class Completions( text: String, @@ -102,9 +102,13 @@ class Completions( end if end includeSymbol + lazy val fuzzyMatcher: Name => Boolean = name => + if completionMode.is(Mode.Member) then CompletionFuzzy.matchesSubCharacters(completionPos.query, name.toString) + else CompletionFuzzy.matches(completionPos.query, name.toString) + def enrichedCompilerCompletions(qualType: Type): (List[CompletionValue], SymbolSearch.Result) = val compilerCompletions = Completion - .rawCompletions(completionPos.originalCursorPosition, completionMode, completionPos.query, path, adjustedPath) + .rawCompletions(completionPos.originalCursorPosition, completionMode, completionPos.query, path, adjustedPath, Some(fuzzyMatcher)) compilerCompletions .toList @@ -423,7 +427,7 @@ class Completions( // class Fo@@ case (td: TypeDef) :: _ - if Fuzzy.matches( + if CompletionFuzzy.matches( td.symbol.name.decoded.replace(Cursor.value, "").nn, filename ) => diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala index bfb31906bce1..776aab8bc2f7 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala @@ -123,7 +123,7 @@ abstract class BaseCompletionSuite extends BasePCSuite: if (assertSingleItem && items.length != 1) then fail( - s"expected single completion item, obtained ${items.length} items.\n${items}" + s"expected single completion item, obtained ${items.length} items.\n${items.map(_.getLabel.nn + "\n")}" ) if (items.size <= itemIndex) then diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala index b487611b9ea1..ec0b6dc20688 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala @@ -156,8 +156,8 @@ class CompletionDocSuite extends BaseCompletionSuite: |Found documentation for scala/collection/Iterator. |Iterator scala.collection |""".stripMargin, - - includeDocs = true + includeDocs = true, + topLines = Some(1) ) @Test def `scala5` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala index f48ba06f699c..e67c31329c1c 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala @@ -17,12 +17,14 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |def main = 100.inc@@ |""".stripMargin, """|incr: Int (extension) + |asInstanceOf[X0]: X0 + |isInstanceOf[X0]: Boolean |""".stripMargin ) @Test def `simple-old-syntax` = check( - """|package example + """package example | |object Test: | implicit class TestOps(a: Int): @@ -30,8 +32,9 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | |def main = 100.test@@ |""".stripMargin, - """|testOps(b: Int): String (implicit) - |""".stripMargin + """testOps(b: Int): String (implicit) + |""".stripMargin, + topLines = Some(1) ) @Test def `simple2` = @@ -93,8 +96,10 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | |def main = "foo".iden@@ |""".stripMargin, - """|identity: String (implicit) - |""".stripMargin // identity2 won't be available + """|identity: String (implicit) + |""".stripMargin, // identity2 won't be available + filter = _.contains("(implicit)") + ) @Test def `filter-by-type-subtype` = @@ -152,7 +157,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | def incr: Int = num + 1 | |def main = 100.incr - |""".stripMargin + |""".stripMargin, + assertSingleItem = false ) @Test def `simple-edit-old` = @@ -174,7 +180,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | def incr: Int = num + 1 | |def main = 100.incr - |""".stripMargin + |""".stripMargin, + assertSingleItem = false ) @Test def `simple-edit-suffix` = @@ -262,6 +269,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | def main = 100.inc@@ |""".stripMargin, """|incr: Int (extension) + |asInstanceOf[X0]: X0 + |isInstanceOf[X0]: Boolean |""".stripMargin ) @@ -276,6 +285,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | def main = 100.inc@@ |""".stripMargin, """|incr: Int (implicit) + |asInstanceOf[X0]: X0 + |isInstanceOf[X0]: Boolean |""".stripMargin ) @@ -290,6 +301,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | def main = 100.inc@@ |""".stripMargin, """|incr: Int (extension) + |asInstanceOf[X0]: X0 + |isInstanceOf[X0]: Boolean |""".stripMargin ) @@ -304,6 +317,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | def main = 100.inc@@ |""".stripMargin, """|incr: Int (implicit) + |asInstanceOf[X0]: X0 + |isInstanceOf[X0]: Boolean |""".stripMargin ) @@ -391,7 +406,8 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |testVal: Int (implicit) |testVar: Int (implicit) |testOps(b: Int): String (implicit) - |""".stripMargin + |""".stripMargin, + topLines = Some(4) ) @Test def `implicit-val-edit` = @@ -413,5 +429,6 @@ class CompletionExtensionSuite extends BaseCompletionSuite: | val testVal: Int = 42 | |def main = 100.testVal - |""".stripMargin + |""".stripMargin, + assertSingleItem = false ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala index d509d5438ab5..20d45030164e 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala @@ -695,28 +695,26 @@ class CompletionKeywordSuite extends BaseCompletionSuite: @Test def `derives-with-extends` = check( - """ - |package foo - | - |trait Bar {} - |trait Baz {} - | - |class Foo(x: Int) extends Bar with Baz der@@ - """.stripMargin, + """|package foo + | + |trait Bar {} + |trait Baz {} + | + |class Foo(x: Int) extends Bar with Baz der@@ + |""".stripMargin, """|derives |""".stripMargin ) @Test def `derives-with-constructor-extends` = check( - """ - |package foo - | - |trait Bar {} - |class Baz(b: Int) {} - | - |class Foo(x: Int) extends Bar with Baz(1) der@@ - """.stripMargin, + """|package foo + | + |trait Bar {} + |class Baz(b: Int) {} + | + |class Foo(x: Int) extends Bar with Baz(1) der@@ + |""".stripMargin, """|derives |""".stripMargin ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionOverrideSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionOverrideSuite.scala index b3abc1474375..94c444b0feb9 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionOverrideSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionOverrideSuite.scala @@ -925,12 +925,15 @@ class CompletionOverrideSuite extends BaseCompletionSuite: | def@@ |} |""".stripMargin, + """|def hello1: Int |override def equals(x$0: Any): Boolean |override def hashCode(): Int + |override def toString(): String + |override val hello2: Int |""".stripMargin, includeDetail = false, - topLines = Some(3) + topLines = Some(5) ) @Test def `path-dependent` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetNegSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetNegSuite.scala index ccd989d811b5..8cbbad0e6ef2 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetNegSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetNegSuite.scala @@ -16,12 +16,12 @@ class CompletionSnippetNegSuite extends BaseCompletionSuite: @Test def `member` = checkSnippet( - """ - |object Main { - | List.appl@@ - |} - |""".stripMargin, - "apply" + """|object Main { + | List.appl@@ + |} + |""".stripMargin, + """|apply + |unapplySeq""".stripMargin ) @Test def `scope` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala index b601a63ff234..5769304919ca 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala @@ -15,6 +15,7 @@ class CompletionSnippetSuite extends BaseCompletionSuite: |} |""".stripMargin, """|apply($0) + |unapplySeq($0) |""".stripMargin ) @@ -429,7 +430,8 @@ class CompletionSnippetSuite extends BaseCompletionSuite: | extension (s: String) | def bar = 0 | val bar = "abc".bar - """.stripMargin + """.stripMargin, + filter = _.contains("bar: Int") ) // https://github.com/scalameta/metals/issues/4004 @@ -446,5 +448,6 @@ class CompletionSnippetSuite extends BaseCompletionSuite: | extension (s: String) | def bar() = 0 | val bar = "abc".bar() - """.stripMargin + """.stripMargin, + filter = _.contains("bar: Int") ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index 59bed797f653..61d5c7707b4a 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -404,6 +404,7 @@ class CompletionSuite extends BaseCompletionSuite: |Function20 scala |Function21 scala |Function22 scala + |PartialFunction scala |""".stripMargin, topLines = Some(25) ) @@ -531,7 +532,6 @@ class CompletionSuite extends BaseCompletionSuite: |until(end: Long): Exclusive[Long] |until(end: Long, step: Long): Exclusive[Long] |""".stripMargin, - postProcessObtained = _.replace("Float", "Double"), stableOrder = false ) @@ -795,6 +795,10 @@ class CompletionSuite extends BaseCompletionSuite: |} |""".stripMargin, """|intNumber: Int + |toInt: Int + |instance: Int + |asInstanceOf[X0]: X0 + |isInstanceOf[X0]: Boolean |""".stripMargin ) @@ -1105,7 +1109,8 @@ class CompletionSuite extends BaseCompletionSuite: |} |""".stripMargin, """|first: java.util.List[Int] - |""".stripMargin + |""".stripMargin, + topLines = Some(1) ) @Test def `object-at-type-pos` = @@ -1329,14 +1334,7 @@ class CompletionSuite extends BaseCompletionSuite: val extensionResult = """|Foo test |Found - scala.collection.Searching - |Font - java.awt - |Form - java.text.Normalizer - |Format - java.text - |FontPeer - java.awt.peer - |FormView - javax.swing.text.html - |Formatter - java.util - |Formatter - java.util.logging - |FocusEvent - java.awt.event""".stripMargin + """.stripMargin @Test def `extension-definition-scope` = check( @@ -1344,7 +1342,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension (x: Fo@@) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-symbol-search` = @@ -1363,7 +1362,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension [A <: Fo@@] |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-type-parameter-symbol-search` = @@ -1382,7 +1382,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension (using Fo@@) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @@ -1392,7 +1393,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension (x: Int)(using Fo@@) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-mix-2` = @@ -1401,7 +1403,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension (using Fo@@)(x: Int)(using Foo) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-mix-3` = @@ -1410,7 +1413,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension (using Foo)(x: Int)(using Fo@@) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-mix-4` = @@ -1419,7 +1423,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension [A](x: Fo@@) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-mix-5` = @@ -1428,7 +1433,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension [A](using Fo@@)(x: Int) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-mix-6` = @@ -1437,7 +1443,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension [A](using Foo)(x: Fo@@) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-mix-7` = @@ -1446,7 +1453,8 @@ class CompletionSuite extends BaseCompletionSuite: |object T: | extension [A](using Foo)(x: Fo@@)(using Foo) |""".stripMargin, - extensionResult + extensionResult, + topLines = Some(2) ) @Test def `extension-definition-select` = @@ -1490,6 +1498,7 @@ class CompletionSuite extends BaseCompletionSuite: """|object O: | val a = List.apply($0) |""".stripMargin, + assertSingleItem = false ) @Test def `multiline-comment` = @@ -1550,13 +1559,21 @@ class CompletionSuite extends BaseCompletionSuite: assertSingleItem = false ) - @Test def `multi-export` = check( """export scala.collection.{AbstractMap, Set@@} |""".stripMargin, """Set scala.collection |SetOps scala.collection + |AbstractSet scala.collection + |BitSet scala.collection + |BitSetOps scala.collection + |SortedSet scala.collection + |SortedSetFactoryDefaults scala.collection + |SortedSetOps scala.collection + |StrictOptimizedSetOps scala.collection + |StrictOptimizedSortedSetOps scala.collection + |GenSet = scala.collection.Set[X] |""".stripMargin ) @@ -1566,6 +1583,15 @@ class CompletionSuite extends BaseCompletionSuite: |""".stripMargin, """Set scala.collection |SetOps scala.collection + |AbstractSet scala.collection + |BitSet scala.collection + |BitSetOps scala.collection + |SortedSet scala.collection + |SortedSetFactoryDefaults scala.collection + |SortedSetOps scala.collection + |StrictOptimizedSetOps scala.collection + |StrictOptimizedSortedSetOps scala.collection + |GenSet = scala.collection.Set[X] |""".stripMargin, ) @@ -1606,7 +1632,8 @@ class CompletionSuite extends BaseCompletionSuite: | List(1,2,3).tes@@ |""".stripMargin, """|test(p: Int => Boolean): List[Int] - |""".stripMargin + |""".stripMargin, + topLines = Some(1) ) @Test def `old-style-extension-type-variable-inference` = @@ -1618,7 +1645,8 @@ class CompletionSuite extends BaseCompletionSuite: | List(1,2,3).tes@@ |""".stripMargin, """|test(p: Int => Boolean): List[Int] - |""".stripMargin + |""".stripMargin, + topLines = Some(1) ) @Test def `instantiate-type-vars-in-extra-apply-completions` = @@ -1643,6 +1671,7 @@ class CompletionSuite extends BaseCompletionSuite: |new ListSet[A]: ListSet[A] - scala.collection.immutable |ListMap[K, V](elems: (K, V)*): ListMap[K, V] - scala.collection.mutable |new ListMap[K, V]: ListMap[K, V] - scala.collection.mutable + |LazyList[A](elems: A*): LazyList[A] |""".stripMargin, filter = _.contains("[") ) @@ -1774,3 +1803,38 @@ class CompletionSuite extends BaseCompletionSuite: filter = _ == "Override java.lang" ) + @Test def `fuzzy-search-test` = + check( + """| + |object MyInterface { + | def someMethod(x: Int): Int = ??? + |} + |object Test { + | MyInterface.m@@ + |} + |""".stripMargin, + """|someMethod(x: Int): Int + |""".stripMargin, + topLines = Some(1) + ) + + @Test def `fuzzy-search-test-multiple` = + check( + """| + |trait MyInterface { + | def someMethod(x: Int): Int = ??? + |} + |object Test { + | extension (interface: MyInterface) def someExtMethod(x: Int): Int = ??? + | implicit class MyInterfaceExtension(interface: MyInterface): + | def someOldExtMethod(x: Int): Int = ??? + | val x: MyInterface = ??? + | x.m@@ + |} + |""".stripMargin, + """|someMethod(x: Int): Int + |someExtMethod(x: Int): Int + |someOldExtMethod(x: Int): Int + |""".stripMargin, + topLines = Some(3) + )