|
Re: Error markers in the outline [message #1737554 is a reply to message #1737487] |
Sat, 09 July 2016 15:52   |
Eclipse User |
|
|
|
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.03438 seconds