mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 08:48:55 +00:00
[serializer] never attempt to call ValueConverter with wrong rule
---Example--- Rule: name=FQN | name=STRING; ------------- When FQN has been parsed but the serializer decided to write out STRING it was calling the IValueConverter with FQN's INode and rule STRING. That's obviously wrong input for the ValueConverter. The fix just prevents the IValueConverter to be called in this scenario, causing the INode's text to be ignored; Instead fresh output is generated via IValueConverter.toString(...) Signed-off-by: Moritz Eysholdt <moritz.eysholdt@typefox.io>
This commit is contained in:
parent
29ddc6b881
commit
59b17ef430
2 changed files with 26 additions and 9 deletions
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue