Подтвердить что ты не робот

Eclipse - "иерархия открытых вызовов" ошибочна

Вот мой пример кода Java:

public class Test {
    public static void foo() {
        Foo.InnerKey key = new Foo.InnerKey();
        getInstance().query(key);
    }

    public static void bar() {
        Bar.InnerKey key = new Bar.InnerKey();
        getInstance().query(key);
    }

    public static MyIF getInstance(){
        // TODO code to get instance
        return null;
    }

}


interface MyIF {
    public void query(Foo.InnerKey key); // Method to open call hierarchy
    public void query(Bar.InnerKey key);
}


class Foo {
    static class InnerKey  {}
}

class Bar {
    static class InnerKey {}
}

Когда я открываю иерархию вызовов метода query(Foo.InnerKey key) из Eclipse (kepler), у меня есть методы foo и bar, которые bar не ожидаются.

enter image description here

Но в netbeans (7.3.1) результат иерархии вызовов в порядке:

enter image description here

Является ли это ошибкой Eclipse? Спасибо.

4b9b3361

Ответ 1

Это определенно ошибка JDT, о которой следует сообщить. И ошибка не связана напрямую с иерархией вызовов, а вместо этого в API поиска org.eclipse.jdt.core при поиске ссылок на методы, где параметр является типом-членом другого типа (например, Foo.InnerKey). Поэтому эта ошибка проявляется для каждой функциональности JDT, которая опирается на поиск ссылок на методы с помощью поисковой системы JDT. Например, вы также получите неправильные результаты при показе ссылок на MyIF#query(Foo.InnerKey) или при использовании поиска Java для поиска метода MyIF#query(Foo.InnerKey). В этих случаях поисковая система не только вернет ссылки на MyIF#query(Foo.InnerKey), как и следовало ожидать, но также и на MyIF#query(Bar.InnerKey).

Соответствующий код, где происходит эта ошибка, находится в org.eclipse.jdt.internal.core.search.matching.MethodLocator#matchMethod(MethodBinding, boolean). И кажется, что ошибка была введена путем исправления JDT Bug 41018.

Вот фрагмент соответствующего кода в классе MethodLocator:

protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
    [...]
    // verify each parameter
    for (int i = 0; i < parameterCount; i++) {
        TypeBinding argType = method.parameters[i];
        int newLevel = IMPOSSIBLE_MATCH;
        if (argType.isMemberType()) {
            // only compare source name for member type (bug 41018)
            newLevel = CharOperation.match(this.pattern.parameterSimpleNames[i], argType.sourceName(), this.isCaseSensitive)
                ? ACCURATE_MATCH
                : IMPOSSIBLE_MATCH;
        } else {
            // TODO (frederic) use this call to refine accuracy on parameter types
            // newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType);
            newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], argType);
            [...]
        }
    }
    [...]
}

Проблема здесь - это оператор if (argType.isMemberType()), который был введен для исправления Ошибка 41018. В комментарии также указано, что для типов членов сравнивается только исходное имя. Если этот оператор if удален, ошибка исчезает, и иерархия вызовов показывает правильные ссылки (но, я думаю, это, конечно, повторит ошибку 41018 - я не тестировал это).

Edit

На стороне примечания также появляется ошибка при отображении исходных кодов Javadoc для MyIF#query(Bar.InnerKey) - как при использовании Javadoc-Hover над методом, так и при показе метода в представлении Javadoc.

public interface MyIF {
    /**
     * Javadoc for: query(Foo.InnerKey key)
     */
    public void query(Foo.InnerKey key); // Method to open call hierarchy
    /**
     * Javadoc for: query(Bar.InnerKey key)
     */
    public void query(Bar.InnerKey key);
}

При наведении указателя метода запроса в классе Test (например, getInstance().query(key)) оба метода найдены, и один из них может выбрать один (без возможности разграничения между ними).

При открытии представления Javadoc и выборе любой из ссылок метода запроса в классе Test, представление Javadoc всегда отображает только Javadoc первого найденного метода в исходном классе (т.е. MyIF#query(Foo.InnerKey)).

Это, похоже, напрямую не связано с описанной выше ошибкой, и это также не будет устранено при удалении упомянутого выше оператора if...

Ответ 2

Я думаю, что это может быть такая же проблема, как эта существующая ошибка (хотя ваш пример проще, ИМО). Я предлагаю вам добавить комментарий и ваш пример к этому отчету об ошибке.

Кроме того, он может быть связан с https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836, который подозревается как преступник для другого, <а2 >