Skip to content
This repository has been archived by the owner on Sep 3, 2020. It is now read-only.

Commit

Permalink
Implement methods not only from the selected template but also from i…
Browse files Browse the repository at this point in the history
…ts ancestry.
  • Loading branch information
pfcoperez committed Sep 29, 2017
1 parent 2cc2155 commit efef6a7
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,32 @@ abstract class ImplementMethods extends MultiStageRefactoring with analysis.Inde
}
}

private def templateAncestry(template: Template): List[Template] =
template :: {
for {
parent <- template.parents
parentImp <- index.declaration(parent.symbol).toList collect {
case ClassDef(_, _, _, impl) => impl
}
ancenstor <- templateAncestry(parentImp)
} yield ancenstor
}

override def prepare(s: Selection): Either[PreparationError, PreparationResult] = {


// Expand the selection to the concrete type when a kind was initially selected.
val maybeSelectedTemplate = (s::s.expandToNextEnclosingTree.toList) flatMap { sel: Selection =>
index.declaration(sel.enclosingTree.symbol)
} collectFirst {
case templateDeclaration: ClassDef => templateDeclaration
case templateDeclaration: ClassDef => templateDeclaration.impl
}

// Get a sequence of methods found in the selected mixed trait.
val methodsToImplement = for {
selectedTemplateDeclaration <- maybeSelectedTemplate.toList
unimplementedMethod <- selectedTemplateDeclaration.impl.body collect {
selectedTemplate <- maybeSelectedTemplate.toList
selectedDeclaration <- templateAncestry(selectedTemplate)
unimplementedMethod <- selectedDeclaration.body collect {
case methodDeclaration: DefDef if methodDeclaration.rhs.isEmpty =>
methodDeclaration
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,55 @@ class ImplementMethodsTest extends TestHelper with TestRefactoring {
} applyRefactoring implementMethods


@Test
def implementMethodFromAncestry() = new FileSet() {
"""
|package implementMethods
|
|trait R {
| def k: Unit
|}
|
|trait T {
| def f(x: Int): String
|}
|
|trait S extends T {
| def g(x: Int): Int
|}
|
|object Obj extends /*(*/S/*)*/ with R {
| val x: Int = ???
|}
""".stripMargin becomes
"""
|package implementMethods
|
|trait R {
| def k: Unit
|}
|
|trait T {
| def f(x: Int): String
|}
|
|trait S extends T {
| def g(x: Int): Int
|}
|
|object Obj extends /*(*/S/*)*/ with R {
| val x: Int = ???
|
| def g(x: Int): Int = {
| ???
| }
|
| def f(x: Int): String = {
| ???
| }
|}
""".stripMargin

} applyRefactoring implementMethods

}

0 comments on commit efef6a7

Please sign in to comment.