ReSharper isn't sorting members

Answered

Hello,

I have the following File Layout:

<?xml version="1.0" encoding="utf-16"?>
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
  <TypePattern DisplayName="COM interfaces" Priority="100">
    <TypePattern.Match>
      <And>
        <Kind Is="Interface" />
        <Or>
          <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
          <HasAttribute Name="System.Runtime.InteropServices.ComImport" />
        </Or>
      </And>
    </TypePattern.Match>
  </TypePattern>
  <TypePattern DisplayName="P/Invoke structs" Priority="100">
    <TypePattern.Match>
      <And>
        <Or>
          <Kind Is="Struct" />
          <Kind Is="Class" />
        </Or>
        <HasAttribute Name="System.Runtime.InteropServices.StructLayoutAttribute" />
      </And>
    </TypePattern.Match>
  </TypePattern>
  <TypePattern DisplayName="P/Invoke classes (xxxNativeMethods)" Priority="100">
    <TypePattern.Match>
      <And>
        <Kind Is="Class" />
        <Name Is=".*NativeMethods" />
      </And>
    </TypePattern.Match>
  </TypePattern>
  <TypePattern DisplayName="DataMembers" Priority="100">
    <TypePattern.Match>
      <And>
        <Or>
          <Kind Is="Field" />
          <Kind Is="Property" />
        </Or>
        <HasAttribute Name="System.Runtime.Serialization.DataMemberAttribute " />
      </And>
    </TypePattern.Match>
  </TypePattern>
  <TypePattern DisplayName="NUnit Test Fixtures" Priority="100">
    <TypePattern.Match>
      <And>
        <Kind Is="Class" />
        <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
        <HasAttribute Name="NUnit.Framework.TestCaseFixtureAttribute" Inherited="True" />
      </And>
    </TypePattern.Match>
    <Entry DisplayName="Setup/Teardown Methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <Or>
            <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
            <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
            <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
            <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
          </Or>
        </And>
      </Entry.Match>
    </Entry>
    <Entry DisplayName="All other members" />
    <Entry DisplayName="Test Methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <HasAttribute Name="NUnit.Framework.TestAttribute" />
        </And>
      </Entry.Match>
    </Entry>
  </TypePattern>
  <TypePattern DisplayName="xUnit" Priority="100">
    <Entry DisplayName="Test Methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <Or>
            <HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
            <HasAttribute Name="Xunit.TheoryAttribute" Inherited="True" />
          </Or>
        </And>
      </Entry.Match>
    </Entry>
  </TypePattern>
  <TypePattern DisplayName="StyleCop Layout" RemoveRegions="All">
    <TypePattern.Match>
      <Or>
        <Kind Is="Class" />
        <Kind Is="Struct" />
        <Kind Is="Interface" />
      </Or>
    </TypePattern.Match>
    <Entry DisplayName="Constants">
      <Entry.Match>
        <Kind Is="Constant" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Static fields">
      <Entry.Match>
        <And>
          <Kind Is="Field" />
          <Static />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <Kind Order="Constant Field" />
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Readonly />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Fields">
      <Entry.Match>
        <Kind Is="Field" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Readonly />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Constructors and destructors" Priority="200">
      <Entry.Match>
        <Or>
          <Kind Is="Constructor" />
          <Kind Is="Destructor" />
        </Or>
      </Entry.Match>
      <Entry.SortBy>
        <Static />
        <Kind Order="Constructor Destructor" />
        <Access Order="Public Internal ProtectedInternal Protected Private" />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Delegates">
      <Entry.Match>
        <Kind Is="Delegate" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Public events">
      <Entry.Match>
        <And>
          <Kind Is="Event" />
          <Access Is="Public" />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Interface events">
      <Entry.Match>
        <And>
          <Kind Is="Event" />
          <ImplementsInterface />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <ImplementsInterface Immediate="True" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Other events">
      <Entry.Match>
        <Kind Is="Event" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Enums">
      <Entry.Match>
        <Kind Is="Enum" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Interfaces">
      <Entry.Match>
        <Kind Is="Interface" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Public properties">
      <Entry.Match>
        <And>
          <Kind Is="Property" />
          <Access Is="Public" />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Interface properties">
      <Entry.Match>
        <And>
          <Kind Is="Property" />
          <ImplementsInterface />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <ImplementsInterface Immediate="True" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Other properties">
      <Entry.Match>
        <Kind Is="Property" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Public indexers" Priority="1000">
      <Entry.Match>
        <And>
          <Kind Is="Indexer" />
          <Access Is="Public" />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Interface indexers" Priority="1000">
      <Entry.Match>
        <And>
          <Kind Is="Indexer" />
          <ImplementsInterface />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <ImplementsInterface Immediate="True" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Other indexers" Priority="1000">
      <Entry.Match>
        <Kind Is="Indexer" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Public methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <Access Is="Public" />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Interface methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <ImplementsInterface />
        </And>
      </Entry.Match>
      <Entry.SortBy>
        <ImplementsInterface Immediate="True" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Other methods">
      <Entry.Match>
        <Kind Is="Method" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Operators">
      <Entry.Match>
        <Kind Is="Operator" />
      </Entry.Match>
      <Entry.SortBy>
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Static />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Nested structs" Priority="600">
      <Entry.Match>
        <Kind Is="Struct" />
      </Entry.Match>
      <Entry.SortBy>
        <Static />
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="Nested classes" Priority="700">
      <Entry.Match>
        <Kind Is="Class" />
      </Entry.Match>
      <Entry.SortBy>
        <Static />
        <Access Order="Public Internal ProtectedInternal Protected Private" />
        <Name />
      </Entry.SortBy>
    </Entry>
    <Entry DisplayName="All other members" />
  </TypePattern>
