Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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  ...de.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 ...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.