Error markers in the outline [message #1737487] |
Fri, 08 July 2016 15:29 |
|
Dear all.
I would like to have error and warning markers on the icons in the outline of my DSL elements that have errors.
It is possible from the Xtext outline API (DefaultOutlineTreeProvider)?
What to do?
Thank you.
Stéphane.
[Updated on: Sat, 09 July 2016 19:53] Report message to a moderator
|
|
|
Re: Error markers in the outline [message #1737554 is a reply to message #1737487] |
Sat, 09 July 2016 19:52 |
|
Dear all.
I have found a solution for drawing the diagnostic decorations in the outline. If someone has a more efficient solution, s/he welcome to reply in this topic.
First, I have defined a label decorator that is managing the diagnostics (I have not found one suitable in the existing ones).
public class DSLDiagnosticLabelDecorator extends BaseLabelProvider implements ILabelDecorator {
private static final Method GET_NODE_METHOD;
static {
try {
GET_NODE_METHOD = AbstractDiagnostic.class.getDeclaredMethod("getNode");
GET_NODE_METHOD.setAccessible(true);
} catch (Exception e) {
throw new Error(e);
}
}
@Inject
private IImageHelper imageHelper;
@Inject
private IImageDescriptorHelper imageDescriptorHelper;
private static boolean inside(INode node, ICompositeNode parentCandidate) {
INode current = node;
while (current != null) {
if (current.equals(parentCandidate)) {
return true;
}
current = current.getParent();
}
return false;
}
protected Image convertToImage(Object imageDescription) {
if (imageDescription instanceof Image) {
return (Image) imageDescription;
} else if (imageDescription instanceof ImageDescriptor) {
return this.imageHelper.getImage((ImageDescriptor) imageDescription);
} else if (imageDescription instanceof String) {
return this.imageHelper.getImage((String) imageDescription);
}
return null;
}
private static boolean hasParserIssue(ICompositeNode node, Iterable<Resource.Diagnostic> issues) {
for (final Resource.Diagnostic resourceDiagnostic : issues) {
if (resourceDiagnostic instanceof AbstractDiagnostic) {
final AbstractDiagnostic diag = (AbstractDiagnostic) resourceDiagnostic;
final INode diagNode;
try {
diagNode = (INode) GET_NODE_METHOD.invoke(diag);
} catch (Exception e) {
throw new Error(e);
}
if (inside(diagNode, node)) {
return true;
}
}
}
return false;
}
protected int getIssueAdornment(XtendMember element) {
final ICompositeNode node = NodeModelUtils.getNode(element);
if (node == null) {
return 0;
}
// Error markers are more important than warning markers.
// Order of checks:
// - parser error (from the resource) or semantic error (from Diagnostician)
// - parser warning or semantic warning
final Resource resource = element.eResource();
if (hasParserIssue(node, resource.getErrors())) {
return JavaElementImageDescriptor.ERROR;
}
final Diagnostic diagnostic = Diagnostician.INSTANCE.validate(element);
switch (diagnostic.getSeverity()) {
case Diagnostic.ERROR:
return JavaElementImageDescriptor.ERROR;
case Diagnostic.WARNING:
return JavaElementImageDescriptor.WARNING;
default:
}
if (hasParserIssue(node, resource.getWarnings())) {
return JavaElementImageDescriptor.WARNING;
}
return 0;
}
protected Point imagesSize() {
return JavaElementImageProvider.BIG_SIZE;
}
@Override
public Image decorateImage(Image image, Object element) {
if (element instanceof XtendMember) {
final int adornment = getIssueAdornment((XtendMember) element);
if (adornment != 0) {
final ImageDescriptor descriptor = this.imageDescriptorHelper.getImageDescriptor(image);
final ImageDescriptor newDescriptor = new JavaElementImageDescriptor(descriptor, adornment, imagesSize());
return convertToImage(newDescriptor);
}
}
return image;
}
@Override
public String decorateText(String text, Object element) {
return text;
}
}
In injection module, I have mapping ILabelProvider to DSLDiagnosticLabelDecorator when it is annotated with a specific name.
Then, I have updated my DSLOutlineTreeProvider as:
public class DSLOutlineTreeProvider extends XbaseWithAnnotationsOutlineTreeProvider {
@Inject
@Named("DiagnosticDecorator")
private ILabelDecorator diagnoticDecorator;
@Override
protected Image _image(Object modelElement) {
final Image img = super._image(modelElement);
return this.diagnoticDecorator.decorateImage(img, modelElement);
}
}
It seems to work.
Again, if someone has a better answer, s/he welcome to give a feedback.
All the best.
Stéphane.
|
|
|
|
Powered by
FUDForum. Page generated in 0.02840 seconds