<commit_before>#pragma once

#include <QtWidgets/QAbstractScrollArea>
#include <QtCore/QTimer>
#include "binaryninjaapi.h"
#include "viewframe.h"
#include "render.h"
#include "commentdialog.h"
#include "menus.h"
#include "statusbarwidget.h"
#include "uicontext.h"

#define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200
#define MAX_STRING_TYPE_LENGTH 1048576

struct BINARYNINJAUIAPI LinearViewLine: public BinaryNinja::LinearDisassemblyLine
{
	BinaryNinja::Ref<BinaryNinja::LinearViewCursor> cursor;
	size_t lineIndex;
};

struct BINARYNINJAUIAPI LinearViewCursorPosition
{
	FunctionRef function;
	BasicBlockRef block;
	uint64_t address;
	BinaryNinja::Ref<BinaryNinja::LinearViewCursor> cursor;
	size_t lineIndex;
	size_t tokenIndex;

	LinearViewCursorPosition();
	LinearViewCursorPosition(const LinearViewCursorPosition& pos);
	LinearViewCursorPosition(const LinearViewLine& line);
	LinearViewCursorPosition& operator=(const LinearViewCursorPosition& pos);

	bool operator==(const LinearViewCursorPosition& other) const;
	bool operator!=(const LinearViewCursorPosition& other) const;
	bool operator<(const LinearViewCursorPosition& other) const;
	bool operator<=(const LinearViewCursorPosition& other) const;
	bool operator>=(const LinearViewCursorPosition& other) const;
	bool operator>(const LinearViewCursorPosition& other) const;

	LinearViewCursorPosition AsLine() const;
};

class BINARYNINJAUIAPI LinearViewHistoryEntry: public HistoryEntry
{
	std::vector<BinaryNinja::LinearViewObjectIdentifier> m_topPath;
	size_t m_topLineIndex;
	uint64_t m_topAddr;
	std::vector<BinaryNinja::LinearViewObjectIdentifier> m_cursorPath;
	size_t m_cursorLineIndex;
	uint64_t m_cursorAddr;
	HighlightTokenState m_highlight;

public:
	const std::vector<BinaryNinja::LinearViewObjectIdentifier>& getTopPath() const { return m_topPath; }
	size_t getTopLineIndex() const { return m_topLineIndex; }
	uint64_t getTopAddress() const { return m_topAddr; }
	const std::vector<BinaryNinja::LinearViewObjectIdentifier>& getCursorPath() const { return m_cursorPath; }
	size_t getCursorLineIndex() const { return m_cursorLineIndex; }
	uint64_t getCursorAddress() const { return m_cursorAddr; }
	const HighlightTokenState& getHighlightTokenState() const { return m_highlight; }

	void setTopPath(const std::vector<BinaryNinja::LinearViewObjectIdentifier>& path) { m_topPath = path; }
	void setTopLineIndex(size_t offset) { m_topLineIndex = offset; }
	void setTopAddress(uint64_t addr) { m_topAddr = addr; }
	void setCursorPath(const std::vector<BinaryNinja::LinearViewObjectIdentifier>& path) { m_cursorPath = path; }
	void setCursorLineIndex(size_t offset) { m_cursorLineIndex = offset; }
	void setCursorAddress(uint64_t addr) { m_cursorAddr = addr; }
	void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; }
};

class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, public BinaryNinja::BinaryDataNotification
{
	Q_OBJECT

	class LinearViewOptionsWidget: public MenuHelper
	{
	public:
		LinearViewOptionsWidget(LinearView* parent);

	protected:
		virtual void showMenu();

	private:
		LinearView* m_view;
	};

	class LinearViewStatusBarWidget: public StatusBarWidget
	{
	public:
		LinearViewStatusBarWidget(LinearView* parent);
		virtual void updateStatus() override;

	private:
		LinearView* m_view;
		LinearViewOptionsWidget* m_options;
	};

	BinaryViewRef m_data;
	ViewFrame* m_view;
	uint64_t m_allocatedLength;

