Получить исходный код метода из файла исходного кода класса - PullRequest
1 голос
/ 08 декабря 2010

У меня есть строка, которая содержит исходный код класса. Теперь у меня есть другая строка, которая содержит полное имя метода в этом классе. Имя метода, например,

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

Это работает более или менее нормально, однако, если метод определен без тела, он завершается ошибкой Любые советы, как решить это?

Ответы [ 3 ]

1 голос
/ 08 декабря 2010

Подсчет фигурных скобок и остановка при уменьшении счетчика до 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
1 голос
/ 08 декабря 2010

Вам, вероятно, придется знать последовательность методов, перечисленных в файле кода.Таким образом, вы можете искать метод закрытия области действия }, который может находиться прямо над началом следующего метода.

Таким образом, ваш код может выглядеть следующим образом:

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

Искать .LastIndexOf(yourMethodTerminator /*probably a} */,...) между строкой nStartOfMethod и nStartOfNextMethod

В этом случае, если вы не знаете последовательность методов, вы можете пропустить метод между, чтобы найти конечную скобку.

1 голос
/ 08 декабря 2010

Посмотрите на: - Парсер для C #

Рекомендуется использовать NRefactory для разбора и токенизации исходного кода, вы должны иметь возможность использовать его для навигации по исходному коду класса и выбора методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...