三.使用Roslyn分析代碼

三.使用Roslyn分析代碼

?上一節(jié)我們實現(xiàn)了一個右擊的上下文命令苦囱,并獲取了用戶選的的位置和內(nèi)容,這一節(jié)我們來看一下如何通過Roslyn來實現(xiàn)代碼分析脾猛。

3.1 分析SolidWroks在線Api的Url格式

通過分析Url我們可以判斷出我們要得到的信息撕彤,通過控制前綴(http://help.solidworks.com/2018/english/api/sldworksapi/)的內(nèi)容可以選擇版本和語言(并沒有選擇)。想要得到特點的接口猛拴,方法羹铅,屬性的Url我們需要組合后面的字符。根據(jù)后面的字符串愉昆,我們需要得到當(dāng)前選擇內(nèi)容的類型职员,是方法屬性還是一個接口,然后獲取到這個接口的命名空間跛溉。
痛苦的是我們無法簡單的根據(jù)一個選擇的字符來的到他的類型信息和命名空間焊切,幸運的是.Net 為我們提供Rosly工具來分析源代碼。

3.2 通過Roslyn解析語義信息

對于接口的話芳室,我們只需要獲取這個接口的命名空間即可专肪,但對于屬性和方法,我們還需要獲取這個屬性或方法所屬的接口或者類渤愁。為了獲取這些信息牵祟,首先我們需要對代碼進行語法分析深夯,從而得到選擇區(qū)域在語法樹上的節(jié)點抖格;
其次,拿到的節(jié)點信息Node咕晋,就要對建立代碼的編譯模型雹拄,從預(yù)編譯模型中獲取語義信息(ISymblo接口);有了語義信息掌呜,我們遍可以解析當(dāng)前節(jié)點的類型滓玖,命名空間等等。

1.語法分析
public ISymbol GetDocPostionSymobl(string ActiveDocPath,int StartPosition,int Length)
        {
            foreach (var project in DuSolidWorksToolsPackage.myVSWorkspace.CurrentSolution.Projects)
            {
                foreach (var doc in project.Documents)
                {
                    if (doc.FilePath == ActiveDocPath)
                    {

                        var Model = doc.GetSemanticModelAsync().GetAwaiter().GetResult();

                        if (Model == null)
                        {
                            return null;
                        }
                        var root = Model.SyntaxTree.GetRoot();

                        CSharpCompilation CsharpComp = Model.Compilation as CSharpCompilation;

                        var node = root.FindNode(new Microsoft.CodeAnalysis.Text.TextSpan(StartPosition, Length));
                        if (node != null)
                        {
                           var mySymbol = GetSymbolInfo(node, Model);
                            return mySymbol;
                        }
                        break;
                    }
                }
            }
            return null;
        }

通過Visual Studio WorkSpace 獲取Visual Stuio 解決方案的語義模型质蕉,再獲取當(dāng)前選擇的節(jié)點

2. 獲取語義信息
public ISymbol GetSymbolInfo(SyntaxNode node, SemanticModel Model)
        {
            var symbolInfo = Model.GetSymbolInfo(node);
            return symbolInfo.Symbol;
        }
3.通過構(gòu)造類來構(gòu)造SolidWorks Api Help的Url鏈接
uRLContructor = new Du.Core.SolidWorksURLContructor(symbolInfo.Symbol);
if (uRLContructor.Result == Du.Core.SolidWorksURLContructor.SolidWorksURLResult.Exist)
{
    SetApiBrowser(uRLContructor, symbolInfo.Symbol);
}

通過一個類來構(gòu)造Ur

    public class SolidWorksURLContructor
    {
        #region 靜態(tài)字段
        public static int NowVersion = 2018;

        public static string NowApiWelcomeUrl {
            get { 
                  return "http://help.solidworks.com/" + NowVersion.ToString() + "/english/api/sldworksapiprogguide/Welcome.htm";

            }
        }
            
            #endregion

        #region  私有字段
        private ISymbol mySymbol;

        #endregion

        #region 公共屬性

        public SolidWorksURLResult Result { get; set; }

        public SolidWorksURLSourse Sourse = SolidWorksURLSourse.Web;

        public string URL { get; set; }
        /// <summary>
        /// api歡迎頁面
        /// </summary>
        public string ApiWelcomeUrl
        {
            get
            {
                switch (Sourse)
                {
                    case SolidWorksURLSourse.Local:
                        break;
                    case SolidWorksURLSourse.Web:
                        return "http://help.solidworks.com/" + Version.ToString() + "/english/api/sldworksapiprogguide/Welcome.htm";
                }
                return "http://help.solidworks.com/" + Version.ToString() + "/english/api/sldworksapiprogguide/Welcome.htm";
            }
        }
        public int Version {
            get { return SolidWorksURLContructor.NowVersion; }
            set {
                SolidWorksURLContructor.NowVersion = value;
                URL = GetUrl();
            }
        }
        #endregion
        /// <summary>
        /// 定向URL
        /// </summary>
        private string SolidWorksApiInitUrl
        {
            get
            {
                return "http://help.solidworks.com/" + Version.ToString() + "/english/api/sldworksapi/";
            }
        }
        #region 構(gòu)造函數(shù)
        public SolidWorksURLContructor(Microsoft.CodeAnalysis.ISymbol symbol)
        {
            mySymbol = symbol;
            URL = GetUrl();
        }
        #endregion

        #region 私有方法

        private string GetUrl()
        {
            string Url = string.Empty;
            switch (mySymbol.Kind)
            {
                case SymbolKind.Alias:
                    break;
                case SymbolKind.ArrayType:
                    break;
                case SymbolKind.Assembly:
                    break;
                case SymbolKind.DynamicType:
                    break;
                case SymbolKind.ErrorType:
                    break;
                case SymbolKind.Event:
                    break;
                //字段
                case SymbolKind.Field:
                    break;
                case SymbolKind.Label:
                    break;
                case SymbolKind.Local:
                    break;
                //方法
                case SymbolKind.Method:
                    Url = PropertyOrMethodURLContructor(mySymbol.ContainingAssembly.Identity.Name,mySymbol.ContainingType.Name,mySymbol.OriginalDefinition.Name);
                    break;
                case SymbolKind.NetModule:
                    break;
                //類名
                case SymbolKind.NamedType:
                    Url = NameTypeURLContructor(mySymbol.ContainingAssembly.Identity.Name, mySymbol.Name);
 
                    break;
                //命名空間
                case SymbolKind.Namespace:
                    Url = NameSpaceURLCon(mySymbol.ContainingAssembly.Identity.Name);
                    break;
                case SymbolKind.Parameter:
                    break;
                case SymbolKind.PointerType:
                    break;
                //屬性
                case SymbolKind.Property:
                    Url = PropertyOrMethodURLContructor(mySymbol.ContainingAssembly.Identity.Name, mySymbol.ContainingType.Name, mySymbol.OriginalDefinition.Name);
                    break;
                case SymbolKind.RangeVariable:
                    break;
                case SymbolKind.TypeParameter:
                    break;
                case SymbolKind.Preprocessing:
                    break;
                case SymbolKind.Discard:
                    break;
            }
            if (string.IsNullOrEmpty(Url))
            {
                Result = SolidWorksURLResult.None;
            }
            else
            {
                Result = SolidWorksURLResult.Exist;
            }
            return Url;
        }

        private string NameSpaceURLCon(string name)
        {
            return "";
        }

        /// <summary>
        /// 屬性或者方法構(gòu)造器
        /// </summary>
        /// <param name="NameSpace"></param>
        /// <param name="originalDefinition"></param>
        /// <returns></returns>
        private string PropertyOrMethodURLContructor(string NameSpace,string TypeName,string originalDefinition)
        {
           
            //http://help.solidworks.com/2018/english/api/sldworksapi/SolidWorks.Interop.sldworks~SolidWorks.Interop.sldworks.IModelDoc2~CustomInfo2.html
            switch (Sourse)
            {
                case SolidWorksURLSourse.Local:
                    break;
                case SolidWorksURLSourse.Web:
                    return (SolidWorksApiInitUrl + NameSpace + "~"+NameSpace+"."+TypeName+"~"+ originalDefinition + ".html");
            }
            return "";
        }

        /// <summary>
        /// 類名的幫助URL構(gòu)造器
        /// </summary>
        /// <param name="NameSpace"></param>
        /// <param name="ClassName"></param>
        /// <returns></returns>
        private string NameTypeURLContructor(string NameSpace, string ClassName)
        {
            string FullName = string.Empty;
            if (ClassName.ToCharArray()[0] == 'I' )
            {
              FullName = NameSpace + ClassName + "_members.html";
            }
            else
            {
                FullName = NameSpace + ".I" + ClassName + "_members.html";
            }
            //string FullName = NameSpace + ".I" + ClassName + " members.html";
            //http://help.solidworks.com/2018/english/api/sldworksapi/SolidWorks.Interop.sldworks~SolidWorks.Interop.sldworks.IModelDoc2_members.html
            switch (Sourse)
            {
                case SolidWorksURLSourse.Local:
                    break;
                case SolidWorksURLSourse.Web:
                    return (SolidWorksApiInitUrl + NameSpace + "~" + FullName);
            }
            return "";
        }
        #endregion

        public enum SolidWorksURLResult
        {
            Exist,
            None
        }
        public enum SolidWorksURLSourse {
            Local,
            Web
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末势篡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子模暗,更是在濱河造成了極大的恐慌禁悠,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兑宇,死亡現(xiàn)場離奇詭異碍侦,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門瓷产,熙熙樓的掌柜王于貴愁眉苦臉地迎上來站玄,“玉大人,你說我怎么就攤上這事濒旦≈昕酰” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵疤估,是天一觀的道長灾常。 經(jīng)常有香客問我,道長铃拇,這世上最難降的妖魔是什么钞瀑? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮慷荔,結(jié)果婚禮上雕什,老公的妹妹穿的比我還像新娘。我一直安慰自己显晶,他們只是感情好贷岸,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著磷雇,像睡著了一般偿警。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上唯笙,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天螟蒸,我揣著相機與錄音,去河邊找鬼崩掘。 笑死七嫌,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的苞慢。 我是一名探鬼主播诵原,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挽放!你這毒婦竟也來了绍赛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤辑畦,失蹤者是張志新(化名)和其女友劉穎吗蚌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航闺,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡褪测,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年猴誊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侮措。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡懈叹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出分扎,到底是詐尸還是另有隱情澄成,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布畏吓,位于F島的核電站墨状,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏菲饼。R本人自食惡果不足惜肾砂,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宏悦。 院中可真熱鬧镐确,春花似錦、人聲如沸饼煞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砖瞧。三九已至息堂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間块促,已是汗流浹背荣堰。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留褂乍,地道東北人持隧。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓即硼,卻偏偏與公主長得像逃片,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子只酥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容