icsharpcode / ILSpy

.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
21.45k stars 3.35k forks source link

Angle brackets in decompiled code lead to errors #1438

Closed adrium closed 5 years ago

adrium commented 5 years ago

I am using the decompiler to convert code from C# 7.0 to C# 2. Everything went fine except the following:

Given the code:

namespace Test
{
    public class AutoPropertyHolder
    {
        public string Property { get; set; }
    }
}

The decompiler generates the backing field as <Property>k__BackingField which I think is the name actually generated by the compiler. Anyway, the resulting code can not be compiled as is. The resulting errors are:

AutoProp.dec.cs(15,18): error CS1519: Invalid token '<' in class, struct, or interface member declaration
AutoProp.dec.cs(15,27): error CS1519: Invalid token '>' in class, struct, or interface member declaration
AutoProp.dec.cs(15,43): error CS1519: Invalid token ';' in class, struct, or interface member declaration
AutoProp.dec.cs(22,12): error CS1525: Invalid expression term '<'
AutoProp.dec.cs(26,5): error CS1525: Invalid expression term '<'

I think it would be useful if the angle brackets are replaced by underscores, if the assembly is decompiled to C#.

Is there already a solution to this? I looked through the setting classes, but did not find anything to solve the issue.

siegfriedpammer commented 5 years ago

Currently we do not have an option to replace invalid identifiers in output. Are you using ILSpy or a custom tool based on the decompiler engine for this task?

adrium commented 5 years ago

I implemented a replacement function in #1440.

To convert, I wrote a quick and dirty tool which takes an assembly and a target language version and decompiles it to one string.

So to convert, I compile and decompile with a different language version.

dgrunwald commented 5 years ago

I thought we already had logic that escaped invalid identifiers? It's intentionally not enabled in the ILSpy UI (there's no need for escaping there; so we only handle non-printable characters); but the whole project decompiler uses it. See class EscapeInvalidIdentifiers.

adrium commented 5 years ago

Oh I did not see that class, thanks for the hint.

Sure, for the UI it is not needed. Closing the issue and pull request.