Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Truncate too long build error messages displayed in resources' marker

Markers are a general mechanism for associating notes and meta-data with
resources.  The Eclipse environments dictates that the text message passed to a
marker should not be bigger than 21000 chars, or an assertion failure saying

> Marker property value is too long

is thrown on the user's face.

The actual logic for resizing the build error problem passed to a marker
already existed in two places. While the message passed to the created marker
was correctly truncated in ``FileUtils.buildError``, it was not in
``ScalaProject.buildErrors``.

As part of this commit, I've centralized the creation of resource markers in
``MarkerFactory``, and build problem markers are now created using
``BuildProblemMarker`` (it's a subclass of ``MarkerFactory```).

More cleaning up could be done so that all markers are created only through
sublcasses of `MarkerFactory``. Though, such a big refactoring seem too risky
at the moment, as this commit will be merged in ``release/2.0.x`` branch.

Fix #1001107
(cherry picked from commit be013c2)

Conflicts:

	org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/BuildReporter.scala
	org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/refined/EclipseRefinedBuildManager.scala
	org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/sbtintegration/EclipseSbtBuildManager.scala
  • Loading branch information...
commit 81d097217bd47e70ca398ea376578b3fce52088a 1 parent b317578
@dotta dotta authored
View
1  org.scala-ide.sdt.core/META-INF/MANIFEST.MF
@@ -82,6 +82,7 @@ Export-Package:
scala.tools.eclipse.markoccurrences,
scala.tools.eclipse.properties,
scala.tools.eclipse.quickfix,
+ scala.tools.eclipse.resources,
scala.tools.eclipse.refactoring,
scala.tools.eclipse.refactoring.rename,
scala.tools.eclipse.refactoring.ui,
View
15 org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaProject.scala
@@ -144,21 +144,6 @@ class ScalaProject private (val underlying: IProject) extends HasLogger {
/** Does this project have the Scala nature? */
def hasScalaNature =
ScalaPlugin.plugin.isScalaProject(underlying)
-
- /** Generic build error, without a source position. It creates a marker in the
- * Problem views.
- */
- def buildError(severity: Int, msg: String, monitor: IProgressMonitor) =
- workspaceRunnableIn(underlying.getWorkspace, monitor) { m =>
- val mrk = underlying.createMarker(plugin.problemMarkerId)
- mrk.setAttribute(IMarker.SEVERITY, severity)
- val string = msg.map {
- case '\n' => ' '
- case '\r' => ' '
- case c => c
- }.mkString("", "", "")
- mrk.setAttribute(IMarker.MESSAGE, string)
- }
def settingsError(severity: Int, msg: String, monitor: IProgressMonitor) =
workspaceRunnableIn(underlying.getWorkspace, monitor) { m =>
View
18 org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/BuildProblemMarker.scala
@@ -0,0 +1,18 @@
+package scala.tools.eclipse.buildmanager
+
+import org.eclipse.core.resources.IResource
+import org.eclipse.core.resources.IMarker
+import scala.tools.eclipse.resources.MarkerFactory
+import scala.tools.eclipse.ScalaPlugin
+import scala.tools.eclipse.ScalaProject
+
+/** Factory for creating markers used to report build problems (i.e., compilation errors). */
+object BuildProblemMarker extends MarkerFactory(ScalaPlugin.plugin.problemMarkerId) {
+ /** Create a marker indicating an error state for the passed Scala `project`. */
+ def create(project: ScalaProject, e: Throwable): Unit =
+ create(project.underlying, "Error in Scala compiler: " + e.getMessage)
+
+ /** Create a marker indicating an error state for the passed `resource`. */
+ def create(resource: IResource, msg: String): Unit =
+ create(resource, IMarker.SEVERITY_ERROR, msg)
+}
View
14 org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/BuildReporter.scala
@@ -1,14 +1,12 @@
package scala.tools.eclipse.buildmanager
import scala.tools.eclipse.{EclipseBuildManager, TaskScanner, ScalaProject}
-
+import scala.tools.eclipse.resources.MarkerFactory
import scala.tools.nsc.Settings
import scala.tools.nsc.reporters.Reporter
import scala.tools.nsc.util.{ Position, NoPosition }
import scala.tools.eclipse.util.{ EclipseResource, FileUtils, HasLogger }
-
import scala.collection.mutable.ListBuffer
-
import org.eclipse.core.resources.{ IFile, IMarker }
import org.eclipse.core.runtime.IProgressMonitor
@@ -40,7 +38,7 @@ abstract class BuildReporter(private[buildmanager] val project0: ScalaProject, s
source.file match {
case EclipseResource(i : IFile) =>
if (!pos.source.file.hasExtension("java")) {
- FileUtils.buildError(i, eclipseSeverity, msg, pos.point, length, pos.line, null)
+ BuildProblemMarker.create(i, eclipseSeverity, msg, MarkerFactory.Position(pos.point, length, pos.line))
prob += new BuildProblem(severity, msg, pos)
} else
logger.info("suppressed error in Java file: %s".format(msg))
@@ -52,11 +50,11 @@ abstract class BuildReporter(private[buildmanager] val project0: ScalaProject, s
// for instance, when a source file (on the sourcepath) is newer than the classfile
// the compiler will create PlainFile instances in that case
prob += new BuildProblem(severity, msg, pos)
- FileUtils.buildError(i, eclipseSeverity, msg, pos.point, length, pos.line, null)
+ BuildProblemMarker.create(i, eclipseSeverity, msg, MarkerFactory.Position(pos.point, length, pos.line))
case _ =>
logger.info("no EclipseResource associated to %s [%s]".format(f.path, f.getClass))
prob += new BuildProblem(severity, msg, NoPosition)
- project0.buildError(eclipseSeverity, msg, null)
+ BuildProblemMarker.create(project0.underlying, eclipseSeverity, msg)
}
}
}
@@ -67,12 +65,12 @@ abstract class BuildReporter(private[buildmanager] val project0: ScalaProject, s
logger.info("[Buildmanager info] " + msg)
case _ =>
prob += new BuildProblem(severity, msg, NoPosition)
- project0.buildError(eclipseSeverity, msg, null)
+ BuildProblemMarker.create(project0.underlying, eclipseSeverity, msg)
}
} catch {
case ex : UnsupportedOperationException =>
prob += new BuildProblem(severity, msg, NoPosition)
- project0.buildError(eclipseSeverity, msg, null)
+ BuildProblemMarker.create(project0.underlying, eclipseSeverity, msg)
}
}
}
View
2  org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/refined/EclipseRefinedBuildManager.scala
@@ -81,7 +81,7 @@ class EclipseRefinedBuildManager(project: ScalaProject, settings0: Settings)
} catch {
case e =>
hasErrors = true
- project.buildError(IMarker.SEVERITY_ERROR, "Error in Scala compiler: " + e.getMessage, null)
+ BuildProblemMarker.create(project, e)
logger.error("Error in Scala compiler", e)
}
if (!hasErrors)
View
12 org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/sbtintegration/EclipseSbtBuildManager.scala
@@ -343,7 +343,7 @@ class EclipseSbtBuildManager(val project: ScalaProject, settings0: Settings)
logger.info("Cannot find Scala library on the classpath. Verify your build path! Using default library corresponding to the compiler")
//ScalaPlugin.plugin.sbtScalaLib.get.toFile
val e = new Exception("Cannot find Scala library on the classpath. Verify your build path!")
- project.buildError(IMarker.SEVERITY_ERROR, e.getMessage(), null)
+ BuildProblemMarker.create(project.underlying, e.getMessage)
logger.error("Error in Scala SBT builder", e)
return
}
@@ -361,13 +361,13 @@ class EclipseSbtBuildManager(val project: ScalaProject, settings0: Settings)
val analysisComp = new AnalysisCompile(conf, this, new SbtProgress())
- val extraAnalysis = upstreamAnalysis(project)
+ val extraAnalysis = upstreamAnalysis(project)
- logger.debug("Retrieved the following upstream analysis: " + extraAnalysis)
+ logger.debug("Retrieved the following upstream analysis: " + extraAnalysis)
val order = project.storage.getString(SettingConverterUtil.convertNameToProperty(properties.ScalaPluginSettings.compileOrder.name))
- analysisComp.doCompile(
- scalac, javac, sources, reporter, settings0, CompileOrderMapper(order), analysisMap = extraAnalysis)
+ analysisComp.doCompile(
+ scalac, javac, sources, reporter, settings0, CompileOrderMapper(order), analysisMap = extraAnalysis)
}
/** Return the Analysis for all the dependencies that are Scala projects, and that
@@ -434,7 +434,7 @@ class EclipseSbtBuildManager(val project: ScalaProject, settings0: Settings)
} catch {
case e =>
hasErrors = true
- project.buildError(IMarker.SEVERITY_ERROR, "Error in Scala compiler: " + e.getMessage, null)
+ BuildProblemMarker.create(project, e)
logger.error("Error in Scala compiler", e)
}
View
80 org.scala-ide.sdt.core/src/scala/tools/eclipse/resources/MarkerFactory.scala
@@ -0,0 +1,80 @@
+package scala.tools.eclipse.resources
+
+import scala.tools.eclipse.util.EclipseUtils.workspaceRunnableIn
+
+import org.eclipse.core.resources.IMarker
+import org.eclipse.core.resources.IResource
+import org.eclipse.core.runtime.IProgressMonitor
+
+object MarkerFactory {
+ case class Position(offset: Int, length: Int, line: Int)
+}
+
+/** Generic factory for creating resource's markers.
+ *
+ * Markers are a general mechanism for associating notes and meta-data with resources.
+ *
+ * @param markerType A unique identifier for the created marker. Mind that a marker `X` can be a subtype of a marker `Y`.
+ * See [[org.eclipse.core.resources.IMarker]] for more information.
+ *
+ * Example:
+ *
+ * {{{ class BuildProblemMarker extends MarkerFactory("org.scala-ide.sdt.core.problem") }}}
+ */
+abstract class MarkerFactory(markerType: String) {
+ /** Create marker without a source position in the Problem view.
+ * @param resource The resource to use to create the marker (hence, the marker will be associated to the passed resource)
+ * @param severity Indicates the marker's error state. Its value can be one of:
+ * [IMarker.SEVERITY_ERROR, IMarker.SEVERITY_WARNING, IMarker.SEVERITY_INFO]
+ * @param msg The text message displayed by the marker. Note, the passed message is truncated to 21000 chars.
+ */
+ def create(resource: IResource, severity: Int, msg: String): Unit =
+ createMarkerInWorkspaceAndApply(resource) { marker =>
+ update(marker, severity, msg)
+ }
+
+ /** Create marker with a source position in the Problem view.
+ * @param resource The resource to use to create the marker (hence, the marker will be associated to the passed resource)
+ * @param severity Indicates the marker's error state. Its value can be one of:
+ * [IMarker.SEVERITY_ERROR, IMarker.SEVERITY_WARNING, IMarker.SEVERITY_INFO]
+ * @param msg The text message displayed by the marker. Note, the passed message is truncated to 21000 chars.
+ * @param pos The source position for the marker.
+ */
+ def create(resource: IResource, severity: Int, msg: String, pos: MarkerFactory.Position): Unit =
+ createMarkerInWorkspaceAndApply(resource) { marker =>
+ update(marker, severity, msg)
+ setPos(marker, pos)
+ }
+
+ private def update(marker: IMarker, severity: Int, msg: String): IMarker = {
+ marker.setAttribute(IMarker.SEVERITY, severity)
+ // Marker attribute values are limited to <= 65535 bytes and setAttribute will assert if they
+ // exceed this. To guard against this we trim to <= 21000 characters ... see
+ // org.eclipse.core.internal.resources.MarkerInfo.checkValidAttribute for justification
+ // of this arbitrary looking number
+ val maxMarkerLen = 21000
+ val trimmedMsg = msg.take(maxMarkerLen)
+
+ val attrValue = trimmedMsg.map {
+ case '\n' | '\r' => ' '
+ case c => c
+ }
+
+ marker.setAttribute(IMarker.MESSAGE, attrValue)
+ marker
+ }
+
+ private def setPos(marker: IMarker, position: MarkerFactory.Position): IMarker = {
+ if (position.offset != -1) {
+ marker.setAttribute(IMarker.CHAR_START, position.offset)
+ marker.setAttribute(IMarker.CHAR_END, position.offset + math.max(position.length, 1))
+ marker.setAttribute(IMarker.LINE_NUMBER, position.line)
+ }
+ marker
+ }
+
+ private def createMarkerInWorkspaceAndApply(resource: IResource)(f: IMarker => Unit): Unit = workspaceRunnableIn(resource.getWorkspace) { _ =>
+ val marker = resource.createMarker(markerType)
+ f(marker)
+ }
+}
View
26 org.scala-ide.sdt.core/src/scala/tools/eclipse/util/FileUtils.scala
@@ -72,32 +72,6 @@ object FileUtils {
def hasBuildErrors(file : IResource) : Boolean =
file.findMarkers(plugin.problemMarkerId, true, IResource.DEPTH_INFINITE).exists(_.getAttribute(IMarker.SEVERITY) == IMarker.SEVERITY_ERROR)
-
- def buildError(file : IFile, severity : Int, msg : String, offset : Int, length : Int, line : Int, monitor : IProgressMonitor) =
- workspaceRunnableIn(file.getWorkspace, monitor) { m =>
- val mrk = file.createMarker(plugin.problemMarkerId)
- mrk.setAttribute(IMarker.SEVERITY, severity)
-
- // Marker attribute values are limited to <= 65535 bytes and setAttribute will assert if they
- // exceed this. To guard against this we trim to <= 21000 characters ... see
- // org.eclipse.core.internal.resources.MarkerInfo.checkValidAttribute for justification
- // of this arbitrary looking number
- val maxMarkerLen = 21000
- val trimmedMsg = msg.take(maxMarkerLen)
-
- val attrValue = trimmedMsg.map {
- case '\n' | '\r' => ' '
- case c => c
- }
-
- mrk.setAttribute(IMarker.MESSAGE , attrValue)
-
- if (offset != -1) {
- mrk.setAttribute(IMarker.CHAR_START, offset)
- mrk.setAttribute(IMarker.CHAR_END, offset + math.max(length, 1))
- mrk.setAttribute(IMarker.LINE_NUMBER, line)
- }
- }
def task(file: IFile, tag: String, msg: String, priority: String, offset: Int, length: Int, line: Int, monitor: IProgressMonitor) =
workspaceRunnableIn(file.getWorkspace, monitor) { m =>
Please sign in to comment.
Something went wrong with that request. Please try again.