using System;
using System.Collections;
using AnticipatingMinds.Genesis.KnowledgeManagement;
using AnticipatingMinds.Genesis.CodeDOM;
using AnticipatingMinds.PlatformServices.Configuration;
using AnticipatingMinds.Genesis.CodeDOM.Utilities;
namespace AnticipatingMinds.KnowledgePack.Design{
public class MethodElementMetricsExceededRuleTemplate : RuleTemplate
{
public MethodElementMetricsExceededRuleTemplate(string templateId, IDictionary templateProperties):base(templateId,templateProperties)
{
}
public override string Name
{
get
{
return ResourceManager.GetLocalizedString("MethodElementMetricsExceededRuleTemplate|Name");
}
}
public override string Description
{
get
{
return ResourceManager.GetLocalizedString("MethodElementMetricsExceededRuleTemplate|Description");
}
}
public override Rule CreateRule(string ruleId, IDictionary ruleProperties)
{
return new MethodElementMetricsExceededRuleRule(ruleId, Id, ruleProperties);
}
public override AnticipatingMinds.CommonUIControls.PropertyPage[] GetRulePropertiesUI(IDictionary ruleProperties)
{
AnticipatingMinds.CommonUIControls.PropertyPage[] pages = new AnticipatingMinds.CommonUIControls.PropertyPage[1];
pages[0] = new MethodElementMetricsExceededPropertyPage(ruleProperties);
return pages;
}
}
public class MethodElementMetricsExceededRuleRule : Rule
{
const string CONFIG_UI_ROOT = @"SOFTWARE\Anticipating Minds\DevAdvantage\Appearance\Rules\MethodElementMetricsExceededRuleTemplate";
private RegistryConfiguration config = new RegistryConfiguration(CONFIG_UI_ROOT, RegistryConfiguration.RegistryTarget.LocalMachine);
private int GetValueMetricClass(string metricType)
{
MetricClasses metricClasses;
string RuleName = this.Name;
switch(metricType)
{
case "Statements":
metricClasses = new StatementsMetricClass(this.RuleMetricDefaultValue, RuleName);
break;
case "LocalVariables":
metricClasses = new LocalVariablesMetricClass(this.RuleMetricDefaultValue, RuleName);
break;
case "MethodArguments":
metricClasses = new MethodArgumentsMetricClass(this.RuleMetricDefaultValue, RuleName);
break;
case "ReturnPoints":
metricClasses = new ReturnPointsMetricClass(this.RuleMetricDefaultValue, RuleName);
break;
default:
metricClasses = new StatementsMetricClass(this.RuleMetricDefaultValue, RuleName);
break;
}
return metricClasses.Value;
}
internal MethodElementMetricsExceededRuleRule(string id, string templateId, IDictionary ruleProperties) : base(id,templateId,ruleProperties)
{
}
#region Rule Property
public new class PropertyName : Rule.PropertyName
{
public const string CurrentMetricsType = "CurrentMetricsType";
public const string MetricDefaultValue = "MetricDefaultValue";
}
public MetricDefaultValue RuleMetricDefaultValue
{
get
{
return GetProperty("MetricDefaultValue", new MetricDefaultValue()) as MetricDefaultValue;
}
set
{
SetProperty("MetricDefaultValue", value);
}
}
public string CurrentMetricsType
{
get{ return GetProperty(PropertyName.CurrentMetricsType, "Statements").ToString();}
set{ SetProperty(PropertyName.CurrentMetricsType, value);}
}
#endregion
private class RuleData
{
public RuleViolationCollection violations = new RuleViolationCollection();
public int Statements;
public int LocalVariables;
public int MethodArguments;
public int ReturnPoints;
}
public override Type[] TargetedCodeElements
{
get
{
return targetedCodeElements;
}
}
public override RuleViolation[] Analyze(object codeElement, System.Threading.ManualResetEvent cancelAnalysisEvent)
{
CodeTypeMemberDeclaration member = codeElement as CodeTypeMemberDeclaration;
if(member == null) return emptyViolationsList;
if(!IsCodeElementInRuleApplicabilityScope(CodeTypeMemberUtils.GetContainingTypeMember(member)))
return emptyViolationsList;
string memberName = MethodElementMetricsExceededRuleUtils.GetMemberName(member);
RuleData ruleData = new RuleData();
// procces analyze for current member
ruleData.MethodArguments = MemberArgumentsCount(member);
if(member is CodeTypeMethodDeclaration)
{
AnalizeMemberStatements(ruleData, (member as CodeTypeMethodDeclaration).Statements, memberName);
}
else if(member is CodeTypePropertyDeclaration)
{
AnalizeMemberStatements(ruleData, (member as CodeTypePropertyDeclaration).SetAccessorStatements, memberName);
AnalizeMemberStatements(ruleData, (member as CodeTypePropertyDeclaration).GetAccessorStatements, memberName);
}
else if(member is CodeTypeEventDeclaration)
{
AnalizeMemberStatements(ruleData, (member as CodeTypeEventDeclaration).RemoveAccessorStatements, memberName);
AnalizeMemberStatements(ruleData, (member as CodeTypeEventDeclaration).AddAccessorStatements, memberName);
}
else if(member is CodeTypeIndexerDeclaration)
{
AnalizeMemberStatements(ruleData, (member as CodeTypeIndexerDeclaration).SetAccessorStatements, memberName);
AnalizeMemberStatements(ruleData, (member as CodeTypeIndexerDeclaration).GetAccessorStatements, memberName);
}
if(ruleData.violations.Count != 0)
return ruleData.violations.ToArray();
else
return emptyViolationsList;
}
private void AnalizeMemberStatements(RuleData ruleData, CodeElement codeElement, string memberName)
{
if(codeElement == null) return;
// init rule Data for current member
ruleData.Statements = 0;
ruleData.ReturnPoints = 0;
ruleData.LocalVariables = 0;
CodeDomWalker.WalkCodeElement(codeElement ,new CodeDomWalker.WalkerCallback(AnalyzeMemberDeclarationForStatement), ruleData);
#region Create Violations
if(ruleData.Statements > GetValueMetricClass("Statements") && this.CurrentMetricsType == "Statements")
{
RuleViolation violation = new RuleViolation(this, codeElement);
violation.Description = ResourceManager.GetLocalizedString("MethodElementMetricsExceeded|Violation|Statements", memberName,ruleData.Statements.ToString() , GetValueMetricClass("Statements").ToString());
violation.Severity = RuleViolation.ViolationSeverity.Suggestion;
ruleData.violations.Add(violation);
}
if(ruleData.LocalVariables > GetValueMetricClass("LocalVariables") && this.CurrentMetricsType == "LocalVariables")
{
RuleViolation violation = new RuleViolation(this, codeElement);
violation.Description = ResourceManager.GetLocalizedString("MethodElementMetricsExceeded|Violation|LocalVariables", memberName,ruleData.LocalVariables.ToString() , GetValueMetricClass("LocalVariables").ToString());
violation.Severity = RuleViolation.ViolationSeverity.Suggestion;
ruleData.violations.Add(violation);
}
if(ruleData.MethodArguments > GetValueMetricClass("MethodArguments") && this.CurrentMetricsType == "MethodArguments")
{
RuleViolation violation = new RuleViolation(this, codeElement);
violation.Description = ResourceManager.GetLocalizedString("MethodElementMetricsExceeded|Violation|MethodArguments", memberName,ruleData.MethodArguments.ToString() , GetValueMetricClass("MethodArguments").ToString());
violation.Severity = RuleViolation.ViolationSeverity.Suggestion;
ruleData.violations.Add(violation);
}
if(ruleData.ReturnPoints > GetValueMetricClass("ReturnPoints") && this.CurrentMetricsType == "ReturnPoints")
{
RuleViolation violation = new RuleViolation(this, codeElement);
violation.Description = ResourceManager.GetLocalizedString("MethodElementMetricsExceeded|Violation|ReturnPoints", memberName,ruleData.ReturnPoints.ToString() , GetValueMetricClass("ReturnPoints").ToString());
violation.Severity = RuleViolation.ViolationSeverity.Suggestion;
ruleData.violations.Add(violation);
}
#endregion
}
private int MemberArgumentsCount(CodeTypeMemberDeclaration member)
{
int count = 0;
if(member is CodeTypeMethodDeclaration)
{
count = (member as CodeTypeMethodDeclaration).Parameters.Count;
}
else if(member is CodeTypeIndexerDeclaration)
{
count = (member as CodeTypeIndexerDeclaration).Parameters.Count + 1;
}
else if(member is CodeTypePropertyDeclaration)
{
count = 1;
}
else if(member is CodeTypeEventDeclaration)
{
count = 1;
}
return count;
}
public CodeDomWalker.WalkerCallbackReturn AnalyzeMemberDeclarationForStatement(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
{
if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
{
return CodeDomWalker.WalkerCallbackReturn.Next;
}
RuleData ruleData = applicationData as RuleData;
// update counter for statements
if(codeElement is CodeStatement && !(codeElement is CodeStatementBlock))
{
ruleData.Statements++;
}
// update counter for return points
if(codeElement is CodeReturnStatement )
{
ruleData.ReturnPoints++;
}
// update counter for local variables
if(codeElement is CodeVariableDeclarationStatement)
{
ruleData.LocalVariables++;
}
return CodeDomWalker.WalkerCallbackReturn.Next;
}
public override void Correct(RuleViolationCorrection[] requestedCorrections, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, System.Threading.ManualResetEvent cancelCorrectionEvent)
{
}
private static RuleViolation[] emptyViolationsList = new RuleViolation[0];
private Type[] targetedCodeElements = {typeof(CodeTypeMemberDeclaration)};
private static Type[] applicableApplicabilityScopeTypes = {typeof(MethodApplicabilityScope),typeof(PropertyApplicabilityScope),typeof(EventApplicabilityScope),typeof(TypeMemberApplicabilityScope),typeof(FileApplicabilityScope)};
public override Type[] ApplicableApplicabilityScopeTypes
{
get
{
return applicableApplicabilityScopeTypes;
}
}
}
}
|