StyleCop Analyzer Throws Exceptions

Oct 4, 2010 at 8:22 PM

I am currently running TFS2008 with an associated BuildServer. Environments currently stand at .NET 3.5 SP1. I have a solution I have created an MSBUILD file for that gets built on a nightly basis. I have installed the MSBUILD Extension pack onto the build server and imported the targets in my build file. I have the following setup in the build file to run StyleCop (installed StyleCop 4.4 on the build server with MSBuild integration):

 <Target Name="AfterCompile">

<CreateItem Include="$(SolutionRoot)\**\*.cs">
      <Output TaskParameter="Include" ItemName="StyleCopFiles"/>
    </CreateItem>

  <MSBuild.ExtensionPack.CodeQuality.StyleCop
      TaskAction="Scan"
      SourceFiles="@(StyleCopFiles)"
      ShowOutput="true"
      ForceFullAnalysis="true"
      CacheResults="false"
      logFile="$(DropLocation)\$(BuildNumber)\StyleCopLog.txt"
      SettingsFile="$(SolutionRoot)\Settings.StyleCop">
    <Output TaskParameter="Succeeded" PropertyName="AllPassed"/>
    <Output TaskParameter="ViolationCount" PropertyName="Violations"/>
    <Output TaskParameter="FailedFiles" ItemName="Failures"/>
  </MSBuild.ExtensionPack.CodeQuality.StyleCop>

  <Message Text="File: %(StyleCopFiles.Identity)"/>
  <Message Text="%(Failures.Identity) - Failed on Line %(Failures.LineNumber). %(Failures.CheckId): %(Failures.Message)"/>

</Target>



StyleCop will begin to analyze the files and find 4 Validation errors before it throws 2 exception and just stops. Here is the BuildLog.txt output for that portion:

Pass 1: Caching.cs...
  Pass 1: Email.cs...
  Exception thrown by analyzer 'Naming Rules' while processing 'C:\Documents and Settings\TFSService\Local Settings\Temp\Daily\Sources\Common\Email.cs'.
  Pass 1: ExceptionPolicy.cs...
  Pass 1: ExecutionContext.cs...
  Pass 1: Logger.cs...
  ..........
  Pass 1: DateUtility.cs...
  Pass 1: StringFormatter.cs...
  Pass 1: StringUtility.cs...
  Exception thrown by analyzer 'Spacing Rules' while processing 'C:\Documents and Settings\TFSService\Local Settings\Temp\Daily\Sources\Common\Utilities\StringUtility.cs'.
  4 violations encountered.
Done executing task "MSBuild.ExtensionPack.CodeQuality.StyleCop".

The contents of the files that caused the exception is nothing special. Here is the contents of Email.cs as an example:

using System;
using System.Configuration;
using System.Net.Mail;
using System.Text;

namespace Common
{
    /// <summary>
    /// A helper class to drive the creation of emails.
    /// </summary>
    public class Email
    {
        /// <summary>
        /// Send an email message.
        /// </summary>
        /// <param name="mailFrom">The mail address the email will appear from.</param>
        /// <param name="mailFromName">The name of the person who the email will appear to be from.</param>
        /// <param name="mailTo">The address of the person to send the email message to.</param>
        /// <param name="mailToName">Name of the mail to.</param>
        /// <param name="subject">The subject line of the email.</param>
        /// <param name="content">The body contents of the email message.</param>
        /// <returns>Returns true if successful</returns>
        public static bool Send(string mailFrom, string mailFromName, string mailTo, string mailToName, string subject, string content)
        {
            return Send(mailFrom, mailFromName, mailTo, mailToName, null, null, subject, content);
        }

        /// <summary>
        /// Send an email message.
        /// </summary>
        /// <param name="mailFrom">The mail address the email will appear from.</param>
        /// <param name="mailFromName">The name of the person who the email will appear to be from.</param>
        /// <param name="mailTo">The address of the person to send the email message to.</param>
        /// <param name="mailToName">Name of the mail to.</param>
        /// <param name="mailCC">The email to CC.</param>
        /// <param name="mailCCName">Name of the mail CC.</param>
        /// <param name="subject">The subject line of the email.</param>
        /// <param name="content">The body contents of the email message.</param>
        /// <returns>Returns true if successful</returns>
        public static bool Send(string mailFrom, string mailFromName, string mailTo, string mailToName, string mailCC, string mailCCName, string subject, string content)
        {
            // validation
            if (string.IsNullOrEmpty(mailFrom)
                || string.IsNullOrEmpty(mailTo)
                || string.IsNullOrEmpty(subject)
                || string.IsNullOrEmpty(content))
            {
                return false;
            }

            // create the mail item
            SmtpClient smtpClient = new SmtpClient();
            MailMessage mailMessage = new MailMessage();
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
            smtpClient.PickupDirectoryLocation = ConfigurationManager.AppSettings["smtp.delivery.directory"];

            if (mailFromName.Length <= 0)
            {
                mailFromName = mailFrom;
            }

            // setup from address
            MailAddress toAddress = new MailAddress(mailTo, mailToName);
            MailAddress fromAddress = new MailAddress(mailFrom, mailFromName);
            mailMessage.To.Add(toAddress);
            mailMessage.From = fromAddress;
            mailMessage.Sender = fromAddress;

            // setup any required carbon copy
            if (!string.IsNullOrEmpty(mailCC))
            {
                MailAddress ccAddress = new MailAddress(mailCC, mailCCName);
                mailMessage.CC.Add(ccAddress);
            }

            // setup mail body
            mailMessage.Priority = MailPriority.High;
            mailMessage.BodyEncoding = Encoding.UTF8;
            mailMessage.IsBodyHtml = false;
            mailMessage.Subject = subject;
            mailMessage.Body = content;

            // send mail item;
            smtpClient.EnableSsl = false;
            smtpClient.Send(mailMessage);

            // no errors
            return true;
        }
    }
}

