Как определить глубину дерева наследования класса Java?

#java #parsing #inheritance #static #javaparser

#java #синтаксический анализ #наследование #статический #javaparser

Вопрос:

Я создаю анализатор, который определяет глубину дерева наследования класса Java.

Я использую javaparser для извлечения этой информации из файла Java.

Как я смогу вычислить DIT?

Я знаю о .getSuperClass(), но это бесполезно при синтаксическом анализе в файле Java как части статического анализатора.

Комментарии:

1. Этот вопрос слишком широкий, поскольку вы не предоставили контекста или кода. В общем случае вы должны рекурсивно анализировать объявление класса и исходный код для любых суперклассов, пока не дойдете до Object . Для суперклассов без исходного кода вам придется либо получить исходный код (правильную версию), либо извлечь объявление класса из скомпилированного .class файла. Это большая сложная задача, и объяснение того, как все сделать, выходит за рамки StackOverflow. Если вам пришлось задать этот вопрос, то вы, вероятно, не готовы решать проблему в целом.

2. @JimGarrison я думал, что идея была довольно простой … возьмите любой класс Java и возвращайтесь назад, пока не дойдете до Object , подсчитывая, сколько классов имеет глубину наследования

3. Это «просто» объяснить, но на этом пути возникает МНОЖЕСТВО сложностей, таких как обработка классов, для которых у вас нет исходного кода. Непонятно, о чем вы просите. Вы надеялись, что кто-нибудь предоставит вам код?

Ответ №1:

Краткий ответ таков: вы не можете сделать это с помощью одного JavaParser, но вы можете очень легко сделать это с помощью JavaSymbolSolver, библиотеки, созданной в дополнение к JavaParser и поддерживаемой той же командой, которая поддерживает JavaParser.

На практике JavaParser выдает вам только AST. В AST суперкласс класса — это просто имя. JavaSymbolSolver находит для вас объявление типа, привязанное к этому имени. В этом объявлении содержится вся информация, необходимая для поиска всех предков и ответа на этот вопрос и на многие другие (например, какие интерфейсы реализованы, прямо и косвенно, какие поля унаследовал класс, какие методы и т.д.)

Отказ от ответственности: Я являюсь оригинальным автором JavaSymbolSolver

Комментарии:

1. Справляется ли это со всей запутанностью Java8? Правила разрешения имен действительно сложны. Как вы это проверяете?

2. Код не так протестирован в боях, как ваш коммерческий продукт 🙂 Это относительно молодой проект, созданный в свободное время. Бывают случаи, когда вывод типа с помощью лямбд может работать некорректно, но в отношении простого получения суперклассов он должен работать нормально, также учитывая общие параметры. Я протестировал его, убедившись, что он правильно разрешает все вызовы методов в паре проектов, использующих Java 8. Поэтому я не буду ставить ничью жизнь на то, что это работает идеально при любых обстоятельствах, но для рассматриваемой проблемы я думаю, что это должно работать как ожидалось, и PR приветствуются 🙂

3. Да, вероятно, проще правильно определить отношения суперклассов, и это все, что нужно для DIT.