2013-12-18 66 views
1

我最近將一個項目從VB6轉換爲VB.NET。作爲轉換過程的一部分,大多數功能的參數標記爲ByRef。舉例來說,我有這樣的功能:在VB.NET中查找未使用的ByRef參數

Function HexToDec(ByRef HexValue As String) As Short 
    HexToDec = Val("&H" & HexValue) 
End Function 

即使參數HexValue被標記爲ByRef,它沒有被分配到的功能。刪除ByRef關鍵字不會改變功能的工作方式。

我的項目中的大部分功能都是這樣的,但有些功能使用ByRef功能。

有沒有什麼好方法可以找到ByRef是不必要的所有功能?特別是,我想知道是否有一種方法使用反射來確定某些字段是否從未分配到。

+0

不幸的是,我不知道一種方法來實現這種自動化。但是,VS 2010及更高版本具有很酷的功能,可以在您踩下它時突出顯示所有符號的出現。它應該大大減少您需要投入的工作量,只需跳過該函數的每個參數並查看它是否被分配,您只需掃描突出顯示的單詞。 – Neolisk

+0

@MattWilko當只讀屬性傳遞給函數時,會在意想不到的地方出現很多問題。不知何故,這不會在VB6版本中發生錯誤,而會在.NET版本中發生。 – Oliver

+0

好吧,這是一個公平的點,我可以理解爲什麼可能會失敗 –

回答

0

看起來像沒有簡單的方法來做到這一點。但是,我的項目很大,所以我不想手動完成。我寫了一個小工具來幫助 - 也許對某個人有用。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Threading.Tasks; 

namespace Test 
{ 
    class Program 
    { 
     static List<string> inUse = new List<string>(); 

     static void Main(string[] args) 
     { 
      var loc = @"C:\Users\Owner\Dev\VB6_Conversion"; 

      var files = DirSearch(loc).ToList(); 

      int i = 0; 
      int tot = files.Count; 
      foreach (var file in files) 
      { 
       Console.WriteLine(i++ + "/" + tot); 

       if (file.EndsWith(".vb")) 
       { 

        var fileData = File.ReadAllText(file); 
        ParseFile(fileData,file); 
       } 
      } 

      var outFile = Path.Combine(Directory.GetCurrentDirectory(), "out.text"); 


      using (var fl = new StreamWriter(outFile)) 
      { 

       Console.WriteLine("\n\n\n"); 
       foreach (var a in inUse) 
       { 
        Console.WriteLine(a); 
        fl.WriteLine(a); 
       } 
      } 

      Console.WriteLine("\n\n\nPress any key..."); 
      Console.Read(); 

     } 

     static IEnumerable<string> DirSearch(string rootDir) 
     { 

      foreach (var file in Directory.EnumerateFiles(rootDir,"*.*",SearchOption.AllDirectories)) 
      { 
       yield return file; 
      } 
     } 


     static void ParseFile(string file, string filename) 
     { 

      var regex1 = @".*Sub .*\(.*\)(.*\r\n)*?.*End Sub"; 
      var regex2 = @".*Function .*\(.*\)(.*\r\n)*?.*End Function"; 

      var rx1 = new Regex(regex1, RegexOptions.Multiline); 
      var rx2 = new Regex(regex2,RegexOptions.Multiline); 

      var mc1 = rx1.Matches(file); 
      var mc2 = rx2.Matches(file); 

      for (int i = 0; i < mc1.Count; i++) 
       FuncTest(mc1[i].Value,filename,file,mc1[i].Index); 
      for (int i = 0; i < mc2.Count; i++) 
       FuncTest(mc2[i].Value,filename,file,mc2[i].Index); 

     } 

     static int findLineNum(string text, int index) 
     { 
      var s = text.Substring(0, index); 

      return s.Count(x => x == '\n'); 
     } 

     static void FuncTest(string text, string filename, string fullFile, int index) 
     { 
      var firstLine = Regex.Split(text,"\r\n")[0]; 

      var regex = @"ByRef ([a-zA-Z0-9_]+)"; 
      var matches = Regex.Matches(firstLine, regex); 

      var variables = new List<string>(); 

      for (int i = 0; i < matches.Count; i++) 
      { 
       variables.Add(matches[i].Groups[1].Value); 
      } 

      foreach (var variable in variables) 
      { 
       if (!variableInUse(text, variable)) 
        continue; 

       var line = findLineNum(fullFile, index); 
       var fln = filename.PadRight(120); 
       var vln = variable.PadRight(40); 

       var ot = "Variable in use: {0}, file: {1}, line: {2}"; 
       inUse.Add(String.Format(ot, vln, fln,line)); 
      } 

     } 

     static bool variableInUse(string text, string variable) 
     { 
      var regex = String.Format(@"^\t*{0} ?=", variable); 

      foreach (var line in Regex.Split(text, "\r\n")) 
      { 
       if (Regex.IsMatch(line, regex)) 
        return true; 
      } 
      return false; 
     } 

    } 
}