Extend FxCop to check WebService Proxy.Url string

Hi Michael,

This thread is a continuation of a thread (id=327628) from the old forum. That thread was started by SunilMenon. Since I did not get any reply to my post on the old forum I am re-sending the same on this forum.

I have tried to create a custom rule for the above request. Can you please go through it and check if its fine.

public override ProblemCollection Check(Member PassedMember)
{
Method oMethod = PassedMember as Method;
InstanceInitializer oInstanceInitializer = PassedMember as InstanceInitializer;
if(oMethod == null)
return null;
if(oInstanceInitializer == null)
return null;

bool IsTrue= false;

bool Iswebservice = false;

InstructionList oInstructionList = oMethod.Instructions;
int instructioncount = oInstructionList.Length;

if(oMethod.NodeType == oInstanceInitializer.NodeType)
{
for(int counter=0; counter < instructioncount; counter++)
{
Instruction oInstruction = oMethod.Instructions[counter];

if (oInstruction == null)
return null;

if (oInstructionList == null)
return null;

Method callee = oInstruction.Value as Method;

if (callee != null)
if (callee.FullName == "System.Web.Services.Protocols.SoapHttpClientProtocol.#ctor")
{
Iswebservice = true;
}

if(oInstructionList[counter].OpCode == OpCode.Call && Iswebservice == true)
{
if (callee != null)
{
if(callee.FullName == "itb.Foundation.FunctionLibrary.GetiMedASURL(System.String,System.String)")
{
IsTrue = true;
}
}
}
}
if(IsTrue == false && Iswebservice == true)
Problems.Add(new Problem(GetResolution(PassedMember.Name.Name)));
}
return Problems;
}

[1800 byte] By [Rati] at [2008-2-27]
# 1
Here are some comments on your implementation

1) you don't need to cast PassedMember to both a Method and an InstanceInitializer instance. Just cast it to InstanceInitializer and return if the result is null. You can retrieve instructions off an InstanceInitializer instance (since it extends Method)
2) this code does not conform to the MS Design Guidelines. The casing of your parameter is wrong, for example (it should be camel- not pascal-cased) and you've renamed an overridden parameter name (it's declared on the base as 'member'). Don't forget to run FxCop on your custom rule code.
3) the checks for null oInstruction and oInstructionList are unnecessary. If oInstructionList were null, you would already have crashed since you dereference the instruction list directly off the method instance earlier. In any case, this value is never null
4) If you want to insure you're looking at an object creation, you should check the Instruction type and see whether it is a NewObj opcode.
5) This code will fail for multiple instances of a WebService created in a method (if there is only one call to GetiMedASURL). This might not be a likely scenario. This implementation has another limitation (which you're probably already aware of). It does not insure that calls occur in the correct order and that there is always a call that process the URL associated with web service creation. Resolving this would require writing a more complext rule, either as an AST rule or a flow analysis check (the latter is currently unsupported in FxCop).
6) Advanced rule implementations that flag call sites either acquire and retain a direct pointer to the methods in question or use the CCI Identifier class to perform fast comparisons. I mention this only foir completeness. String comparisons against type names are fine as a start. They are fragile, however, and not as performant as other options.

Michael

MichaelFanning-MS at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...

Visual Studio Team System

Site Classified