|
1 | 1 | package scala.tools.refactoring.implementations |
2 | 2 |
|
3 | 3 | import scala.tools.refactoring.common.InteractiveScalaCompiler |
| 4 | +import scala.tools.refactoring.transformation.TreeFactory |
4 | 5 | import scala.tools.refactoring.{MultiStageRefactoring, analysis} |
5 | 6 |
|
6 | | -abstract class ImplementMethods extends MultiStageRefactoring with analysis.Indexes with InteractiveScalaCompiler { |
| 7 | +abstract class ImplementMethods extends MultiStageRefactoring with analysis.Indexes with TreeFactory with InteractiveScalaCompiler { |
7 | 8 |
|
8 | 9 | import global._ |
9 | 10 |
|
10 | | - override type PreparationResult = Seq[DefDef] |
| 11 | + case class PreparationResult(targetTemplate: Template, methodsToImplement: Seq[DefDef]) |
11 | 12 |
|
12 | 13 | override def prepare(s: Selection): Either[PreparationError, PreparationResult] = { |
| 14 | + |
13 | 15 | val methodsToImplement = for { |
14 | | - selectedClassDeclaration <- index.declaration(s.enclosingTree.symbol).toSeq collect { |
| 16 | + selectedTemplateDeclaration <- index.declaration(s.enclosingTree.symbol).toSeq collect { |
15 | 17 | case traitDeclaration: ClassDef => traitDeclaration |
16 | 18 | } |
17 | | - unimplementedMethod <- selectedClassDeclaration.impl.body collect { |
| 19 | + unimplementedMethod <- selectedTemplateDeclaration.impl.body collect { |
18 | 20 | case methodDeclaration: DefDef if methodDeclaration.rhs.isEmpty => methodDeclaration |
19 | 21 | } |
20 | 22 | } yield unimplementedMethod |
21 | | - if(methodsToImplement.isEmpty) Left { |
| 23 | + |
| 24 | + val targetTemplate = s.expandToNextEnclosingTree.flatMap { |
| 25 | + _.selectedSymbolTree collect { |
| 26 | + case target: Template => target |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + if(targetTemplate.isEmpty) Left { |
| 31 | + PreparationError("No target class in selection") |
| 32 | + } |
| 33 | + else if(methodsToImplement.isEmpty) Left { |
22 | 34 | PreparationError("There are not methods to implement") |
23 | 35 | } |
24 | | - else Right(methodsToImplement) |
| 36 | + else Right(PreparationResult(targetTemplate.get, methodsToImplement)) |
25 | 37 | } |
26 | 38 |
|
27 | 39 | override type RefactoringParameters = Unit |
28 | 40 |
|
29 | 41 | override def perform(selection: Selection, prepared: PreparationResult, params: RefactoringParameters) = { |
30 | | - ??? |
| 42 | + import prepared._ |
| 43 | + |
| 44 | + val findTemplate = filter { |
| 45 | + case t: Template => t == targetTemplate |
| 46 | + } |
| 47 | + |
| 48 | + val addMethods = transform { |
| 49 | + case tpl @ Template(_, _, body) if tpl == prepared.targetTemplate => |
| 50 | + val methodsBody = Block(Ident("???") :: Nil, EmptyTree) |
| 51 | + val methodWithRhs = methodsToImplement.map(_ copy (rhs = methodsBody)) |
| 52 | + tpl.copy(body = body ++ methodWithRhs).replaces(tpl) |
| 53 | + } |
| 54 | + |
| 55 | + val transformation = topdown { |
| 56 | + matchingChildren { |
| 57 | + findTemplate &> |
| 58 | + addMethods |
| 59 | + } |
| 60 | + } |
| 61 | + Right(transformFile(selection.file, transformation)) |
31 | 62 | } |
32 | 63 | } |
0 commit comments