Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Move type to file" can bring along #endregion directive, resulting in non-compiling code #57077

Closed
drewnoakes opened this issue Oct 11, 2021 · 2 comments
Assignees
Labels
Area-IDE Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it Resolution-Duplicate The described behavior is tracked in another issue
Milestone

Comments

@drewnoakes
Copy link
Member

Version Used: Version 17.1.0 Preview 1.0 [31810.13.main]

Steps to Reproduce:

namespace ConsoleApp340;

class C
{
    #region Foo

    string S { get; }

    #endregion

    class I { }
}

Caret on class I, invoke lightbulb, select "Move type to C.I.cs".

Expected Behavior:

C.I.cs contains:

namespace ConsoleApp340;

partial class C
{
    class I { }
}

Actual Behavior:

C.I.cs contains the following non-compiling code:

namespace ConsoleApp340;

partial class C
{
    #endregion

    class I { }
}

The #endregion in the original file is also pulled into column 0 (leading white space removed).

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Oct 11, 2021
@jinujoseph jinujoseph added Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Oct 13, 2021
@jinujoseph jinujoseph added this to the Backlog milestone Oct 13, 2021
@yvef
Copy link

yvef commented Dec 26, 2021

Hi. I see that the problem is with trivia handling. Because the leading and the trailing trivia(s) have a different processing approach.
In fact, that poses a common problem. How to preserve the scope of preprocessor directives correctly. (Keep open and close directives and only refer to the target (movable) SyntaxNode). Just examples of the problem:

namespace N1
{
    public class A
    {

#if DEBUG // the leading trivia of "Value" property
        public string Value { get; set; }

        #region // the leading trivia of "B" class

        public class B { }

        #endregion // the leading trivia of "Value2" property
#endif // the same as "#endregion"

        public string Value2 { get; set; }
    }
}

Regarding to the comments it will introduce (file A.B.cs):

namespace N1
{
    public partial class A
    {
        #region // the trivia of "B" class

        public class B { }
    }
}

If we remove #region/endregion directives from the source file, the code without compile error will be generated as file A.B.cs

namespace N1
{
    public partial class A
    {
        public class B { }
    }
}

As expected - #if/#endif directives are missing, but this is the wrong compilation unit right now.

The next example:

namespace N1
{
    public class A
    {
#if DEBUG
        //public string Value { get; set; }
#endif
        public class B { }
    }
}

Introduce the A.B.cs file:

namespace N1
{
    public partial class A
    {
#if DEBUG
        //public string Value { get; set; }
#endif // redundant scope
        public class B { }
    }
}

So, I can suggest during the MoveType process, which is going in AbstractMoveTypeService.MoveTypeEditor ignore directives while member definitions subtracted from the target node. and only then resolve the directive that have correct scope and only related to the movable things.
For example:

namespace N1
{
    public class A
    {

#if DEBUG
        public string Value { get; set; }

        #region
#if Dir2
#endif
        public class B { }

        #endregion
#endif

        public string Value2 { get; set; }
    }
}

Step 1:

namespace N1
{
    public partial class A
    {

#if DEBUG
        #region
#if Dir2 // to remove
#endif // to remove
        public class B { }
        #endregion
#endif
    }
}
namespace N1
{
    public partial class A
    {

#if DEBUG
        #region
        public class B { }
        #endregion
#endif
    }
}

Any other ideas?

@sharwell
Copy link
Member

sharwell commented Jan 4, 2022

Duplicate of #19613

@sharwell sharwell marked this as a duplicate of #19613 Jan 4, 2022
@sharwell sharwell closed this as completed Jan 4, 2022
@sharwell sharwell added the Resolution-Duplicate The described behavior is tracked in another issue label Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it Resolution-Duplicate The described behavior is tracked in another issue
Projects
None yet
Development

No branches or pull requests

5 participants