The email.cs file runs validation fine, without exception, and validation count comes to 1 on my local system (I don't see any exceptions thrown in the output window in VS2008).

 Questions:

1. Why is the analyzer throwing these exceptions?

2. Why does the process stop after 2 exceptions?

Any help on these issues from anyone would be greatly appreciated.

Coordinator
Oct 5, 2010 at 8:17 AM

Firstly, thanks for posting such a clear issue and repro code! It's really appreciated.

The 'problem in your code' is this line

     MailAddress ccAddress = new MailAddress(mailCC, mailCCName);

In it's simplest form, this is a repro

namespace Common
{
    public class Email
    {
        public static bool Send()
        {
            var Ba;
        }
    }
}

If you use var a, it works fine. At first I thought it was this issue: http://msbuildextensionpack.codeplex.com/workitem/4314?ProjectName=msbuildextensionpack but it seems different.

I'm going to see if it repros in the latest preview release and raise to the stylecop team. Will get back to you when I have some results.

Mike

 

Coordinator
Oct 5, 2010 at 8:40 AM

Raised here: http://stylecop.codeplex.com/workitem/6754

Coordinator
Oct 5, 2010 at 10:32 AM

Fixed with http://msbuildextensionpack.codeplex.com/SourceControl/changeset/changes/55768

Mike

Oct 5, 2010 at 3:06 PM

Thanks so much for your help Mike. I pulled down and compiled the latest code and tested fully on the build server - everything is running now with no exceptions.

Now just need to find the time to fix 1207 StyleCop violations that were found :(

Dec 9, 2010 at 10:40 AM
Edited Dec 9, 2010 at 10:41 AM

Hi,

I have got exactly the same problem with Style Cop 4.4.0.14 and Extension Pack 4.0.

The source code that crashed the Style Cop is (four different files):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data.Linq.Mapping;

namespace dotEditor.Plugins.BannerManager.DataAccess.Core
{
    public static class ExtensionMethods
    {
        public static PropertyInfo GetPrimaryKey(this Type entityType)
        {
            foreach (PropertyInfo property in entityType.GetProperties())
            {
                if (property.IsPrimaryKey())
                {
                    if (property.PropertyType != typeof(int))
                    {
                        throw new ApplicationException(string.Format("Primary key, '{0}', of type '{1}' is not int", property.Name, entityType));
                    }
                    return property;
                }
            }
            throw new ApplicationException(string.Format("No primary key defined for type {0}", entityType.Name));
        }

        public static TAttribute GetAttributeOf<TAttribute>(this PropertyInfo propertyInfo)
        {
            object[] attributes = propertyInfo.GetCustomAttributes(typeof(TAttribute), true);
            if (attributes.Length == 0)
                return default(TAttribute);
            return (TAttribute)attributes[0];
        }

        public static bool IsPrimaryKey(this PropertyInfo propertyInfo)
        {
            var columnAttribute = propertyInfo.GetAttributeOf<ColumnAttribute>();
            if (columnAttribute == null) return false;
            return columnAttribute.IsPrimaryKey;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dotEditor.Plugins.BannerManager.DataAccess.Core
{
    public interface IDataContext
    {

    }
}

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;

/* auto generated by dotEditor */
public partial class header : UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        NewsRepeater.DataSource = News;
        NewsRepeater.DataBind();

        DataBind();
    }

    public int JobsAvailableToday
    {
        get
        {
            return 0;
        }
    }

    public IList<string> News
    {
        get
        {
            return new List<string> { "Meet Flying Fish at London Preview Day", "Flying Fish Ski in Chamonix", "Gap Year in Australia" };
        }
        
    }
}

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

/* auto generated by dotEditor */
public partial class de_9d837 : UserControl
{
    public String PhoneNumberAustralia
    {
        get
        {
            return "02 9969 8590";
        }
    }

    public String PhoneNumberUK
    {
        get
        {
            return "0871 250 2500";
        }
    }

    public String PhoneNumberWorld
    {
        get
        {
            return "+44 1983 280641";
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

The Wokr Item: http://stylecop.codeplex.com/workitem/6754 is still opened. Do you know when could we expect it to be fixed?

Thanks!

Coordinator
Dec 9, 2010 at 10:47 AM

are you building with the latest code in the extension pack? this was fixed here: http://msbuildextensionpack.codeplex.com/SourceControl/changeset/changes/55768

the fix will be in the december release, but you can build locally now.

 

Mike

Dec 9, 2010 at 10:54 AM
mikefourie wrote:

are you building with the latest code in the extension pack? this was fixed here: http://msbuildextensionpack.codeplex.com/SourceControl/changeset/changes/55768

the fix will be in the december release, but you can build locally now.

 

Mike

 No, I was not using the latest. I used the latest official release.

Thanks for the information!

Coordinator
Dec 9, 2010 at 10:59 AM

Sure, this will help: http://msbuildextensionpack.codeplex.com/wikipage?title=DevelopingLatest&referringTitle=Documentation

 

Dec 23, 2010 at 6:48 AM

I've just installed the latest december 2010 release (4.0.2.0). All works fine now.

Thanks very much!