	RenderContext m_render;
	int m_cols, m_rows;
	uint64_t m_scrollBarMultiplier;
	int m_wheelDelta;
	bool m_updatingScrollBar;

	bool m_updatesRequired;
	bool m_updateBounds;

	LinearViewCursorPosition m_cursorPosition, m_selectionStartPos;
	bool m_tokenSelection = false;
	HighlightTokenState m_highlight;
	uint64_t m_navByRefTarget;
	bool m_navByRef = false;

	SettingsRef m_settings;
	DisassemblySettingsRef m_options;
	BNFunctionGraphType m_type;

	BinaryNinja::Ref<BinaryNinja::LinearViewCursor> m_topPosition, m_bottomPosition;
	std::vector<LinearViewLine> m_lines;
	size_t m_topLine;

	QTimer* m_updateTimer;

	ContextMenuManager m_contextMenuManager;
	QPointer<CommentDialog> m_commentDialog;

	std::map<FunctionRef, BinaryNinja::AdvancedFunctionAnalysisDataRequestor> m_analysisRequestors;

	std::string m_navigationMode = "";

	void adjustSize(int width, int height);

	void setTopToAddress(uint64_t addr);
	void setTopToOrderingIndex(uint64_t idx);
	void refreshLines(size_t lineOffset = 0, bool refreshUIContext = true);
	bool cachePreviousLines();
	bool cacheNextLines();
	void updateCache();
	void refreshAtCurrentLocation();
	bool navigateToAddress(uint64_t addr, bool center, bool updateHighlight, bool navByRef = false);

	void scrollLines(int count);

	void bindActions();
	void getHexDumpLineBytes(const BinaryNinja::LinearDisassemblyLine& line, size_t& skippedBytes, size_t& totalBytes,
		size_t& totalCols);

	void setSectionSemantics(const std::string& name, BNSectionSemantics semantics);

	bool isLineValidHighlight(const BinaryNinja::LinearDisassemblyLine& line);
	void ensureLineVisible(size_t line);

