0
0 комментариев

У меня есть вопрос относительно этого замечательного инструмента.
Всем, кто с ним знаком, известно, что он является замечательным парсером языка C++ и его можно использовать для анализа кода.

И мне как раз понадобилось это сделать. Если быть конкретнее, мне необходимо получить список параметров из метода класса в виде: «Название парамера»: «Тип параметра».

Проект очень большой. Это разработка на движке Unreal Engine 4. Поэтому проект имеет бешеное разнообразие типов, макросов и прочих необычных директив компилятора. Более того, огромное количества хедеров.

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

В данном случае я использую питоновскую обёртку Clang’а и просто загружаю файлы листинга с помощью clang.cindex.Index и index.parse.

В итоге я получаю дерево пространств имён. Классов, различных подсущностей и т д… И вроде могу просто уже спокойно это дерево разбирать… Однако… Если происходит какая либо ошибка (не найден инклуд или что-то ещё), то типы данных, которые в результате этой ошибки не были отпарсены ранее, превращаются в тип «int«. И это очень печально. В результате выходит, что использованный по нанзначению инструмент не работает с такими правилами.
Однако, я думаю здесь есть специалисты, которые укажут на то, что я делаю не так.

В общем то цель моя просто спарсить аргументы, мне не нужно для этого подключать инклуды (если всё это дело подключать, это превратится в длительную операцию, и, вообще этот номер не пройдёт, так как нужно знать какие дейфайны нужны для всего проекта целиком).
Что здесь можно сделать? Или не использовать Clang вовсе и какие-то другие решения здесь более приемлемы?

Пример кода, который нужно анализировать:

// Fill out your copyright notice in the Description page of Project Settings.
 
#pragma once
 
#include "UMG.h"
#include "Components/Overlay.h"
#include "MinimapMark.h"
#include "GUI/GUIBase.h"
#include "Tools.h"
#include "Minimap.generated.h"
 
 
USTRUCT(BlueprintType, Blueprintable)
struct FMinimapEntityEntry
{
    GENERATED_USTRUCT_BODY()
 
    UPROPERTY()
    AActor * Actor;
 
    UPROPERTY()
    UMinimapMark * Mark;
 
    UPROPERTY()
    UOverlaySlot * Slot;
};
 
 
UCLASS(Abstract)
class PROJECT_API UMinimap : public UGUIBase
{
    GENERATED_BODY()
 
 
public:
    UMinimap(const FObjectInitializer& ObjectInitializer);
    virtual TSharedRef<SWidget> RebuildWidget() override;
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);
 
// Exposed functions
    ReceiverMethod(SetMarksData)
    UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Minimap)
    void UpdateMarks(const TArray<AActor*>& Actors, AActor* Player);
    virtual void UpdateMarks_Implementation(const TArray<AActor*>& Actors, AActor* Player);
 
    UFUNCTION(BlueprintCallable, Category = Minimap)
    void AddActor(AActor* Actor);
 
    UFUNCTION(BlueprintCallable, Category = Minimap)
    void RemoveActor(AActor* Actor);
 
 
// Exposed fields
    TArray<AActor*> MapActors;
    FMinimapEntityEntry PlayerMark;
    TArray<FMinimapEntityEntry> Marks;
 
 
private:  // local widget pointers
    TWeakObjectPtr<UImage> Image;
    TWeakObjectPtr<UOverlay> Overlay;
 
    FRotator GetRotation();
 
};

Нужно извлечь параметры из функции UpdateMarks (типы и имена аргументов).

UFUNCTION и ReceiverMethod — это просто макросы.


Добавить комментарий