Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Error markers in the outline
icon14.gif  Error markers in the outline [message #1737487] Fri, 08 July 2016 11:29 Go to next message
Eclipse UserFriend
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 15:53] by Moderator

Re: Error markers in the outline [message #1737554 is a reply to message #1737487] Sat, 09 July 2016 15:52 Go to previous messageGo to next message
Eclipse UserFriend
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.
Re: Error markers in the outline [message #1737607 is a reply to message #1737554] Mon, 11 July 2016 04:48 Go to previous message
Eclipse UserFriend
I did not find any suitable solution based on a ILogicalContainerProvider. If someone has an idea, s/he is welcome.

[Updated on: Mon, 11 July 2016 07:10] by Moderator

Previous Topic:MWE2 Fragments for generating highlighting formats for third-party tools
Next Topic:[CLOSED] How to optimize generated code?
Goto Forum:
  


Current Time: Wed Jul 23 15:47:29 EDT 2025

Powered by FUDForum. Page generated in 0.03438 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top