	TypeRef createStructure(BinaryNinja::QualifiedName& name, uint64_t size);
	StructureRef defineInnerType(TypeRef type, TypeRef baseType, uint64_t offset, uint64_t size);
	StructureRef defineInnerPointer(TypeRef type, ArchitectureRef arch, uint64_t baseAddress, uint64_t offset, uint64_t size);
	StructureRef defineInnerStruct(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerArray(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerName(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerUnknownType(QWidget* parent, TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerIntegerSize(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerSign(TypeRef type, uint64_t offset, uint64_t size);
	TypeRef getPointerTypeAndName(ArchitectureRef arch, uint64_t addr, std::string& name);
	std::string getVariableName(uint64_t addr);

	BinaryNinja::Ref<BinaryNinja::LinearViewObject> createLinearViewObject();
	LinearViewCursorPosition getPositionForCursor(BinaryNinja::LinearViewCursor* cursor);
	bool updateCursor(LinearViewCursorPosition& cursorToUpdate, BinaryNinja::LinearViewCursor* matched, bool fullMatch);
	bool updateCursor(LinearViewCursorPosition& cursorToUpdate, BinaryNinja::LinearViewCursor* newCursor);
	bool updateCursor(LinearViewCursorPosition& cursorToUpdate,
		const std::vector<BinaryNinja::LinearViewObjectIdentifier>& path,
		BinaryNinja::LinearViewCursor* newCursor);
	uint64_t getOrderingIndexForLine(const LinearViewLine& line);

	void updateAnalysisRequestorsForCache();

private Q_SLOTS:
	void viewInHexEditor();
	void viewInGraph();
	void viewInTypesView(std::string typeName = "");
	void copyAddressSlot();
	void goToAddress();
	void defineNameAtAddr(uint64_t addr);
	void defineName();
	void undefineName();
	void createFunc();
	void defineFuncName();<commit_msg>Support for adding HLIL instruction highlighting<commit_after>#pragma once

#include <QtWidgets/QAbstractScrollArea>
#include <QtCore/QTimer>
#include "binaryninjaapi.h"
#include "viewframe.h"
#include "render.h"
#include "commentdialog.h"
#include "menus.h"
#include "statusbarwidget.h"
#include "uicontext.h"

#define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200
#define MAX_STRING_TYPE_LENGTH 1048576

struct BINARYNINJAUIAPI LinearViewLine: public BinaryNinja::LinearDisassemblyLine
{
	BinaryNinja::Ref<BinaryNinja::LinearViewCursor> cursor;
	size_t lineIndex;
};

struct BINARYNINJAUIAPI LinearViewCursorPosition
{
	FunctionRef function;
	BasicBlockRef block;
	uint64_t address;
	BinaryNinja::Ref<BinaryNinja::LinearViewCursor> cursor;
	size_t lineIndex;
	size_t tokenIndex;

	LinearViewCursorPosition();
	LinearViewCursorPosition(const LinearViewCursorPosition& pos);
	LinearViewCursorPosition(const LinearViewLine& line);
	LinearViewCursorPosition& operator=(const LinearViewCursorPosition& pos);

	bool operator==(const LinearViewCursorPosition& other) const;
	bool operator!=(const LinearViewCursorPosition& other) const;
	bool operator<(const LinearViewCursorPosition& other) const;
	bool operator<=(const LinearViewCursorPosition& other) const;
	bool operator>=(const LinearViewCursorPosition& other) const;
	bool operator>(const LinearViewCursorPosition& other) const;

	LinearViewCursorPosition AsLine() const;
};

class BINARYNINJAUIAPI LinearViewHistoryEntry: public HistoryEntry
{
	std::vector<BinaryNinja::LinearViewObjectIdentifier> m_topPath;
	size_t m_topLineIndex;
	uint64_t m_topAddr;
	std::vector<BinaryNinja::LinearViewObjectIdentifier> m_cursorPath;
	size_t m_cursorLineIndex;
	uint64_t m_cursorAddr;
	HighlightTokenState m_highlight;

public:
	const std::vector<BinaryNinja::LinearViewObjectIdentifier>& getTopPath() const { return m_topPath; }
	size_t getTopLineIndex() const { return m_topLineIndex; }
	uint64_t getTopAddress() const { return m_topAddr; }
	const std::vector<BinaryNinja::LinearViewObjectIdentifier>& getCursorPath() const { return m_cursorPath; }
	size_t getCursorLineIndex() const { return m_cursorLineIndex; }
	uint64_t getCursorAddress() const { return m_cursorAddr; }
	const HighlightTokenState& getHighlightTokenState() const { return m_highlight; }

	void setTopPath(const std::vector<BinaryNinja::LinearViewObjectIdentifier>& path) { m_topPath = path; }
	void setTopLineIndex(size_t offset) { m_topLineIndex = offset; }
	void setTopAddress(uint64_t addr) { m_topAddr = addr; }
	void setCursorPath(const std::vector<BinaryNinja::LinearViewObjectIdentifier>& path) { m_cursorPath = path; }
	void setCursorLineIndex(size_t offset) { m_cursorLineIndex = offset; }
	void setCursorAddress(uint64_t addr) { m_cursorAddr = addr; }
	void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; }
};

class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, public BinaryNinja::BinaryDataNotification
{
	Q_OBJECT

	class LinearViewOptionsWidget: public MenuHelper
	{
	public:
		LinearViewOptionsWidget(LinearView* parent);

	protected:
		virtual void showMenu();

	private:
		LinearView* m_view;
	};

	class LinearViewStatusBarWidget: public StatusBarWidget
	{
	public:
		LinearViewStatusBarWidget(LinearView* parent);
		virtual void updateStatus() override;

	private:
		LinearView* m_view;
		LinearViewOptionsWidget* m_options;
	};

	BinaryViewRef m_data;
	ViewFrame* m_view;
	uint64_t m_allocatedLength;

	RenderContext m_render;
	int m_cols, m_rows;
	uint64_t m_scrollBarMultiplier;
	int m_wheelDelta;
	bool m_updatingScrollBar;

	bool m_updatesRequired;
	bool m_updateBounds;

	LinearViewCursorPosition m_cursorPosition, m_selectionStartPos;
	bool m_tokenSelection = false;
	HighlightTokenState m_highlight;
	uint64_t m_navByRefTarget;
	bool m_navByRef = false;

	SettingsRef m_settings;
	DisassemblySettingsRef m_options;
	BNFunctionGraphType m_type;

	BinaryNinja::Ref<BinaryNinja::LinearViewCursor> m_topPosition, m_bottomPosition;
	std::vector<LinearViewLine> m_lines;
	size_t m_topLine;

	QTimer* m_updateTimer;

	ContextMenuManager m_contextMenuManager;
	QPointer<CommentDialog> m_commentDialog;

	std::map<FunctionRef, BinaryNinja::AdvancedFunctionAnalysisDataRequestor> m_analysisRequestors;

	std::string m_navigationMode = "";

	void adjustSize(int width, int height);

	void setTopToAddress(uint64_t addr);
	void setTopToOrderingIndex(uint64_t idx);
	void refreshLines(size_t lineOffset = 0, bool refreshUIContext = true);
	bool cachePreviousLines();
	bool cacheNextLines();
	void updateCache();
	void refreshAtCurrentLocation();
	bool navigateToAddress(uint64_t addr, bool center, bool updateHighlight, bool navByRef = false);

	void scrollLines(int count);

	void bindActions();
	void getHexDumpLineBytes(const BinaryNinja::LinearDisassemblyLine& line, size_t& skippedBytes, size_t& totalBytes,
		size_t& totalCols);

	void setSectionSemantics(const std::string& name, BNSectionSemantics semantics);

	bool isLineValidHighlight(const BinaryNinja::LinearDisassemblyLine& line);
	void ensureLineVisible(size_t line);

	TypeRef createStructure(BinaryNinja::QualifiedName& name, uint64_t size);
	StructureRef defineInnerType(TypeRef type, TypeRef baseType, uint64_t offset, uint64_t size);
	StructureRef defineInnerPointer(TypeRef type, ArchitectureRef arch, uint64_t baseAddress, uint64_t offset, uint64_t size);
	StructureRef defineInnerStruct(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerArray(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerName(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerUnknownType(QWidget* parent, TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerIntegerSize(TypeRef type, uint64_t offset, uint64_t size);
	StructureRef defineInnerSign(TypeRef type, uint64_t offset, uint64_t size);
	TypeRef getPointerTypeAndName(ArchitectureRef arch, uint64_t addr, std::string& name);
	std::string getVariableName(uint64_t addr);

	BinaryNinja::Ref<BinaryNinja::LinearViewObject> createLinearViewObject();
	LinearViewCursorPosition getPositionForCursor(BinaryNinja::LinearViewCursor* cursor);
	bool updateCursor(LinearViewCursorPosition& cursorToUpdate, BinaryNinja::LinearViewCursor* matched, bool fullMatch);
	bool updateCursor(LinearViewCursorPosition& cursorToUpdate, BinaryNinja::LinearViewCursor* newCursor);
	bool updateCursor(LinearViewCursorPosition& cursorToUpdate,
		const std::vector<BinaryNinja::LinearViewObjectIdentifier>& path,
		BinaryNinja::LinearViewCursor* newCursor);
	uint64_t getOrderingIndexForLine(const LinearViewLine& line);

	void updateAnalysisRequestorsForCache();

	ArchitectureRef getArchitecture(const LinearViewLine& line);

private Q_SLOTS:
	void viewInHexEditor();
	void viewInGraph();
	void viewInTypesView(std::string typeName = "");
	void copyAddressSlot();
	void goToAddress();
	void defineNameAtAddr(uint64_t addr);
	void defineName();
	void undefineName();
	void createFunc();
	void defineFuncName();
{'fraction_non_alphanumeric': 0.08273792512146327, 'fraction_numerical': 0.01157473563875393, 'mean_word_length': 8.560792349726777, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4637073', 'n_tokens_mistral': 4581, 'n_tokens_neox': 4268, 'n_words': 980}