Debugger: Clean up source utils

Change-Id: Ibfe20af9c4c413657b6a238337ff9af661857b3e
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hjk
2014-09-19 17:06:26 +02:00
parent 3491b1f22a
commit 7a50386446
4 changed files with 42 additions and 111 deletions

View File

@@ -52,20 +52,6 @@ void AbstractEditorSupport::updateDocument()
m_modelmanager->updateSourceFiles(QSet<QString>() << fileName()); m_modelmanager->updateSourceFiles(QSet<QString>() << fileName());
} }
QString AbstractEditorSupport::functionAt(const CppModelManager *modelManager,
const QString &fileName,
int line, int column)
{
if (!modelManager)
return QString();
const CPlusPlus::Snapshot snapshot = modelManager->snapshot();
if (const CPlusPlus::Document::Ptr document = snapshot.document(fileName))
return document->functionAt(line, column);
return QString();
}
QString AbstractEditorSupport::licenseTemplate(const QString &file, const QString &className) QString AbstractEditorSupport::licenseTemplate(const QString &file, const QString &className)
{ {
return Internal::CppFileSettings::licenseTemplate(file, className); return Internal::CppFileSettings::licenseTemplate(file, className);

View File

@@ -52,11 +52,6 @@ public:
void updateDocument(); void updateDocument();
unsigned revision() const { return m_revision; } unsigned revision() const { return m_revision; }
// TODO: find a better place for common utility functions
static QString functionAt(const CppModelManager *mm,
const QString &fileName,
int line, int column);
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString()); static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());
private: private:

View File

