📄 vsnetcollector.cs
字号:
/* ---------------------------------------------------------------------------------------------------
*
* PocketUML v0.01.0016
*
*
* Written by Jie Tang.
* Bug report : jiet@msn.com
*
*
* Copyright 2001 James <jiet@msn.com>
* All rights reserved.
*
* This source file(s) may be redistributed unmodified by any means
* PROVIDING they are not sold for profit without the authors expressed
* written consent, and providing that this notice and the authors name
* and all copyright notices remain intact.
*
* Any use of the software in source or binary forms, with or without
* modification, must include, in the user documentation ("About" box and
* printed documentation) and internal comments to the code, notices to
* the end user as follows:
*
* "Portions Copyright 2001 Tang Jie
*
* An email letting me know that you are using it would be nice as well.
* That's not much to ask considering the amount of work that went into
* this.
*
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED. USE IT AT YOUT OWN RISK. THE AUTHOR ACCEPTS NO
* LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
*
*/
//-----------------------------------------------------------------------------------------------------
// Update Information.
//-----------------------------------------------------------------------------------------------------
///
/// PocketUML Namespace
/// Parse UML Data from c# project source code...
///
/// PocketUML v0.1
/// Created by Jie Tang 04/10/2002.
///
using System;
using EnvDTE;
using System.Collections;
using System.Xml;
///
/// PocketUML Namespace
///
namespace PocketUML
{
///
/// Operate the data
///
namespace DataOperator
{
using PocketUML.Data;
/// <summary>
/// Get Code Data from project source code...
/// </summary>
public class VsNetCollector
{
public VsNetCollector()
{
//
// TODO: Add constructor logic here
//
codeData = new Data.CodeData();
IsWriteObjectInfo = false;
}
/// <summary>
/// Collect UML element datas from VS.NET solutions.
/// </summary>
public void Collect()
{
// First collect solutions
try
{
CollectSolutions();
}
catch ( Exception e )
{
this.appObject.StatusBar.Text = e.ToString();
System.Windows.Forms.MessageBox.Show( e.ToString() );
}
}
/// <summary>
/// Collect Solutions informations
/// </summary>
private void CollectSolutions()
{
EnvDTE.Solution sln = appObject.Solution;
SolutionData slnData = new SolutionData();
// Add solution data
codeData.AddSolution( slnData );
// Save Data
slnData.Name = sln.FullName;
slnData.Parent = codeData;
slnData.VSObjectReference = sln;
slnData.ElementType = enumElementType.elementTypeSolution;
CollectProjects( sln, slnData );
}
private void CollectProjects( EnvDTE.Solution sln, SolutionData slnData )
{
// Get all the projects and add then to the solution data
for( int i = 0 ; i < sln.Count; i ++ )
{
// First muse ensure the project is a C# based project
// check...
EnvDTE.Project prj = sln.Item(i+1);
if (prj.FullName.EndsWith(".csproj") == true)
{
ProjectData prjData = new ProjectData();
// Add Prject Data
slnData.AddMember( prjData );
// Save Data
prjData.Name = prj.Name;
prjData.Parent = slnData;
prjData.VSObjectReference = prj;
prjData.ElementType = enumElementType.elementTypeProject;
CollectProjectItem( prj, prjData );
}
}
}
private void CollectProjectItem( EnvDTE.Project prj, ProjectData prjData )
{
for( int i = 0 ; i < prj.ProjectItems.Count ; i ++ )
{
// First must ensure the ProjectItems is a C# source code
// otherwise break this circle
EnvDTE.ProjectItem prjItem = prj.ProjectItems.Item(i+1);
if (prjItem.Name.EndsWith(".cs") == true && prjItem.Name.IndexOf("Assembly") == -1)
{
ProjectItemData prjItemData = new ProjectItemData();
// Add ProjectItem Data
prjData.AddMember( prjItemData );
// Save data
prjItemData.Parent = prjData;
prjItemData.VSObjectReference = prjItem;
prjItemData.Name = prjItem.Name;
prjItemData.ElementType = enumElementType.elementTypeProjectItem;
CollectCodeModel( prjItem, prjItemData );
}
else if( prjItem.ProjectItems.Count > 0 )
CollectProjectSubItem( prjItem.ProjectItems, prjData );
}
}
private void CollectProjectSubItem( EnvDTE.ProjectItems prj, ProjectData prjData )
{
for( int i = 0 ; i < prj.Count ; i ++ )
{
// First must ensure the ProjectItems is a C# source code
// otherwise break this circle
EnvDTE.ProjectItem prjItem = prj.Item(i+1);
if (prjItem.Name.EndsWith(".cs") == true && prjItem.Name.IndexOf("Assembly") == -1)
{
ProjectItemData prjItemData = new ProjectItemData();
// Add ProjectItem Data
prjData.AddMember( prjItemData );
// Save data
prjItemData.Parent = prjData;
prjItemData.VSObjectReference = prjItem;
prjItemData.Name = prjItem.Name;
prjItemData.ElementType = enumElementType.elementTypeProjectItem;
CollectCodeModel( prjItem, prjItemData );
}
else if( prjItem.ProjectItems.Count > 0 )
CollectProjectSubItem( prjItem.ProjectItems, prjData );
}
}
private void CollectCodeModel( EnvDTE.ProjectItem prjItem, ProjectItemData prjItemData )
{
EnvDTE.FileCodeModel codeModel = prjItem.FileCodeModel;
CodeModelData codeModelData = new CodeModelData();
// Add Code Mode data
prjItemData.AddMember( codeModelData );
// Save Data
codeModelData.Parent = prjItemData;
codeModelData.LanguageName = codeModel.Language;
codeModelData.VSObjectReference = codeModel;
codeModelData.ElementType = enumElementType.elementTypeCodeModel;
CollectCodeElements( codeModel, codeModelData );
}
private void CollectCodeElements( EnvDTE.FileCodeModel codeModel, CodeModelData codeModelData )
{
EnvDTE.CodeElements codeElements = codeModel.CodeElements;
CodeElementsData codeElementsData = new CodeElementsData();
// Add Code Elements
codeModelData.AddMember( codeElementsData );
// Save Data
codeElementsData.Parent = codeModelData;
codeElementsData.VSObjectReference = codeElements;
codeElementsData.ElementType = enumElementType.elementTypeCodeElements;
CollectCodeElement( codeElements, codeElementsData );
}
private void CollectCodeElement( EnvDTE.CodeElements codeElements, CodeElementsData codeElementsData )
{
// Get All the code elements
for( int i = 0; i < codeElements.Count; i ++ )
{
EnvDTE.CodeElement codeElement = codeElements.Item(i+1);
CollectElementData( codeElement, codeElementsData );
}
}
/// <summary>
/// Common function used to collect data from EnvDTE.CodeElement
/// </summary>
/// <param name="codeElement">EnvDTE.CodeElement ref: MSDN Automation Object Model Chart</param>
/// <param name="elementData">PocketUML.Data.ElementData</param>
private void CollectElementData( EnvDTE.CodeElement codeElement, ElementData parentElementData )
{
// Start parse the element data......
// Now Support:
// Namespace
// Class
// Delegate
// Interface
// Enum
// Struct
// Parameter
// Variabel
// Property
// Function
// I think it's might enouth for draw a UML graphics.
// But if future needed, i'll rewrite this code to a spearate function
// to collect one of those kind elements information.
if( codeElement.Kind == vsCMElement.vsCMElementOther )
{
///
/// Unknow Type
///
// Initialization a new element data object
ElementData elementData = new ElementData();
elementData.Parent = parentElementData;
elementData.VSObjectReference = codeElement;
// Save this object
parentElementData.AddMember( elementData );
elementData.ElementType = enumElementType.elementTypeUnknow;
elementData.Name = codeElement.Name;
}
else if( codeElement.Kind == vsCMElement.vsCMElementNamespace )
{
///
/// Namespace Type
///
// Initialization a new element data object
NameSpaceData namespaceData = new NameSpaceData();
namespaceData.Parent = parentElementData;
namespaceData.VSObjectReference = codeElement;
// Save this object
parentElementData.AddMember( namespaceData );
EnvDTE.CodeNamespace codeNameSpace = (EnvDTE.CodeNamespace) codeElement;
namespaceData.ElementType = enumElementType.elementTypeNameSpace;
namespaceData.Name = codeNameSpace.Name;
namespaceData.DocComment = codeNameSpace.DocComment;
// Check if it has elements
if( codeNameSpace.Members.Count > 0 )
{
for( int i = 0 ; i < codeNameSpace.Members.Count ; i ++ )
{
CollectElementData( codeNameSpace.Members.Item( i+1 ), namespaceData );
}
}
}
else if( codeElement.Kind == vsCMElement.vsCMElementClass )
{
///
/// Class Type
///
// If code element isn't code type, it's cann't be parsed ...
if( codeElement.IsCodeType == false ) return;
EnvDTE.CodeClass codeClass = (EnvDTE.CodeClass) codeElement;
//////// Might be Error here .... ////////
///Because I have used a enum conversion
ClassData classData = new ClassData();
classData.Parent = parentElementData;
classData.VSObjectReference= codeClass;
// Save this object
parentElementData.AddMember( classData );
classData.AccessType = (Data.enumElementAccessType)(int) codeClass.Access;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -