2010-12-08 6 views
1

ここには、クラスのソースコードを含むStringがあります。今私は、このクラスのメソッドのフルネームを含む別のStringを持っています。メソッド名は、例えば、。クラスソースコードファイルからメソッドのソースコードを取得します。

public void (java.lang.String test) 

ここで、このメソッドのソースコードを、クラスのソースコードを持つ文字列から見直したいと思います。どうやってやるの? String#indexOf(methodName)私は方法のソースコードの開始を見つけることができますが、私はどのように最後を見つけるのですか?

==== ==== EDIT

私は、カウントカーリーブレースのアプローチを使用:

internal void retrieveSourceCode() 
     { 
      int startPosition = parentClass.getSourceCode().IndexOf(this.getName()); 
      if (startPosition != -1) 
      { 
       String subCode = parentClass.getSourceCode().Substring(startPosition, parentClass.getSourceCode().Length - startPosition); 

       for (int i = 0; i < subCode.Length; i++) 
       { 
        String c = subCode.Substring(0, i); 
        int open = c.Split('{').Count() - 1; 
        int close = c.Split('}').Count() - 1; 

        if (open == close && open != 0) 
        { 
         sourceCode = c; 
         break; 
        } 
       } 

      } 
      Console.WriteLine("SourceCode for " + this.getName() + "\n" + sourceCode); 
     } 

方法は、本体なしで定義されている場合、これは、しかし、多かれ少なかれ、正常に動作し、それは失敗する。どのようにそれを解決するためのヒント?

+0

あなたが解析しているコードの言語に完全に依存しているとします。Javaのように見えますが、その場合は中括弧を数えることになります。 – lesscode

+0

これはjavaです。だからあなたは開いたカールを数えることをお勧めします、そして、これが0ならば、方法は完了ですか? –

+0

これはikvmを使用していますか? – IanNorton

答えて

1

カウントが0に減少したときに中かっこを停止して停止するのが実際の方法です。もちろん、リテラルとして表示される中カッコを考慮する必要があります。コメントと文字列の中かっこ。

これは全体的には、コマンドラインパーサーを構築して本当に確実に動作させたいと思っている場合には、複雑さに匹敵します。あなたがそれを取り除くことができると分かっているならば、私はそれをお勧めしませんが、いくつかのコーナーをカットしてすべてのブレースを数えることができます。

更新:

ここブレースカウントを行うにはいくつかのサンプルコードです。私が言ったように、これは感謝していない仕事であり、あなたは正しいものをたくさん持っています(本質的に、あなたはミニレクサーを書いています)。これはC#にあります。これはJavaに最も近いため、私は自信を持ってコードを書くことができます。

以下のコードは完全ではなく、おそらく100%正確ではありません(例:C#の逐語的な文字列は@と開始引用の間にスペースを入れることはできませんが、それについて知っていましたか? )

// sourceCode is a string containing all the source file's text 
var sourceCode = "..."; 

// startIndex is the index of the char AFTER the opening brace 
// for the method we are interested in 
var methodStartIndex = 42; 

var openBraces = 1; 
var insideLiteralString = false; 
var insideVerbatimString = false; 
var insideBlockComment = false; 
var lastChar = ' '; // White space is ignored by the C# parser, 
        // so a space is a good "neutral" character 

for (var i = methodStartIndex; openBraces > 0; ++i) { 
    var ch = sourceCode[i]; 

    switch (ch) { 
     case '{': 
      if (!insideBlockComment && !insideLiteralString && !insideVerbatimString) { 
       ++openBraces; 
      } 
      break; 
     case '}': 
      if (!insideBlockComment && !insideLiteralString && !insideVerbatimString) { 
       --openBraces; 
      } 
      break; 
     case '"': 
      if (insideBlockComment) { 
       continue; 
      } 
      if (insideLiteralString) { 
       // "Step out" of the string if this is the closing quote 
       insideLiteralString = lastChar != '\'; 
      } 
      else if (insideVerbatimString) { 
       // If this quote is part of a two-quote pair, do NOT step out 
       // (it means the string contains a literal quote) 

       // This can throw, but only for source files with syntax errors 
       // I 'm ignoring this possibility here... 
       var nextCh = sourceCode[i + 1]; 

       if (nextCh == '"') { 
        ++i; // skip that next quote 
       } 
       else { 
        insideVerbatimString = false; 
       } 
      } 
      else { 
       if (lastChar == '@') { 
        insideVerbatimString = true; 
       } 
       else { 
        insideLiteralString = true; 
       } 
      } 
      break; 
     case '/': 
      if (insideLiteralString || insideVerbatimString) { 
       continue; 
      } 

      // TODO: parse this 
      // It can start a line comment, if followed by/
      // It can start a block comment, if followed by * 
      // It can end a block comment, if preceded by * 

      // Line comments are intended to be handled by just incrementing i 
      // until you see a CR and/or LF, hence no insideLineComment flag. 
      break; 
    } 

    lastChar = ch; 
} 

// From the values of methodStartIndex and i we can now do sourceCode.Substring and get the method source 
+0

どのコードスニフットも中カッコを数えますか? – RoflcoptrException

1

は見ておいてください - それは、ソースコードを解析し、tokeniseするNRefactoryを使用することをお勧めしますParser for C#

を、あなたのクラスのソースをナビゲートし、方法を選ぶためにそれを使用することができるはずです。

1

あなたは、おそらく、コードファイルにリストされている方法のシーケンスを知っている必要があります。そのため、メソッドを閉じるメソッド}を探すことができます。これは次のメソッドの開始の直前にある可能性があります。

だからコードは次のようになります。あなたはは、メソッドのシーケンスを知らないならば、この場合、

nStartOfMethodの文字列の間と nStartOfNextMethod .LastIndexOf(yourMethodTerminator /*probably a} */,...)ため

nStartOfMethod = String.indexOf(methodName) 
nStartOfNextMethod = String.indexOf(NextMethodName) 

見て、あなたは終わりのブレースを見つけるために、中間のメソッドをスキップしてしまうかもしれません。

+0

残念ながら、メソッドはソートされません – RoflcoptrException

関連する問題