package org.xpect.xtext.lib.util;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parsetree.reconstr.impl.NodeIterator;
import org.eclipse.xtext.resource.XtextResource;
import org.xpect.XpectImport;
import org.xpect.XpectInvocation;
import org.xpect.parameter.IStatementRelatedRegion;
import org.xpect.setup.XpectSetupFactory;
import org.xpect.state.Creates;
import org.xpect.state.XpectStateAnnotation;
import org.xpect.text.IRegion;
import org.xpect.text.Region;
import org.xpect.text.Text;
import org.xpect.xtext.lib.setup.ThisResource;
import org.xpect.xtext.lib.util.NextLine.NextLineProvider;
@Retention(RetentionPolicy.RUNTIME)
@XpectStateAnnotation
@XpectImport(NextLineProvider.class)
public @interface NextLine {
@XpectSetupFactory
public static class NextLineProvider {
private final IRegion nextLine;
public NextLineProvider(@ThisResource XtextResource resource, XpectInvocation statement) {
ICompositeNode rootNode = resource.getParseResult().getRootNode();
ILeafNode leaf = findNextNonHiddenLeaf(rootNode, statement);
String document = rootNode.getText();
Text text = new Text(document);
int offset = leaf.getOffset();
int start = text.currentLineStart(offset);
int end = text.currentLineEnd(offset);
this.nextLine = new Region(document, start, end - start);
}
private ILeafNode findNextNonHiddenLeaf(ICompositeNode rootNode, XpectInvocation statement) {
IStatementRelatedRegion statementRegion = statement.getExtendedRegion();
ILeafNode leaf = NodeModelUtils.findLeafNodeAtOffset(rootNode, statementRegion.getOffset() + statementRegion.getLength());
NodeIterator it = new NodeIterator(leaf);
while (it.hasNext()) {
INode next = it.next();
if (next instanceof ILeafNode && !((ILeafNode) next).isHidden())
return (ILeafNode) next;
}
throw new IllegalStateException("No line with non-hidden tokens found after \n" + statementRegion.toString());
}
@Creates(NextLine.class)
public IRegion getNextLine() {
return nextLine;
}
}
}