从类源代码文件中检索方法源代码 [英] Retrieve method source code from class source code file

查看:176
本文介绍了从类源代码文件中检索方法源代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里有一个包含类源代码的字符串.现在,我有另一个String,其中包含此类中的方法的全名.方法名称例如是

I have here a String that contains the source code of a class. Now i have another String that contains the full name of a method in this class. The method name is e.g.

public void (java.lang.String test)

现在,我想从字符串和类的源代码中重新获得此方法的源代码.我怎样才能做到这一点?使用String#indexOf(methodName),我可以找到方法源代码的开头,但是如何找到结尾?

Now I want to retieve the source code of this method from the string with the class' source code. How can I do that? With String#indexOf(methodName) i can find the start of the method source code, but how do i find the end?

==== EDIT ====

====EDIT====

我使用了大括号计数方法:

I used the count curly-braces approach:

 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);
        }

这或多或少可以正常工作,但是,如果定义的方法没有主体,则它将失败.有提示如何解决吗?

This works more or less fine, However, if a method is defined without body, it fails. Any hints how to solve that?

推荐答案

计算括号并在计数减少到0时停止是确实可行的方法.当然,您需要考虑大括号,它们显示为文字,因此不应计入,例如在注释和字符串中大括号.

Counting braces and stopping when the count decreases to 0 is indeed the way to go. Of course, you need to take into account braces that appear as literals and should thus not be counted, e.g. braces in comments and strings.

总的来说,这是一种不费吹灰之力,如果说要使其真正可靠地工作,则要构建一个命令行解析器,其复杂程度可比拟.如果您知道您可以使用它,可以开一些角,只计算所有括号,尽管我不建议这样做.

Overall this is kind of a thankless endeavour, comparable in complexity to say, building a command line parser if you want to get it working really reliably. If you know you can get away with it you could cut some corners and just count all the braces, although I do not recommend it.

更新:

这里有一些示例代码来进行大括号计数.就像我说的那样,这是一项令人费力的工作,您必须弄清很多细节(实质上,您正在编写一个微型词法分析器).它在C#中,因为它是最接近Java的语言,我可以放心地编写代码.

Here's some sample code to do the brace counting. As I said, this is a thankless job and there are tons of details you have to get right (in essence, you 're writing a mini-lexer). It's in C#, as this is the closest to Java I can write code in with confidence.

下面的代码不完整,并且可能不是100%正确的(例如:C#中的逐字字符串不允许@和左引号之间有空格,但是我是否知道这是事实还是忘了它?)

The code below is not complete and probably not 100% correct (for example: verbatim strings in C# do not allow spaces between the @ and the opening quote, but did I know that for a fact or just forgot about it?)

// 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

这篇关于从类源代码文件中检索方法源代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