</Patterns>

I'm trying to sort the class through Code Cleanup and it does nothing! however, when I remove the block below it seems to work!

  <TypePattern DisplayName="xUnit" Priority="100">
    <Entry DisplayName="Test Methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <Or>
            <HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
            <HasAttribute Name="Xunit.TheoryAttribute" Inherited="True" />
          </Or>
        </And>
      </Entry.Match>
    </Entry>
  </TypePattern>

It doesn't seems like the issue is related to xUnit, any entry that I will put instead of that will cause it to fail, even if it's empty one.

It seems like a bug to me but if not then why it happens?

6 comments
Comment actions Permalink
Official comment

Hello Eyal,

Since xUnit pattern does not have TypePattern.Match and has higher priority than StyleCop pattern it affects all classes instead of StyleCop one. That's why all files are not rearranged.

As you may see in NUnit pattern, there is the follow TypePattern.Match to match NUnit classes only and rearrange them. It won't affect other classes:

<TypePattern.Match>
<And>
<Kind Is="Class" />
<HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
<HasAttribute Name="NUnit.Framework.TestCaseFixtureAttribute" Inherited="True" />
</And>
</TypePattern.Match>

But since xUnit does not have attributes to mark test classes the same way can't be used for xUnit test files.

So, you may decrease the priority of xUnit pattern to Lowest, then Stylecop pattern will be applied for most of classes in a solution.  

Thanks! 

Comment actions Permalink

Yes, you're right! but if I will do what you're suggesting then what will happen is R# will sort xUnit methods and I really don't want that.. :(

 

I can probably create a rule that tells R# not to sort classes that their name ends with say "Tests", I don't like these kind of rules but I guess I don't really have a choice here.

 

0
Comment actions Permalink

@Eyal you could create a custom attribute(s) for your ordering purposes that don't do anything else other than let you target methods other than by name

0
Comment actions Permalink

@Chris, yeah, you're right! the issue with that is it's a bit weird to do it, what I would really love is a way for R# to pick into the class  and say something like "if one of the members look like whatever is specified then do nothing". I tried this like this but it didn't work.

<TypePattern DisplayName="xUnit" Priority="100">
    <TypePattern.Match>
      <And>
        <Kind Is="Class" />
        <HasMember>
          <And>
            <Kind Is="Method" />
            <Or>
              <HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
              <HasAttribute Name="Xunit.TheoryAttribute" Inherited="True" />
            </Or>
          </And>
        </HasMember>
      </And>
    </TypePattern.Match>
    <Entry DisplayName="Test Methods">
      <Entry.Match>
        <And>
          <Kind Is="Method" />
          <Or>
            <HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
            <HasAttribute Name="Xunit.TheoryAttribute" Inherited="True" />
          </Or>
        </And>
      </Entry.Match>
    </Entry>
  </TypePattern>

 Anyway, thanks for the suggestion!

0
Comment actions Permalink

i agree the specification is extremely difficult to work with and many times i attempted to do much customization i just give up at some point from the actual output never meeting my expected output

0
Comment actions Permalink

@Chris, yeah, that's because it's complicated and not intuitive, I suggested this long time ago but R# needs to get smarter about things and use conventions over configuration for some things or mixture of both where it's appropriate, it was really great if you can give R# a specimen of code and tell it to build the layout, formatting style and naming style and then do some micro adjustment for correction using the current options.

Not to mention that R# lack the ability to generate code to give you a glimpse of how your settings look like, I mean really, this kind of user feedback should really be there.

With each release of C# there are more and more features added and more options are added to R# that you don't even know where to start to configure it from scratch or what new options will get added to R# that will break the formatting of your code.

 

0

Please sign in to leave a comment.