CQLをいじる

とりあえず標準で用意されているクエリをいじっていく。

Source Code Quality constraints

実際のコード(テキスト)に対するチェック

Methods too big

このクエリはコードが30行を超えたものをリストアップするもの。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbLinesOfCode > 30 ORDER BY NbLinesOfCode DESC

でも実際に引っ掛かってくるのはデザイナが生成する「InitiailizeComponent」メソッドばかりなのであまり意味がない。

なので「InitializeComponent」メソッドを無視するように変更する。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbLinesOfCode > 30 AND !NameIs "InitializeComponent()" ORDER BY NbLinesOfCode DESC

Methods poorly commented

これはコードの量(ここでは10行以上)に対してコメントの少ないメソッドをリストアップするもの。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE PercentageComment < 20 AND NbLinesOfCode > 10  ORDER BY PercentageComment ASC

これにはIEnumerableを返すメソッドが自動的に生成するイテレータクラスのMoveNextメソッドまでが引っ掛かってしまうので、これを無視するようにしておく。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE PercentageComment < 20 AND NbLinesOfCode > 10 AND !NameIs "MoveNext()"  ORDER BY PercentageComment ASC

本当はCompilerGeneretedAttributeでマークされた型のメソッドは無視するとやりたいけど、SELECTがMETHODSに対して行われているので無理っぽい(このへん要望事項だな)。

Code Quality constraints

コードから実際に生成されるILに対するチェッック

Methods too big

ILが200行?を超えるものをリストアップする。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC

これも「InitializeComponent()」「MoveNext()」を無視するように変更する。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbILInstructions > 200 AND !NameIs "InitializeComponent()" AND !NameIs "MoveNext()" ORDER BY NbILInstructions DESC

Methods with too many local variables

ローカル変数が15個を超えるもの

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbVariables > 15 ORDER BY NbVariables DESC

「InitializeComponent」を(ry

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbVariables > 15 AND !NameIs "InitializeComponent()" ORDER BY NbVariables DESC

Design constraints

クラス設計について

Inheritance tree too deep

継承ツリーが10を超えるもの

WARN IF Count > 0 IN SELECT TYPES WHERE DepthOfInheritance >= 6 ORDER BY DepthOfInheritance DESC

Formから派生したクラスは、その時点で6を超えているので、Formから派生したクラスの場合のみ12にする。

WARN IF Count > 0 IN SELECT TYPES WHERE DepthOfInheritance >= 6 OR DeriveFrom "System.Windows.Forms.Form" AND DepthOfInheritance >= 12 ORDER BY DepthOfInheritance DESC

Potentially unused code

使われていない可能性のあるコード

Potentially unused methods

使われていないメソッド

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE 
 MethodCa == 0 AND
 !IsPublic AND
 !IsEntryPoint AND
 !IsExplicitInterfaceImpl AND
 !IsClassConstructor AND
 !IsFinalizer

余計なものが山程引っ掛かってくるので、

  • 「On〜」から始まるメソッド(基底クラスが呼び出す)
  • 「MoveNext()」(ry
  • 「Dispose」メソッド
  • 引数なしコンストラクタ、シリアル化コンストラク
  • イベントのアクセサ

を無視する。

WARN IF Count > 0 IN SELECT TOP 200 METHODS WHERE 
 MethodCa == 0 AND
 !IsPublic AND
 !IsEntryPoint AND
 !IsExplicitInterfaceImpl AND
 !IsClassConstructor AND
 !IsFinalizer AND
 !NameLike "^On" AND
 !NameIs "MoveNext()" AND
 !NameIs "Dispose(Boolean)" AND
 !NameIs ".ctor()" AND !NameIs ".ctor(SerializationInfo,StreamingContext)" AND
 !IsEventAdder AND !IsEventRemover

これはあてにならない。

Optimal Encapsulation

カプセル化しる!

以下のやつは山程引っ掛かってくるので上限を上げておく。

  • Methods that could be declared as 'internal' in C#, 'Friend' in VB.NET
  • Methods that could be declared as 'protected' in C#, 'Protected' in VB.NET
  • Methods that could be declared as 'private' in C#, 'Private' in VB.NET
  • Types that could be declared as internal

このへんは結構参考になる。

Naming constraints

命名規約

Misnamed methods

メソッド名が駄目

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE 
 !NameLike "^[A-Z]" AND 
 !(IsClassConstructor OR IsConstructor OR 
 IsPropertyGetter  OR IsPropertySetter OR
 IsIndexerGetter OR IsIndexerSetter OR
 IsEventAdder OR IsEventRemover OR
 IsOperator) AND !IsGeneratedByCompiler AND !IsInFrameworkAssembly

イベントハンドラ(button_Clickとか)が引っ掛かってくるので無視する。

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE 
 !NameLike "^[A-Z]" AND 
 !(IsClassConstructor OR IsConstructor OR 
 IsPropertyGetter  OR IsPropertySetter OR
 IsIndexerGetter OR IsIndexerSetter OR
 IsEventAdder OR IsEventRemover OR
 IsOperator) AND !IsGeneratedByCompiler AND !IsInFrameworkAssembly AND
 !(IsPrivate AND NameLike ".*_.*")

次回はこの結果を受けて、コードをどのように改善すればいいかを考えてみる。