面向c#的函數(shù)調(diào)用路徑生成方法
【專利摘要】本發(fā)明提供一種面向C#的函數(shù)調(diào)用路徑生成方法,包括:通過C#程序中與函數(shù)相關(guān)的信息,所述信息包括:類、命名空間、數(shù)據(jù)集信息、參數(shù)信息;根據(jù)每一函數(shù)的調(diào)用關(guān)系,分別生成每一函數(shù)的函數(shù)調(diào)用關(guān)系樹,其中所述函數(shù)調(diào)用關(guān)系樹的每一節(jié)點(diǎn)代表一個(gè)函數(shù),且每一節(jié)點(diǎn)的子節(jié)點(diǎn)代表一個(gè)分支,且每一節(jié)點(diǎn)的兄弟節(jié)點(diǎn)與其父節(jié)點(diǎn)為并列關(guān)系;根據(jù)所有函數(shù)的函數(shù)調(diào)用關(guān)系樹,組合為C#程序的全局的函數(shù)調(diào)用關(guān)系樹本發(fā)明提供一種面向C#的函數(shù)調(diào)用路徑生成方法,包括:通過C#程序中與函數(shù)相關(guān)的信息,所述信息包括:類、命名空間、數(shù)據(jù)集信息、參數(shù)信息;根據(jù)每一函數(shù)的調(diào)用關(guān)系,分別生成每一函數(shù)的函數(shù)調(diào)用關(guān)系樹,其中所述函數(shù)調(diào)用關(guān)系樹的每一節(jié)點(diǎn)代表一個(gè)函數(shù),且每一節(jié)點(diǎn)的子節(jié)點(diǎn)代表一個(gè)分支,且每一節(jié)點(diǎn)的兄弟節(jié)點(diǎn)與其父節(jié)點(diǎn)為并列關(guān)系;根據(jù)所有函數(shù)的函數(shù)調(diào)用關(guān)系樹,組合為C#程序的全局的函數(shù)調(diào)用關(guān)系樹。
【專利說明】
面向c#的函數(shù)調(diào)用路徑生成方法
技術(shù)領(lǐng)域
[0001] 本發(fā)明設(shè)及計(jì)算機(jī)技術(shù)領(lǐng)域,尤其設(shè)及一種面向C#的函數(shù)調(diào)用路徑生成方法。
【背景技術(shù)】
[0002] C#作為一種面向?qū)ο蟮母呒?jí)語言,由于其搭載環(huán)境Visual studio功能強(qiáng)大、可視 性強(qiáng)、更新較快,而逐漸成為軟件開發(fā)中的常用語言。隨著微軟對(duì)Visual Studio的版本更 新,其功能越來越強(qiáng)大,C#作為搭載在改壞境下的高級(jí)程序設(shè)計(jì)語言,集成C++和化va的優(yōu) 點(diǎn),逐漸成為開發(fā)過程中一種重要語言,C#作為面向?qū)ο笳Z言,具有封裝、繼承和多態(tài)等性 質(zhì),相較于化va語言,二者在語法上也各有特點(diǎn)。由于VS的功能強(qiáng)大,程序編寫過程中已經(jīng) 規(guī)避了大多數(shù)的語法錯(cuò)誤,但邏輯上的錯(cuò)誤,需要程序在運(yùn)行才能找到。函數(shù)調(diào)用路徑的測(cè) 試方法將函數(shù)調(diào)用和程序的邏輯結(jié)構(gòu)相結(jié)合,將代碼的分析粒度擴(kuò)展到函數(shù),既避免了路 徑的大規(guī)模增長又保證了軟件測(cè)試充分性[1]。對(duì)打吾言進(jìn)行函數(shù)調(diào)用路徑的測(cè)試需要通過 對(duì)源代碼進(jìn)行詞法語法分析獲得靜態(tài)函數(shù)調(diào)用路徑。Java語言的函數(shù)調(diào)用路徑測(cè)試是在基 于Soot的基礎(chǔ)上,獲取靜態(tài)函數(shù)調(diào)用路徑。對(duì)于C#程序,前者的過程顯然過于復(fù)雜、繁瑣,而 后者在C#程序顯然不適用。
[000;3]微軟在 Visual Studio2010 中開始引入 DGML(Directed Graph Markup Language),并且在該語言的基礎(chǔ)上自動(dòng)生成依賴關(guān)系圖等有向圖。DGML即有向圖標(biāo)記語 言,是一種完全符合XML格式的語言。隨后微軟在VS2012版本中引入了代碼圖功能,代碼圖 可W清晰地顯示代碼結(jié)構(gòu)。代碼圖是一種DGML表示的圖,在其DGML文件中詳細(xì)記錄了程序 中的命名空間、類和成員之間的依賴關(guān)系信息,雖然代碼圖本身能夠分析C#程序并生成函 數(shù)的依賴關(guān)系,但是運(yùn)種依賴關(guān)系是包含關(guān)系并沒有邏輯結(jié)構(gòu),不能直觀的得到程序的執(zhí) 行過程從而無法用于生成測(cè)試用例。目前國內(nèi)外針對(duì)C#程序的測(cè)試方法較少,對(duì)代碼圖和 DGML的研究也相對(duì)較少。
[0004] 由于C#語言包含類、對(duì)象、命名空間、重載、委托等多變而又復(fù)雜的形態(tài),給C#程序 的理解和測(cè)試帶來了很大困難。
【發(fā)明內(nèi)容】
[0005] 針對(duì)現(xiàn)有技術(shù)中存在的對(duì)C#語言多變且復(fù)雜導(dǎo)致對(duì)C#程序的理解和測(cè)試帶來了 很大困難的問題,本發(fā)明要解決的技術(shù)問題是提供一種面向C#的函數(shù)調(diào)用路徑生成方法。
[0006] 為了解決上述問題,本發(fā)明實(shí)施例提出了一種面向C#的函數(shù)調(diào)用路徑生成方法, 包括:
[0007] 步驟1、通過C#程序中與函數(shù)相關(guān)的信息,所述信息包括:類、命名空間、數(shù)據(jù)集信 息、參數(shù)信息;
[000引步驟2、根據(jù)每一函數(shù)的調(diào)用關(guān)系,分別生成每一函數(shù)的函數(shù)調(diào)用關(guān)系樹,其中所 述函數(shù)調(diào)用關(guān)系樹的每一節(jié)點(diǎn)代表一個(gè)函數(shù),且每一節(jié)點(diǎn)的子節(jié)點(diǎn)代表一個(gè)分支,且每一 節(jié)點(diǎn)的兄弟節(jié)點(diǎn)與其父節(jié)點(diǎn)為并列關(guān)系;
[0009] 步驟3、根據(jù)所有函數(shù)的函數(shù)調(diào)用關(guān)系樹,組合為C#程序的全局的函數(shù)調(diào)用關(guān)系 樹。
[0010] 其中,所述步驟1具體包括:從DGML文件中獲取程序所有的類;從DGML文件中獲取 類的所有函數(shù);將類自動(dòng)生成構(gòu)造函數(shù)。
[0011] 其中,所述步驟2中具體包括:
[0012] 步驟21、對(duì)每個(gè)成員函數(shù)進(jìn)行分析,獲取成員函數(shù)的執(zhí)行語句;
[0013] 步驟22、對(duì)執(zhí)行語句進(jìn)行分析W確定判斷每條語句是否有函數(shù)調(diào)用,W確定該執(zhí) 行語句是否存在分支結(jié)構(gòu);如果存在分支結(jié)構(gòu),獲取分支結(jié)構(gòu)的方法體,然后對(duì)方法體里的 每條語句進(jìn)行分析判斷是否還存在函數(shù)調(diào)用,如果是則將被調(diào)用函數(shù)的信息加入到函數(shù)調(diào) 用關(guān)系樹中。
[0014] 其中,所述步驟22具體包括:
[0015] 步驟221、判斷執(zhí)行語句中是否有函數(shù)調(diào)用,如果有則將函數(shù)調(diào)用順序、調(diào)用的函 數(shù)添加到列表中;
[0016] 步驟222、判斷執(zhí)行語句中是否有控制關(guān)鍵字,如果有則確定其中的第一個(gè)被調(diào)用 函數(shù)W獲取函數(shù)調(diào)用的順序,并根據(jù)函數(shù)調(diào)用的順序依次將函數(shù)添加到列表中;
[0017] 步驟23、生成每一函數(shù)的S元組T(M,R,S);其中,M表示函數(shù)集合;R表示函數(shù)的調(diào) 用順序關(guān)系<順序節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn),分支節(jié)點(diǎn)〉表示順序結(jié)構(gòu)為樹的左孩子,分支結(jié)構(gòu)為樹的 右孩子;S表示源函數(shù)也是函數(shù)調(diào)用關(guān)系樹的頭節(jié)點(diǎn);
[0018] 步驟24、根據(jù)所述每一函數(shù)的=元組生成每一函數(shù)的函數(shù)調(diào)用關(guān)系樹。
[0019] 本發(fā)明的上述技術(shù)方案的有益效果如下:上述方案中提出了一種面向C#的函數(shù)調(diào) 用路徑生成方法,其結(jié)合VS下的代碼圖功能得到函數(shù)及函數(shù)的依賴關(guān)系信息對(duì)源代碼進(jìn)行 分析,采用樹結(jié)構(gòu)存儲(chǔ)函數(shù)的依賴關(guān)系和邏輯結(jié)構(gòu),W此獲取每一個(gè)函數(shù)的函數(shù)調(diào)用關(guān)系 樹;然后將程序中所有的函數(shù)調(diào)用關(guān)系樹進(jìn)行組合W得到全局的函數(shù)調(diào)用關(guān)系樹。同時(shí)通 過本發(fā)明實(shí)施例中的舉例說明可W看出,本發(fā)明實(shí)施例的方法是可行的,能夠得到C#程序 的函數(shù)調(diào)用路徑,有助于開發(fā)人員對(duì)軟件系統(tǒng)的理解W及測(cè)試人員進(jìn)行基于函數(shù)調(diào)用路徑 的測(cè)試。
【附圖說明】
[0020] 圖1為本發(fā)明實(shí)施例中的DGML的描述圖;
[0021] 圖2為本發(fā)明實(shí)施例中的一個(gè)舉例說明的函數(shù)調(diào)用關(guān)系圖;
[0022] 圖3為本發(fā)明實(shí)施例中的另一個(gè)舉例說明的函數(shù)調(diào)用關(guān)系圖;
[0023] 圖4為根據(jù)圖3所示的函數(shù)調(diào)用關(guān)系生成的函數(shù)調(diào)用關(guān)系樹。
【具體實(shí)施方式】
[0024] 為使本發(fā)明要解決的技術(shù)問題、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合附圖及具 體實(shí)施例進(jìn)行詳細(xì)描述。
[0025] 軟件系統(tǒng)被修改或擴(kuò)充后,為了驗(yàn)證對(duì)軟件的修改是否達(dá)到預(yù)期的目的,并且沒 有引入新的錯(cuò)誤而重復(fù)進(jìn)行的測(cè)試稱為回歸測(cè)試。在實(shí)際測(cè)試的回歸測(cè)試中,由于測(cè)試人 員不了解程序的內(nèi)部結(jié)構(gòu),所用的測(cè)試方法就是全部重測(cè),但是在大中型軟件系統(tǒng)中的路 徑數(shù)目急劇增大,全部重測(cè)往往會(huì)帶來高昂的代價(jià)。因此研究人員提出了面向函數(shù)調(diào)用路 徑的思想獲取函數(shù)的調(diào)用路徑,可W快速獲取與該函數(shù)相關(guān)的路徑,從而進(jìn)行有針對(duì)性的 測(cè)試,有利于生成測(cè)試用例。具體請(qǐng)參考:ZHANG Zhihua,MU Yongmin.Based on the path to override the generated function calls Research[J].ACTA ELECTRONICA SINICA, 2010,138(8):1808-1811。
[00%] RegressiontestCl.O作為自主開發(fā)的基于函數(shù)調(diào)用路徑的測(cè)試工具,通過該工具 可W獲取C語言的全局靜態(tài)路徑集和動(dòng)態(tài)函數(shù)調(diào)用路徑;具體請(qǐng)參考張志華,牟永敏.基于 函數(shù)調(diào)用的路徑覆蓋生成技術(shù)研究[J].電子學(xué)報(bào),2010,38(8): 1808-1811。該方法具體為:
[0027] 首先對(duì)被測(cè)的源代碼進(jìn)行靜態(tài)分析,生成包含代碼內(nèi)部控制邏輯的函數(shù)調(diào)用關(guān)系 圖,從而獲取靜態(tài)的函數(shù)調(diào)用路徑;具體請(qǐng)參考:Yuhui Z肥NG,Yongmin Mu, Zhihua ZHANG..Rearch on the Static Function Call Path Generating Automcatically[C] .The 2nd IEEE International Conference on Information Management and Engineering. Chengdu, 2010.1~5;
[0028] 對(duì)被測(cè)程序進(jìn)行插裝,確定一組測(cè)試用例,在程序的執(zhí)行中獲取動(dòng)態(tài)的函數(shù)調(diào)用 序列;具體請(qǐng)參考:牟永敏,姜智巧,張志華.面向C程序插裝的路徑提取[J].計(jì)算機(jī)工程與 應(yīng)用.2011(01)。
[0029] 對(duì)于面向?qū)ο笳Z言由于其語法特點(diǎn),使用面向過程的函數(shù)調(diào)用路徑的生成方法: 開發(fā)詞法分析器、語法分析器等來靜態(tài)分析程序源碼,獲取函數(shù)的函數(shù)調(diào)用路徑,明顯會(huì)增 大工作量。因此在生成化va的函數(shù)調(diào)用路徑時(shí),研究人員提出了基于Soot來生成化va的函 數(shù)調(diào)用路徑,具體請(qǐng)參考:朱緒利,牟永敏,張志華.基于Soot控制流圖的函數(shù)調(diào)用路徑分析 [J].數(shù)據(jù)通信,2012年第一期。在該方法中,通過Soot編譯化框架將化va信息生成JimpleS 地址文件,從而確定多態(tài)調(diào)用點(diǎn)信息,按照多態(tài)唯一性靜態(tài)分析算法,確定多態(tài)唯一性信 息,提取函數(shù)間關(guān)聯(lián)信息,定義函數(shù)調(diào)用樹,并分析單個(gè)函數(shù)調(diào)用關(guān)系樹與程序函數(shù)調(diào)用圖 之間的關(guān)系,通過組合算法生成程序的函數(shù)調(diào)用關(guān)系圖。
[0030] 雖然研究人員先后提取了C、C++Java版本的函數(shù)調(diào)用路徑,但方法不能通用,且 因 C#語言多變而又復(fù)雜,之前沒有進(jìn)行相關(guān)研究。
[0031] 發(fā)明人通過研究發(fā)現(xiàn),Visual studio(簡稱VS)生成的代碼圖的DGML文件詳細(xì)記 錄了函數(shù)之間的依賴關(guān)系,運(yùn)為生成C#的函數(shù)調(diào)用路徑提供了幫助。使用Visual Studio可 W生成代碼內(nèi)部的關(guān)系圖即代碼圖,直觀顯示源代碼中的復(fù)雜關(guān)系。其中,得到的代碼圖就 在代碼編輯器的右側(cè),運(yùn)樣就能在編碼的時(shí)候看到代碼的結(jié)構(gòu)。該關(guān)系圖是用DGML語言描 述的,DGML的描述圖如圖1所示。
[00創(chuàng)在DGML描述語言中,主要描述程序內(nèi)部信息的標(biāo)簽是Node、Links和 IdentifierAliases:
[0033] 其中IdentifierAliases主要是對(duì)函數(shù)和類W別名標(biāo)記,運(yùn)里的別名對(duì)應(yīng)阿拉伯 數(shù)字;除此之外還記錄了程序的命名空間和數(shù)據(jù)集W及函數(shù)的參數(shù)信息,即使是重名的函 數(shù)也可W區(qū)分。函數(shù)參數(shù)信息一般在Id屬性中WOverloadin評(píng)arameters備注。
[0034] 區(qū)別于Identif ierAliases ,Node標(biāo)簽記錄的信息函數(shù)和類的信息,例如:類 (CodeSchema_class)、方法(CodeSchema_Method)、構(gòu)造函數(shù)(IsConstructor=" true")、接 口(〔0(165。1161]1日_1]116處日。6)、委托(〔0(165。1161]1日_〇616邑日16)、名稱化日661)、函數(shù)類型 (I sPub I i C)等。Node標(biāo)簽會(huì)自動(dòng)生成類中沒有聲明的構(gòu)造成員方法。
[0035] Links標(biāo)簽記錄函數(shù)之間的關(guān)系信息,包括:類與成員函數(shù)的包含(Contains)、調(diào) 用(CodeSchema_CalIs)、繼承(InheritsFrom)、接口 的實(shí)現(xiàn)(Implements) W及委托等。 Source和化rget,表示代碼圖中箭頭的起點(diǎn)和終點(diǎn),也記錄了函數(shù)中調(diào)用與被調(diào)用,類與函 數(shù)包含和被包含的關(guān)系,W及繼承中的父類與子類被繼承與繼承的關(guān)系,接口中的繼承與 實(shí)現(xiàn)的關(guān)系。
[0036] VS生成的代碼圖只有包含關(guān)系,沒有邏輯結(jié)構(gòu),對(duì)于W下代碼:
[0037;
[0038] 可W生成如圖2所示的函數(shù)調(diào)用關(guān)系圖。
[0039] 針對(duì)現(xiàn)有技術(shù)中缺少本發(fā)明實(shí)施例提出了一種面向C#的函數(shù)調(diào)用路徑生成方法, 具體包括:
[0040] 步驟1、W樹結(jié)構(gòu)記錄函數(shù)的調(diào)用關(guān)系。
[0041] 在C#程序中,可W樹形結(jié)構(gòu)來標(biāo)識(shí)函數(shù)的調(diào)用關(guān)系,稱為函數(shù)調(diào)用關(guān)系樹。在函數(shù) 調(diào)用關(guān)系樹中的每一個(gè)節(jié)點(diǎn)代表一個(gè)函數(shù),其孩子代表一個(gè)分支;如果函數(shù)沒有分支,則孩 子代表接下來要執(zhí)行的函數(shù)名;節(jié)點(diǎn)的兄弟標(biāo)識(shí)與父節(jié)點(diǎn)是并列關(guān)系,在程序中用來表示 多條分支。
[0042] 在C#程序中,與函數(shù)相關(guān)的信息包括:類、命名空間、數(shù)據(jù)集信息、參數(shù)信息;而運(yùn) 些信息都存儲(chǔ)在代碼圖的DGML文件中。DGML文件W別名作為索引記錄函數(shù),運(yùn)里也可W使 用別名來作為C#函數(shù)調(diào)用關(guān)系樹的節(jié)點(diǎn),減少了存儲(chǔ)大量的函數(shù)信息,可W提高算法的運(yùn) 行效率。
[0043] 在圖3所示的函數(shù)調(diào)用路徑,可W表示為圖4所示的函數(shù)調(diào)用關(guān)系樹。@6對(duì)應(yīng)函數(shù) Test,@7對(duì)應(yīng)函數(shù)f0,@8對(duì)應(yīng)函數(shù)n,@9對(duì)應(yīng)函數(shù)f2。使用=元組T(M,R,S)來表示調(diào)用關(guān)系: M表示函數(shù)集合;R表示函數(shù)的調(diào)用順序關(guān)系<順序節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn),分支節(jié)點(diǎn)〉表示順序結(jié)構(gòu) 為樹的左孩子,分支結(jié)構(gòu)為樹的右孩子;S表示源函數(shù)也是函數(shù)調(diào)用關(guān)系樹的頭節(jié)點(diǎn)。那么 對(duì)于圖3相對(duì)應(yīng)的代碼:
[0044] M={@6,@7,@8,@9};
[0045] R={(@8,@6,null),(@7,@8,@9),(@7,@9,null)},
[0046] S= {@6};
[0047] 該函數(shù)調(diào)用關(guān)系序列所對(duì)應(yīng)的全局函數(shù)調(diào)用關(guān)系樹如圖4所示。說明程序中有兩 條路徑:
[0048] 化thl:@6-〉@8-〉@7
[0049] 化th2:@6-〉@9-〉@7;
[0050] 如前所述的,@9是@8的右孩子也就是兄弟節(jié)點(diǎn);體現(xiàn)的是并列關(guān)系。生成的函數(shù)調(diào) 用關(guān)系樹即表現(xiàn)了運(yùn)種結(jié)構(gòu)特征。從S元組中也可W看出@6順序執(zhí)行了 @8,但是@8和@9是 并列關(guān)系,那么@6和@9也可W是一種順序結(jié)構(gòu)。而上面程序中的if-else語句正是運(yùn)種關(guān) 系。
[0051 ] 而針對(duì)W下的代碼:
[0化2]
[00£
[0054] 對(duì)于一個(gè)帶有繼承關(guān)系的程序來說在,父類為Contact ;Friend和Family為繼承了 Con化Ct類的子類;main函數(shù)中變量con巧日con2分別調(diào)用了子類的方法;化iend和Fami Iy分 別對(duì)父類方法進(jìn)行了重寫。但是con4調(diào)用了 Family的構(gòu)造函數(shù),卻調(diào)用了父類的方法。在代 碼圖的DGML文件中詳細(xì)記錄了運(yùn)種函數(shù)調(diào)用信息,包括@4繼承了( Inhe;ritsF;rom)@3, Family繼承了Contact類,@5繼承了@3,F(xiàn);riend類繼承了Contact類。由此可W看出,如果調(diào) 用了父類的方法,DGML會(huì)記錄(Target)調(diào)用了父類的方法,但如果子類對(duì)父類進(jìn)行了重寫 后,調(diào)用了運(yùn)個(gè)重寫方法,DGML會(huì)記錄(Tar ge t)調(diào)用的是子類方法。對(duì)于接口,DGML的記錄 方法類似。
[0化日]它的函數(shù)調(diào)用關(guān)系樹W=元組來表示:
[0化6] 1={@8,@10,@11,@12,@13,@14,@15};其中的@10,@11,@12是〔#程序的代碼圖自動(dòng) 為Con化Ct類、Family類、化iend類生成的構(gòu)造函數(shù)。
[0057] R={(@1〇,@8,null),(@12,@10,null),,null,null),(@13,@ 11,null),(@14,@11,null),(@15,@14,null),(@13,@15,null)},
[0化引 S= {(@8)};
[0059] 運(yùn)里使用<1?37,乂曰1116〉字典的數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)函數(shù)調(diào)用關(guān)系樹,key中存儲(chǔ)源函 數(shù),value存儲(chǔ)調(diào)用關(guān)系。對(duì)于上面源碼中的Main函數(shù),key中存儲(chǔ)函數(shù)簽名:<@8〉; value中 存儲(chǔ)調(diào)用關(guān)系,即被調(diào)函數(shù)集合List<Method〉。函數(shù)的調(diào)用關(guān)系W-個(gè)Struct結(jié)構(gòu)存儲(chǔ), Struct中WS個(gè)變量來記錄函數(shù)調(diào)用關(guān)系^hildID,ID JrotherID〉。當(dāng)前節(jié)點(diǎn)ID,節(jié)點(diǎn)的 左孩子化i IdID用來表示順序調(diào)用,節(jié)點(diǎn)的右孩子即兄弟節(jié)點(diǎn)化other ID用來表示分支結(jié) 構(gòu)。
[0060] 函數(shù)調(diào)用關(guān)系樹的生成算法如下:
[0061;
[0063]
[0064] 2、生成全局函數(shù)調(diào)用關(guān)系樹
[0065] 獲取程序的入口點(diǎn),從入口點(diǎn)的函數(shù)調(diào)用關(guān)系樹開始,將每一個(gè)函數(shù)的函數(shù)調(diào)用 關(guān)系樹加入到全局的函數(shù)調(diào)用關(guān)系樹中。加入的運(yùn)棵函數(shù)調(diào)用關(guān)系樹的葉子節(jié)點(diǎn)的左孩子 指向被代替的那個(gè)函數(shù)的左孩子節(jié)點(diǎn)。
[0066] 全局函數(shù)調(diào)用關(guān)系樹的生成算法如下:
[0067]
[006引
[0069] 在此基礎(chǔ)上生成全局的函數(shù)調(diào)用路徑只需要將函數(shù)調(diào)用關(guān)系樹中的兄弟節(jié)點(diǎn)使 用同一父節(jié)點(diǎn)。根據(jù)別名編號(hào)從程序的DGML文件中提取函數(shù)的相關(guān)信息(讀取XML文件的過 程)生成帶有函數(shù)具體信息的函數(shù)調(diào)用路徑。
[0070] 舉例說明:
[0071] W下面的源碼為例,按照上面的算法進(jìn)行分析,得到此程序的函數(shù)調(diào)用路徑。如下 所示源碼是一個(gè)用于加減乘除的運(yùn)算,Computor類是一個(gè)計(jì)算器,內(nèi)部定義了加(Add)減 (Minus)乘(Multiply)除(Divide)方法,W及警告(Warning)方法,當(dāng)除數(shù)為0時(shí),執(zhí)行警告。 主函數(shù)在Program類中,程序的命名空間為Exp,對(duì)運(yùn)個(gè)程序進(jìn)行分析:
[0072]
[007<
[0075] 利用本發(fā)明實(shí)施例的方法來對(duì)源代碼和DGML文件進(jìn)行處理,則根據(jù)各個(gè)類的各個(gè) 函數(shù)獲取函數(shù)調(diào)用關(guān)系樹。W下為Main函數(shù)的分析結(jié)果:
[0076] @7
[0077] <@8,@7,null〉
[007引 <@14,@8,null>
[0079] <il6,il4,null>
[0080] <@9,@16,null>
[0081 ] <@17,@9,null>
[0082] <null,il7,il0>
[0083] <null,ilO,null>
[0084] 從上面可WMain函數(shù)(即@7)分別調(diào)用了 @8、@14、@16、@9、@17、@10,其所對(duì)應(yīng)的函 數(shù)分別是ComputoH )(代碼圖自動(dòng)為Computor類生成的構(gòu)造函數(shù))、NumA、NumB、Add()、 胖曰^1叫〇、山乂1(16()。根據(jù)本發(fā)明實(shí)施例中的左孩子為順序結(jié)構(gòu)、右孩子為分支結(jié)構(gòu)的原 貝1J,可W確定@17和@10是兄弟節(jié)點(diǎn);運(yùn)一點(diǎn)與程序的邏輯結(jié)構(gòu)相同。
[0085] 進(jìn)一步的,分析Computor類的Add方法得到函數(shù)調(diào)用關(guān)系樹:
[0086] @9
[0087] <014,@9,null)
[008引 <@16,@14,null〉
[0089] 根據(jù)^上現(xiàn)實(shí)的可知,Add函數(shù)(gp@9)調(diào)用了@14和@16,分別是屬性NumA和NumB, 且它們之間是順序結(jié)構(gòu);這與程序的內(nèi)部信息相同。程序中六(1(1、]?;[11113、]?11;^1口17、(1;[¥1(16的 調(diào)用結(jié)構(gòu)類似,獲取的函數(shù)調(diào)用關(guān)系樹類似。
[0090] 將局部的函數(shù)調(diào)用關(guān)系樹組合成全局的函數(shù)調(diào)用關(guān)系樹,獲取到的函數(shù)調(diào)用路徑 如下:
[0091] Pathl
[0092] @7:E邱.Program.CodeSchema_Method<Main(System.StringArray Rank二1)〉
[0093] @8: E邱? Computor ? CodeSchema_Method<Computor 0〉
[0094] @14: E邱? Computor ? (^社目客誠目巧過-口的口目別式曲欄八〉
[00 巧]@16: E邱? Computor ? CodeSchema_Propei'ty<NumB〉
[0096] @9:E邱?Computor?CodeSchema_Method<Add()〉
[0097] @14: E邱? Computor ? (^社目客誠目巧過-口的口目別式曲欄八〉
[0098] @16: E邱? Computor ? CodeSchema_Propei'ty<NumB〉
[0099] @17:E邱?Computor?CodeSchema_Method<Warning()〉
[0100] Path2
[0101] @7:Exp. Program.CodeSchema_Method〈Main(System.StringArray 民ank二I)〉
[0102] @8: E邱? Computor ? CodeSchema_Method<Computor 0〉
[0103] @14: E邱? Computor ? (^社目客誠目巧過-口的口目別式曲欄八〉
[0104] @16: E邱? Computor ? CodeSchema_Propei'ty<NumB〉
[010日]@9:E邱?Computor?CodeSchema_Method<Add()〉
[0106] @14: E邱? Computor ? (^社目客誠目巧過-口的口目別式曲欄八〉
[0107] @16: E邱? Computor ? CodeSchema_Propei'ty<NumB〉
[0108] @10:E邱?Computor?CodeSchema_Method<divide 0〉
[0109] @14: E邱? Computor ? (^社目客誠目巧過-口的口目別式曲欄八〉
[0110] @16: E邱? Computor ? CodeSchema_Propei'ty<NumB〉
[0111] W上是由全局函數(shù)調(diào)用關(guān)系樹結(jié)合DGML文件中存儲(chǔ)的函數(shù)信息獲取的詳細(xì)的函 數(shù)調(diào)用路徑;從該路徑可知程序中有兩條函數(shù)調(diào)用路徑這與程序中的分支結(jié)構(gòu)對(duì)應(yīng)。從結(jié) 果可W看出,此程序準(zhǔn)確的提取了程序的函數(shù)調(diào)用路徑。
[0112] 由于DGML給出的函數(shù)信息準(zhǔn)確、詳細(xì),程序已經(jīng)基本可W解決簡單的包括繼承、接 口、多態(tài)相關(guān)的程序D
[0113] W上所述是本發(fā)明的優(yōu)選實(shí)施方式,應(yīng)當(dāng)指出,對(duì)于本技術(shù)領(lǐng)域的普通技術(shù)人員 來說,在不脫離本發(fā)明所述原理的前提下,還可W作出若干改進(jìn)和潤飾,這些改進(jìn)和潤飾也 應(yīng)視為本發(fā)明的保護(hù)范圍。
【主權(quán)項(xiàng)】
1. 一種面向C#的函數(shù)調(diào)用路徑生成方法,其特征在于,包括: 步驟1、通過C#程序中與函數(shù)相關(guān)的信息,所述信息包括:類、命名空間、數(shù)據(jù)集信息、參 數(shù)信息; 步驟2、根據(jù)每一函數(shù)的調(diào)用關(guān)系,分別生成每一函數(shù)的函數(shù)調(diào)用關(guān)系樹,其中所述函 數(shù)調(diào)用關(guān)系樹的每一節(jié)點(diǎn)代表一個(gè)函數(shù),且每一節(jié)點(diǎn)的子節(jié)點(diǎn)代表一個(gè)分支,且每一節(jié)點(diǎn) 的兄弟節(jié)點(diǎn)與其父節(jié)點(diǎn)為并列關(guān)系; 步驟3、根據(jù)所有函數(shù)的函數(shù)調(diào)用關(guān)系樹,組合為C#程序的全局的函數(shù)調(diào)用關(guān)系樹。2. 根據(jù)權(quán)利要求1所述的面向C#的函數(shù)調(diào)用路徑生成方法,其特征在于,所述步驟1具 體包括:從DGML文件中獲取程序所有的類;從DGML文件中獲取類的所有函數(shù);將類自動(dòng)生成 構(gòu)造函數(shù)。3. 根據(jù)權(quán)利要求1所述的面向C#的函數(shù)調(diào)用路徑生成方法,其特征在于,所述步驟2中 具體包括: 步驟21、對(duì)每個(gè)成員函數(shù)進(jìn)行分析,獲取成員函數(shù)的執(zhí)行語句; 步驟22、對(duì)執(zhí)行語句進(jìn)行分析以確定判斷每條語句是否有函數(shù)調(diào)用,以確定該執(zhí)行語 句是否存在分支結(jié)構(gòu);如果存在分支結(jié)構(gòu),獲取分支結(jié)構(gòu)的方法體,然后對(duì)方法體里的每條 語句進(jìn)行分析判斷是否還存在函數(shù)調(diào)用,如果是則將被調(diào)用函數(shù)的信息加入到函數(shù)調(diào)用關(guān) 系樹中。4. 根據(jù)權(quán)利要求1所述的面向C#的函數(shù)調(diào)用路徑生成方法,其特征在于,所述步驟22具 體包括: 步驟221、判斷執(zhí)行語句中是否有函數(shù)調(diào)用,如果有則將函數(shù)調(diào)用順序、調(diào)用的函數(shù)添 加到列表中; 步驟222、判斷執(zhí)行語句中是否有控制關(guān)鍵字,如果有則確定其中的第一個(gè)被調(diào)用函數(shù) 以獲取函數(shù)調(diào)用的順序,并根據(jù)函數(shù)調(diào)用的順序依次將函數(shù)添加到列表中; 步驟23、生成每一函數(shù)的三元組T(M,R,S);其中,Μ表示函數(shù)集合;R表示函數(shù)的調(diào)用順 序關(guān)系〈順序節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn),分支節(jié)點(diǎn)〉表示順序結(jié)構(gòu)為樹的左孩子,分支結(jié)構(gòu)為樹的右孩 子;S表示源函數(shù)也是函數(shù)調(diào)用關(guān)系樹的頭節(jié)點(diǎn); 步驟24、根據(jù)所述每一函數(shù)的三元組生成每一函數(shù)的函數(shù)調(diào)用關(guān)系樹。
【文檔編號(hào)】G06F9/44GK106020848SQ201610397615
【公開日】2016年10月12日
【申請(qǐng)日】2016年6月7日
【發(fā)明人】牟永敏
【申請(qǐng)人】北京信息科技大學(xué), 牟永敏