mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 00:38:56 +00:00
improved error handling in serializer
This commit is contained in:
parent
8fa9c56032
commit
87c30892b7
4 changed files with 91 additions and 15 deletions
|
@ -0,0 +1,15 @@
|
|||
package org.eclipse.xtext.parsetree.reconstr;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XtextSerializationException extends RuntimeException {
|
||||
private IInstanceDescription desc;
|
||||
|
||||
public XtextSerializationException(IInstanceDescription desc, String msg) {
|
||||
super(msg);
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public IInstanceDescription getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import org.eclipse.xtext.conversion.IValueConverterService;
|
|||
import org.eclipse.xtext.parsetree.AbstractNode;
|
||||
import org.eclipse.xtext.parsetree.CompositeNode;
|
||||
import org.eclipse.xtext.parsetree.LeafNode;
|
||||
import org.eclipse.xtext.parsetree.NodeAdapter;
|
||||
import org.eclipse.xtext.parsetree.NodeUtil;
|
||||
import org.eclipse.xtext.parsetree.reconstr.IInstanceDescription;
|
||||
|
||||
|
@ -26,8 +27,8 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
|
|||
Map<AbstractElement, Integer> map = null;
|
||||
if (numberOfOccurences.containsKey(node)) {
|
||||
map = numberOfOccurences.get(node);
|
||||
}
|
||||
if (map==null)
|
||||
}
|
||||
if (map == null)
|
||||
map = new HashMap<AbstractElement, Integer>();
|
||||
Integer n = 0;
|
||||
if (map.containsKey(ele)) {
|
||||
|
@ -37,7 +38,7 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
|
|||
n++;
|
||||
map.put(ele, n);
|
||||
numberOfOccurences.put(node, map);
|
||||
return n-1;
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -60,17 +61,17 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
|
|||
@Override
|
||||
protected void before(IInstanceDescription desc, AbstractElement element) {
|
||||
CompositeNode rootNode = getEntryNode(desc);
|
||||
|
||||
iterateChldren(element, rootNode);
|
||||
if (rootNode != null)
|
||||
iterateChldren(element, rootNode);
|
||||
}
|
||||
// private String debugInfo(EObject grammarElement) {
|
||||
// return grammarElement.toString();
|
||||
// }
|
||||
|
||||
private CompositeNode getEntryNode(IInstanceDescription desc) {
|
||||
CompositeNode rootNode = NodeUtil.getNodeAdapter(desc.getDelegate()).getParserNode();
|
||||
NodeAdapter nodeAdapter = NodeUtil.getNodeAdapter(desc.getDelegate());
|
||||
if (nodeAdapter == null)
|
||||
return null;
|
||||
CompositeNode rootNode = nodeAdapter.getParserNode();
|
||||
// go up normalizable rulecalls
|
||||
while (rootNode.getParent()!=null && rootNode.getParent().getElement()==null)
|
||||
while (rootNode.getParent() != null && rootNode.getParent().getElement() == null)
|
||||
rootNode = rootNode.getParent();
|
||||
return rootNode;
|
||||
}
|
||||
|
@ -79,7 +80,7 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
|
|||
EList<AbstractNode> leafNodes = rootNode.getChildren();
|
||||
boolean consumingMode = false;
|
||||
int skip = getOccurencesAndIncrease(rootNode, element);
|
||||
for (int x = leafNodes.size()-1; x>=0;x--) {
|
||||
for (int x = leafNodes.size() - 1; x >= 0; x--) {
|
||||
AbstractNode an = leafNodes.get(x);
|
||||
if (an instanceof LeafNode) {
|
||||
LeafNode n = (LeafNode) an;
|
||||
|
@ -89,7 +90,7 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
|
|||
prepend(n.getText());
|
||||
}
|
||||
if (n.getGrammarElement() == element) {
|
||||
if (skip==0) {
|
||||
if (skip == 0) {
|
||||
consumingMode = true;
|
||||
} else {
|
||||
skip--;
|
||||
|
@ -97,12 +98,12 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
|
|||
}
|
||||
} else if (an instanceof CompositeNode) {
|
||||
CompositeNode cn = (CompositeNode) an;
|
||||
if (rootNode.getElement()==null) {
|
||||
if (rootNode.getElement() == null) {
|
||||
iterateChldren(element, cn);
|
||||
}
|
||||
}
|
||||
// if (n.getGrammarElement() == element)
|
||||
// log.info(debugInfo(n.getGrammarElement()));
|
||||
// if (n.getGrammarElement() == element)
|
||||
// log.info(debugInfo(n.getGrammarElement()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.parsetree.reconstr.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -168,5 +170,16 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
}
|
||||
return 1-featureConsumedCounter.get(feature);
|
||||
}
|
||||
|
||||
public String uniqueStateString() {
|
||||
StringBuffer buff = new StringBuffer();
|
||||
buff.append(getDelegate());
|
||||
List<String> features = new ArrayList<String>(featureConsumedCounter.keySet());
|
||||
Collections.sort(features);
|
||||
for (String f : features) {
|
||||
buff.append(f).append(featureConsumedCounter.get(f));
|
||||
}
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.eclipse.xtext.parsetree.reconstr;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.parser.IAstFactory;
|
||||
import org.eclipse.xtext.parsetree.reconstr.callbacks.WhitespacePreservingCallback;
|
||||
import org.eclipse.xtext.tests.AbstractGeneratorTest;
|
||||
|
||||
|
@ -19,15 +20,61 @@ public class WhitespacePreservingCallbackTest extends AbstractGeneratorTest {
|
|||
check("a \t /* foo bar */ + b");
|
||||
}
|
||||
|
||||
public void testFail1() throws Exception {
|
||||
IAstFactory f = getASTFactory();
|
||||
failsWith(f.create("Add"), XtextSerializationException.class);
|
||||
}
|
||||
|
||||
|
||||
public void testFail2() throws Exception {
|
||||
IAstFactory f = getASTFactory();
|
||||
EObject add = f.create("Add");
|
||||
|
||||
// one operand INVALID
|
||||
EObject atom1 = f.create("Atom");
|
||||
f.set(atom1, "name", "x");
|
||||
f.add(add, "addOperands", atom1);
|
||||
failsWith(add, XtextSerializationException.class);
|
||||
|
||||
// two operands VALID
|
||||
EObject atom2 = f.create("Atom");
|
||||
f.set(atom2, "name", "x");
|
||||
f.add(add, "addOperands", atom2);
|
||||
assertNotNull(serialize(add));
|
||||
|
||||
// three operands INVALID
|
||||
EObject atom3 = f.create("Atom");
|
||||
f.set(atom3, "name", "x");
|
||||
f.add(add, "addOperands", atom3);
|
||||
failsWith(add, XtextSerializationException.class);
|
||||
}
|
||||
|
||||
private void check(String m1) throws Exception {
|
||||
assertEquals(m1, parseAndSerialize(m1));
|
||||
}
|
||||
|
||||
private String parseAndSerialize(String model) throws Exception {
|
||||
EObject result = (EObject) getModel(model);
|
||||
return serialize(result);
|
||||
}
|
||||
|
||||
private String serialize(EObject result) {
|
||||
IParseTreeConstructor con = getParseTreeConstructor();
|
||||
WhitespacePreservingCallback cb = new WhitespacePreservingCallback(getValueConverterService());
|
||||
con.update(result, cb);
|
||||
return cb.toString();
|
||||
}
|
||||
|
||||
private void failsWith(EObject o, Class<? extends RuntimeException> clazz) {
|
||||
try {
|
||||
IParseTreeConstructor con = getParseTreeConstructor();
|
||||
WhitespacePreservingCallback cb = new WhitespacePreservingCallback(getValueConverterService());
|
||||
con.update(o, cb);
|
||||
fail("Should fail with "+clazz.getSimpleName());
|
||||
} catch (RuntimeException e) {
|
||||
if (!clazz.isInstance(e)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue