Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Change ScalaProject.withSourceFile to take another parameter (what to…
… do if compiler did not initialize). Changed all call sites to either ignore the error (pass Unit or some other value), or do the default orElse action, which is to throw InvalidCompilerSettings.

Also, refactored ScalaHyperlinkDetector and ScalaCompletionProposalComputer to reduce instances of classes nested within closures nested within closures.
  • Loading branch information
lindydonna committed Jan 31, 2011
1 parent 0f04ff8 commit e6a4fc0
Show file tree
Hide file tree
Showing 19 changed files with 278 additions and 252 deletions.
Expand Up @@ -55,12 +55,12 @@ trait LocateSymbol { self : ScalaPresentationCompiler =>
}
} else findClassFile) flatMap { file =>
(if (sym.pos eq NoPosition) {
file.withSourceFile{ (f, _) =>
file.withSourceFile { (f, _) =>
val pos = new Response[Position]
getLinkPos(sym, f, pos)
askReload(scu, scu.getContents)
pos.get.left.toOption
}
} (None)
} else Some(sym.pos)) flatMap { p =>
if (p eq NoPosition) None else Some(file, p.point)
}
Expand Down
Expand Up @@ -22,9 +22,9 @@ class ScalaDebugHover extends JavaSourceHover {
val start = hoverRegion.getOffset
val length = hoverRegion.getLength
val end = start+length
scu.withSourceFile({ (sourceFile, compiler) =>
scu.withSourceFile ({ (sourceFile, compiler) =>
compiler.debugInfo(sourceFile, start, length)
})
}) (_noHoverInfo)
}
case _ => super.getHoverInfo(textViewer, hoverRegion)
}
Expand Down
94 changes: 47 additions & 47 deletions org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaHyperlinkDetector.scala 100755 → 100644
Expand Up @@ -24,60 +24,60 @@ import util.Logger
class ScalaHyperlinkDetector extends AbstractHyperlinkDetector with Logger {
def detectHyperlinks(viewer : ITextViewer, region : IRegion, canShowMultipleHyperlinks : Boolean) : Array[IHyperlink] = {
val textEditor = getAdapter(classOf[ITextEditor]).asInstanceOf[ITextEditor]
Option(EditorUtility.getEditorInputJavaElement(textEditor, false)).flatMap { _ match {
case scu : ScalaCompilationUnit => Some(scu)
case _ => None
}
}.map { scu =>
scu.withSourceFile { (sourceFile, compiler) =>
val wordRegion = ScalaWordFinder.findWord(viewer.getDocument, region.getOffset)
if (wordRegion == null || wordRegion.getLength == 0) null else {
val pos = compiler.rangePos(sourceFile, wordRegion.getOffset, wordRegion.getOffset, wordRegion.getOffset + wordRegion.getLength)

val response = new compiler.Response[compiler.Tree]
compiler.askTypeAt(pos, response)
val typed = response.get

log("detectHyperlinks: wordRegion = "+wordRegion)
EditorUtility.getEditorInputJavaElement(textEditor, false) match {
case scu : ScalaCompilationUnit =>
scu.withSourceFile({ (sourceFile, compiler) =>
val wordRegion = ScalaWordFinder.findWord(viewer.getDocument, region.getOffset)
if (wordRegion == null || wordRegion.getLength == 0) null else {
val pos = compiler.rangePos(sourceFile, wordRegion.getOffset, wordRegion.getOffset, wordRegion.getOffset + wordRegion.getLength)

compiler.ask { () =>
case class Hyperlink(file : Openable, pos : Int) extends IHyperlink {
def getHyperlinkRegion = wordRegion
def getTypeLabel = null
def getHyperlinkText = "Open Declaration"
def open = {
EditorUtility.openInEditor(file, true) match {
case editor : ITextEditor => editor.selectAndReveal(pos, 0)
case _ =>
}
}
}
val response = new compiler.Response[compiler.Tree]
compiler.askTypeAt(pos, response)
val typed = response.get

log("detectHyperlinks: wordRegion = "+wordRegion)

compiler.ask { () =>
case class Hyperlink(file : Openable, pos : Int) extends IHyperlink {
def getHyperlinkRegion = wordRegion
def getTypeLabel = null
def getHyperlinkText = "Open Declaration"
def open = {
EditorUtility.openInEditor(file, true) match {
case editor : ITextEditor => editor.selectAndReveal(pos, 0)
case _ =>
}
}
}
import compiler.{log =>_, _}
typed.left.toOption map ( _ match {
case st : SymTree => st.symbol
case Annotated(atp, _) => atp.symbol
case t => log("unhandled tree " + t); NoSymbol
}) flatMap { sym =>
if (sym.isPackage || sym == NoSymbol || sym.isJavaDefined) None else {
compiler.locate(sym, scu) map { case (f, pos) => Hyperlink(f, pos) }
}
} match {
case Some(hyper) => Left(Array[IHyperlink](hyper))
case None => Right( () => codeSelect(textEditor, wordRegion, scu) )
}
case st : SymTree => st.symbol
case Annotated(atp, _) => atp.symbol
case t => log("unhandled tree " + t); NoSymbol
} flatMap { sym =>
if (sym.isPackage || sym == NoSymbol || sym.isJavaDefined) None else {
compiler.locate(sym, scu) map { case (f, pos) => Hyperlink(f, pos) }
}
}
} match {
case Some(hyper) => Left(Array[IHyperlink](hyper))
case None => Right( () => codeSelect(textEditor, wordRegion, scu) )
}
}
} match {
case Left(l) => l
case Right(cont) => cont()
}
} match {
case Left(l) => l
case Right(cont) => cont()
}
}
}.getOrElse(null)
}) (null)

case _ => null
}
}

//Default path used for selecting.
def codeSelect(textEditor : ITextEditor, wordRegion : IRegion, scu : ScalaCompilationUnit) : Array[IHyperlink] = {
textEditor.getAction("OpenEditor") match {
case openAction : SelectionDispatchAction =>
case openAction : SelectionDispatchAction =>
try {
val editorInput = textEditor.getEditorInput
def isLinkable(element : IJavaElement) = {
Expand All @@ -101,7 +101,7 @@ class ScalaHyperlinkDetector extends AbstractHyperlinkDetector with Logger {
} catch {
case _ => null
}
case _ => null
}
case _ => null
}
}
}
Expand Up @@ -162,7 +162,7 @@ class ScalaPlugin extends AbstractUIPlugin with IResourceChangeListener with IEl
case ssf : ScalaSourceFile if (delta.getKind == IJavaElementDelta.REMOVED) =>
val project = ssf.getJavaProject.getProject
if (project.isOpen)
getScalaProject(ssf.getJavaProject.getProject).withPresentationCompiler { _.discardSourceFile(ssf) }
getScalaProject(ssf.getJavaProject.getProject).doWithPresentationCompiler { _.discardSourceFile(ssf) }

case _ : PackageFragment | _ : PackageFragmentRoot | _ : JavaProject =>
findRemovedSource(delta.getAffectedChildren)
Expand Down
43 changes: 32 additions & 11 deletions org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaProject.scala
Expand Up @@ -380,25 +380,46 @@ class ScalaProject(val underlying: IProject) {
sourceFolders.exists(_ == sourceFolderPath)
}
}

/**
* Performs `op` on the presentation compiler, if the compiler has been initialized.
* Otherwise, do nothing (no exception thrown).
*/
def doWithPresentationCompiler(op: ScalaPresentationCompiler => Unit): Unit = {
presentationCompiler {
case Some(c) => op(c)
case None =>
}
}

def defaultOrElse[T]: T = {
if (underlying.isOpen)
failedCompilerInitialization("Compiler failed to initialize properly.");

// FIXME: this now shows 2 dialog boxes, the one above and the one caused by the throw below
// will investigate further -DM
throw InvalidCompilerSettings() // DM: see if this error is easier to catch
// DM: commented out the null below.
// null.asInstanceOf[T] // we're already in deep trouble here, so one more NPE won't kill us
}

def withPresentationCompiler[T](op: ScalaPresentationCompiler => T): T = {
/**
* If the presentation compiler has failed to initialize and no `orElse` is specified,
* the default handler throws an `InvalidCompilerSettings` exception
* If T = Unit, then doWithPresentationCompiler can be used, which does not throw.
*/
def withPresentationCompiler[T](op: ScalaPresentationCompiler => T)(orElse: => T = defaultOrElse): T = {
presentationCompiler {
case Some(c) => op(c)
case None =>
if (underlying.isOpen)
failedCompilerInitialization("Compiler failed to initialize properly.");
// FIXME: this now shows 2 dialog boxes, the one above and the one caused by the throw below
// will investigate further -DM
throw InvalidCompilerSettings() // DM: see if this error is easier to catch
// DM: commented out the null below.
// null.asInstanceOf[T] // we're already in deep trouble here, so one more NPE won't kill us
case None => orElse
}
}

def withSourceFile[T](scu: ScalaCompilationUnit)(op: (SourceFile, ScalaPresentationCompiler) => T): T =
def withSourceFile[T](scu: ScalaCompilationUnit)(op: (SourceFile, ScalaPresentationCompiler) => T)(orElse: => T = defaultOrElse): T = {
withPresentationCompiler { compiler =>
compiler.withSourceFile(scu)(op)
}
} {orElse}
}

def resetPresentationCompiler {
presentationCompiler.invalidate
Expand Down
Expand Up @@ -25,7 +25,7 @@ class ScalaStructureSelectEnclosingAction(editor: ScalaSourceFileEditor, selecti
val selection = editor.getSelectionProvider.getSelection.asInstanceOf[ITextSelection]

val scalaSourceFile = editor.getEditorInput.asInstanceOf[IAdaptable].getAdapter(classOf[IJavaElement]).asInstanceOf[ScalaSourceFile]
scalaSourceFile.withSourceFile { (src, compiler) =>
scalaSourceFile.doWithSourceFile { (src, compiler) =>
import compiler._
val currentPos = rangePos(src, selection.getOffset, selection.getOffset, selection.getOffset + selection.getLength)

Expand All @@ -52,8 +52,6 @@ class ScalaStructureSelectEnclosingAction(editor: ScalaSourceFileEditor, selecti
selectionHistory.listenToSelectionChanges()
}
}
}

}
}

}

0 comments on commit e6a4fc0

Please sign in to comment.