@@ -36,6 +36,7 @@
#include <cpptools/abstracteditorsupport.h> #include <cpptools/abstracteditorsupport.h>
#include <cpptools/cppprojectfile.h> #include <cpptools/cppprojectfile.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cplusplus/CppDocument.h>
#include <cplusplus/ExpressionUnderCursor.h> #include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Overview.h> #include <cplusplus/Overview.h>
@@ -48,7 +49,10 @@
enum { debug = 0 }; enum { debug = 0 };
// Debug helpers for code model. @todo: Move to some CppTools library? using namespace CppTools;
using namespace CPlusPlus;
using namespace TextEditor;
namespace CPlusPlus { namespace CPlusPlus {
static void debugCppSymbolRecursion(QTextStream &str, const Overview &o, static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
@@ -80,7 +84,7 @@ static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
QDebug operator<<(QDebug d, const Symbol &s) QDebug operator<<(QDebug d, const Symbol &s)
{ {
QString output; QString output;
CPlusPlus::Overview o; Overview o;
QTextStream str(&output); QTextStream str(&output);
debugCppSymbolRecursion(str, o, s, true, 0); debugCppSymbolRecursion(str, o, s, true, 0);
d.nospace() << output; d.nospace() << output;
@@ -119,6 +123,7 @@ QDebug operator<<(QDebug d, const Scope &scope)
d.nospace() << output; d.nospace() << output;
return d; return d;
} }
} // namespace CPlusPlus } // namespace CPlusPlus
namespace Debugger { namespace Debugger {
@@ -144,8 +149,8 @@ if (true) {
typedef QHash<QString, int> SeenHash; typedef QHash<QString, int> SeenHash;
static void blockRecursion(const CPlusPlus::Overview &overview, static void blockRecursion(const Overview &overview,
const CPlusPlus::Scope *scope, const Scope *scope,
unsigned line, unsigned line,
QStringList *uninitializedVariables, QStringList *uninitializedVariables,
SeenHash *seenHash, SeenHash *seenHash,
@@ -154,7 +159,7 @@ static void blockRecursion(const CPlusPlus::Overview &overview,
// Go backwards in case someone has identical variables in the same scope. // Go backwards in case someone has identical variables in the same scope.
// Fixme: loop variables or similar are currently seen in the outer scope // Fixme: loop variables or similar are currently seen in the outer scope
for (int s = scope->memberCount() - 1; s >= 0; --s){ for (int s = scope->memberCount() - 1; s >= 0; --s){
const CPlusPlus::Symbol *symbol = scope->memberAt(s); const Symbol *symbol = scope->memberAt(s);
if (symbol->isDeclaration()) { if (symbol->isDeclaration()) {
// Find out about shadowed symbols by bookkeeping // Find out about shadowed symbols by bookkeeping
// the already seen occurrences in a hash. // the already seen occurrences in a hash.
@@ -171,13 +176,13 @@ static void blockRecursion(const CPlusPlus::Overview &overview,
} }
} }
// Next block scope. // Next block scope.
if (const CPlusPlus::Scope *enclosingScope = scope->enclosingBlock()) if (const Scope *enclosingScope = scope->enclosingBlock())
blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1); blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1);
} }
// Inline helper with integer error return codes. // Inline helper with integer error return codes.
static inline static inline
int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot, int getUninitializedVariablesI(const Snapshot &snapshot,
const QString &functionName, const QString &functionName,
const QString &file, const QString &file,
int line, int line,
@@ -187,26 +192,26 @@ int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
// Find document // Find document
if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1) if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1)
return 1; return 1;
const CPlusPlus::Snapshot::const_iterator docIt = snapshot.find(file); const Snapshot::const_iterator docIt = snapshot.find(file);
if (docIt == snapshot.end()) if (docIt == snapshot.end())
return 2; return 2;
const CPlusPlus::Document::Ptr doc = docIt.value(); const Document::Ptr doc = docIt.value();
// Look at symbol at line and find its function. Either it is the // Look at symbol at line and find its function. Either it is the
// function itself or some expression/variable. // function itself or some expression/variable.
const CPlusPlus::Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0); const Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0);
if (!symbolAtLine) if (!symbolAtLine)
return 4; return 4;
// First figure out the function to do a safety name check // First figure out the function to do a safety name check
// and the innermost scope at cursor position // and the innermost scope at cursor position
const CPlusPlus::Function *function = 0; const Function *function = 0;
const CPlusPlus::Scope *innerMostScope = 0; const Scope *innerMostScope = 0;
if (symbolAtLine->isFunction()) { if (symbolAtLine->isFunction()) {
function = symbolAtLine->asFunction(); function = symbolAtLine->asFunction();
if (function->memberCount() == 1) // Skip over function block if (function->memberCount() == 1) // Skip over function block
if (CPlusPlus::Block *block = function->memberAt(0)->asBlock()) if (Block *block = function->memberAt(0)->asBlock())
innerMostScope = block; innerMostScope = block;
} else { } else {
if (const CPlusPlus::Scope *functionScope = symbolAtLine->enclosingFunction()) { if (const Scope *functionScope = symbolAtLine->enclosingFunction()) {
function = functionScope->asFunction(); function = functionScope->asFunction();
innerMostScope = symbolAtLine->isBlock() ? innerMostScope = symbolAtLine->isBlock() ?
symbolAtLine->asBlock() : symbolAtLine->asBlock() :
@@ -218,7 +223,7 @@ int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
// Compare function names with a bit off fuzz, // Compare function names with a bit off fuzz,
// skipping modules from a CDB symbol "lib!foo" or namespaces // skipping modules from a CDB symbol "lib!foo" or namespaces
// that the code model does not show at this point // that the code model does not show at this point
CPlusPlus::Overview overview; Overview overview;
const QString name = overview.prettyName(function->name()); const QString name = overview.prettyName(function->name());
if (!functionName.endsWith(name)) if (!functionName.endsWith(name))
return 11; return 11;
@@ -233,7 +238,7 @@ int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
return 0; return 0;
} }
bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot, bool getUninitializedVariables(const Snapshot &snapshot,
const QString &function, const QString &function,
const QString &file, const QString &file,
int line, int line,
@@ -253,77 +258,32 @@ bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
return rc == 0; return rc == 0;
} }
//QByteArray gdbQuoteTypes(const QByteArray &type)
//{
// // gdb does not understand sizeof(Core::IDocument*).
// // "sizeof('Core::IDocument*')" is also not acceptable,
// // it needs to be "sizeof('Core::IDocument'*)"
// //
// // We never will have a perfect solution here (even if we had a full blown
// // C++ parser as we do not have information on what is a type and what is
// // a variable name. So "a<b>::c" could either be two comparisons of values
// // 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
// // assume here it is the latter.
// //return type;
// // (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
// // (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
// if (isPointerType(type))
// return gdbQuoteTypes(stripPointerType(type)) + '*';
// QByteArray accu;
// QByteArray result;
// int templateLevel = 0;
// const char colon = ':';
// const char singleQuote = '\'';
// const char lessThan = '<';
// const char greaterThan = '>';
// for (int i = 0; i != type.size(); ++i) {
// const char c = type.at(i);
// if (isLetterOrNumber(c) || c == '_' || c == colon || c == ' ') {
// accu += c;
// } else if (c == lessThan) {
// ++templateLevel;
// accu += c;
// } else if (c == greaterThan) {
// --templateLevel;
// accu += c;
// } else if (templateLevel > 0) {
// accu += c;
// } else {
// if (accu.contains(colon) || accu.contains(lessThan))
// result += singleQuote + accu + singleQuote;
// else
// result += accu;
// accu.clear();
// result += c;
// }
// }
// if (accu.contains(colon) || accu.contains(lessThan))
// result += singleQuote + accu + singleQuote;
// else
// result += accu;
// //qDebug() << "GDB_QUOTING" << type << " TO " << result;
// return result;
//}
// Utilities to decode string data returned by the dumper helpers.
// Editor tooltip support // Editor tooltip support
bool isCppEditor(TextEditor::BaseTextEditorWidget *editorWidget) bool isCppEditor(BaseTextEditorWidget *editorWidget)
{ {
const TextEditor::BaseTextDocument *document = editorWidget->textDocument(); const BaseTextDocument *document = editorWidget->textDocument();
return CppTools::ProjectFile::classify(document->filePath()) != CppTools::ProjectFile::Unclassified; return ProjectFile::classify(document->filePath()) != ProjectFile::Unclassified;
} }
QString cppFunctionAt(const QString &fileName, int line, int column)
{
CppModelManager *modelManager = CppModelManager::instance();
if (!modelManager)
return QString();
const Snapshot snapshot = modelManager->snapshot();
if (const Document::Ptr document = snapshot.document(fileName))
return document->functionAt(line, column);
return QString();
}
// Return the Cpp expression, and, if desired, the function // Return the Cpp expression, and, if desired, the function
QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos, QString cppExpressionAt(BaseTextEditorWidget *editorWidget, int pos,
int *line, int *column, QString *function /* = 0 */) int *line, int *column, QString *function /* = 0 */)
{ {
using namespace CppTools;
*line = *column = 0; *line = *column = 0;
if (function) if (function)
function->clear(); function->clear();
@@ -338,7 +298,7 @@ QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
tc.movePosition(QTextCursor::EndOfWord); tc.movePosition(QTextCursor::EndOfWord);
// Fetch the expression's code. // Fetch the expression's code.
CPlusPlus::ExpressionUnderCursor expressionUnderCursor; ExpressionUnderCursor expressionUnderCursor;
expr = expressionUnderCursor(tc); expr = expressionUnderCursor(tc);
*column = tc.positionInBlock(); *column = tc.positionInBlock();
*line = tc.blockNumber(); *line = tc.blockNumber();
@@ -348,8 +308,7 @@ QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
} }
if (function && !expr.isEmpty()) if (function && !expr.isEmpty())
*function = AbstractEditorSupport::functionAt(modelManager, *function = cppFunctionAt(editorWidget->textDocument()->filePath(), *line, *column);
editorWidget->textDocument()->filePath(), *line, *column);
return expr; return expr;
} }
@@ -379,14 +338,5 @@ QString fixCppExpression(const QString &expIn)
return removeObviousSideEffects(exp); return removeObviousSideEffects(exp);
} }
QString cppFunctionAt(const QString &fileName, int line)
{
using namespace CppTools;
using namespace CPlusPlus;
CppModelManager *modelManager = CppModelManager::instance();
return AbstractEditorSupport::functionAt(modelManager,
fileName, line, 1);
}
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger

View File

@@ -43,7 +43,7 @@ bool isCppEditor(TextEditor::BaseTextEditorWidget *editorWidget);
QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos, QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
int *line, int *column, QString *function = 0); int *line, int *column, QString *function = 0);
QString fixCppExpression(const QString &exp); QString fixCppExpression(const QString &exp);
QString cppFunctionAt(const QString &fileName, int line); QString cppFunctionAt(const QString &fileName, int line, int column = 0);
// Get variables that are not initialized at a certain line // Get variables that are not initialized at a certain line
// of a function from the code model. Shadowed variables will // of a function from the code model. Shadowed variables will