1 Star 0 Fork 1

wangliangfmail / ASTAutoAddLog

forked from 水月洞天 / ASTAutoAddLog 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
mainwindow.cpp 9.74 KB
一键复制 编辑 原始数据 按行查看 历史
ch593030323 提交于 2021-06-15 16:10 . 代码优化
/*
* Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd.
*
* Author: zccrs <zccrs@live.com>
*
* Maintainer: zccrs <zhangjide@deepin.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QtWidgets>
#include "cplusplus/CppDocument.h"
#include "cplusplus/TranslationUnit.h"
#include "CppRewriter.h"
#include "cplusplus/AST.h"
#include "cplusplus/Parser.h"
#include "cplusplus/Bind.h"
#include <QStringList>
#include <cplusplus/ASTVisitor.h>
#include <QHeaderView>
using namespace CPlusPlus;
static QString symbolName(Symbol *symbol)
{
if(nullptr == symbol)
return "";
const Identifier *objectId = symbol->identifier();
if(nullptr == objectId)
return "";
return QByteArray(objectId->chars(), static_cast<int>(objectId->size()));
}
static const int roleFilePath = Qt::UserRole + 1;
static const int roleIsFile = Qt::UserRole + 2;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("ASTAutoAddLog");
m_treeModel = new QStandardItemModel(this);
ui->treeView->setModel(m_treeModel);
m_FuncModel = new QStandardItemModel(this);
m_FuncModel->setHorizontalHeaderLabels(QStringList() << "funcName" << "argNameList" << "start" << "end");
ui->tableView->setModel(m_FuncModel);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onOpenRootFloder);
connect(ui->actioncollapseAll, &QAction::triggered, ui->treeView, &QTreeView::collapseAll);
connect(ui->actionexpandAll, &QAction::triggered, ui->treeView, &QTreeView::expandAll);
connect(ui->actionRun, &QAction::triggered, this, &MainWindow::onRun);
connect(ui->actionExit, &QAction::triggered, this, &MainWindow::onExit);
connect(ui->treeView, &QTreeView::clicked, this, &MainWindow::onSourceFileClick);
resize(1100, 600);
openFloder("/home/chz/Documents/git_code/konsole");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onOpenRootFloder()
{
QString dir = QFileDialog::getExistingDirectory(this, "", "~");
if(dir.isEmpty()) {
return;
}
openFloder(dir);
}
void MainWindow::onSourceFileClick(const QModelIndex &index)
{
auto createItem = [](const QString &text, bool isCheckable = false)->QStandardItem*{
QStandardItem *item = new QStandardItem(text);
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
if(isCheckable)
item->setData(Qt::Checked, Qt::CheckStateRole);
return item;
};
m_FuncModel->removeRows(0, m_FuncModel->rowCount());
QString filepath = index.data(roleFilePath).toString();
for(const FunctionInfo &info : getFuncInfo(filepath)) {
if(info.funcName.trimmed().isEmpty())
continue;
m_FuncModel->appendRow(QList<QStandardItem*>()
<< createItem(info.funcName)
<< createItem(info.argNameList.join(","))
<< createItem(QString::number(info.start))
<< createItem(QString::number(info.end))
);
}
for(int column = 0; column < m_FuncModel->columnCount(); column ++) {
ui->tableView->resizeColumnToContents(column);
ui->tableView->setColumnWidth(column, ui->tableView->columnWidth(column) + 50);
}
}
void MainWindow::onRun()
{
//备份根目录文件夹
backupRootDirectory();
//获取所有选择的文件
QStringList checkedFiles = getCheckedFiles(m_treeModel->invisibleRootItem());
foreach(const QString &filepath, checkedFiles) {
QList<FunctionInfo> infos = getFuncInfo(filepath);
//在文件头添加debug头文件
prependDebugLink(filepath);
//获取源码
QByteArray content = readFile(filepath);
//从大到小遍历,把log相关代码写入源码中
for(int k = infos.count() - 1; k >= 0; k --) {
insertFile(content, infos[k]);
}
//保存
writeFile(content, filepath);
}
}
void MainWindow::onExit()
{
this->close();
}
void MainWindow::createTreeNode(const QString &root, const QString &dir)
{
if(fileCount(dir) == 0)
return;
createFilePathNode(root, dir);
foreach(const QFileInfo &info, QDir(dir).entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst)) {
if(info.isFile()){
if(info.fileName().endsWith(".cpp")
|| info.fileName().endsWith(".c")) {
createFilePathNode(root, info.filePath());
}
}
if(info.isDir()) {
createTreeNode(root, info.filePath());
}
}
}
void MainWindow::createFilePathNode(const QString &root, const QString &filepath)
{
QStringList list = filepath.mid(root.size()).split("/");
QStandardItem *parentItem = m_treeModel->invisibleRootItem();
for(int index = 0; index < list.count(); index ++) {
bool finded = false;
for(int row = 0; row < parentItem->rowCount(); row ++) {
if(parentItem->child(row, 0)->text() == list[index]) {
parentItem = parentItem->child(row, 0);
finded = true;
break;
}
}
if(!finded) {
QStandardItem *item = new QStandardItem;
item->setText(list[index]);
item->setData(filepath, roleFilePath);
item->setData(QFileInfo(filepath).isFile(), roleIsFile);
item->setData(Qt::Checked, Qt::CheckStateRole);
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
parentItem->appendRow(item);
parentItem = item;
}
}
}
QList<FunctionInfo> MainWindow::getFuncInfo(const QString &filepath)
{
QList<FunctionInfo> list;
//判断是否为文件
if(!QFileInfo(filepath).isFile())
return list;
QFile file(filepath);
if(!file.open(QFile::ReadOnly))
return list;
QByteArray all = file.readAll();
Document::Ptr doc = Document::create(filepath);
//导入数据
doc->setUtf8Source(all);
//解析
if(!doc->parse())
return list;
doc->check();
//解析指针
ASTVisitor visitor(doc->translationUnit());
//遍历所有的symbol
for(uint k = 0, count = doc->globalSymbolCount(); k < count; k ++)
{
//symbol 是函数时
if(doc->globalSymbolAt(k)->isFunction()) {
list.append(FunctionInfo());
//获取函数体信息
Function *func = doc->globalSymbolAt(k)->asFunction();
//获取函数名
list.last().funcName = symbolName(doc->globalSymbolAt(k));
//获取函数参数
for(uint k = 0, count = func->argumentCount(); k < count; k ++)
{
list.last().argNameList << symbolName(func->argumentAt(k));
}
//获取函数开始行和结束行
uint line_start;
uint line_end;
visitor.getPosition(func->startOffset(), &line_start);
visitor.getPosition(func->endOffset(), &line_end);
list.last().start = line_start;
list.last().end = line_end;
}
}
return list;
}
void MainWindow::openFloder(const QString &dir)
{
m_treeModel->clear();
m_treeModel->setHorizontalHeaderItem(0, new QStandardItem(dir));
//遍历生成item
createTreeNode(dir, dir);
//设置root item
QStandardItem *item = m_treeModel->item(0, 0);
if(item)
item->setText(QFileInfo(dir).fileName());
ui->treeView->expandAll();
ui->tableView->resizeColumnToContents(0);
}
QByteArray MainWindow::readFile(const QString &filepath)
{
return "";
}
void MainWindow::insertFile(QByteArray &source, int line, const QByteArray &content)
{
}
void MainWindow::insertFile(QByteArray &source, FunctionInfo info)
{
}
void MainWindow::writeFile(QByteArray &source, const QString &filepath)
{
}
void MainWindow::backupRootDirectory()
{
}
void MainWindow::prependDebugLink(const QString &filepath)
{
}
int MainWindow::fileCount(const QString &dir)
{
int count = 0;
foreach(const QFileInfo &info, QDir(dir).entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst)) {
if(info.isFile()){
if(info.fileName().endsWith(".cpp")
|| info.fileName().endsWith(".c")) {
count ++;
}
}
if(info.isDir()) {
count += fileCount(info.filePath());
}
}
return count;
}
QStringList MainWindow::getCheckedFiles(QStandardItem *item)
{
QStringList fileList;
for(int row = 0; row < item->rowCount(); row ++) {
QStandardItem *child = item->child(row);
if(child->data(roleIsFile).toBool()) {
if(child->data(Qt::CheckStateRole).toInt() == Qt::Checked){
fileList << child->data(roleFilePath).toString();
}
} else {
fileList << getCheckedFiles(child);
}
}
return fileList;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wangliangfmail/astauto-add-log.git
git@gitee.com:wangliangfmail/astauto-add-log.git
wangliangfmail
astauto-add-log
ASTAutoAddLog
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891