VSマクロ(プロパティー一括生成)をVS2003対応

2008/02/19 (火) VS2005マクロ(プロパティー一括生成)
のマクロをVisualStudio2003、VisualStudio2005両対応に修正。

Continue文がないだけで非常に読みづらい気がする・・・

If文をネストすればもっと単純になるけれど、ネスト深いプログラムは嫌いだし。


気になる点

VS2003でVBのソースからマクロを生成した場合

    Private _bar As Integer = 0
    ''' <summary>
    ''' 
    ''' </summary>
    Public Property Bar() As Int32
    〜以下略〜

Integer型が「Int32」として生成される。C#はちゃんと「int」になるのに。

VS2003のバグかも。

     ' 選択範囲の変数からプロパティーを生成する(VB.NET、C#対応)
     ' 既に同名のプロパティーがあれば作成しない
     ' 
     ' プロパティー名の規則
     ' 1:変数は"_"(アンダースコア)から始まること
     ' 2:プロパティー名は変数の先頭1文字を削除し、次の文字を大文字に変換した名前とする
     '   (ex. 「_foo 」→「Foo」)
     ' VS2003,VS2005対応
     Sub MakeProperty()
         ' 現在の選択範囲
         Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
         Dim selTop As VirtualPoint = sel.TopPoint
         Dim selBottom As VirtualPoint = sel.BottomPoint
         ' もし下から上へ選択している場合は、選択範囲を交換する
         If selTop.Line = DTE.ActiveDocument.Selection.ActivePoint.Line Then
             sel.SwapAnchor()
         End If
 
         Dim actPoint As TextPoint = DTE.ActiveDocument.Selection.ActivePoint
         ' 現在キャレットがある場所のクラスを取得
         Dim elm As CodeElement = actPoint.CodeElement(vsCMElement.vsCMElementClass)
         Dim cls As CodeClass = elm
         Dim typ As CodeType = CType(elm, CodeType)
 
         'クラス内に既に存在するプロパティー一覧を作成する(重複作成しないためのチェック用)
         Dim lstProp As New System.Collections.Specialized.StringCollection
         For Each ite As CodeElement In typ.Members
             If TypeOf ite Is CodeProperty Then
                 lstProp.Add(ite.Name)
             End If
         Next
 
         ' 編集用オブジェクト
         Dim editPoint As EditPoint
         Dim sbProp As New System.Text.StringBuilder
 
         Dim blnContinue As Boolean = True
         Dim newLine As String = System.Environment.NewLine
         ' クラス内のメンバーに対して
         For Each ite As CodeElement In typ.Members
             blnContinue = True
             sbProp.Length = 0
 
             ' 変数であるかチェック
             If blnContinue AndAlso Not TypeOf ite Is CodeVariable Then
                 blnContinue = False
             End If
 
             ' 変数が選択範囲内かチェック
             Dim elmVal As CodeVariable = Nothing
             If blnContinue Then
                 elmVal = DirectCast(ite, CodeVariable)
                 Dim valLine As Integer = elmVal.StartPoint.Line
                 If Not (selTop.Line <= valLine AndAlso valLine <= selBottom.Line) Then
                     blnContinue = False
                 End If
             End If
 
             ' 変数名の先頭がアンダースコアであるかチェック
             If blnContinue AndAlso elmVal.Name.Substring(0, 1) <> "_" Then
                 blnContinue = False
             End If
 
             ' 同じ名前のプロパティーが存在している場合は作成しない
             If blnContinue AndAlso lstProp.Contains(GetPropNm(elmVal.Name)) Then
                 blnContinue = False
             End If
 
             ' プロパティー文字列を生成する
             If blnContinue Then
                 If DTE.ActiveDocument.Language = "Basic" Then
                     ' 編集中ファイルがVBの場合
                     sbProp.AppendFormat("''' <summary>").Append(newLine)
                     sbProp.AppendFormat("''' ").Append(newLine)
                     sbProp.AppendFormat("''' </summary>").Append(newLine)
                     sbProp.AppendFormat("Public Property {0}() As {1}", GetPropNm(elmVal.Name), elmVal.Type.AsString).Append(newLine)
                     sbProp.AppendFormat("    Get").Append(newLine)
                     sbProp.AppendFormat("        Return {0}", elmVal.Name).Append(newLine)
                     sbProp.AppendFormat("    End Get").Append(newLine)
                     sbProp.AppendFormat("    Set(ByVal value As {0})", elmVal.Type.AsString).Append(newLine)
                     sbProp.AppendFormat("        {0} = value", elmVal.Name).Append(newLine)
                     sbProp.AppendFormat("    End Set").Append(newLine)
                     sbProp.AppendFormat("End Property").Append(newLine)
                 ElseIf DTE.ActiveDocument.Language = "CSharp" Then
                     ' 編集中ファイルがC#の場合
                     sbProp.AppendFormat("/// <summary>").Append(newLine)
                     sbProp.AppendFormat("/// ").Append(newLine)
                     sbProp.AppendFormat("/// </summary>").Append(newLine)
                     sbProp.AppendFormat("public {0} {1}", elmVal.Type.AsString, GetPropNm(elmVal.Name)).Append(newLine)
                     sbProp.AppendFormat("{{").Append(newLine)
                     sbProp.AppendFormat("        get {{ return {0}; }}", elmVal.Name).Append(newLine)
                     sbProp.AppendFormat("        set {{ {0} = value; }}", elmVal.Name).Append(newLine)
                     sbProp.AppendFormat("}}").Append(newLine)
                 End If
 
                 ' 変数の次の行にプロパティーを追加する
                 editPoint = elmVal.EndPoint().CreateEditPoint()
                 editPoint.Insert(System.Environment.NewLine)
                 editPoint.Insert(sbProp.ToString)
             End If
 
         Next
         ' プロパティーのフォーマットを行う
         sel.LineDown(True, 12)
         sel.SmartFormat()
         sel.LineUp(False)
     End Sub
 
 
    ' 変数名からプロパティー名を生成して返す
     Private Function GetPropNm(ByVal varNm As String) As String
         Dim nm As String = varNm.Substring(1)
         Return nm.Substring(0, 1).ToUpper() & nm.Substring(1)
     End Function