codecadwallader / codemaid

CodeMaid is an open source Visual Studio extension to cleanup and simplify our C#, C++, F#, VB, PHP, PowerShell, JSON, XAML, XML, ASP, HTML, CSS, LESS, SCSS, JavaScript and TypeScript coding.
http://www.codemaid.net
GNU Lesser General Public License v3.0
1.92k stars 362 forks source link

`#endif` between method and its Attribute is getting deleted. #879

Open MineCake147E opened 2 years ago

MineCake147E commented 2 years ago

Environment

Description

I wrote this code:

namespace CodeMaidBugRepro
{
    public class Class1
    {
#if DEBUG
        [Obsolete]
#endif
        public uint A(uint b) => b;
    }
}

After running the code cleanup with CodeMaid, the #endif gets removed, making build impossible.

Steps to recreate

  1. Create a class library project.
  2. Write a method.
  3. Add [Obsolete] on top of the method. [DebuggerStepThrough] also gets affected.
  4. Surround the attribute with #if and #endif.
  5. Click on "Clean Up Active Documents" or turn on "Automatic Cleanup On Save" and save the document.

Current behavior

The #endif gets removed.

Expected behavior

The #endif should remain alive.

codecadwallader commented 2 years ago

Thanks for reporting the issue. I have been able to reproduce it. This looks to be fitting into a series of issues related to a breaking change in an underlying vsCMAccess API. When we try to set access modifiers using the same API from previous versions it is now causing breaking changes to the code.

As a workaround, if you disable CodeMaid->Options->Cleaning->Insert->Insert explicit access modifier fields on methods that should(tm) avoid the issue for now.

codecadwallader commented 2 years ago

I've confirmed this issue happens in both VS2019 and VS2022. I've sent an email to Microsoft to try and get some help digging down into the API.

codecadwallader commented 2 years ago

While looking in that area, there is also room for improvement in that CodeElementHelper doesn't recognize some syntax patterns (e.g. method arrow definitions) as well as GetTextToFirstMatch which was recently updated for VS2022 is not respecting the startPoint. These issues are separate from the underlying API issue, but in the example above they would prevent the API from being called if the access modifier was already present.

WeihanLi commented 2 years ago

Hi @codecadwallader , thanks for your working, any update on this?

codecadwallader commented 2 years ago

Hi @WeihanLi , the latest update is I'm waiting for feedback from Microsoft on this issue if you would like to look/comment over there: https://github.com/dotnet/roslyn/issues/58315

flamewave commented 2 years ago

I am also getting this issue, but it's removing the entire #if .... #endif block. For example:

[Attribute1]
#if CONDITION // This line to the endif are being removed on auto-format.
[Attribute2]
#endif
public string MyProperty { get; set; }

Using the Visual Studio "Format Document" feature does not remove the block, only when auto-formatting using CodeMaid.

jacobdeboer33 commented 2 years ago

Hi there

This problem also occurs in the following situation:

region Attributes

[Attribute1] [Attribute2]

endregion

public class Class1 { }

The #endregion element will be removed when doing a cleanup

codecadwallader commented 2 years ago

Thank you for providing the additional situation. It looks like it may be awhile before the SDK is resolved so I am considering disabling the explicit access modifier logic for everyone in the meantime to avoid these unexpected code corruptions.

FerdinandStapenhorst commented 1 year ago

When I have this C# code:

#if USE_NEW_REQUESTS
    [RequestTypeHandler]
#endif

after clean up it looks like this:

#if USE_NEW_REQUESTS
    [RequestTypeHandler]

The workaround As a workaround, if you disable CodeMaid->Options->Cleaning->Insert->Insert explicit access modifier fields on methods that should(tm) avoid the issue for now. does not work for me. Is there any other workaround I could use?

codecadwallader commented 1 year ago

Is the [RequestTypeHandler] decorating a method or another type of element? If for example that is on a property you would want to also disable inserting explicit access modifiers on properties.

FerdinandStapenhorst commented 1 year ago

It decorates a class:

#if USE_NEW_REQUESTS
    [RequestTypeHandler]
#endif
    public class DmViews
    {
        #region Statics
        private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger("_DmHttpServer.DmRequests.Views");
        ...

I disabled it for classes and now it works. Thanks!

AppFzx commented 1 year ago

It seems the bug deletes comments between attributes and definition as well. e.g. In this example, the comment gets deleted on cleanup:

[TestCase("valX")]
[TestCase("valY")]
// need testcase for valZ
public async task SomeTest(string val)
perahoky commented 7 months ago

Hello, we have the same bug/problem with codemaid in our productive environment.

codemaid cleanups document despite it contains pre processor#'s (and therefore disabled) and removes pre processor's in some places like described by others.