`
zhaozhongwei
  • 浏览: 54046 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

Markers and Annotations in Eclipse for Error Feedback(forward)

阅读更多

Motto:

Ninety per cent of most magic merely consists of knowing one extra fact.
Terry Pratchett, Night Watch

Development in Eclipse keeps fascinating me, as there are a lot of very thoroughly designed services and features integrated to allow detailed customization – on the other hand, “with big power comes big responsibility”, but at least a steep learning curve. I had such an experience with the problem handling support not long ago.

We developed our own textual language, that provided error markers and editor annotations as error feedback. The problem was that the editor annotations were sometimes missing: our planned functionality worked like we like to add an annotation each time our marker was added, but the annotations were not always updated (so we got an inconsistent state between markers and annotations – but not every time).

Of course that was caused by the fact that we were rolling out our own implementation of marker/annotation synchronization – we were not aware that the JFace TextEditor provides such a service out of the box – and I did not found it documented on the various locations (that’s why this blog post is born :) ).

Our requirements

First of all, lets assemble the various ways Eclipse editors can provide error feedback:

  • The most basic (and least usable) way is the use of pop-up windows – they are annoying, and not persistent (after pressing a button, they disappear, before the error could be solved).
  • Writing to the Error log view – a bit better, but the log could be overwhelmed, if the messages are too many, because they cannot be deleted when the problem is solved.
  • Displaying the error in the Problems view – that’s one of the standard places, where parse errors should be displayed. The problems view is generated by reading (and filtering) the error marker type (org.eclipse.core.resources.problemmarker ).
  • Marking the files in the Project Navigator view with a small symbol, if they contain errors/warnings. This is also handled using the previously mentioned error marker.
  • Underlining the erroneous parts in the editor. For this reason annotations should be added to the JFace Document Model used by the JFace TextEditor component.

The basic idea is to create a marker and an annotation each time a problem is found. The problem with annotations, that creating them requires some connection with the editor object, or at least the document model, but our parser should not depend on the editor (core component should not depend on the GUI!).

Mark My Words!

The management of the markers is well described in the Mark My Words tutorial. Basically markers are attached to IResources , and provide a simple key-value interface with a freely definable key set (and the IMarker interface specifies some commonly used keys).

Following the tutorial we could create our own marker with the parent of the org.eclipse.core.resources.problemmarker marker, after this adding the markers to the selected files managed the error display in the Problems and Project Navigator views.

So our marker definition looks as follows:

1
2
3
4
5
6
7
8
<extension id ="org.eclipse.viatra2.loaders.vtclparsermarker"
     name ="VTCL Parsing Problems"
     point ="org.eclipse.core.resources.markers" >
   <super type ="org.eclipse.core.resources.problemmarker" >
   </super>
   <persistent value ="true" >
   </persistent>
</extension>

The problem marker understands severity, error message and line number parameters, and is capable of displaying them in the Problems view.

1
2
3
4
IMarker marker = file.createMarker ( markerId) ;
marker.setAttribute ( IMarker.SEVERITY , severity) ;
marker.setAttribute ( IMarker.MESSAGE , message) ;
marker.setAttribute ( IMarker.LINE_NUMBER , line) ;

Annotating the document manually

As stated before, markers could be added easily without knowing anything about who has opened the file currently, so they are really useful for error feedback, but this information should be also available in the open editors.

Our first idea may be to create some glue code, that listens to the marker changes, and updates our editor accordingly. The drawbacks of this approach are first the fact that we have to code something that trivial, and the second (as we saw in our project), that the editor update could be quite tricky (missing or not deleted annotations).

My theory is, that we have encountered some kind of race condition with our naive implementation, as the annotation creation code was always executed, but sometimes the results were lost. So, in the end, this listener is not so trivial. :(

Automatic annotation display

This was the part that gave us the most headache – we did not understand, what caused the inconsistent display problem. On the other hand, knowing one extra fact (“magic”) the problem is trivially solvable.

So, here comes the Eclipse magic: we don’t have to create this service manually, we should reuse the already existing one. For that, we would need that our marker also become a child marker of the org.eclipse.core.resources.textmarker , and a minimal set of position data should be added to the marker.

This position information is described by the start and end offset value – instead of the human-readable line/column position information a machine-readable single position is used: the number of characters that has to be read from the start of the string stream. Its lucky, that most parser generators provide such output that this information is trivially available from the AST level.

1
2
3
4
5
6
7
8
9
10
11
<extension id ="org.eclipse.viatra2.loaders.vtclparsermarker"
     name ="VTCL Parsing Problems"
     point ="org.eclipse.core.resources.markers" >
   <super type ="org.eclipse.core.resources.problemmarker" >
   </super>
   <persistent value ="true" >
   </persistent>
   <!-- The following item is added -->
   <super type ="org.eclipse.core.resources.textmarker" >
   </super>
</extension>

And the marker creator Java code looks as follows:

1
2
3
4
5
6
7
8
IMarker marker = file.createMarker ( markerId) ;
marker.setAttribute ( IMarker.SEVERITY , severity) ;
marker.setAttribute ( IMarker.MESSAGE , message) ;
marker.setAttribute ( IMarker.LINE_NUMBER , line) ;
if ( pos.offset != 0 ) {
marker.setAttribute ( IMarker.CHAR_START ,pos.offset ) ;
marker.setAttribute ( IMarker.CHAR_END ,pos.offset + pos.length ) ;
}

After that, the platform uses a default implementation, that provides the well-known wriggly underline to annotate our text files with the associated markers.

Summary

Alltogether, the following steps are needed to provide a simple error reporting for our existing editor:

  • Create a custom marker type
    • With a supertype of org.eclipse.core.resources.problemmarker to display the report in the problems view
    • With a supertype of org.eclipse.core.resources.textmarker to underline the errors in the textual editor
  • Create a marker instance
    • Setting the IMarker.SEVERITY , IMarker.MESSAGE and IMarker.LINE_NUMBER attributes for the Problems view.
    • Setting the IMarker.CHAR_START and IMarker.CHAR_END for the editor annotations.

Conclusion

The Eclipse text editors provide a well-defined, easy to use error reporting mechanism nearly for free. The main catch is, we have to be careful to set everything – if something is missing, we got the silent failure issue – no exception is thrown, but something is not shown.

The biggest issue in our implementation was that the IMarker.CHAR_START and IMarker.CHAR_END marker attributes are ignored, if the used marker is not a text attribute, making this problem hard to identify.

A fine thing with this error reporting mechanism is, that it is independent of the concrete text editor used: when we changed our implementation in the VIATRA framework, the resulting reports were visible in every text editor (e.g. the dedicated VIATRA text editor, or the default text editor in Eclipse) – thus helping error recovery.

分享到:
评论

相关推荐

    android 画图软件源码 markers-for-android

    "markers-for-android"是一款专为Android平台设计的画图软件的源代码库,它提供了丰富的绘图功能,包括压感支持和多指触控画图。这个项目对于想要深入理解Android图形绘制、触摸事件处理以及自定义View的开发者来说...

    The Lancaster Corpus of Mandarin Chinese

    The corpus is suitable for use in both monolingual research into modern Mandarin Chinese and cross-linguistic contrast of Chinese and British/American English. The corpus sampled 15 written text ...

    EmEditor中文版

    Right clicking on each marker in the Markers toolbar displays a context menu, and allows you to enable or disable each marker, search for each marker, or change the match condition (case sensitivity, ...

    ComponentOne Studio for Silverlight 2013 v1

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for Silverlight provides built-in printing, cell merging, column ...

    ComponentOne Studio for WPF2012 v3 1/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for WPF provides built-in printing, cell merging, column aggregation, ...

    ComponentOne Studio for Silverlight 2013 v1 3/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for Silverlight provides built-in printing, cell merging, column ...

    ComponentOne Studio for WPF2012 v3 2/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for WPF provides built-in printing, cell merging, column aggregation, ...

    ComponentOne Studio for Silverlight 2013 v1 2/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for Silverlight provides built-in printing, cell merging, column ...

    ComponentOne Studio for Silverlight 2012 v3 1/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for Silverlight provides built-in printing, cell merging, column ...

    openlayers 添加标注 markers

    openlayers 添加标注 markers 怎么给Google地图添加标注

    Leaflet.Canvas-Markers-0.2.0

    《Leaflet.Canvas-Markers-0.2.0:在地图上绘制高性能的canvas标记》 在Web开发中,地图已经成为一种常见的数据可视化工具,而Leaflet作为一款轻量级的JavaScript库,因其易于使用和强大的功能深受开发者喜爱。本文...

    ComponentOne Studio for Silverlight 2012 v3 2/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for Silverlight provides built-in printing, cell merging, column ...

    Markers in diagnosis of lung cancer: Several common detection methods

    肺癌是目前全球范围内最常见的癌症类型,同时也是癌症死亡的主要原因,特别是在工业化国家。肺癌的发生过程可能追溯到数年甚至数十年以前。不幸的是,超过一半的肺癌患者在晚期阶段才被诊断出病情,而在更加可治疗的...

    stp_file_for_study

    STP viewer is a professional tool for viewing CAD models with excellent speed and ... The very interesting feature in STP viewer is tree view where you can see all markers that are used in 3D object.

    ComponetOne Studio for WPF 2013 v1 3/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for WPF provides built-in printing, cell merging, column aggregation, ...

    ComponetOne Studio for WPF 2013 v1 1/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for WPF provides built-in printing, cell merging, column aggregation, ...

    ComponetOne Studio for WPF 2013 v1 2/3

    Inspired by Microsoft Excel for creating bound and unbound grids and scrolling speed 10x faster than the competition, FlexGrid for WPF provides built-in printing, cell merging, column aggregation, ...

    Eclipse插件开发内部培训3

    Eclipse插件开发内部培训第三部分主要关注Eclipse平台中的资源管理和相关API的使用。Eclipse作为一个强大的集成开发环境(IDE),其插件体系基于Java虚拟机(JVM)上的Equinox,这是一个基于OSGI框架的扩展点系统。该...

    Eclipse平台扩展点清单

    org.eclipse.core.resources.markers** 此扩展点用于定义标记(Marker),如错误或警告标志,它们可以附加到文件或项目上。 **4. org.eclipse.core.resources.moveDeleteHook** 此扩展点用于定义移动和删除钩子...

Global site tag (gtag.js) - Google Analytics