roslyn: Code generation involving some literals does not work correctly
For instance, I want to generate something like:
class A
{
public A() : this(2.0d)
{
}
public A(double value)
{
}
}
What we do with value
is really beside the point. The point is the double
literal d
is dropped from the Literal
specification. As is the f
if I wanted to specify a float
literal.
There are double
and float
versions of Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Literal
, right? i.e.
public static SyntaxToken Literal(float value);
public static SyntaxToken Literal(double value);
By contrast, the long
version of the same does respect the literal specification, i.e. 2L
,
public static SyntaxToken Literal(long value);
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 58 (34 by maintainers)
Note: i don’t know what the antlr bit was about. It seems like a non-sequitor here. As do the comments about nodes/tokens/etc. As this is a code generation problem, and the code generation is working as expected, with appropriate mechanisms for all code-gen authors to get the behavior they want, it seems like this was not an API problem but stemmed from a misunderstanding from the user on how these APIs worked.
It might be worthwhile to improve the docs here in the future if there is more confusion.
@mwpowellhtx It sounds like the
D
suffix is omitted for doubles. This suffix is optional whenever there is a decimal point in the literal text. Can you confirm that the text you get forLiteral(0.0d)
is0.0
, which is one of several allowed forms for this token?Note: i wrote this up in about 20 seconds 😃
As you want, it produces the value with the
D
:Why? It’s just an added dll…
In that case, you will have to use the appropriate overloads where you specify the text you want.
They are doing the right thing.
Literal(float)
should already be addingF
(likeLiteral(long)
addsL
), andLiteral(double)
should not be adding anything (just likeLiteral(int)
).It looks like it generated exactly the right thing.
0
is the representation for the double-value 0 to .net.As i mentioned above, the two expected ways to handle this are to either explicitly provide the string in the format you want (since there are tons of ways it could be formatted). Or to use SyntaxGenerator, which attempts to be less strict and makes these sorts of decisions on your behalf.
You’re using the raw API which doesn’t interpret (which i mentioned yesterday). When you use the raw API, you get almost no special handling on your behalf. It gives you a huge amount of control, but you’re taking a lot of the effort into your own hands. If you want that effort reduced, you can use the existing APIs that attempt to do that (however, you may lose some control you want at some points).
However, SyntaxFactory is not going to become SyntaxGenerator. Its purpose is to be the low-level raw api that everyone else can build on top of.
The behavior looks correct to me. There are two things you can do here. The first, as mentioned above, is to call the appropriate overload of Literal that allows you to specify exactly what you want for the text.
The second is to use SyntaxGenerator which is the nicer user-facing (i.e. “less-raw”) approach to syntax generation. It will always place a ‘D’ after a double for example.
The generated code isn’t useful to me here 😃 I need to see waht you’re actually doing to generate it 😄 We can take this to gitter if you want.
However, based on what you’ve said, you can address this the appropriate way by calling
Literal(value.ToString("R", CultureInfo.InvariantCulture) + "D", value)