| Summary: | Serialization fails for cross references | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | [Modeling] TMF | Reporter: | Marco <marco> | ||||||
| Component: | Xtext | Assignee: | Project Inbox <tmf.xtext-inbox> | ||||||
| Status: | CLOSED FIXED | QA Contact: | |||||||
| Severity: | major | ||||||||
| Priority: | P3 | CC: | moritz.eysholdt, sebastian.zarnekow, sven.efftinge | ||||||
| Version: | unspecified | Flags: | sebastian.zarnekow:
helios+
|
||||||
| Target Milestone: | RC1 | ||||||||
| Hardware: | PC | ||||||||
| OS: | All | ||||||||
| Whiteboard: | |||||||||
| Attachments: |
|
||||||||
|
Description
Marco
Could you provide the relevant parts of the stack trace? Did you perform any semantic modification on the parsed model? No programmatic changes of model, just loaded and/or edit in Xtext editor. java.lang.NullPointerException at org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter.getRuleName(AbstractLexerBasedConverter.java:90) at org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter.assertTokens(AbstractLexerBasedConverter.java:58) at org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter.toString(AbstractLexerBasedConverter.java:47) at org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService.toString(AbstractDeclarativeValueConverterService.java:51) at org.eclipse.xtext.parsetree.reconstr.impl.CrossReferenceSerializer.getConvertedValue(CrossReferenceSerializer.java:61) at org.eclipse.xtext.parsetree.reconstr.impl.CrossReferenceSerializer.serializeCrossRef(CrossReferenceSerializer.java:84) at org.eclipse.xtext.parsetree.reconstr.impl.AbstractParseTreeConstructor$AssignmentToken.serializeInternal(AbstractParseTreeConstructor.java:247) at org.eclipse.xtext.parsetree.reconstr.impl.AbstractParseTreeConstructor$AbstractToken.serialize(AbstractParseTreeConstructor.java:152) at org.eclipse.xtext.parsetree.reconstr.impl.AbstractParseTreeConstructor.write(AbstractParseTreeConstructor.java:737) at org.eclipse.xtext.parsetree.reconstr.impl.AbstractParseTreeConstructor.write(AbstractParseTreeConstructor.java:732) at org.eclipse.xtext.parsetree.reconstr.impl.AbstractParseTreeConstructor.write(AbstractParseTreeConstructor.java:732) at org.eclipse.xtext.parsetree.reconstr.impl.AbstractParseTreeConstructor.serializeSubtree(AbstractParseTreeConstructor.java:724) at org.eclipse.xtext.parsetree.reconstr.Serializer.serialize(Serializer.java:53) at org.eclipse.xtext.parsetree.reconstr.Serializer.serialize(Serializer.java:69) at org.eclipse.xtext.parsetree.reconstr.Serializer.serialize(Serializer.java:63) Thanks for stacktrace - however it is not as insightful as I hoped. Can you provide some more details, please? Which ruleName is passed into AbstractDeclarativeValueConverterService.toString(..)? What are the names of your terminal rules? Did you customize the IValueConverterService? Can you probably reproduce it in a minimal example? Btw: It's not the token that is null but the rule that your valueconverter has been configured with. Created attachment 168605 [details]
Prevent NPE in ValueConverter.getRuleName()
The patch changes the semantics of the default implementation of the value converter service. It will no longer register every value converter but only the ones that match actually available rules. A lexer based value converter without an actual rule throws an exception when it's instantiated.
I created converters for my IDs:
GENERALID : STRICTID | FLEXID ;
terminal STRICTID : '^'?(LETTER | '_') (LETTER | '_' | DIGIT)* ;
terminal FLEXID : ('[' (!(']'|'\n'|'\r'))* ']') ;
terminal DIGIT : ('0'..'9') ;
terminal LETTER : ('a'..'z' | 'A'..'Z') ;
public class StmlTerminalConverters extends DefaultTerminalConverters {
@ValueConverter(rule = "GENERALID")
public IValueConverter<String> GENERALID() {
return new AbstractNullSafeConverter<String>() {
@Override
protected String internalToValue(String string, AbstractNode node)
throws ValueConverterException {
if (string.startsWith("[") && string.endsWith("]"))
return FLEXID().toValue(string, node);
return ID().toValue(string, node);
}
@Override
protected String internalToString(String value) {
if (! value.matches("[a-zA-Z]\\w*"))
return FLEXID().toString(value);
return ID().toString(value);
}
};
}
@Inject
private AbstractIDValueConverter idValueConverter;
@ValueConverter(rule = "STRICTID")
public IValueConverter<String> STRICTID() {
return idValueConverter;
}
@ValueConverter(rule = "FLEXID")
public IValueConverter<String> FLEXID() {
return new AbstractNullSafeConverter<String>() {
@Override
protected String internalToValue(String string, AbstractNode node)
throws ValueConverterException {
return string.substring(1, string.length()-1);
}
@Override
protected String internalToString(String value) {
return "[" + value + "]";
}
};
}
}
Would prepare a small example based. What is the simplest way to implement something that triggers the Serializer then?
But probably you already find the problem in my converter.
/m
Hi Marco,
you may not used the injectable AbstractIDConverter for your StrictIDRule directly as it works for rules named "ID" only. Please try to use a subclass of the AbstractIdValueConverter and pass the right rule name to the superclass-constructor. Soemthing like new IDValueConverter(grammarAccess.getGrammar(), "STRICTID") {} should do the trick. The RC1 is likely to contain a public constructor in IDConverter or even a less error-prone solution.
Regards,
Sebastian
In http://git.softeys.de/tmf.xtext.git/commitdiff/0034f070abd9ec8183e9b0f9dca62ff650858412 I fixed a bug which caused the ValueConverter to be called for parser rules. Eventualy this is related? Created attachment 168689 [details]
IValueConverter, which are rule specific, should be instantiatable via guice
The patch introduces an extension interface IValueConverter.RuleSpecific to mark value converters which are specific to a lexer rule (they need the rule info to validate the value for toString(value)). The ValueConverterService reads the annotation @ValueConverter(ruleName) to identify actual converter instances. If the instance implements RuleSpecific, the service configures the converter with the right rule. This makes it easier for clients to use e.g. the IDValueConverter for a rule "SomeID".
(In reply to comment #8) > In > http://git.softeys.de/tmf.xtext.git/commitdiff/0034f070abd9ec8183e9b0f9dca62ff650858412 > I fixed a bug which caused the ValueConverter to be called for parser rules. > Eventualy this is related? Thanks for the pointer. The causer for this bug was another issue that I introduced with a recent change in M7. Fixed in HEAD. Closing bug which were set to RESOLVED before Eclipse Neon.0. |