VS2005マクロ(プロパティー一括生成)
VS2005マクロ(プロパティー一括生成)を書いてみた。
Eclipseを使っていたときお世話になった機能「GetterおよびSetterの生成」がVisualStudio2005になかったっぽいので作ってみました。
マクロがVC++6の頃とは随分変わってしまい困りましたがなんとかできました。
以下の行を選択してマクロを実行すると
Private _foo As String = "" Private _bar As Integer = 0
以下のようにプロパティーが一括生成されます
Private _foo As String = "" ''' <summary> ''' ''' </summary> Public Property Foo() As String Get Return _foo End Get Set(ByVal value As String) _foo = value End Set End Property Private _bar As Integer = 0 ''' <summary> ''' ''' </summary> Public Property Bar() As Integer Get Return _bar End Get Set(ByVal value As Integer) _bar = value End Set End Property
参考にしたマクロ
- VisualStudio2005のサンプルマクロ(「DevStudio6Editor」がVC++6のマクロを移植したものなので参考になります。)
- VisualStudio2005のサンプルマクロ (Utilitiesの「InsertDocComments」)
C#とBasicに対応しています。(VisualStudio.NET2003は確認してません)
#Region "変数からプロパティーを生成" ' 選択範囲の変数からプロパティーを生成する(VB.NET、C#対応) ' 既に同名のプロパティーがあれば作成しない ' ' プロパティー名の規則 ' 1:変数は"_"(アンダースコア)から始まること ' 2:プロパティー名は変数の先頭1文字を削除し、次の文字を大文字に変換した名前とする ' (ex. 「_foo 」→「Foo」) 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.Generic.List(Of String) 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 Text.StringBuilder ' クラス内のメンバーに対して For Each ite As CodeElement In typ.Members sbProp.Length = 0 ' 変数であるかチェック If Not TypeOf ite Is CodeVariable Then Continue For End If ' 変数が選択範囲内かチェック Dim elmVal As CodeVariable = DirectCast(ite, CodeVariable) Dim valLine As Integer = elmVal.StartPoint.Line If Not (selTop.Line <= valLine AndAlso valLine <= selBottom.Line) Then Continue For End If ' 変数名の先頭がアンダースコアであるかチェック If elmVal.Name.Substring(0, 1) <> "_" Then Continue For End If ' 同じ名前のプロパティーが存在している場合は作成しない If lstProp.Contains(GetPropNm(elmVal.Name)) Then Continue For End If ' プロパティー文字列を生成する If DTE.ActiveDocument.Language = "Basic" Then ' 編集中ファイルがVBの場合 sbProp.AppendFormat("''' <summary>").AppendLine() sbProp.AppendFormat("''' ").AppendLine() sbProp.AppendFormat("''' </summary>").AppendLine() sbProp.AppendFormat("Public Property {0}() As {1}", GetPropNm(elmVal.Name), elmVal.Type.AsString).AppendLine() sbProp.AppendFormat(" Get").AppendLine() sbProp.AppendFormat(" Return {0}", elmVal.Name).AppendLine() sbProp.AppendFormat(" End Get").AppendLine() sbProp.AppendFormat(" Set(ByVal value As {0})", elmVal.Type.AsString).AppendLine() sbProp.AppendFormat(" {0} = value", elmVal.Name).AppendLine() sbProp.AppendFormat(" End Set").AppendLine() sbProp.AppendFormat("End Property").AppendLine() ElseIf DTE.ActiveDocument.Language = "CSharp" Then ' 編集中ファイルがC#の場合 sbProp.AppendFormat("/// <summary>").AppendLine() sbProp.AppendFormat("/// ").AppendLine() sbProp.AppendFormat("/// </summary>").AppendLine() sbProp.AppendFormat("public {0} {1}", elmVal.Type.AsString, GetPropNm(elmVal.Name)).AppendLine() sbProp.AppendFormat("{{").AppendLine() sbProp.AppendFormat(" get {{ return {0}; }}", elmVal.Name).AppendLine() sbProp.AppendFormat(" set {{ {0} = value; }}", elmVal.Name).AppendLine() sbProp.AppendFormat("}}").AppendLine() End If ' 変数の次の行にプロパティーを追加する editPoint = elmVal.GetEndPoint().CreateEditPoint() editPoint.Insert(System.Environment.NewLine) editPoint.Insert(sbProp.ToString) 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 #End Region