Как найти номер строки начала процедуры в Eclipse - PullRequest
2 голосов
/ 18 февраля 2009

У меня есть код, который правильно находит номер строки IMethod в Eclipse под Windows:

IMethod method= ...;
String source= type.getCompilationUnit().getSource();
int lineNumber= 1;
for (int i= 0; i < method.getSourceRange().getOffset(); i++)
    if (source.charAt(i) == Character.LINE_SEPARATOR)
        lineNumber++;

Тем не менее, это не работает на Mac, предположим, потому что символ разделителя строк отличается, хотя исходный код, на котором он работает, тот же.

  1. есть ли встроенный способ получить номер строки без необходимости обходить каждый символ источника? (кажется, что должно быть, но я не смог его найти)
  2. если нет, то существует ли независимый от платформы способ подсчета разрывов строк в строке?

Спасибо

Кент Бек

Ответы [ 4 ]

3 голосов
/ 18 февраля 2009

Я не могу ответить (1), но я дам (2) шанс.

Как ни странно, я думаю, ваш код работал только по стечению обстоятельств. Character.LINE_SEPARATOR обозначает категорию Unicode; он не должен быть символом новой строки платформы, но просто имеет значение 13 , которое (как вы, вероятно, знаете) равно '\r'. Если я правильно помню, Mac, начиная с OS X, использовал '\n' для перевода строки, поэтому он не работает.

В прошлом я получил символ разделителя строк: System.getProperty("line.separator"). Возвращает String, поэтому он может не подойти. Поскольку он, похоже, работает с '\r' в Windows, я предполагаю, что простой проверки для '\n' также будет достаточно. В качестве альтернативы вы можете использовать BufferedReader, обернутый вокруг StringReader, как предложил Wouter Lievens.

1 голос
/ 18 февраля 2009

Я вместо этого использовал регулярное выражение, потому что это было проще. Это делает код O (n ^ 2) из ​​числа методов, которые мне нужно использовать в файле, но я ожидаю, что это должно быть небольшое число, так что пока это приемлемо.

private int getMethodLineNumber(final IType type, IMethod method) throws JavaModelException {
    String source= type.getCompilationUnit().getSource();
    String sourceUpToMethod= source.substring(0, method.getSourceRange().getOffset());
    Pattern lineEnd= Pattern.compile("$", Pattern.MULTILINE | Pattern.DOTALL);
    return lineEnd.split(sourceUpToMethod).length;
}

Спасибо всем за помощь.

С уважением,

Kent

0 голосов
/ 18 февраля 2009

Вы можете использовать IScanner , созданный ToolFactory , как используется в этом классе (не для подсчета строки, но, тем не менее, это дает идею)

Надеемся, что реализация внутреннего затмения IScanner будет работать правильно на любой платформе.

IBuffer buffer = imethod.getOpenable().getBuffer();
ISourceRange sourceRange = imethod.getSourceRange();
ISourceRange nameRange = imethod.getNameRange();
IScanner scanner = null; // delay initialization

if (sourceRange != null && nameRange != null) {
    if (scanner == null) {
        scanner= ToolFactory.createScanner(false, false, true, false);
        scanner.setSource(buffer.getCharacters());
    }
    scanner.resetTo(sourceRange.getOffset(), nameRange.getOffset());
} else {
    return 0 // no lines;
}
// use scanner to count lines
0 голосов
/ 18 февраля 2009

Вы можете обернуть String экземпляром BufferedReader, который поддерживает метод readLine(). Этот метод, по-видимому, правильно анализирует любой тип разделителя.

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