-
Notifications
You must be signed in to change notification settings - Fork 308
/
ScalaQuickAssistProcessor.scala
84 lines (72 loc) · 3.27 KB
/
ScalaQuickAssistProcessor.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package scala.tools.eclipse
package quickfix
import org.eclipse.ui.IEditorPart
import org.eclipse.jface.text.source.Annotation
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.ProblemAnnotation
import org.eclipse.jdt.ui.JavaUI
import org.eclipse.core.runtime.CoreException
import org.eclipse.jdt.core.ICompilationUnit
import org.eclipse.jdt.core.search.IJavaSearchConstants
import org.eclipse.jdt.internal.codeassist.ISearchRequestor
import org.eclipse.jdt.internal.compiler.env.{ AccessRestriction, INameEnvironment }
import org.eclipse.jdt.internal.core.{ DefaultWorkingCopyOwner, JavaProject }
import org.eclipse.jdt.internal.ui.text.correction.{ SimilarElement, SimilarElementsRequestor }
import org.eclipse.jdt.ui.text.java._
import org.eclipse.core.resources.IMarker
import scala.tools.eclipse.javaelements.ScalaSourceFile
import scala.tools.eclipse.util.FileUtils
import scala.util.matching.Regex
import org.eclipse.jface.text.Position
import scala.collection.JavaConversions._
class ScalaQuickAssistProcessor extends org.eclipse.jdt.ui.text.java.IQuickAssistProcessor {
import ScalaQuickAssistProcessor._
override def hasAssists(context: IInvocationContext): Boolean = true
override def getAssists(context: IInvocationContext, locations: Array[IProblemLocation]): Array[IJavaCompletionProposal] =
context.getCompilationUnit match {
case ssf: ScalaSourceFile => {
val editor = JavaUI.openInEditor(context.getCompilationUnit)
val corrections = {
for ((ann, pos) <- getAnnotationsAtOffset(editor, context.getSelectionOffset())) yield {
suggestAssist(context.getCompilationUnit(), ann.getText, pos)
}
}.flatten
corrections match {
case Nil => null
case correction => correction.distinct.toArray
}
}
// The caller expects null to mean "no assists".
case _ => null
}
private def getAnnotationsAtOffset(part: IEditorPart, offset: Int): List[Pair[Annotation, Position]] = {
import ScalaQuickAssistProcessor._
val model = JavaUI.getDocumentProvider.getAnnotationModel(part.getEditorInput)
val annotationsWithPositions = model.getAnnotationIterator collect {
case ann: Annotation => (ann, model.getPosition(ann))
}
val annotationsAtOffset = annotationsWithPositions filter {
case (_, pos) => isInside(offset, pos.offset, pos.offset + pos.length)
}
annotationsAtOffset.toList
}
private def suggestAssist(compilationUnit: ICompilationUnit, problemMessage: String, location: Position): List[IJavaCompletionProposal] = {
List(
ExtractLocalProposal,
InlineLocalProposal,
RenameProposal,
ExtractMethodProposal
).filter(_.isValidProposal) :::
(problemMessage match {
case ImplicitConversionFound(s) => List(new ImplicitConversionExpandingProposal(s, location))
case ImplicitArgFound(s) => List(new ImplicitArgumentExpandingProposal(s, location))
case _ => Nil
})
}
}
object ScalaQuickAssistProcessor {
private def isInside(offset: Int, start: Int, end: Int) = {
(start to end) contains offset
}
private final val ImplicitConversionFound = "Implicit conversions found: (.*)".r
private final val ImplicitArgFound = "Implicit arguments found: (.*)".r
}