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

Commit 9f454a0

Browse files
committed
Avoid adding implemented methods.
1 parent 5231769 commit 9f454a0

File tree

1 file changed

+43
-7
lines changed

1 file changed

+43
-7
lines changed

src/main/scala/scala/tools/refactoring/implementations/ImplementMethods.scala

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,66 @@ abstract class ImplementMethods extends MultiStageRefactoring with analysis.Inde
1010

1111
case class PreparationResult(targetTemplate: Template, methodsToImplement: Seq[DefDef])
1212

13+
/* Helper class to box methods so they can be
14+
compared in terms of their signature.
15+
*/
16+
implicit class OverloadedMethod(val method: DefDef) {
17+
18+
private val key = {
19+
import method.{name, tparams, vparamss}
20+
21+
val vparamsTypes = for {
22+
paramList <- vparamss
23+
param <- paramList
24+
} yield param.tpt.tpe
25+
26+
(name, tparams, vparamsTypes)
27+
28+
}
29+
30+
override def hashCode(): RunId = key.hashCode()
31+
32+
override def equals(obj: scala.Any): Boolean = obj match {
33+
case that: OverloadedMethod => key == that.key
34+
case _ => false
35+
}
36+
}
37+
1338
override def prepare(s: Selection): Either[PreparationError, PreparationResult] = {
1439

40+
// Get a sequence of methods found in the selected mixed trait.
1541
val methodsToImplement = for {
1642
selectedTemplateDeclaration <- index.declaration(s.enclosingTree.symbol).toSeq collect {
17-
case traitDeclaration: ClassDef => traitDeclaration
43+
case templateDeclaration: ClassDef => templateDeclaration
1844
}
1945
unimplementedMethod <- selectedTemplateDeclaration.impl.body collect {
20-
case methodDeclaration: DefDef if methodDeclaration.rhs.isEmpty => methodDeclaration
46+
case methodDeclaration: DefDef if methodDeclaration.rhs.isEmpty =>
47+
methodDeclaration
2148
}
2249
} yield unimplementedMethod
2350

51+
// Use the selection to find the template where the methods should be implemented.
2452
val targetTemplate = s.expandToNextEnclosingTree.flatMap {
2553
_.selectedSymbolTree collect {
2654
case target: Template => target
2755
}
2856
}
2957

30-
if(targetTemplate.isEmpty) Left {
58+
targetTemplate map { t => // If the selection has indeed a target template...
59+
if(methodsToImplement.isEmpty) Left { //... as long as there are methods in the mixed trait...
60+
PreparationError("There are not methods to implement")
61+
} else Right { //... these are selected to be defined in the target template.
62+
// If and only if they're not already defined there.
63+
val implementedMethods: Set[OverloadedMethod] = {
64+
t.body collect {
65+
case methodDef: DefDef => new OverloadedMethod(methodDef)
66+
} toSet
67+
}
68+
PreparationResult(t, methodsToImplement.filterNot(implementedMethods contains _))
69+
}
70+
} getOrElse Left {
3171
PreparationError("No target class in selection")
3272
}
33-
else if(methodsToImplement.isEmpty) Left {
34-
PreparationError("There are not methods to implement")
35-
}
36-
else Right(PreparationResult(targetTemplate.get, methodsToImplement))
3773
}
3874

3975
override type RefactoringParameters = Unit

0 commit comments

Comments
 (0)