Commit ce7b56f9 authored by dt's avatar dt
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 11124300 a7e120b3
......@@ -51,6 +51,9 @@ qrc_*.cpp
*.Debug
*.Release
# translation related:
share/qtcreator/translations/extract-mimetypes.xq
# Directories to ignore
# ---------------------
......
......@@ -10,7 +10,7 @@ Windows XP SP2, Windows Vista
(K)Ubuntu Linux 5.04, (K)Ubuntu Linux 7.04 32bit and 64bit
Mac OS 10.4 and later
Building the sources requires Qt 4.5.0 or later.
Building the sources requires Qt 4.6.0 or later.
Third-party components
======================
......@@ -23,7 +23,7 @@ we thank the authors who made this possible:
Compiling Qt Creator
====================
You need Qt 4.5 to build Qt Creator.
You need Qt 4.6 to build Qt Creator.
We recommend that you build Qt Creator not in the source directory, but in a separate directory.
To do that, use the following commands:
mkdir $BUILD_DIRECTORY
......
......@@ -19,8 +19,10 @@ unix {
QDOC = SRCDIR=$$PWD OUTDIR=$$OUT_PWD/doc/html $$QDOC_BIN
HELPGENERATOR = $$(QTDIR)/bin/qhelpgenerator
} else {
QDOC = set SRCDIR=$$PWD&& set OUTDIR=$$OUT_PWD/doc/html&& $$QDOC_BIN
HELPGENERATOR = $$(QTDIR)\bin\qhelpgenerator.exe
QDOC = set SRCDIR=$$PWD&& set OUTDIR=$$OUT_PWD/doc/html&& $$QDOC_BIN
# Always run qhelpgenerator inside its own cmd; this is a workaround for
# an unusual bug which causes qhelpgenerator.exe to do nothing
HELPGENERATOR = cmd /C $$(QTDIR)\bin\qhelpgenerator.exe
}
QHP_FILE = $$OUT_PWD/doc/html/qtcreator.qhp
......
......@@ -284,7 +284,7 @@ int main(int argc, char **argv)
}
if (!coreplugin) {
QString nativePaths = QDir::toNativeSeparators(pluginPaths.join(QLatin1String(",")));
const QString reason = QCoreApplication::translate("Application", "Couldn't find 'Core.pluginspec' in %1").arg(nativePaths);
const QString reason = QCoreApplication::translate("Application", "Could not find 'Core.pluginspec' in %1").arg(nativePaths);
displayError(msgCoreLoadFailure(reason));
return 1;
}
......@@ -313,6 +313,17 @@ int main(int argc, char **argv)
displayError(msgCoreLoadFailure(coreplugin->errorString()));
return 1;
}
{
QStringList errors;
foreach (ExtensionSystem::PluginSpec *p, pluginManager.plugins())
if (p->hasError())
errors.append(p->errorString());
if (!errors.isEmpty())
QMessageBox::warning(0,
QCoreApplication::translate("Application", "Qt Creator - Plugin loader messages"),
errors.join(QString::fromLatin1("\n\n")));
}
if (isFirstInstance) {
// Set up lock and remote arguments for the first instance only.
// Silently fallback to unconnected instances for any subsequent
......
......@@ -276,7 +276,12 @@ QList<Scope *> LookupContext::buildVisibleScopes()
QList<Scope *> scopes;
if (_symbol) {
for (Scope *scope = _symbol->scope(); scope; scope = scope->enclosingScope()) {
Scope *scope = _symbol->scope();
if (Function *fun = _symbol->asFunction())
scope = fun->members(); // handle ctor initializers.
for (; scope; scope = scope->enclosingScope()) {
if (scope == _thisDocument->globalSymbols())
break;
......
......@@ -454,7 +454,7 @@ bool PluginManager::runningTests() const
*/
QString PluginManager::testDataDirectory() const
{
QByteArray ba = qgetenv("IDETESTDIR");
QByteArray ba = qgetenv("QTCREATOR_TEST_DIR");
QString s = QString::fromLocal8Bit(ba.constData(), ba.size());
if (s.isEmpty()) {
s = IDE_TEST_DIR;
......
......@@ -787,14 +787,13 @@ bool PluginSpecPrivate::loadLibrary()
PluginLoader loader(libName);
if (!loader.load()) {
hasError = true;
errorString = loader.errorString();
errorString.append(QCoreApplication::translate("PluginSpec", "\nLibrary base name: %1").arg(libName));
errorString = libName + QString::fromLatin1(": ") + loader.errorString();
return false;
}
IPlugin *pluginObject = qobject_cast<IPlugin*>(loader.instance());
if (!pluginObject) {
hasError = true;
errorString = QCoreApplication::translate("PluginSpec", "Plugin is not valid (doesn't derive from IPlugin)");
errorString = QCoreApplication::translate("PluginSpec", "Plugin is not valid (does not derive from IPlugin)");
loader.unload();
return false;
}
......
......@@ -52,7 +52,7 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent,
: QDialog(parent)
{
m_ui.setupUi(this);
QPushButton *discardButton = m_ui.buttonBox->addButton(tr("Don't Save"), QDialogButtonBox::DestructiveRole);
QPushButton *discardButton = m_ui.buttonBox->addButton(tr("Do not Save"), QDialogButtonBox::DestructiveRole);
m_ui.buttonBox->button(QDialogButtonBox::Save)->setDefault(true);
m_ui.buttonBox->button(QDialogButtonBox::Save)->setFocus(Qt::TabFocusReason);
m_ui.buttonBox->button(QDialogButtonBox::Save)->setMinimumWidth(130); // bad magic number to avoid resizing of button
......
......@@ -302,8 +302,8 @@ QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
static QMessageBox::StandardButton skipFailedPrompt(QWidget *parent, const QString &fileName)
{
return QMessageBox::question(parent,
FileManager::tr("Can't save file"),
FileManager::tr("Can't save changes to '%1'. Do you want to continue and loose your changes?").arg(fileName),
FileManager::tr("Cannot save file"),
FileManager::tr("Cannot save changes to '%1'. Do you want to continue and lose your changes?").arg(fileName),
QMessageBox::YesToAll| QMessageBox::Yes|QMessageBox::No,
QMessageBox::No);
}
......
......@@ -880,6 +880,9 @@ void CPPEditor::renameSymbolUnderCursor()
break;
}
}
if (m_renameSelections.isEmpty())
findReferences();
}
void CPPEditor::onContentsChanged(int position, int charsRemoved, int charsAdded)
......
......@@ -220,14 +220,12 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
contextMenu->addAction(cmd);
am->actionContainer(CppTools::Constants::M_TOOLS_CPP)->addAction(cmd);
if (! qgetenv("QTCREATOR_REFERENCES").isEmpty()) {
QAction *findReferencesAction = new QAction(tr("Find References"), this);
cmd = am->registerAction(findReferencesAction,
Constants::FIND_REFERENCES, context);
connect(findReferencesAction, SIGNAL(triggered()), this, SLOT(findReferences()));
contextMenu->addAction(cmd);
am->actionContainer(CppTools::Constants::M_TOOLS_CPP)->addAction(cmd);
}
QAction *findReferencesAction = new QAction(tr("Find References"), this);
cmd = am->registerAction(findReferencesAction,
Constants::FIND_REFERENCES, context);
connect(findReferencesAction, SIGNAL(triggered()), this, SLOT(findReferences()));
contextMenu->addAction(cmd);
am->actionContainer(CppTools::Constants::M_TOOLS_CPP)->addAction(cmd);
m_actionHandler = new TextEditor::TextEditorActionHandler(CppEditor::Constants::C_CPPEDITOR,
TextEditor::TextEditorActionHandler::Format
......
......@@ -817,11 +817,10 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
const Snapshot snapshot = m_manager->snapshot();
if (Document::Ptr thisDocument = snapshot.value(fileName)) {
Symbol *symbol = thisDocument->findSymbolAt(line, column);
Symbol *lastVisibleSymbol = thisDocument->findSymbolAt(line, column);
typeOfExpression.setSnapshot(m_manager->snapshot());
QList<TypeOfExpression::Result> resolvedTypes = typeOfExpression(expression, thisDocument, symbol,
QList<TypeOfExpression::Result> resolvedTypes = typeOfExpression(expression, thisDocument, lastVisibleSymbol,
TypeOfExpression::Preprocess);
LookupContext context = typeOfExpression.lookupContext();
......@@ -847,7 +846,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
m_completionOperator == T_SLOT)) {
// Apply signal/slot completion on 'this'
expression = QLatin1String("this");
resolvedTypes = typeOfExpression(expression, thisDocument, symbol);
resolvedTypes = typeOfExpression(expression, thisDocument, lastVisibleSymbol);
context = typeOfExpression.lookupContext();
}
......@@ -883,7 +882,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
// Resolve the type of this expression
QList<TypeOfExpression::Result> results =
typeOfExpression(baseExpression, thisDocument, symbol, TypeOfExpression::Preprocess);
typeOfExpression(baseExpression, thisDocument, lastVisibleSymbol, TypeOfExpression::Preprocess);
// If it's a class, add completions for the constructors
foreach (const TypeOfExpression::Result &result, results) {
......
......@@ -51,6 +51,7 @@
#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/ResolveExpression.h>
#include <cplusplus/Overview.h>
#include <cplusplus/TypeOfExpression.h>
#include <QtCore/QTime>
#include <QtCore/QtConcurrentRun>
......@@ -130,8 +131,17 @@ protected:
bool checkCandidates(const QList<Symbol *> &candidates) const
{
// ### FIXME return isDeclSymbol(LookupContext::canonicalSymbol(candidates));
return true;
if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates)) {
#if 0
qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName()
<< canonicalSymbol->line() << canonicalSymbol->column()
<< "candidates:" << candidates.size();
#endif
return isDeclSymbol(canonicalSymbol);
}
return false;
}
bool isDeclSymbol(Symbol *symbol) const
......@@ -158,26 +168,163 @@ protected:
return LookupContext(lastVisibleSymbol, _exprDoc, _doc, _snapshot);
}
void ensureNameIsValid(NameAST *ast)
{
if (ast && ! ast->name)
ast->name = _sem.check(ast, /*scope = */ 0);
}
virtual bool visit(MemInitializerAST *ast)
{
if (ast->name && ast->name->asSimpleName() != 0) {
ensureNameIsValid(ast->name);
SimpleNameAST *simple = ast->name->asSimpleName();
if (identifier(simple->identifier_token) == _id) {
LookupContext context = currentContext(ast);
const QList<Symbol *> candidates = context.resolve(simple->name);
if (checkCandidates(candidates))
reportResult(simple->identifier_token);
}
}
accept(ast->expression);
return false;
}
virtual bool visit(PostfixExpressionAST *ast)
{
_postfixExpressionStack.append(ast);
return true;
}
virtual void endVisit(PostfixExpressionAST *)
{
_postfixExpressionStack.removeLast();
}
virtual bool visit(MemberAccessAST *ast)
{
if (ast->member_name) {
if (SimpleNameAST *simple = ast->member_name->asSimpleName()) {
if (identifier(simple->identifier_token) == _id) {
Q_ASSERT(! _postfixExpressionStack.isEmpty());
checkExpression(_postfixExpressionStack.last()->firstToken(),
simple->identifier_token);
return false;
}
}
}
return true;
}
void checkExpression(unsigned startToken, unsigned endToken)
{
const unsigned begin = tokenAt(startToken).begin();
const unsigned end = tokenAt(endToken).end();
const QString expression = _source.mid(begin, end - begin);
// qDebug() << "*** expression:" << expression;
TypeOfExpression typeofExpression;
typeofExpression.setSnapshot(_snapshot);
unsigned line, column;
getTokenStartPosition(startToken, &line, &column);
Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
const QList<TypeOfExpression::Result> results =
typeofExpression(expression, _doc, lastVisibleSymbol,
TypeOfExpression::Preprocess);
QList<Symbol *> candidates;
foreach (TypeOfExpression::Result r, results) {
FullySpecifiedType ty = r.first;
Symbol *lastVisibleSymbol = r.second;
candidates.append(lastVisibleSymbol);
}
if (checkCandidates(candidates))
reportResult(endToken);
}
virtual bool visit(QualifiedNameAST *ast)
{
if (! ast->name) {
//qWarning() << "invalid AST at" << _doc->fileName() << line << column;
ast->name = _sem.check(ast, /*scope */ static_cast<Scope *>(0));
for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier;
nested_name_specifier; nested_name_specifier = nested_name_specifier->next) {
if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
TemplateIdAST *template_id = 0;
if (! simple_name) {
template_id = class_or_namespace_name->asTemplateId();
if (template_id) {
for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
template_arguments; template_arguments = template_arguments->next) {
accept(template_arguments->template_argument);
}
}
}
if (simple_name || template_id) {
const unsigned identifier_token = simple_name
? simple_name->identifier_token
: template_id->identifier_token;
if (identifier(identifier_token) == _id)
checkExpression(ast->firstToken(), identifier_token);
}
}
}
Q_ASSERT(ast->name != 0);
Identifier *id = ast->name->identifier();
if (id == _id && ast->unqualified_name) {
if (ast->unqualified_name) {
SimpleNameAST *simple_name = ast->unqualified_name->asSimpleName();
TemplateIdAST *template_id = 0;
if (! simple_name) {
template_id = ast->unqualified_name->asTemplateId();
if (template_id) {
for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
template_arguments; template_arguments = template_arguments->next) {
accept(template_arguments->template_argument);
}
}
}
if (simple_name || template_id) {
const unsigned identifier_token = simple_name
? simple_name->identifier_token
: template_id->identifier_token;
if (identifier(identifier_token) == _id)
checkExpression(ast->firstToken(), identifier_token);
}
}
return false;
}
virtual bool visit(SimpleNameAST *ast)
{
Identifier *id = identifier(ast->identifier_token);
if (id == _id) {
LookupContext context = currentContext(ast);
const QList<Symbol *> candidates = context.resolve(ast->name);
if (checkCandidates(candidates))
reportResult(ast->unqualified_name->firstToken());
reportResult(ast->identifier_token);
}
return false;
}
virtual bool visit(SimpleNameAST *ast)
virtual bool visit(DestructorNameAST *ast)
{
Identifier *id = identifier(ast->identifier_token);
if (id == _id) {
......@@ -212,6 +359,8 @@ private:
QByteArray _source;
Document::Ptr _exprDoc;
Semantic _sem;
QList<PostfixExpressionAST *> _postfixExpressionStack;
QList<QualifiedNameAST *> _qualifiedNameStack;
};
} // end of anonymous namespace
......@@ -230,6 +379,7 @@ CppFindReferences::~CppFindReferences()
}
static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future,
const QMap<QString, QString> wl,
Snapshot snapshot,
Symbol *symbol)
{
......@@ -239,20 +389,19 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future,
Identifier *symbolId = symbol->identifier();
Q_ASSERT(symbolId != 0);
const QString fileName = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
QStringList files(fileName);
files += snapshot.dependsOn(fileName);
QStringList files(sourceFile);
files += snapshot.dependsOn(sourceFile);
qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size();
future.setProgressRange(0, files.size());
tm.start();
for (int i = 0; i < files.size(); ++i) {
const QString &fn = files.at(i);
future.setProgressValueAndText(i, QFileInfo(fn).fileName());
const QString &fileName = files.at(i);
future.setProgressValueAndText(i, QFileInfo(fileName).fileName());
Document::Ptr previousDoc = snapshot.value(fn);
Document::Ptr previousDoc = snapshot.value(fileName);
if (previousDoc) {
Control *control = previousDoc->control();
Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size());
......@@ -260,13 +409,20 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future,
continue; // skip this document, it's not using symbolId.
}
QFile f(fn);
if (! f.open(QFile::ReadOnly))
continue;
QByteArray source;
const QString source = QTextStream(&f).readAll(); // ### FIXME
const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fn);
Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fn);
if (wl.contains(fileName))
source = snapshot.preprocessedCode(wl.value(fileName), fileName);
else {
QFile file(fileName);
if (! file.open(QFile::ReadOnly))
continue;
const QString contents = QTextStream(&file).readAll(); // ### FIXME
source = snapshot.preprocessedCode(contents, fileName);
}
Document::Ptr doc = snapshot.documentFromSource(source, fileName);
doc->tokenize();
Control *control = doc->control();
......@@ -277,17 +433,21 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future,
process(symbol, id, unit->ast());
}
}
future.setProgressValue(files.size());
}
void CppFindReferences::findAll(const Snapshot &snapshot, Symbol *symbol)
void CppFindReferences::findAll(Symbol *symbol)
{
_resultWindow->clearContents();
_resultWindow->popup(true);
const Snapshot snapshot = _modelManager->snapshot();
const QMap<QString, QString> wl = _modelManager->buildWorkingCopyList();
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
QFuture<Core::Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, snapshot, symbol);
QFuture<Core::Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, wl, snapshot, symbol);
m_watcher.setFuture(result);
Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
......
......@@ -62,7 +62,7 @@ Q_SIGNALS:
void changed();
public:
void findAll(const CPlusPlus::Snapshot &snapshot, CPlusPlus::Symbol *symbol);
void findAll(CPlusPlus::Symbol *symbol);
private Q_SLOTS:
void displayResult(int);
......
......@@ -742,7 +742,7 @@ void CppModelManager::removeEditorSupport(AbstractEditorSupport *editorSupport)
void CppModelManager::findReferences(CPlusPlus::Symbol *symbol)
{
if (symbol->identifier())
m_findReferences->findAll(snapshot(), symbol);
m_findReferences->findAll(symbol);
}
QMap<QString, QString> CppModelManager::buildWorkingCopyList()
......
......@@ -19,7 +19,7 @@ CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
}
exists ($$CDB_PATH) {
message("Experimental: Adding support for $$CDB_PATH")
message("Adding support for $$CDB_PATH")
DEFINES+=CDB_ENABLED
......
......@@ -389,7 +389,7 @@ static inline const char *codeLevelName(ULONG level)
bool CdbDebugEnginePrivate::setCodeLevel()
{
const ULONG codeLevel = theDebuggerBoolSetting(StepByInstruction) ?
const ULONG codeLevel = theDebuggerBoolSetting(OperateByInstruction) ?
DEBUG_LEVEL_ASSEMBLY : DEBUG_LEVEL_SOURCE;
ULONG currentCodeLevel = DEBUG_LEVEL_ASSEMBLY;
HRESULT hr = m_cif.debugControl->GetCodeLevel(&currentCodeLevel);
......@@ -455,9 +455,12 @@ CdbDebugEngine::CdbDebugEngine(DebuggerManager *manager, const QSharedPointer<Cd
m_d(new CdbDebugEnginePrivate(manager, options, this))
{
m_d->m_consoleStubProc.setMode(Core::Utils::ConsoleProcess::Suspend);
connect(&m_d->m_consoleStubProc, SIGNAL(processError(QString)), this, SLOT(slotConsoleStubError(QString)));
connect(&m_d->m_consoleStubProc, SIGNAL(processStarted()), this, SLOT(slotConsoleStubStarted()));
connect(&m_d->m_consoleStubProc, SIGNAL(wrapperStopped()), this, SLOT(slotConsoleStubTerminated()));
connect(&m_d->m_consoleStubProc, SIGNAL(processError(QString)),
this, SLOT(slotConsoleStubError(QString)));
connect(&m_d->m_consoleStubProc, SIGNAL(processStarted()),
this, SLOT(slotConsoleStubStarted()));
connect(&m_d->m_consoleStubProc, SIGNAL(wrapperStopped()),
this, SLOT(slotConsoleStubTerminated()));
connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggerOutput(int,QString)),
manager, SLOT(showDebuggerOutput(int,QString)));
connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggerInputPrompt(int,QString)),
......@@ -1198,8 +1201,8 @@ void CdbDebugEngine::activateFrame(int frameIndex)
QString errorMessage;
bool success = false;
do {
StackHandler *stackHandler = manager()->stackHandler();
StackHandler *stackHandler = manager()->stackHandler();
do {
WatchHandler *watchHandler = manager()->watchHandler();
const int oldIndex = stackHandler->currentIndex();
if (frameIndex >= stackHandler->stackSize()) {
......@@ -1227,10 +1230,15 @@ void CdbDebugEngine::activateFrame(int frameIndex)
if (CdbStackFrameContext *sgc = m_d->getStackFrameContext(frameIndex, &errorMessage))
success = sgc->populateModelInitially(watchHandler, &errorMessage);
watchHandler->endCycle();
} else {
success = true;
}
} while (false);
if (!success)
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
if (!success) {
const QString msg = QString::fromLatin1("Internal error: activateFrame() failed for frame #1 of %2, thread %3: %4").
arg(frameIndex).arg(stackHandler->stackSize()).arg(m_d->m_currentThreadId).arg(errorMessage);
warning(msg);
}
m_d->m_firstActivatedFrame = false;
}
......@@ -1533,6 +1541,28 @@ void CdbDebugEnginePrivate::setDebuggeeHandles(HANDLE hDebuggeeProcess, HANDLE
m_hDebuggeeThread = hDebuggeeThread;
}
// Set thread in CDB engine
bool CdbDebugEnginePrivate::setCDBThreadId(unsigned long threadId, QString *errorMessage)
{
ULONG currentThreadId;
HRESULT hr = m_cif.debugSystemObjects->GetCurrentThreadId(&currentThreadId);
if (FAILED(hr)) {
*errorMessage = msgComFailed("GetCurrentThreadId", hr);
return false;
}
if (currentThreadId == threadId)
return true;
hr =