mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 08:48:55 +00:00
Merge pull request #967 from eclipse/ak/bug_489547
[bug 489547] Allow to provide offset and length for SyntheticLinkingLeafNode
This commit is contained in:
commit
dcd274fd07
2 changed files with 115 additions and 166 deletions
|
@ -7,23 +7,17 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.linking.lazy;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.EReference;
|
||||
import org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.xtext.XtextFactory;
|
||||
import org.eclipse.xtext.nodemodel.BidiTreeIterable;
|
||||
import org.eclipse.xtext.nodemodel.BidiTreeIterator;
|
||||
import org.eclipse.xtext.nodemodel.ICompositeNode;
|
||||
import org.eclipse.xtext.nodemodel.ILeafNode;
|
||||
import org.eclipse.xtext.nodemodel.INode;
|
||||
import org.eclipse.xtext.nodemodel.SyntaxErrorMessage;
|
||||
import org.eclipse.xtext.nodemodel.util.NodeTreeIterator;
|
||||
import org.eclipse.xtext.nodemodel.util.ReversedBidiTreeIterable;
|
||||
import org.eclipse.xtext.util.ITextRegion;
|
||||
import org.eclipse.xtext.util.ITextRegionWithLineInformation;
|
||||
import org.eclipse.xtext.util.TextRegion;
|
||||
import org.eclipse.xtext.util.TextRegionWithLineInformation;
|
||||
import org.eclipse.xtext.nodemodel.impl.CompositeNode;
|
||||
import org.eclipse.xtext.nodemodel.impl.LeafNode;
|
||||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
|
||||
import org.eclipse.xtext.parser.IParseResult;
|
||||
import org.eclipse.xtext.resource.XtextResource;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
|
@ -39,179 +33,99 @@ public class SyntheticLinkingSupport {
|
|||
private LazyLinker lazyLinker;
|
||||
|
||||
public void createAndSetProxy(EObject obj, EReference eRef, String crossRefString) {
|
||||
lazyLinker.createAndSetProxy(obj, new SyntheticLinkingLeafNode(obj, crossRefString), eRef);
|
||||
createAndSetProxy(obj, eRef, crossRefString, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.10
|
||||
*/
|
||||
public void createAndSetProxy(EObject obj, EReference eRef, String crossRefString, int offset, int length) {
|
||||
INode crossReferenceNode = createCrossReferenceNode(obj, eRef, crossRefString, offset, length);
|
||||
lazyLinker.createAndSetProxy(obj, crossReferenceNode, eRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.10
|
||||
*/
|
||||
protected INode createCrossReferenceNode(EObject obj, EReference eRef, String crossRefString, int offset, int length) {
|
||||
CompositeNode parent = getParent(obj, eRef, crossRefString, offset, length);
|
||||
EObject grammarElement = getGrammarElement(obj, eRef, crossRefString, offset, length);
|
||||
return new SyntheticLinkingLeafNode(obj, crossRefString, offset, length, grammarElement, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.10
|
||||
*/
|
||||
protected EObject getGrammarElement(EObject obj, EReference eRef, String crossRefString, int offset, int length) {
|
||||
return XtextFactory.eINSTANCE.createKeyword();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.10
|
||||
*/
|
||||
protected CompositeNode getParent(EObject obj, EReference eRef, String crossRefString, int offset, int length) {
|
||||
ICompositeNode node = NodeModelUtils.getNode(obj);
|
||||
if (node != null) {
|
||||
ICompositeNode rootNode = node.getRootNode();
|
||||
if (rootNode instanceof CompositeNode)
|
||||
return (CompositeNode) rootNode;
|
||||
}
|
||||
Resource resource = obj.eResource();
|
||||
if (resource instanceof XtextResource) {
|
||||
IParseResult parseResult = ((XtextResource) resource).getParseResult();
|
||||
if (parseResult != null) {
|
||||
ICompositeNode rootNode = parseResult.getRootNode();
|
||||
if (rootNode instanceof CompositeNode)
|
||||
return (CompositeNode) rootNode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SyntheticLinkingLeafNode implements ILeafNode, BidiTreeIterable<INode> {
|
||||
|
||||
private final static int OFFSET = 0;
|
||||
private final static int LENGTH = 1;
|
||||
private final static int LINE = -1;
|
||||
class SyntheticLinkingLeafNode extends LeafNode {
|
||||
|
||||
private final String text;
|
||||
private final EObject grammarElement;
|
||||
private final EObject semanticElement;
|
||||
|
||||
public SyntheticLinkingLeafNode(EObject semanticElement, String text) {
|
||||
public SyntheticLinkingLeafNode(EObject semanticElement, String text, int offset, int length, EObject grammarElement, CompositeNode parent) {
|
||||
this.text = text;
|
||||
this.semanticElement = semanticElement;
|
||||
this.grammarElement = XtextFactory.eINSTANCE.createKeyword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICompositeNode getParent() {
|
||||
return null;
|
||||
basicSetTotalOffset(offset);
|
||||
basicSetTotalLength(length);
|
||||
basicSetGrammarElement(grammarElement);
|
||||
basicSetParent(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSiblings() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPreviousSibling() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextSibling() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INode getPreviousSibling() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INode getNextSibling() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICompositeNode getRootNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ILeafNode> getLeafNodes() {
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalOffset() {
|
||||
return OFFSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
return OFFSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalLength() {
|
||||
return LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalEndOffset() {
|
||||
return LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndOffset() {
|
||||
return LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalStartLine() {
|
||||
return LINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartLine() {
|
||||
return LINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalEndLine() {
|
||||
return LINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndLine() {
|
||||
return LINE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EObject getGrammarElement() {
|
||||
return grammarElement;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EObject getSemanticElement() {
|
||||
return semanticElement;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasDirectSemanticElement() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyntaxErrorMessage getSyntaxErrorMessage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BidiTreeIterable<INode> getAsTreeIterable() {
|
||||
return this;
|
||||
protected EObject basicGetSemanticElement() {
|
||||
return semanticElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BidiTreeIterator<INode> iterator() {
|
||||
return new NodeTreeIterator(this);
|
||||
protected boolean basicHasSiblings() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BidiTreeIterable<INode> reverse() {
|
||||
return new ReversedBidiTreeIterable<INode>(this);
|
||||
protected boolean basicHasNextSibling() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ITextRegion getTextRegion() {
|
||||
return new TextRegion(OFFSET, LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextRegion getTotalTextRegion() {
|
||||
return new TextRegion(OFFSET, LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextRegionWithLineInformation getTextRegionWithLineInformation() {
|
||||
return new TextRegionWithLineInformation(OFFSET, LENGTH, LINE, LINE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextRegionWithLineInformation getTotalTextRegionWithLineInformation() {
|
||||
return new TextRegionWithLineInformation(OFFSET, LENGTH, LINE, LINE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
protected boolean basicHasPreviousSibling() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,10 @@ import org.eclipse.xtext.linking.importedURI.ImportedURIPackage;
|
|||
import org.eclipse.xtext.linking.importedURI.Main;
|
||||
import org.eclipse.xtext.linking.importedURI.Type;
|
||||
import org.eclipse.xtext.linking.lazy.SyntheticLinkingSupport;
|
||||
import org.eclipse.xtext.nodemodel.INode;
|
||||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
|
||||
import org.eclipse.xtext.resource.XtextResourceSet;
|
||||
import org.eclipse.xtext.util.LineAndColumn;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -43,32 +46,64 @@ public class Bug437669Test extends AbstractXtextTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUnresolved() {
|
||||
public void testUnresolved_01() {
|
||||
Type type = resolve("BlaBlaBla");
|
||||
Resource resource = type.eResource();
|
||||
assertEquals(resource.getErrors().toString(), 1, resource.getErrors().size());
|
||||
|
||||
Diagnostic diagnostic = (Diagnostic) resource.getErrors().get(0);
|
||||
assertEquals(-1, diagnostic.getLine());
|
||||
assertEquals(0, diagnostic.getOffset());
|
||||
assertEquals(1, diagnostic.getLength());
|
||||
assertEquals(1, diagnostic.getLine());
|
||||
assertEquals(1, diagnostic.getColumn());
|
||||
assertEquals("Couldn't resolve reference to Type 'BlaBlaBla'.", diagnostic.getMessage());
|
||||
}
|
||||
|
||||
private Type resolve(String text) {
|
||||
@Test
|
||||
public void testUnresolved_02() {
|
||||
Type type = getContext();
|
||||
INode nameNode = NodeModelUtils.findNodesForFeature(type, ImportedURIPackage.Literals.TYPE__NAME).get(0);
|
||||
resolve(type, "BlaBlaBla", nameNode.getOffset(), nameNode.getLength());
|
||||
Resource resource = type.eResource();
|
||||
assertEquals(resource.getErrors().toString(), 1, resource.getErrors().size());
|
||||
|
||||
LineAndColumn lineAndColumn = NodeModelUtils.getLineAndColumn(nameNode, nameNode.getOffset());
|
||||
|
||||
Diagnostic diagnostic = (Diagnostic) resource.getErrors().get(0);
|
||||
assertEquals(nameNode.getOffset(), diagnostic.getOffset());
|
||||
assertEquals(nameNode.getLength(), diagnostic.getLength());
|
||||
assertEquals(lineAndColumn.getLine(), diagnostic.getLine());
|
||||
assertEquals(lineAndColumn.getColumn(), diagnostic.getColumn());
|
||||
assertEquals("Couldn't resolve reference to Type 'BlaBlaBla'.", diagnostic.getMessage());
|
||||
}
|
||||
|
||||
protected Type resolve(String text) {
|
||||
Type type = getContext();
|
||||
return resolve(type, text);
|
||||
}
|
||||
|
||||
protected Type resolve(Type type, String text) {
|
||||
SyntheticLinkingSupport syntheticLinkingSupport = get(SyntheticLinkingSupport.class);
|
||||
syntheticLinkingSupport.createAndSetProxy(type, ImportedURIPackage.Literals.TYPE__EXTENDS, text);
|
||||
EcoreUtil.resolveAll(type.eResource().getResourceSet());
|
||||
return type;
|
||||
}
|
||||
|
||||
protected Type resolve(Type type, String text, int offset, int length) {
|
||||
SyntheticLinkingSupport syntheticLinkingSupport = get(SyntheticLinkingSupport.class);
|
||||
syntheticLinkingSupport.createAndSetProxy(type, ImportedURIPackage.Literals.TYPE__EXTENDS, text, offset, length);
|
||||
EcoreUtil.resolveAll(type.eResource().getResourceSet());
|
||||
return type;
|
||||
}
|
||||
|
||||
protected Type getContext() {
|
||||
XtextResourceSet resourceSet = get(XtextResourceSet.class);
|
||||
resourceSet.setClasspathURIContext(getClass().getClassLoader());
|
||||
|
||||
URI uri = URI.createURI("classpath:/org/eclipse/xtext/linking/02.importuritestlanguage");
|
||||
Resource resource = resourceSet.getResource(uri, true);
|
||||
Main main = (Main) resource.getContents().get(0);
|
||||
Type type = main.getTypes().get(0);
|
||||
|
||||
SyntheticLinkingSupport syntheticLinkingSupport = get(SyntheticLinkingSupport.class);
|
||||
syntheticLinkingSupport.createAndSetProxy(type, ImportedURIPackage.Literals.TYPE__EXTENDS, text);
|
||||
|
||||
EcoreUtil.resolveAll(resourceSet);
|
||||
return type;
|
||||
return main.getTypes().get(0);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue