Commit 1fd12ab6 authored by con's avatar con

Merge remote branch 'origin/2.0'

Conflicts:
	src/plugins/cpptools/cppcodecompletion.cpp
parents 64d65fb6 acea722d
......@@ -37,7 +37,7 @@ leave room for the Qt 4 target page.
<wizard version="1" kind="project"
class="qt4project" firstpage="10"
id="QmlRuntimePlugin" category="F.Projects">
<description>Creates a plug-in for the QML runtime.</description>
<description>Creates a C++ plugin to extend the funtionality of the QML runtime.</description>
<displayname>QML Runtime Plug-in</displayname>
<displaycategory>QML Runtime Plug-in</displaycategory>
<files>
......
......@@ -574,6 +574,17 @@ QString PluginManager::testDataDirectory() const
return s;
}
/*!
\fn void PluginManager::profilingReport(const char *what, const PluginSpec *spec = 0)
Create a profiling entry showing the elapsed time if profiling is activated.
*/
void PluginManager::profilingReport(const char *what, const PluginSpec *spec)
{
d->profilingReport(what, spec);
}
//============PluginManagerPrivate===========
/*!
......@@ -601,6 +612,7 @@ PluginSpecPrivate *PluginManagerPrivate::privateSpec(PluginSpec *spec)
PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager) :
extension(QLatin1String("xml")),
m_profileElapsedMS(0),
m_profilingVerbosity(0),
q(pluginManager)
{
}
......@@ -679,6 +691,13 @@ void PluginManagerPrivate::addObject(QObject *obj)
if (debugLeaks)
qDebug() << "PluginManagerPrivate::addObject" << obj << obj->objectName();
if (m_profilingVerbosity && !m_profileTimer.isNull()) {
// Report a timestamp when adding an object. Useful for profiling
// its initialization time.
const int absoluteElapsedMS = m_profileTimer->elapsed();
qDebug(" %-43s %8dms", obj->metaObject()->className(), absoluteElapsedMS);
}
allObjects.append(obj);
}
emit q->objectAdded(obj);
......@@ -954,6 +973,8 @@ void PluginManagerPrivate::initProfiling()
m_profileTimer->start();
m_profileElapsedMS = 0;
qDebug("Profiling started");
} else {
m_profilingVerbosity++;
}
}
......@@ -966,7 +987,7 @@ void PluginManagerPrivate::profilingReport(const char *what, const PluginSpec *s
if (spec) {
qDebug("%-22s %-22s %8dms (%8dms)", what, qPrintable(spec->name()), absoluteElapsedMS, elapsedMS);
} else {
qDebug("%-22s %8dms (%8dms)", what, absoluteElapsedMS, elapsedMS);
qDebug("%-45s %8dms (%8dms)", what, absoluteElapsedMS, elapsedMS);
}
}
}
......@@ -118,6 +118,8 @@ public:
bool runningTests() const;
QString testDataDirectory() const;
void profilingReport(const char *what, const PluginSpec *spec = 0);
signals:
void objectAdded(QObject *obj);
void aboutToRemoveObject(QObject *obj);
......
......@@ -85,6 +85,7 @@ public:
QStringList arguments;
QScopedPointer<QTime> m_profileTimer;
int m_profileElapsedMS;
unsigned m_profilingVerbosity;
// Look in argument descriptions of the specs for the option.
PluginSpec *pluginForOption(const QString &option, bool *requiresArgument) const;
......
......@@ -106,6 +106,11 @@ Interpreter::ObjectValue *Bind::findFunctionScope(AST::FunctionDeclaration *node
return _functionScopes.value(node);
}
bool Bind::isGroupedPropertyBinding(AST::Node *node) const
{
return _groupedPropertyBindings.contains(node);
}
ObjectValue *Bind::switchObjectValue(ObjectValue *newObjectValue)
{
ObjectValue *oldObjectValue = _currentObjectValue;
......@@ -139,7 +144,6 @@ ExpressionNode *Bind::expression(UiScriptBinding *ast) const
ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitializer *initializer)
{
ObjectValue *parentObjectValue = 0;
const QString typeName = toString(qualifiedTypeNameId);
// normal component instance
ASTObjectValue *objectValue = new ASTObjectValue(qualifiedTypeNameId, initializer, _doc, &_engine);
......@@ -204,8 +208,20 @@ bool Bind::visit(UiPublicMember *)
bool Bind::visit(UiObjectDefinition *ast)
{
ObjectValue *value = bindObject(ast->qualifiedTypeNameId, ast->initializer);
_qmlObjects.insert(ast, value);
// an UiObjectDefinition may be used to group property bindings
// think anchors { ... }
bool isGroupedBinding = false;
for (UiQualifiedId *it = ast->qualifiedTypeNameId; it; it = it->next) {
if (!it->next)
isGroupedBinding = it->name->asString().at(0).isLower();
}
if (!isGroupedBinding) {
ObjectValue *value = bindObject(ast->qualifiedTypeNameId, ast->initializer);
_qmlObjects.insert(ast, value);
} else {
_groupedPropertyBindings.insert(ast);
}
return false;
}
......
......@@ -63,6 +63,7 @@ public:
Interpreter::Context *context) const;
Interpreter::ObjectValue *findFunctionScope(AST::FunctionDeclaration *node) const;
bool isGroupedPropertyBinding(AST::Node *node) const;
static QString toString(AST::UiQualifiedId *qualifiedId, QChar delimiter = QChar('.'));
......@@ -100,6 +101,7 @@ private:
Interpreter::ObjectValue *_rootObjectValue;
QHash<AST::Node *, Interpreter::ObjectValue *> _qmlObjects;
QSet<AST::Node *> _groupedPropertyBindings;
QHash<AST::FunctionDeclaration *, Interpreter::ObjectValue *> _functionScopes;
QStringList _includedScripts;
......
......@@ -1472,6 +1472,8 @@ const Value *Context::lookup(const QString &name)
const ObjectValue *Context::lookupType(const QmlJS::Document *doc, UiQualifiedId *qmlTypeName)
{
const ObjectValue *objectValue = typeEnvironment(doc);
if (!objectValue)
return 0;
for (UiQualifiedId *iter = qmlTypeName; objectValue && iter; iter = iter->next) {
if (! iter->name)
......@@ -1490,6 +1492,8 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, UiQualifiedId
const ObjectValue *Context::lookupType(const QmlJS::Document *doc, const QStringList &qmlTypeName)
{
const ObjectValue *objectValue = typeEnvironment(doc);
if (!objectValue)
return 0;
foreach (const QString &name, qmlTypeName) {
const Value *value = objectValue->property(name, this);
......
......@@ -66,10 +66,24 @@ void ScopeBuilder::setQmlScopeObject(Node *node)
{
ScopeChain &scopeChain = _context->scopeChain();
scopeChain.qmlScopeObjects.clear();
if (_doc->bind()->isGroupedPropertyBinding(node)) {
UiObjectDefinition *definition = cast<UiObjectDefinition *>(node);
if (!definition)
return;
const Value *v = scopeObjectLookup(definition->qualifiedTypeNameId);
if (!v)
return;
const ObjectValue *object = v->asObjectValue();
if (!object)
return;
scopeChain.qmlScopeObjects.clear();
scopeChain.qmlScopeObjects += object;
}
const ObjectValue *scopeObject = _doc->bind()->findQmlObject(node);
if (scopeObject) {
scopeChain.qmlScopeObjects.clear();
scopeChain.qmlScopeObjects += scopeObject;
} else {
return; // Probably syntax errors, where we're working with a "recovered" AST.
......@@ -130,3 +144,28 @@ void ScopeBuilder::setQmlScopeObject(Node *node)
}
}
}
const Value *ScopeBuilder::scopeObjectLookup(AST::UiQualifiedId *id)
{
// do a name lookup on the scope objects
const Value *result = 0;
foreach (const ObjectValue *scopeObject, _context->scopeChain().qmlScopeObjects) {
const ObjectValue *object = scopeObject;
for (UiQualifiedId *it = id; it; it = it->next) {
result = object->property(it->name->asString(), _context);
if (!result)
break;
if (it->next) {
object = result->asObjectValue();
if (!object) {
result = 0;
break;
}
}
}
if (result)
break;
}
return result;
}
......@@ -13,6 +13,7 @@ namespace AST {
namespace Interpreter {
class Context;
class Value;
}
class QMLJS_EXPORT ScopeBuilder
......@@ -27,6 +28,7 @@ public:
private:
void setQmlScopeObject(AST::Node *node);
const Interpreter::Value *scopeObjectLookup(AST::UiQualifiedId *id);
Document::Ptr _doc;
Interpreter::Context *_context;
......
......@@ -50,6 +50,12 @@ const char * const IDE_VERSION_LONG = IDE_VERSION;
const char * const IDE_AUTHOR = "Nokia Corporation";
const char * const IDE_YEAR = "2010";
#ifdef IDE_VERSION_DESCRIPTION
const char * const IDE_VERSION_DESCRIPTION_STR = STRINGIFY(IDE_VERSION_DESCRIPTION);
#else
const char * const IDE_VERSION_DESCRIPTION_STR = "";
#endif
#ifdef IDE_REVISION
const char * const IDE_REVISION_STR = STRINGIFY(IDE_REVISION);
#else
......
......@@ -61,7 +61,11 @@ VersionDialog::VersionDialog(QWidget *parent)
layout->setSizeConstraint(QLayout::SetFixedSize);
QString version = QLatin1String(IDE_VERSION_LONG);
version += QDate(2007, 25, 10).toString(Qt::SystemLocaleDate);
QString ideVersionDescription;
#ifdef IDE_VERSION_DESCRIPTION
ideVersionDescription = tr("(%1)").arg(QLatin1String(IDE_VERSION_DESCRIPTION_STR));
#endif
QString ideRev;
#ifdef IDE_REVISION
......@@ -70,21 +74,23 @@ VersionDialog::VersionDialog(QWidget *parent)
#endif
const QString description = tr(
"<h3>Qt Creator %1</h3>"
"<h3>Qt Creator %1 %8</h3>"
"Based on Qt %2 (%3 bit)<br/>"
"<br/>"
"Built on %4 at %5<br />"
"<br/>"
"%8"
"%9"
"<br/>"
"Copyright 2008-%6 %7. All rights reserved.<br/>"
"<br/>"
"The program is provided AS IS with NO WARRANTY OF ANY KIND, "
"INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A "
"PARTICULAR PURPOSE.<br/>")
.arg(version, QLatin1String(QT_VERSION_STR), QString::number(QSysInfo::WordSize),
.arg(version,
QLatin1String(QT_VERSION_STR), QString::number(QSysInfo::WordSize),
QLatin1String(__DATE__), QLatin1String(__TIME__), QLatin1String(IDE_YEAR),
(QLatin1String(IDE_AUTHOR)), ideRev);
(QLatin1String(IDE_AUTHOR)), ideVersionDescription,
ideRev);
QLabel *copyRightLabel = new QLabel(description);
copyRightLabel->setWordWrap(true);
......
......@@ -215,16 +215,16 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
wizardParameters.setDisplayName(tr("C++ Class"));
wizardParameters.setId(QLatin1String("A.Class"));
wizardParameters.setKind(Core::IWizard::ClassWizard);
wizardParameters.setDescription(tr("Creates a header and a source file for a new class."));
wizardParameters.setDescription(tr("Creates a C++ header and a source file for a new class that you can add to a C++ project."));
addAutoReleasedObject(new CppClassWizard(wizardParameters, core));
wizardParameters.setKind(Core::IWizard::FileWizard);
wizardParameters.setDescription(tr("Creates a C++ source file."));
wizardParameters.setDescription(tr("Creates a C++ source file that you can add to a C++ project."));
wizardParameters.setDisplayName(tr("C++ Source File"));
wizardParameters.setId(QLatin1String("B.Source"));
addAutoReleasedObject(new CppFileWizard(wizardParameters, Source, core));
wizardParameters.setDescription(tr("Creates a C++ header file."));
wizardParameters.setDescription(tr("Creates a C++ header file that you can add to a C++ project."));
wizardParameters.setDisplayName(tr("C++ Header File"));
wizardParameters.setId(QLatin1String("C.Header"));
addAutoReleasedObject(new CppFileWizard(wizardParameters, Header, core));
......
......@@ -32,15 +32,15 @@
#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/texteditorsettings.h>
#include <QtCore/QTextStream>
#include <QtCore/QCoreApplication>
using namespace CppTools::Internal;
CompletionSettingsPage::CompletionSettingsPage(CppCodeCompletion *completion)
: m_completion(completion)
, m_page(new Ui_CompletionSettingsPage)
CompletionSettingsPage::CompletionSettingsPage()
: m_page(new Ui_CompletionSettingsPage)
{
}
......@@ -64,23 +64,27 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
QWidget *w = new QWidget(parent);
m_page->setupUi(w);
const TextEditor::CompletionSettings &settings =
TextEditor::TextEditorSettings::instance()->completionSettings();
int caseSensitivityIndex = 0;
switch (m_completion->caseSensitivity()) {
case CppCodeCompletion::CaseSensitive:
switch (settings.m_caseSensitivity) {
case TextEditor::CaseSensitive:
caseSensitivityIndex = 0;
break;
case CppCodeCompletion::CaseInsensitive:
case TextEditor::CaseInsensitive:
caseSensitivityIndex = 1;
break;
case CppCodeCompletion::FirstLetterCaseSensitive:
case TextEditor::FirstLetterCaseSensitive:
caseSensitivityIndex = 2;
break;
}
m_page->caseSensitivity->setCurrentIndex(caseSensitivityIndex);
m_page->autoInsertBrackets->setChecked(m_completion->autoInsertBrackets());
m_page->partiallyComplete->setChecked(m_completion->isPartialCompletionEnabled());
m_page->spaceAfterFunctionName->setChecked(m_completion->isSpaceAfterFunctionName());
m_page->autoInsertBrackets->setChecked(settings.m_autoInsertBrackets);
m_page->partiallyComplete->setChecked(settings.m_partiallyComplete);
m_page->spaceAfterFunctionName->setChecked(settings.m_spaceAfterFunctionName);
if (m_searchKeywords.isEmpty()) {
QTextStream(&m_searchKeywords) << m_page->caseSensitivityLabel->text()
<< ' ' << m_page->autoInsertBrackets->text()
......@@ -88,15 +92,19 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
<< ' ' << m_page->spaceAfterFunctionName->text();
m_searchKeywords.remove(QLatin1Char('&'));
}
return w;
}
void CompletionSettingsPage::apply()
{
m_completion->setCaseSensitivity(caseSensitivity());
m_completion->setAutoInsertBrackets(m_page->autoInsertBrackets->isChecked());
m_completion->setPartialCompletionEnabled(m_page->partiallyComplete->isChecked());
m_completion->setSpaceAfterFunctionName(m_page->spaceAfterFunctionName->isChecked());
TextEditor::CompletionSettings settings;
settings.m_caseSensitivity = caseSensitivity();
settings.m_autoInsertBrackets = m_page->autoInsertBrackets->isChecked();
settings.m_partiallyComplete = m_page->partiallyComplete->isChecked();
settings.m_spaceAfterFunctionName = m_page->spaceAfterFunctionName->isChecked();
TextEditor::TextEditorSettings::instance()->setCompletionSettings(settings);
}
bool CompletionSettingsPage::matches(const QString &s) const
......@@ -104,14 +112,14 @@ bool CompletionSettingsPage::matches(const QString &s) const
return m_searchKeywords.contains(s, Qt::CaseInsensitive);
}
CppCodeCompletion::CaseSensitivity CompletionSettingsPage::caseSensitivity() const
TextEditor::CaseSensitivity CompletionSettingsPage::caseSensitivity() const
{
switch (m_page->caseSensitivity->currentIndex()) {
case 0: // Full
return CppCodeCompletion::CaseSensitive;
return TextEditor::CaseSensitive;
case 1: // None
return CppCodeCompletion::CaseInsensitive;
return TextEditor::CaseInsensitive;
default: // First letter
return CppCodeCompletion::FirstLetterCaseSensitive;
return TextEditor::FirstLetterCaseSensitive;
}
}
......@@ -30,10 +30,9 @@
#ifndef COMPLETIONSETTINGSPAGE_H
#define COMPLETIONSETTINGSPAGE_H
#include <texteditor/completionsettings.h>
#include <texteditor/texteditoroptionspage.h>
#include "cppcodecompletion.h"
QT_BEGIN_NAMESPACE
class Ui_CompletionSettingsPage;
QT_END_NAMESPACE
......@@ -41,12 +40,14 @@ QT_END_NAMESPACE
namespace CppTools {
namespace Internal {
// TODO: Move this class to the text editor plugin
class CompletionSettingsPage : public TextEditor::TextEditorOptionsPage
{
Q_OBJECT
public:
CompletionSettingsPage(CppCodeCompletion *completion);
CompletionSettingsPage();
~CompletionSettingsPage();
QString id() const;
......@@ -58,9 +59,8 @@ public:
virtual bool matches(const QString &) const;
private:
CppCodeCompletion::CaseSensitivity caseSensitivity() const;
TextEditor::CaseSensitivity caseSensitivity() const;
CppCodeCompletion *m_completion;
Ui_CompletionSettingsPage *m_page;
QString m_searchKeywords;
};
......
......@@ -57,6 +57,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/completionsettings.h>
#include <texteditor/itexteditor.h>
#include <texteditor/itexteditable.h>
#include <texteditor/basetexteditor.h>
......@@ -436,10 +437,6 @@ CppCodeCompletion::CppCodeCompletion(CppModelManager *manager)
m_manager(manager),
m_editor(0),
m_startPosition(-1),
m_caseSensitivity(FirstLetterCaseSensitive),
m_autoInsertBrackets(true),
m_partialCompletionEnabled(true),
m_spaceAfterFunctionName(false),
m_forcedCompletion(false),
m_completionOperator(T_EOF_SYMBOL),
m_objcEnabled(true)
......@@ -451,46 +448,6 @@ QIcon CppCodeCompletion::iconForSymbol(Symbol *symbol) const
return m_icons.iconForSymbol(symbol);
}
CppCodeCompletion::CaseSensitivity CppCodeCompletion::caseSensitivity() const
{
return m_caseSensitivity;
}
void CppCodeCompletion::setCaseSensitivity(CaseSensitivity caseSensitivity)
{
m_caseSensitivity = caseSensitivity;
}
bool CppCodeCompletion::autoInsertBrackets() const
{
return m_autoInsertBrackets;
}
void CppCodeCompletion::setAutoInsertBrackets(bool autoInsertBrackets)
{
m_autoInsertBrackets = autoInsertBrackets;
}
bool CppCodeCompletion::isPartialCompletionEnabled() const
{
return m_partialCompletionEnabled;
}
void CppCodeCompletion::setPartialCompletionEnabled(bool partialCompletionEnabled)
{
m_partialCompletionEnabled = partialCompletionEnabled;
}
bool CppCodeCompletion::isSpaceAfterFunctionName() const
{
return m_spaceAfterFunctionName;
}
void CppCodeCompletion::setSpaceAfterFunctionName(bool spaceAfterFunctionName)
{
m_spaceAfterFunctionName = spaceAfterFunctionName;
}
/*
Searches backwards for an access operator.
*/
......@@ -1512,7 +1469,7 @@ void CppCodeCompletion::completions(QList<TextEditor::CompletionItem> *completio
return;
if (m_completionOperator != T_LPAREN) {
filter(m_completions, completions, key, m_caseSensitivity);
filter(m_completions, completions, key);
} else if (m_completionOperator == T_LPAREN ||
m_completionOperator == T_SIGNAL ||
......@@ -1590,7 +1547,9 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
//qDebug() << "current symbol:" << overview.prettyName(symbol->name())
//<< overview.prettyType(symbol->type());
if (m_autoInsertBrackets && symbol && symbol->type()) {
const bool autoInsertBrackets = completionSettings().m_autoInsertBrackets;
if (autoInsertBrackets && symbol && symbol->type()) {
if (Function *function = symbol->type()->asFunctionType()) {
// If the member is a function, automatically place the opening parenthesis,
// except when it might take template parameters.
......@@ -1603,8 +1562,8 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
extraChars += QLatin1Char('<');
}
} else if (! function->isAmbiguous()) {
if (m_spaceAfterFunctionName)
extraChars += QLatin1Char(' ');
if (completionSettings().m_spaceAfterFunctionName)
extraChars += QLatin1Char(' ');
extraChars += QLatin1Char('(');
// If the function doesn't return anything, automatically place the semicolon,
......@@ -1631,7 +1590,7 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
}
}
if (m_autoInsertBrackets && item.data.canConvert<CompleteFunctionDeclaration>()) {
if (autoInsertBrackets && item.data.canConvert<CompleteFunctionDeclaration>()) {
// everything from the closing parenthesis on are extra chars, to
// make sure an auto-inserted ")" gets replaced by ") const" if necessary
int closingParen = toInsert.lastIndexOf(QLatin1Char(')'));
......@@ -1667,7 +1626,7 @@ bool CppCodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem
} else if (completionItems.count() == 1) {
complete(completionItems.first());
return true;
} else if (m_partialCompletionEnabled && m_completionOperator != T_LPAREN) {
} else if (m_completionOperator != T_LPAREN) {
return TextEditor::ICompletionCollector::partiallyComplete(completionItems);
}
......
......@@ -86,18 +86,6 @@ public:
QIcon iconForSymbol(CPlusPlus::Symbol *symbol) const;
CaseSensitivity caseSensitivity() const;
void setCaseSensitivity(CaseSensitivity caseSensitivity);
bool autoInsertBrackets() const;
void setAutoInsertBrackets(bool autoInsertBrackets);
bool isPartialCompletionEnabled() const;
void setPartialCompletionEnabled(bool partialCompletionEnabled);
bool isSpaceAfterFunctionName() const;
void setSpaceAfterFunctionName(bool spaceAfterFunctionName);
private:
void addKeywords();
void addMacros(const QString &fileName, const CPlusPlus::Snapshot &snapshot);
......@@ -159,10 +147,6 @@ private:
TextEditor::ITextEditable *m_editor;
int m_startPosition; // Position of the cursor from which completion started
CaseSensitivity m_caseSensitivity;
bool m_autoInsertBrackets;
bool m_partialCompletionEnabled;
bool m_spaceAfterFunctionName;
bool m_forcedCompletion;
unsigned m_completionOperator;
bool m_objcEnabled;
......
......@@ -51,6 +51,7 @@
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/filemanager.h>
#include <texteditor/texteditorsettings.h>
#include <cppeditor/cppeditorconstants.h>
#include <QtCore/QtConcurrentRun>
......@@ -109,8 +110,8 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
m_modelManager, SLOT(updateSourceFiles(QStringList)));
addAutoReleasedObject(m_modelManager);
m_completion = new CppCodeCompletion(m_modelManager);
addAutoReleasedObject(m_completion);
CppCodeCompletion *completion = new CppCodeCompletion(m_modelManager);
addAutoReleasedObject(completion);
CppLocatorFilter *locatorFilter = new CppLocatorFilter(m_modelManager,
core->editorManager());
......@@ -118,7 +119,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
addAutoReleasedObject(new CppClassesFilter(m_modelManager, core->editorManager()));
addAutoReleasedObject(new CppFunctionsFilter(m_modelManager, core->editorManager()));
addAutoReleasedObject(new CppCurrentDocumentFilter(m_modelManager, core->editorManager()));