Merge pull request #990 from eclipse/me/serializer_value_converter

[serializer] never attempt to call ValueConverter with wrong rule
This commit is contained in:
Moritz Eysholdt 2016-04-12 19:50:13 +02:00
commit 405d67687b
2 changed files with 26 additions and 9 deletions

View file

@ -37,15 +37,22 @@ public class LinkingHelper {
* may be any crossreferencable element, i.e. a keyword or a rulecall
*/
public String getRuleNameFrom(EObject grammarElement) {
AbstractRule rule = getRuleFrom(grammarElement);
return rule != null ? rule.getName() : null;
}
/**
* @since 2.10
*/
public AbstractRule getRuleFrom(EObject grammarElement) {
if (!(grammarElement instanceof Keyword || grammarElement instanceof RuleCall || grammarElement instanceof CrossReference))
throw new IllegalArgumentException("grammarElement is of type: '" + grammarElement.eClass().getName() + "'");
AbstractRule rule = null;
EObject elementToUse = grammarElement;
if (grammarElement instanceof CrossReference)
elementToUse = ((CrossReference) grammarElement).getTerminal();
if (elementToUse instanceof RuleCall)
rule = ((RuleCall) elementToUse).getRule();
return rule != null ? rule.getName() : null;
return ((RuleCall) elementToUse).getRule();
return null;
}
public String getCrossRefNodeAsString(INode node, boolean convert) {

View file

@ -8,14 +8,16 @@
package org.eclipse.xtext.serializer.tokens;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.linking.impl.LinkingHelper;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parsetree.reconstr.impl.TokenUtil;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.xtext.RuleNames;
import org.eclipse.xtext.serializer.diagnostic.ITokenDiagnosticProvider;
import org.eclipse.xtext.xtext.RuleNames;
import com.google.inject.Inject;
@ -26,10 +28,13 @@ public class ValueSerializer implements IValueSerializer {
@Inject
private IValueConverterService converter;
@Inject
private RuleNames ruleNames;
@Inject
private LinkingHelper linkingHelper;
@Inject
protected ITokenDiagnosticProvider diagnostics;
@ -54,13 +59,18 @@ public class ValueSerializer implements IValueSerializer {
@Override
public String serializeAssignedValue(EObject context, RuleCall ruleCall, Object value, INode node, Acceptor errors) {
AbstractRule rule = ruleCall.getRule();
String ruleName = ruleNames.getQualifiedName(rule);
if (node != null) {
Object converted = converter.toValue(NodeModelUtils.getTokenText(node), ruleNames.getQualifiedName(ruleCall.getRule()), node);
if (converted != null && converted.equals(value))
return tokenUtil.serializeNode(node);
AbstractRule nodeRule = linkingHelper.getRuleFrom(node.getGrammarElement());
if (rule == nodeRule) {
Object converted = converter.toValue(NodeModelUtils.getTokenText(node), ruleName, node);
if (converted != null && converted.equals(value))
return tokenUtil.serializeNode(node);
}
}
try {
String str = converter.toString(value, ruleNames.getQualifiedName(ruleCall.getRule()));
String str = converter.toString(value, ruleName);
if (str != null)
return str;
if (errors != null)