qwertie / ecsharp

Home of LoycCore, the LES language of Loyc trees, the Enhanced C# parser, the LeMP macro preprocessor, and the LLLPG parser generator.
http://ecsharp.net
Other
172 stars 25 forks source link

Type.Namespace and FullName outputting incorrectly by LeMP #116

Closed dadhi closed 3 years ago

dadhi commented 3 years ago

I have this code inside quote {}

precompute(factories.Select((f, i) => quote {
    if (serviceType == typeof($(LNode.Id(typeof(A).FullName))))

and expecting

    if (serviceType == typeof(LibWithEcs.A)) {

but getting

   if (serviceType == typeof(Submission_num1_plusA)) {

Btw, if I output Namespace along I am getting @__empty__ instead.

The A is defined in compileAndRuntime earlier in the same file:

    namespace LibWithEcs
    {
        public class A {}

Here is the commit: https://github.com/dadhi/LempTest/commit/2956c1a114c9b63b247a7bd72efec3129dd968b3

So, for now, I am omitting the namespace in the output.

dadhi commented 3 years ago

Ok, seems like A namespace is just empty, so it is stripped for some reason.

qwertie commented 3 years ago

Consider this C# interactive session:

> class A { public class InnerA { } }
> typeof (A.InnerA).FullName
"Submission#21+A+InnerA"

When sanitized into a valid identifier, this is Submission_num21_plusA_plusInnerA. Since compileTime is based on the C# Interactive engine, this explains the result you're getting. Remember that namespaces are not supported by C# interactive and are stripped out by LeMP.

Even if namespaces were supported, LNode.Id(typeof(A).FullName) still wouldn't do what you want, because Namespace.A is not an identifier, it is an expression that calls the . operator. If you treat Namespace.A as an identifier, it will be sanitized into Namespace_periodA in the output. Instead, you would need to write a function to convert the string "Namespace.A" into an expression, as there currently isn't a standard function for doing that.

dadhi commented 3 years ago

Ok, thanks for the answer.