Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Error markers in the outline
icon14.gif  Error markers in the outline [message #1737487] Fri, 08 July 2016 15:29 Go to next message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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 Go to previous messageGo to next message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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 08:48 Go to previous message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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 11:10]

Report message to a 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: Sun Jan 17 20:05:29 GMT 2021

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

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

Back to the top