Search code examples
c#structstylecop

Discover StructLayoutAttribute StyleCop


I am trying to write a StyleCop-rule which checks for maintainability conventions.

When targeting a Struct, I want to skip the Struct if it is declared with a StructLayoutAttribute.

As described in the following code, I target a Struct. If the Struct contains the StructLayoutAttribute, I want to return.

But how do I put the attribute inside the contain-method; because it is not included in the StyleCop API?

Edit: I have added new logic of what I have tried; with all the ways of trying down below, the fields inside a struct with the attribute still get flagged by StyleCop.

public void IsStructNameCorrect(Struct structItem)
{
    string attribText = "";

    if (structItem.Attributes.Count == 1)
        return;

    if(structItem.Attributes.Contains(/*StructLayoutAttributeHere*/)
        return;

    foreach (Attribute attrib in structItem.Attributes)
    {
        attribText = attribText + attrib.CodePartType;
    }

    if (attribText.Contains("Layout"))
        return;

    foreach (CsElement csElement in structItem.ChildElements)
    {
        if (csElement.ElementType == ElementType.Field)
        {
            Field field = (Field)csElement;
            if (!field.Readonly)
            {
                AddViolation(field, field.LineNumber, "FieldNotReadOnly", field.Name);
            }
        }

    }
}

Solution

  • I managed to get there myself; though kind of in a dirty way, but it does the job. If anyone does know how to actually target the attribute please do tell!

    What it did is I used a bool that sets to true if the struct-attributes contain the text "StructLayout".

    Then below I check if the attribute is false, and if it is I add violations if the field is not readonly.

    public void IsStructNameCorrect(Struct structItem)
    {
        string attribText = "";
        bool hasStructLayout = false;
    
        foreach (Attribute attrib in structItem.Attributes)
            attribText = attribText + attrib.Text;
    
        if (attribText.Contains("StructLayout"))
            hasStructLayout = true;
    
        if (!hasStructLayout)
        {
            foreach (CsElement csElement in structItem.ChildElements)
            {
                if (csElement.ElementType == ElementType.Field)
                {
                    Field field = (Field)csElement;
                    if (!field.Readonly)
                    {
                        AddViolation(field, field.LineNumber, "FieldNotReadOnly", field.Name);
                    }
                }
            }
        }
    }