forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/11.0'
Change-Id: I8be5a00000a6699346ed1c44c0711d1f017462a7
This commit is contained in:
@@ -70,4 +70,9 @@ macro.see = "\\sa"
|
|||||||
macro.function = "\\fn"
|
macro.function = "\\fn"
|
||||||
|
|
||||||
navigation.landingpage = "$IDE_DISPLAY_NAME Manual"
|
navigation.landingpage = "$IDE_DISPLAY_NAME Manual"
|
||||||
|
|
||||||
|
# Auto-generate navigation linking based on "All Topics":
|
||||||
|
navigation.toctitles = "All Topics"
|
||||||
|
navigation.toctitles.inclusive = false
|
||||||
|
|
||||||
buildversion = "$IDE_DISPLAY_NAME Manual $QTC_VERSION"
|
buildversion = "$IDE_DISPLAY_NAME Manual $QTC_VERSION"
|
||||||
|
|||||||
@@ -2003,10 +2003,20 @@ bool Check::visit(TypeOfExpression *ast)
|
|||||||
/// ### Maybe put this into the context as a helper function.
|
/// ### Maybe put this into the context as a helper function.
|
||||||
const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!_importsOk)
|
if (!_importsOk)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (!id)
|
||||||
|
return nullptr; // ### error?
|
||||||
|
|
||||||
|
if (id->name.isEmpty()) // possible after error recovery
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
QString propertyName = id->name.toString();
|
||||||
|
|
||||||
|
if (propertyName == "id" && !id->next)
|
||||||
|
return nullptr; // ### should probably be a special value
|
||||||
|
|
||||||
QList<const ObjectValue *> scopeObjects = _scopeChain.qmlScopeObjects();
|
QList<const ObjectValue *> scopeObjects = _scopeChain.qmlScopeObjects();
|
||||||
if (scopeObjects.isEmpty())
|
if (scopeObjects.isEmpty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -2021,24 +2031,9 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
|||||||
return isAttachedProperty;
|
return isAttachedProperty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (! id)
|
|
||||||
return nullptr; // ### error?
|
|
||||||
|
|
||||||
if (id->name.isEmpty()) // possible after error recovery
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
QString propertyName = id->name.toString();
|
|
||||||
|
|
||||||
if (propertyName == "id" && !id->next)
|
|
||||||
return nullptr; // ### should probably be a special value
|
|
||||||
|
|
||||||
// attached properties
|
// attached properties
|
||||||
bool isAttachedProperty = getAttachedTypes(propertyName);
|
bool isAttachedProperty = getAttachedTypes(propertyName);
|
||||||
|
|
||||||
if (scopeObjects.isEmpty())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// global lookup for first part of id
|
// global lookup for first part of id
|
||||||
const Value *value = nullptr;
|
const Value *value = nullptr;
|
||||||
for (int i = scopeObjects.size() - 1; i >= 0; --i) {
|
for (int i = scopeObjects.size() - 1; i >= 0; --i) {
|
||||||
@@ -2053,6 +2048,13 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
// We omit M16 messages if the type using ImmediateProperties
|
||||||
|
// Ideally, we should obtain them through metaobject information
|
||||||
|
const bool omitMessage = !m_typeStack.isEmpty()
|
||||||
|
&& ((m_typeStack.last() == "PropertyChanges")
|
||||||
|
|| m_typeStack.last() == "Binding")
|
||||||
|
&& !m_idStack.isEmpty() && m_idStack.last().contains(propertyName);
|
||||||
|
if (!omitMessage)
|
||||||
addMessage(ErrInvalidPropertyName, id->identifierToken, propertyName);
|
addMessage(ErrInvalidPropertyName, id->identifierToken, propertyName);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public:
|
|||||||
"is not reachable in the running tree. "
|
"is not reachable in the running tree. "
|
||||||
"It is possible that no barrier was added to the tree, "
|
"It is possible that no barrier was added to the tree, "
|
||||||
"or the storage is not reachable from where it is referenced. "
|
"or the storage is not reachable from where it is referenced. "
|
||||||
"The WaitForBarrier task will finish with error. ");
|
"The WaitForBarrier task finishes with an error. ");
|
||||||
return SetupResult::StopWithError;
|
return SetupResult::StopWithError;
|
||||||
}
|
}
|
||||||
Barrier *activeSharedBarrier = activeBarrier->barrier();
|
Barrier *activeSharedBarrier = activeBarrier->barrier();
|
||||||
|
|||||||
@@ -138,6 +138,369 @@ private:
|
|||||||
Returns the const pointer to the associated \c Task instance.
|
Returns the const pointer to the associated \c Task instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class Tasking::GroupItem
|
||||||
|
\inheaderfile solutions/tasking/tasktree.h
|
||||||
|
\inmodule TaskingSolution
|
||||||
|
\brief GroupItem represents the basic element that may be a part of any
|
||||||
|
\l {Tasking::Group} {Group}.
|
||||||
|
|
||||||
|
GroupItem is a basic element that may be a part of any \l {Tasking::Group} {Group}.
|
||||||
|
It encapsulates the functionality provided by any GroupItem's subclass.
|
||||||
|
It is a value type and it is safe to copy the GroupItem instance,
|
||||||
|
even when it is originally created via the subclass' constructor.
|
||||||
|
|
||||||
|
There are four main kinds of GroupItem:
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li GroupItem Kind
|
||||||
|
\li Brief Description
|
||||||
|
\row
|
||||||
|
\li \l CustomTask
|
||||||
|
\li Defines asynchronous task type and task's start, done, and error handlers.
|
||||||
|
Aliased with a unique task name, such as, \c ConcurrentCallTask<ResultType>
|
||||||
|
or \l NetworkQueryTask. Asynchronous tasks are the main reason for using a task tree.
|
||||||
|
\row
|
||||||
|
\li \l Group
|
||||||
|
\li A container for other group items. Since the group is of the GroupItem type,
|
||||||
|
it's possible to nest it inside another group. The group is seen by its parent
|
||||||
|
as a single asynchronous task.
|
||||||
|
\row
|
||||||
|
\li \l Storage
|
||||||
|
\li Enables the child tasks of a group to exchange data.
|
||||||
|
When Storage is placed inside a group, the task tree instantiates
|
||||||
|
the storage object just before the group is entered,
|
||||||
|
and destroys it just after the group is finished.
|
||||||
|
\row
|
||||||
|
\li Other group control items
|
||||||
|
\li The items returned by \l {Tasking::parallelLimit()} {parallelLimit()} or
|
||||||
|
\l {Tasking::workflowPolicy()} {workflowPolicy()} influence the group's behavior.
|
||||||
|
The items returned by \l {Tasking::onGroupSetup()} {onGroupSetup()},
|
||||||
|
\l {Tasking::onGroupDone()} {onGroupDone()} or
|
||||||
|
\l {Tasking::onGroupError()} {onGroupError()} define custom handlers called when
|
||||||
|
the group starts or ends execution.
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class Tasking::Group
|
||||||
|
\inheaderfile solutions/tasking/tasktree.h
|
||||||
|
\inmodule TaskingSolution
|
||||||
|
\brief Group represents the basic element for composing declarative recipes describing
|
||||||
|
how to execute and handle a nested tree of asynchronous tasks.
|
||||||
|
|
||||||
|
Group is a container for other group items. It encloses child tasks into one unit,
|
||||||
|
which is seen by the group's parent as a single, asynchronous task.
|
||||||
|
Since Group is of the GroupItem type, it may also be a child of Group.
|
||||||
|
|
||||||
|
Insert child tasks into the group by using aliased custom task names, such as,
|
||||||
|
\c ConcurrentCallTask<ResultType> or \c NetworkQueryTask:
|
||||||
|
|
||||||
|
\code
|
||||||
|
const Group group {
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
ConcurrentCallTask<int>(...)
|
||||||
|
};
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
The group's behavior may be customized by inserting the items returned by
|
||||||
|
\l {Tasking::parallelLimit()} {parallelLimit()} or
|
||||||
|
\l {Tasking::workflowPolicy()} {workflowPolicy()} functions:
|
||||||
|
|
||||||
|
\code
|
||||||
|
const Group group {
|
||||||
|
parallel,
|
||||||
|
continueOnError,
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
NetworkQueryTask(...)
|
||||||
|
};
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
The group may contain nested groups:
|
||||||
|
|
||||||
|
\code
|
||||||
|
const Group group {
|
||||||
|
finishAllAndDone,
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
Group {
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
Group {
|
||||||
|
parallel,
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
}
|
||||||
|
ConcurrentCallTask<QString>(...)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
The group may dynamically instantiate a custom storage structure, which may be used for
|
||||||
|
inter-task data exchange:
|
||||||
|
|
||||||
|
\code
|
||||||
|
struct MyCustomStruct { QByteArray data; };
|
||||||
|
|
||||||
|
TreeStorage<MyCustomStruct> storage;
|
||||||
|
|
||||||
|
const auto onFirstSetup = [](NetworkQuery &task) { ... };
|
||||||
|
const auto onFirstDone = [storage](const NetworkQuery &task) {
|
||||||
|
// storage-> gives a pointer to MyCustomStruct instance,
|
||||||
|
// created dynamically by the running task tree.
|
||||||
|
storage->data = task.reply()->readAll();
|
||||||
|
};
|
||||||
|
const auto onSecondSetup = [storage](ConcurrentCall<QImage> &task) {
|
||||||
|
// storage-> gives a pointer to MyCustomStruct. Since the group is sequential,
|
||||||
|
// the stored MyCustomStruct was already updated inside the onFirstDone handler.
|
||||||
|
const QByteArray storedData = storage->data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Group group {
|
||||||
|
// When the group is entered by a running task tree, it creates MyCustomStruct
|
||||||
|
// instance dynamically. It is later accessible from all handlers via
|
||||||
|
// the *storage or storage-> operators.
|
||||||
|
sequential,
|
||||||
|
Storage(storage),
|
||||||
|
NetworkQueryTask(onFirstSetup, onFirstDone),
|
||||||
|
ConcurrentCallTask<QImage>(onSecondSetup)
|
||||||
|
};
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn Group::Group(const QList<GroupItem> &children)
|
||||||
|
|
||||||
|
Constructs a group with a given list of \a children.
|
||||||
|
|
||||||
|
This constructor is useful when the child items of the group are not known at compile time,
|
||||||
|
but later, at runtime:
|
||||||
|
|
||||||
|
\code
|
||||||
|
const QStringList sourceList = ...;
|
||||||
|
|
||||||
|
QList<GroupItem> groupItems { parallel };
|
||||||
|
|
||||||
|
for (const QString &source : sourceList) {
|
||||||
|
const NetworkQueryTask task(...); // use source for setup handler
|
||||||
|
groupItems << task;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Group group(groupItems);
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn Group::Group(std::initializer_list<GroupItem> children)
|
||||||
|
|
||||||
|
Constructs a group from std::initializer_list given by \a children.
|
||||||
|
|
||||||
|
This constructor is useful when all child items of the group are known at compile time:
|
||||||
|
|
||||||
|
\code
|
||||||
|
const Group group {
|
||||||
|
finishAllAndDone,
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
Group {
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
Group {
|
||||||
|
parallel,
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
NetworkQueryTask(...),
|
||||||
|
}
|
||||||
|
ConcurrentCallTask<QString>(...)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn GroupItem Group::withTimeout(std::chrono::milliseconds timeout, const GroupEndHandler &handler) const
|
||||||
|
|
||||||
|
Attaches \c TimeoutTask to a copy of \c this group, elapsing after \a timeout in milliseconds,
|
||||||
|
with an optionally provided timeout \a handler, and returns the coupled item.
|
||||||
|
|
||||||
|
When the group finishes before \a timeout passes,
|
||||||
|
the returned item finishes immediately with the group's result.
|
||||||
|
Otherwise, the \a handler is invoked (if provided), the group is stopped,
|
||||||
|
and the returned item finishes with an error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class Tasking::CustomTask
|
||||||
|
\inheaderfile solutions/tasking/tasktree.h
|
||||||
|
\inmodule TaskingSolution
|
||||||
|
\brief A class template used for declaring task items and defining their setup,
|
||||||
|
done, and error handlers.
|
||||||
|
|
||||||
|
The CustomTask class template is used inside TaskTree for describing custom task items.
|
||||||
|
|
||||||
|
Custom task names are aliased with unique names inside the \l Tasking namespace
|
||||||
|
via the TASKING_DECLARE_TASK or TASKING_DECLARE_TEMPLATE_TASK macros.
|
||||||
|
For example, \c ConcurrentCallTask<T> is an alias to the CustomTask that is defined
|
||||||
|
to work with \c ConcurrentCall<T> as an associated task class.
|
||||||
|
The following table contains all the built-in tasks and their associated task classes:
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Aliased Task Name (Tasking Namespace)
|
||||||
|
\li Associated Task Class
|
||||||
|
\li Brief Description
|
||||||
|
\row
|
||||||
|
\li ConcurrentCallTask<ReturnType>
|
||||||
|
\li ConcurrentCall<ReturnType>
|
||||||
|
\li Starts an asynchronous task. Runs in a separate thread.
|
||||||
|
\row
|
||||||
|
\li NetworkQueryTask
|
||||||
|
\li NetworkQuery
|
||||||
|
\li Sends a network query.
|
||||||
|
\row
|
||||||
|
\li TaskTreeTask
|
||||||
|
\li TaskTree
|
||||||
|
\li Starts a nested task tree.
|
||||||
|
\row
|
||||||
|
\li TimeoutTask
|
||||||
|
\li \c std::chrono::milliseconds
|
||||||
|
\li Starts a timer.
|
||||||
|
\row
|
||||||
|
\li WaitForBarrierTask
|
||||||
|
\li MultiBarrier<Limit>
|
||||||
|
\li Starts an asynchronous task waiting for the barrier to pass.
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\typealias CustomTask::Task
|
||||||
|
|
||||||
|
Type alias for \c Adapter::Type.
|
||||||
|
|
||||||
|
This is the associated task's type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\typealias CustomTask::EndHandler
|
||||||
|
|
||||||
|
Type alias for \c std::function<void(const Task &)>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <typename Adapter> template <typename SetupHandler> CustomTask<Adapter>::CustomTask<Adapter>(SetupHandler &&setup, const EndHandler &done, const EndHandler &error)
|
||||||
|
|
||||||
|
Constructs the CustomTask instance and attaches the \a setup, \a done, and \a error
|
||||||
|
handlers to the task. When the running task tree is about to start the task,
|
||||||
|
it instantiates the associated \l Task object, invokes \a setup handler with a \e reference
|
||||||
|
to the created task, and starts it. When the running task finishes with success or an error,
|
||||||
|
the task tree invokes \a done or \a error handler, respectively,
|
||||||
|
with a \e {const reference} to the created task.
|
||||||
|
|
||||||
|
The passed \a setup handler is either of the \c std::function<SetupResult(Task &)> or
|
||||||
|
\c std::function<void(Task &)> type. For example:
|
||||||
|
|
||||||
|
\code
|
||||||
|
static void parseAndLog(const QString &input);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
const QString input = ...;
|
||||||
|
|
||||||
|
const auto onFirstSetup = [input](ConcurrentCall<void> &task) {
|
||||||
|
if (input == "Skip")
|
||||||
|
return SetupResult::StopWithDone; // This task won't start, the next one will
|
||||||
|
if (input == "Error")
|
||||||
|
return SetupResult::StopWithError; // This task and the next one won't start
|
||||||
|
task.setConcurrentCallData(parseAndLog, input);
|
||||||
|
// This task will start, and the next one will start after this one finished with success
|
||||||
|
return SetupResult::Continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto onSecondSetup = [input](ConcurrentCall<void> &task) {
|
||||||
|
task.setConcurrentCallData(parseAndLog, input);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Group group {
|
||||||
|
ConcurrentCallTask<void>(onFirstSetup),
|
||||||
|
ConcurrentCallTask<void>(onSecondSetup)
|
||||||
|
};
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
When the passed \a setup handler is of the \c std::function<SetupResult(Task &)> type,
|
||||||
|
the return value of the handler instructs the running tree on how to proceed after
|
||||||
|
the handler's invocation is finished. The default return value of SetupResult::Continue
|
||||||
|
instructs the tree to continue running, i.e. to execute the associated \c Task.
|
||||||
|
The return value of SetupResult::StopWithDone or SetupResult::StopWithError instructs
|
||||||
|
the tree to skip the task's execution and finish immediately with success or an error,
|
||||||
|
respectively.
|
||||||
|
When the return type is either SetupResult::StopWithDone or SetupResult::StopWithError,
|
||||||
|
the task's \a done or \a error handler (even if provided) are not called afterwards.
|
||||||
|
|
||||||
|
The \a setup handler may be of a shortened form of std::function<void(Task &)>,
|
||||||
|
i.e. the return value is void. In this case it's assumed that the return value is
|
||||||
|
SetupResult::Continue by default.
|
||||||
|
|
||||||
|
When the running task finishes, one of \a done or \a error handlers is called,
|
||||||
|
depending on whether it finished with success or an error, respectively.
|
||||||
|
Both handlers are of std::function<void(const Task &)> type.
|
||||||
|
|
||||||
|
\sa onSetup(), onDone(), onError()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <typename Adapter> template <typename SetupHandler> CustomTask<Adapter> &CustomTask<Adapter>::onSetup(SetupHandler &&handler)
|
||||||
|
|
||||||
|
Attaches the setup \a handler to \c this task.
|
||||||
|
The \a handler is invoked when the task is about to be started.
|
||||||
|
|
||||||
|
This function enables defining the task's details with a
|
||||||
|
\l {https://en.wikipedia.org/wiki/Fluent_interface}{fluent interface} style:
|
||||||
|
|
||||||
|
\code
|
||||||
|
const auto onQuerySetup = [](NetworkQuery &task) { ... };
|
||||||
|
const auto onQueryError = [](const NetworkQuery &task) { ... };
|
||||||
|
|
||||||
|
const Group group {
|
||||||
|
NetworkQueryTask(onQuerySetup, {}, onQueryError),
|
||||||
|
NetworkQueryTask().onSetup(onQuerySetup).onError(onQueryError), // fluent interface style
|
||||||
|
NetworkQueryTask(onQuerySetup, {}, onQueryError).withTimeout(500ms)
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\sa CustomTask(), onDone(), onError()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <typename Adapter> CustomTask<Adapter> &CustomTask<Adapter>::onDone(const EndHandler &handler)
|
||||||
|
|
||||||
|
Attaches the done \a handler to \c this task.
|
||||||
|
The handler is invoked when the task finishes with success.
|
||||||
|
|
||||||
|
This function enables defining the task's details with a fluent interface style.
|
||||||
|
|
||||||
|
\sa CustomTask(), onSetup(), onError()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <typename Adapter> CustomTask<Adapter> &CustomTask<Adapter>::onError(const EndHandler &handler)
|
||||||
|
|
||||||
|
Attaches the error \a handler to \c this task.
|
||||||
|
The handler is invoked when the task finishes with an error.
|
||||||
|
|
||||||
|
This function enables defining the task's details with a fluent interface style.
|
||||||
|
|
||||||
|
\sa CustomTask(), onSetup(), onDone()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <typename Adapter> GroupItem CustomTask<Adapter>::withTimeout(std::chrono::milliseconds timeout, const GroupItem::GroupEndHandler &handler) const
|
||||||
|
|
||||||
|
Attaches \c TimeoutTask to a copy of \c this task, elapsing after \a timeout in milliseconds,
|
||||||
|
with an optionally provided timeout \a handler, and returns the coupled item.
|
||||||
|
|
||||||
|
When the task finishes before \a timeout passes,
|
||||||
|
the returned item finishes immediately with the task's result.
|
||||||
|
Otherwise, the \a handler is invoked (if provided), the task is stopped,
|
||||||
|
and the returned item finishes with an error.
|
||||||
|
|
||||||
|
\sa onSetup()
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro TASKING_DECLARE_TASK(CustomTaskName, TaskAdapterClass)
|
\macro TASKING_DECLARE_TASK(CustomTaskName, TaskAdapterClass)
|
||||||
\relates Tasking
|
\relates Tasking
|
||||||
@@ -158,13 +521,6 @@ private:
|
|||||||
For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
|
For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
\class Tasking::GroupItem
|
|
||||||
\inheaderfile solutions/tasking/tasktree.h
|
|
||||||
\inmodule TaskingSolution
|
|
||||||
\brief The GroupItem class represents the basic element for composing nested tree structures.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\enum Tasking::WorkflowPolicy
|
\enum Tasking::WorkflowPolicy
|
||||||
|
|
||||||
|
|||||||
@@ -321,14 +321,14 @@ public:
|
|||||||
using EndHandler = std::function<void(const Task &)>;
|
using EndHandler = std::function<void(const Task &)>;
|
||||||
static Adapter *createAdapter() { return new Adapter; }
|
static Adapter *createAdapter() { return new Adapter; }
|
||||||
CustomTask() : GroupItem({&createAdapter}) {}
|
CustomTask() : GroupItem({&createAdapter}) {}
|
||||||
template <typename SetupFunction>
|
template <typename SetupHandler>
|
||||||
CustomTask(SetupFunction &&function, const EndHandler &done = {}, const EndHandler &error = {})
|
CustomTask(SetupHandler &&setup, const EndHandler &done = {}, const EndHandler &error = {})
|
||||||
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupFunction>(function)),
|
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)),
|
||||||
wrapEnd(done), wrapEnd(error)}) {}
|
wrapEnd(done), wrapEnd(error)}) {}
|
||||||
|
|
||||||
template <typename SetupFunction>
|
template <typename SetupHandler>
|
||||||
CustomTask &onSetup(SetupFunction &&function) {
|
CustomTask &onSetup(SetupHandler &&handler) {
|
||||||
setTaskSetupHandler(wrapSetup(std::forward<SetupFunction>(function)));
|
setTaskSetupHandler(wrapSetup(std::forward<SetupHandler>(handler)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
CustomTask &onDone(const EndHandler &handler) {
|
CustomTask &onDone(const EndHandler &handler) {
|
||||||
@@ -346,20 +346,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename SetupFunction>
|
template<typename SetupHandler>
|
||||||
static GroupItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
|
static GroupItem::TaskSetupHandler wrapSetup(SetupHandler &&handler) {
|
||||||
static constexpr bool isDynamic = std::is_same_v<SetupResult,
|
static constexpr bool isDynamic = std::is_same_v<SetupResult,
|
||||||
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
|
std::invoke_result_t<std::decay_t<SetupHandler>, typename Adapter::Type &>>;
|
||||||
constexpr bool isVoid = std::is_same_v<void,
|
constexpr bool isVoid = std::is_same_v<void,
|
||||||
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
|
std::invoke_result_t<std::decay_t<SetupHandler>, typename Adapter::Type &>>;
|
||||||
static_assert(isDynamic || isVoid,
|
static_assert(isDynamic || isVoid,
|
||||||
"Task setup handler needs to take (Task &) as an argument and has to return "
|
"Task setup handler needs to take (Task &) as an argument and has to return "
|
||||||
"void or SetupResult. The passed handler doesn't fulfill these requirements.");
|
"void or SetupResult. The passed handler doesn't fulfill these requirements.");
|
||||||
return [=](TaskInterface &taskInterface) {
|
return [=](TaskInterface &taskInterface) {
|
||||||
Adapter &adapter = static_cast<Adapter &>(taskInterface);
|
Adapter &adapter = static_cast<Adapter &>(taskInterface);
|
||||||
if constexpr (isDynamic)
|
if constexpr (isDynamic)
|
||||||
return std::invoke(function, *adapter.task());
|
return std::invoke(handler, *adapter.task());
|
||||||
std::invoke(function, *adapter.task());
|
std::invoke(handler, *adapter.task());
|
||||||
return SetupResult::Continue;
|
return SetupResult::Continue;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -66,22 +66,22 @@ BoostTestSettings::BoostTestSettings(Id settingsId)
|
|||||||
seed.setEnabler(&randomize);
|
seed.setEnabler(&randomize);
|
||||||
|
|
||||||
randomize.setSettingsKey("Randomize");
|
randomize.setSettingsKey("Randomize");
|
||||||
randomize.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
randomize.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
randomize.setLabelText(Tr::tr("Randomize"));
|
randomize.setLabelText(Tr::tr("Randomize"));
|
||||||
randomize.setToolTip(Tr::tr("Randomize execution order."));
|
randomize.setToolTip(Tr::tr("Randomize execution order."));
|
||||||
|
|
||||||
systemErrors.setSettingsKey("SystemErrors");
|
systemErrors.setSettingsKey("SystemErrors");
|
||||||
systemErrors.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
systemErrors.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
systemErrors.setLabelText(Tr::tr("Catch system errors"));
|
systemErrors.setLabelText(Tr::tr("Catch system errors"));
|
||||||
systemErrors.setToolTip(Tr::tr("Catch or ignore system errors."));
|
systemErrors.setToolTip(Tr::tr("Catch or ignore system errors."));
|
||||||
|
|
||||||
fpExceptions.setSettingsKey("FPExceptions");
|
fpExceptions.setSettingsKey("FPExceptions");
|
||||||
fpExceptions.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
fpExceptions.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
fpExceptions.setLabelText(Tr::tr("Floating point exceptions"));
|
fpExceptions.setLabelText(Tr::tr("Floating point exceptions"));
|
||||||
fpExceptions.setToolTip(Tr::tr("Enable floating point exception traps."));
|
fpExceptions.setToolTip(Tr::tr("Enable floating point exception traps."));
|
||||||
|
|
||||||
memLeaks.setSettingsKey("MemoryLeaks");
|
memLeaks.setSettingsKey("MemoryLeaks");
|
||||||
memLeaks.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
memLeaks.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
memLeaks.setDefaultValue(true);
|
memLeaks.setDefaultValue(true);
|
||||||
memLeaks.setLabelText(Tr::tr("Detect memory leaks"));
|
memLeaks.setLabelText(Tr::tr("Detect memory leaks"));
|
||||||
memLeaks.setToolTip(Tr::tr("Enable memory leak detection."));
|
memLeaks.setToolTip(Tr::tr("Enable memory leak detection."));
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ CTestSettings::CTestSettings(Id settingsId)
|
|||||||
|
|
||||||
outputOnFail.setSettingsKey("OutputOnFail");
|
outputOnFail.setSettingsKey("OutputOnFail");
|
||||||
outputOnFail.setLabelText(Tr::tr("Output on failure"));
|
outputOnFail.setLabelText(Tr::tr("Output on failure"));
|
||||||
|
outputOnFail.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
outputOnFail.setDefaultValue(true);
|
outputOnFail.setDefaultValue(true);
|
||||||
|
|
||||||
outputMode.setSettingsKey("OutputMode");
|
outputMode.setSettingsKey("OutputMode");
|
||||||
@@ -70,9 +71,11 @@ CTestSettings::CTestSettings(Id settingsId)
|
|||||||
|
|
||||||
scheduleRandom.setSettingsKey("ScheduleRandom");
|
scheduleRandom.setSettingsKey("ScheduleRandom");
|
||||||
scheduleRandom.setLabelText(Tr::tr("Schedule random"));
|
scheduleRandom.setLabelText(Tr::tr("Schedule random"));
|
||||||
|
scheduleRandom.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
|
|
||||||
stopOnFailure.setSettingsKey("StopOnFail");
|
stopOnFailure.setSettingsKey("StopOnFail");
|
||||||
stopOnFailure.setLabelText(Tr::tr("Stop on failure"));
|
stopOnFailure.setLabelText(Tr::tr("Stop on failure"));
|
||||||
|
stopOnFailure.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
|
|
||||||
parallel.setSettingsKey("Parallel");
|
parallel.setSettingsKey("Parallel");
|
||||||
parallel.setToolTip(Tr::tr("Run tests in parallel mode using given number of jobs."));
|
parallel.setToolTip(Tr::tr("Run tests in parallel mode using given number of jobs."));
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ GTestSettings::GTestSettings(Id settingsId)
|
|||||||
setLayouter([this] {
|
setLayouter([this] {
|
||||||
return Row { Form {
|
return Row { Form {
|
||||||
runDisabled, br,
|
runDisabled, br,
|
||||||
|
throwOnFailure, br,
|
||||||
breakOnFailure, br,
|
breakOnFailure, br,
|
||||||
repeat, iterations, br,
|
repeat, iterations, br,
|
||||||
shuffle, seed, br,
|
shuffle, seed, br,
|
||||||
@@ -49,24 +50,29 @@ GTestSettings::GTestSettings(Id settingsId)
|
|||||||
|
|
||||||
runDisabled.setSettingsKey("RunDisabled");
|
runDisabled.setSettingsKey("RunDisabled");
|
||||||
runDisabled.setLabelText(Tr::tr("Run disabled tests"));
|
runDisabled.setLabelText(Tr::tr("Run disabled tests"));
|
||||||
|
runDisabled.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
runDisabled.setToolTip(Tr::tr("Executes disabled tests when performing a test run."));
|
runDisabled.setToolTip(Tr::tr("Executes disabled tests when performing a test run."));
|
||||||
|
|
||||||
shuffle.setSettingsKey("Shuffle");
|
shuffle.setSettingsKey("Shuffle");
|
||||||
shuffle.setLabelText(Tr::tr("Shuffle tests"));
|
shuffle.setLabelText(Tr::tr("Shuffle tests"));
|
||||||
|
shuffle.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
shuffle.setToolTip(Tr::tr("Shuffles tests automatically on every iteration by the given seed."));
|
shuffle.setToolTip(Tr::tr("Shuffles tests automatically on every iteration by the given seed."));
|
||||||
|
|
||||||
repeat.setSettingsKey("Repeat");
|
repeat.setSettingsKey("Repeat");
|
||||||
repeat.setLabelText(Tr::tr("Repeat tests"));
|
repeat.setLabelText(Tr::tr("Repeat tests"));
|
||||||
|
repeat.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
repeat.setToolTip(Tr::tr("Repeats a test run (you might be required to increase the timeout to "
|
repeat.setToolTip(Tr::tr("Repeats a test run (you might be required to increase the timeout to "
|
||||||
"avoid canceling the tests)."));
|
"avoid canceling the tests)."));
|
||||||
|
|
||||||
throwOnFailure.setSettingsKey("ThrowOnFailure");
|
throwOnFailure.setSettingsKey("ThrowOnFailure");
|
||||||
throwOnFailure.setLabelText(Tr::tr("Throw on failure"));
|
throwOnFailure.setLabelText(Tr::tr("Throw on failure"));
|
||||||
|
throwOnFailure.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
throwOnFailure.setToolTip(Tr::tr("Turns assertion failures into C++ exceptions."));
|
throwOnFailure.setToolTip(Tr::tr("Turns assertion failures into C++ exceptions."));
|
||||||
|
|
||||||
breakOnFailure.setSettingsKey("BreakOnFailure");
|
breakOnFailure.setSettingsKey("BreakOnFailure");
|
||||||
breakOnFailure.setDefaultValue(true);
|
breakOnFailure.setDefaultValue(true);
|
||||||
breakOnFailure.setLabelText(Tr::tr("Break on failure while debugging"));
|
breakOnFailure.setLabelText(Tr::tr("Break on failure while debugging"));
|
||||||
|
breakOnFailure.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||||
breakOnFailure.setToolTip(Tr::tr("Turns failures into debugger breakpoints."));
|
breakOnFailure.setToolTip(Tr::tr("Turns failures into debugger breakpoints."));
|
||||||
|
|
||||||
groupMode.setSettingsKey("GroupMode");
|
groupMode.setSettingsKey("GroupMode");
|
||||||
|
|||||||
@@ -296,9 +296,8 @@ void TestResultModel::addTestResult(const TestResult &testResult, bool autoExpan
|
|||||||
if (parentItem) {
|
if (parentItem) {
|
||||||
parentItem->appendChild(newItem);
|
parentItem->appendChild(newItem);
|
||||||
if (autoExpand) {
|
if (autoExpand) {
|
||||||
parentItem->expand();
|
QMetaObject::invokeMethod(this, [parentItem]{ parentItem->expand(); },
|
||||||
newItem->expand();
|
Qt::QueuedConnection);
|
||||||
newItem->forAllChildren([](TreeItem *it) { it->expand(); });
|
|
||||||
}
|
}
|
||||||
updateParent(newItem);
|
updateParent(newItem);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
|
|||||||
onCopyItemTriggered(getTestResult(m_treeView->currentIndex()));
|
onCopyItemTriggered(getTestResult(m_treeView->currentIndex()));
|
||||||
});
|
});
|
||||||
connect(m_model, &TestResultModel::requestExpansion, this, [this](const QModelIndex &idx) {
|
connect(m_model, &TestResultModel::requestExpansion, this, [this](const QModelIndex &idx) {
|
||||||
m_treeView->expand(m_filterModel->mapFromSource(idx));
|
m_treeView->expandRecursively(m_filterModel->mapFromSource(idx));
|
||||||
});
|
});
|
||||||
connect(TestRunner::instance(), &TestRunner::testRunStarted,
|
connect(TestRunner::instance(), &TestRunner::testRunStarted,
|
||||||
this, &TestResultsPane::onTestRunStarted);
|
this, &TestResultsPane::onTestRunStarted);
|
||||||
|
|||||||
@@ -152,14 +152,17 @@ CppEditor::CppCodeStyleSettings ClangFormatFile::toCppCodeStyleSettings(
|
|||||||
// to be false
|
// to be false
|
||||||
settings.indentAccessSpecifiers = (style.AccessModifierOffset != -1 * int(style.IndentWidth));
|
settings.indentAccessSpecifiers = (style.AccessModifierOffset != -1 * int(style.IndentWidth));
|
||||||
|
|
||||||
settings.indentNamespaceBody = style.NamespaceIndentation
|
if (style.NamespaceIndentation == FormatStyle::NamespaceIndentationKind::NI_All) {
|
||||||
== FormatStyle::NamespaceIndentationKind::NI_All;
|
settings.indentNamespaceBody = true;
|
||||||
settings.indentNamespaceBraces = settings.indentNamespaceBody;
|
settings.indentNamespaceBraces = settings.indentNamespaceBody;
|
||||||
|
}
|
||||||
|
|
||||||
settings.indentClassBraces = style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
|
if (style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
|
||||||
|
settings.indentClassBraces = true;
|
||||||
settings.indentEnumBraces = settings.indentClassBraces;
|
settings.indentEnumBraces = settings.indentClassBraces;
|
||||||
settings.indentBlockBraces = settings.indentClassBraces;
|
settings.indentBlockBraces = settings.indentClassBraces;
|
||||||
settings.indentFunctionBraces = settings.indentClassBraces;
|
settings.indentFunctionBraces = settings.indentClassBraces;
|
||||||
|
}
|
||||||
|
|
||||||
settings.indentSwitchLabels = style.IndentCaseLabels;
|
settings.indentSwitchLabels = style.IndentCaseLabels;
|
||||||
#if LLVM_VERSION_MAJOR >= 11
|
#if LLVM_VERSION_MAJOR >= 11
|
||||||
|
|||||||
@@ -207,13 +207,13 @@ void fromCppCodeStyleSettings(clang::format::FormatStyle &style,
|
|||||||
else
|
else
|
||||||
style.AccessModifierOffset = -1 * style.IndentWidth;
|
style.AccessModifierOffset = -1 * style.IndentWidth;
|
||||||
|
|
||||||
if (settings.indentNamespaceBody || settings.indentNamespaceBraces)
|
if (settings.indentNamespaceBody && settings.indentNamespaceBraces)
|
||||||
style.NamespaceIndentation = FormatStyle::NamespaceIndentationKind::NI_All;
|
style.NamespaceIndentation = FormatStyle::NamespaceIndentationKind::NI_All;
|
||||||
else
|
else
|
||||||
style.NamespaceIndentation = FormatStyle::NamespaceIndentationKind::NI_None;
|
style.NamespaceIndentation = FormatStyle::NamespaceIndentationKind::NI_None;
|
||||||
|
|
||||||
if (settings.indentClassBraces || settings.indentEnumBraces || settings.indentBlockBraces
|
if (settings.indentClassBraces && settings.indentEnumBraces && settings.indentBlockBraces
|
||||||
|| settings.indentFunctionBraces)
|
&& settings.indentFunctionBraces)
|
||||||
style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
|
style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
|
||||||
else
|
else
|
||||||
style.BreakBeforeBraces = FormatStyle::BS_Custom;
|
style.BreakBeforeBraces = FormatStyle::BS_Custom;
|
||||||
|
|||||||
@@ -64,9 +64,8 @@ static QString appendYamlSuffix(const char *filePathFragment)
|
|||||||
void ReadExportedDiagnosticsTest::testTidy()
|
void ReadExportedDiagnosticsTest::testTidy()
|
||||||
{
|
{
|
||||||
const FilePath sourceFile = filePath("tidy.modernize-use-nullptr.cpp");
|
const FilePath sourceFile = filePath("tidy.modernize-use-nullptr.cpp");
|
||||||
const FilePath exportedFile = createFile(
|
const FilePath exportedFile
|
||||||
filePath(appendYamlSuffix("tidy.modernize-use-nullptr")).toString(),
|
= createFile(filePath(appendYamlSuffix("tidy.modernize-use-nullptr")), sourceFile);
|
||||||
sourceFile.toString());
|
|
||||||
Diagnostic expectedDiag;
|
Diagnostic expectedDiag;
|
||||||
expectedDiag.name = "modernize-use-nullptr";
|
expectedDiag.name = "modernize-use-nullptr";
|
||||||
expectedDiag.location = {sourceFile, 2, 25};
|
expectedDiag.location = {sourceFile, 2, 25};
|
||||||
@@ -86,8 +85,8 @@ void ReadExportedDiagnosticsTest::testTidy()
|
|||||||
|
|
||||||
void ReadExportedDiagnosticsTest::testAcceptDiagsFromFilePaths_None()
|
void ReadExportedDiagnosticsTest::testAcceptDiagsFromFilePaths_None()
|
||||||
{
|
{
|
||||||
const QString sourceFile = filePath("tidy.modernize-use-nullptr.cpp").toString();
|
const FilePath sourceFile = filePath("tidy.modernize-use-nullptr.cpp");
|
||||||
const FilePath exportedFile = createFile(filePath("tidy.modernize-use-nullptr.yaml").toString(),
|
const FilePath exportedFile = createFile(filePath("tidy.modernize-use-nullptr.yaml"),
|
||||||
sourceFile);
|
sourceFile);
|
||||||
const auto acceptNone = [](const FilePath &) { return false; };
|
const auto acceptNone = [](const FilePath &) { return false; };
|
||||||
const expected_str<Diagnostics> diags
|
const expected_str<Diagnostics> diags
|
||||||
@@ -101,8 +100,7 @@ void ReadExportedDiagnosticsTest::testTidy_ClangAnalyzer()
|
|||||||
{
|
{
|
||||||
const FilePath sourceFile = filePath("clang-analyzer.dividezero.cpp");
|
const FilePath sourceFile = filePath("clang-analyzer.dividezero.cpp");
|
||||||
const FilePath exportedFile
|
const FilePath exportedFile
|
||||||
= createFile(filePath(appendYamlSuffix("clang-analyzer.dividezero")).toString(),
|
= createFile(filePath(appendYamlSuffix("clang-analyzer.dividezero")), sourceFile);
|
||||||
sourceFile.toString());
|
|
||||||
Diagnostic expectedDiag;
|
Diagnostic expectedDiag;
|
||||||
expectedDiag.name = "clang-analyzer-core.DivideZero";
|
expectedDiag.name = "clang-analyzer-core.DivideZero";
|
||||||
expectedDiag.location = {sourceFile, 4, 15};
|
expectedDiag.location = {sourceFile, 4, 15};
|
||||||
@@ -134,8 +132,8 @@ void ReadExportedDiagnosticsTest::testTidy_ClangAnalyzer()
|
|||||||
void ReadExportedDiagnosticsTest::testClazy()
|
void ReadExportedDiagnosticsTest::testClazy()
|
||||||
{
|
{
|
||||||
const FilePath sourceFile = filePath("clazy.qgetenv.cpp");
|
const FilePath sourceFile = filePath("clazy.qgetenv.cpp");
|
||||||
const FilePath exportedFile = createFile(filePath(appendYamlSuffix("clazy.qgetenv")).toString(),
|
const FilePath exportedFile = createFile(filePath(appendYamlSuffix("clazy.qgetenv")),
|
||||||
sourceFile.toString());
|
sourceFile);
|
||||||
Diagnostic expectedDiag;
|
Diagnostic expectedDiag;
|
||||||
expectedDiag.name = "clazy-qgetenv";
|
expectedDiag.name = "clazy-qgetenv";
|
||||||
expectedDiag.location = {sourceFile, 7, 5};
|
expectedDiag.location = {sourceFile, 7, 5};
|
||||||
@@ -259,17 +257,16 @@ void ReadExportedDiagnosticsTest::testOffsetMultiByteCodePoint2()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace FILE_PATH with a real absolute file path in the *.yaml files.
|
// Replace FILE_PATH with a real absolute file path in the *.yaml files.
|
||||||
FilePath ReadExportedDiagnosticsTest::createFile(const QString &yamlFilePath,
|
FilePath ReadExportedDiagnosticsTest::createFile(const Utils::FilePath &yamlFilePath,
|
||||||
const QString &filePathToInject) const
|
const Utils::FilePath &filePathToInject) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(QDir::isAbsolutePath(filePathToInject), return {});
|
QTC_ASSERT(filePathToInject.isAbsolutePath(), return {});
|
||||||
const FilePath newFileName = m_baseDir->absolutePath(QFileInfo(yamlFilePath).fileName());
|
const FilePath newFileName = m_baseDir->filePath().resolvePath(yamlFilePath);
|
||||||
|
|
||||||
FileReader reader;
|
FileReader reader;
|
||||||
if (QTC_GUARD(reader.fetch(FilePath::fromString(yamlFilePath),
|
if (QTC_GUARD(reader.fetch(yamlFilePath, QIODevice::ReadOnly | QIODevice::Text))) {
|
||||||
QIODevice::ReadOnly | QIODevice::Text))) {
|
|
||||||
QByteArray contents = reader.data();
|
QByteArray contents = reader.data();
|
||||||
contents.replace("FILE_PATH", filePathToInject.toLocal8Bit());
|
contents.replace("FILE_PATH", filePathToInject.toString().toLocal8Bit());
|
||||||
|
|
||||||
FileSaver fileSaver(newFileName, QIODevice::WriteOnly | QIODevice::Text);
|
FileSaver fileSaver(newFileName, QIODevice::WriteOnly | QIODevice::Text);
|
||||||
QTC_CHECK(fileSaver.write(contents));
|
QTC_CHECK(fileSaver.write(contents));
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ private slots:
|
|||||||
void testOffsetMultiByteCodePoint2();
|
void testOffsetMultiByteCodePoint2();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::FilePath createFile(const QString &yamlFilePath, const QString &filePathToInject) const;
|
Utils::FilePath createFile(const Utils::FilePath &yamlFilePath,
|
||||||
|
const Utils::FilePath &filePathToInject) const;
|
||||||
Utils::FilePath filePath(const QString &fileName) const;
|
Utils::FilePath filePath(const QString &fileName) const;
|
||||||
|
|
||||||
CppEditor::Tests::TemporaryCopiedDir * const m_baseDir;
|
CppEditor::Tests::TemporaryCopiedDir * const m_baseDir;
|
||||||
|
|||||||
@@ -298,10 +298,6 @@ ProjectWizardPage::ProjectWizardPage(QWidget *parent)
|
|||||||
scrollArea,
|
scrollArea,
|
||||||
}.attachTo(this);
|
}.attachTo(this);
|
||||||
|
|
||||||
connect(m_projectComboBox, &QComboBox::currentIndexChanged,
|
|
||||||
this, &ProjectWizardPage::projectChanged);
|
|
||||||
connect(m_addToVersionControlComboBox, &QComboBox::currentIndexChanged,
|
|
||||||
this, &ProjectWizardPage::versionControlChanged);
|
|
||||||
connect(m_vcsManageButton, &QAbstractButton::clicked, this, &ProjectWizardPage::manageVcs);
|
connect(m_vcsManageButton, &QAbstractButton::clicked, this, &ProjectWizardPage::manageVcs);
|
||||||
setProperty(SHORT_TITLE_PROPERTY, Tr::tr("Summary"));
|
setProperty(SHORT_TITLE_PROPERTY, Tr::tr("Summary"));
|
||||||
|
|
||||||
@@ -376,6 +372,7 @@ void ProjectWizardPage::initializeVersionControls()
|
|||||||
// 2) Directory is managed and VCS does not support "Add" -> None available
|
// 2) Directory is managed and VCS does not support "Add" -> None available
|
||||||
// 3) Directory is not managed -> Offer all VCS that support "CreateRepository"
|
// 3) Directory is not managed -> Offer all VCS that support "CreateRepository"
|
||||||
|
|
||||||
|
m_addToVersionControlComboBox->disconnect();
|
||||||
QList<IVersionControl *> versionControls = VcsManager::versionControls();
|
QList<IVersionControl *> versionControls = VcsManager::versionControls();
|
||||||
if (versionControls.isEmpty())
|
if (versionControls.isEmpty())
|
||||||
hideVersionControlUiElements();
|
hideVersionControlUiElements();
|
||||||
@@ -419,6 +416,9 @@ void ProjectWizardPage::initializeVersionControls()
|
|||||||
int newIdx = m_activeVersionControls.indexOf(currentSelection) + 1;
|
int newIdx = m_activeVersionControls.indexOf(currentSelection) + 1;
|
||||||
setVersionControlIndex(newIdx);
|
setVersionControlIndex(newIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(m_addToVersionControlComboBox, &QComboBox::currentIndexChanged,
|
||||||
|
this, &ProjectWizardPage::versionControlChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectWizardPage::runVersionControl(const QList<GeneratedFile> &files, QString *errorMessage)
|
bool ProjectWizardPage::runVersionControl(const QList<GeneratedFile> &files, QString *errorMessage)
|
||||||
@@ -457,6 +457,7 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const FilePaths &pa
|
|||||||
IWizardFactory::WizardKind kind,
|
IWizardFactory::WizardKind kind,
|
||||||
ProjectAction action)
|
ProjectAction action)
|
||||||
{
|
{
|
||||||
|
m_projectComboBox->disconnect();
|
||||||
BestNodeSelector selector(m_commonDirectory, paths);
|
BestNodeSelector selector(m_commonDirectory, paths);
|
||||||
|
|
||||||
TreeItem *root = m_model.rootItem();
|
TreeItem *root = m_model.rootItem();
|
||||||
@@ -489,6 +490,8 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const FilePaths &pa
|
|||||||
setAddingSubProject(action == AddSubProject);
|
setAddingSubProject(action == AddSubProject);
|
||||||
|
|
||||||
m_projectComboBox->setEnabled(m_model.rowCount(QModelIndex()) > 1);
|
m_projectComboBox->setEnabled(m_model.rowCount(QModelIndex()) > 1);
|
||||||
|
connect(m_projectComboBox, &QComboBox::currentIndexChanged,
|
||||||
|
this, &ProjectWizardPage::projectChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectWizardPage::setNoneLabel(const QString &label)
|
void ProjectWizardPage::setNoneLabel(const QString &label)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ add_qtc_library(QmlDesignerUtils STATIC
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_library(QmlDesignerUtils
|
extend_qtc_library(QmlDesignerUtils
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
extend_qtc_library(QmlDesignerCore
|
extend_qtc_library(QmlDesignerCore
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ add_qtc_plugin(QmlDesigner
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1088,7 +1088,7 @@ add_qtc_plugin(assetexporterplugin
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(assetexporterplugin
|
extend_qtc_plugin(assetexporterplugin
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1121,7 +1121,7 @@ add_qtc_plugin(componentsplugin
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(componentsplugin
|
extend_qtc_plugin(componentsplugin
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1141,7 +1141,7 @@ add_qtc_plugin(qmlpreviewplugin
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(qmlpreviewplugin
|
extend_qtc_plugin(qmlpreviewplugin
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1163,7 +1163,7 @@ add_qtc_plugin(qtquickplugin
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(qtquickplugin
|
extend_qtc_plugin(qtquickplugin
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
env_with_default("QDS_DISABLE_COMPILE_WARNING_AS_ERROR" ENV_QDS_DISABLE_COMPILE_WARNING_AS_ERROR OFF)
|
if(BUILD_DESIGNSTUDIO AND ($<CONFIG:Debug> OR WITH_TESTS))
|
||||||
option(DISABLE_COMPILE_WARNING_AS_ERROR "Dont treat warnings as errors" ${ENV_QDS_DISABLE_COMPILE_WARNING_AS_ERROR})
|
set(ENABLE_COMPILE_WARNING_AS_ERROR_DEFAULT ON)
|
||||||
add_feature_info("Treat warnings as errors" ${DISABLE_COMPILE_WARNING_AS_ERROR} "")
|
else()
|
||||||
|
set(ENABLE_COMPILE_WARNING_AS_ERROR_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
env_with_default("QDS_ENABLE_COMPILE_WARNING_AS_ERROR" ENV_ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
|
${ENABLE_COMPILE_WARNING_AS_ERROR_DEFAULT})
|
||||||
|
option(ENABLE_COMPILE_WARNING_AS_ERROR "Treat warnings as errors in QmlDesigner" ${ENV_ENABLE_COMPILE_WARNING_AS_ERROR})
|
||||||
|
add_feature_info("Treat warnings as errors in QmlDesigner" ${ENABLE_COMPILE_WARNING_AS_ERROR} "")
|
||||||
|
|
||||||
add_qtc_plugin(QmlDesignerBase
|
add_qtc_plugin(QmlDesignerBase
|
||||||
CONDITION TARGET Qt::QuickWidgets
|
CONDITION TARGET Qt::QuickWidgets
|
||||||
@@ -12,7 +18,7 @@ add_qtc_plugin(QmlDesignerBase
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesignerBase
|
extend_qtc_plugin(QmlDesignerBase
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ add_qtc_plugin(QmlProjectManager
|
|||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlProjectManager
|
extend_qtc_plugin(QmlProjectManager
|
||||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -301,6 +301,21 @@ expected_str<QList<ExampleItem *>> parseExamples(const QByteArray &manifestData,
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ordered list of "known" categories
|
||||||
|
// TODO this should be defined in the manifest
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(QList<QString>,
|
||||||
|
defaultOrder,
|
||||||
|
{QStringList() << "Application Examples"
|
||||||
|
<< "Desktop"
|
||||||
|
<< "Mobile"
|
||||||
|
<< "Embedded"
|
||||||
|
<< "Graphics"
|
||||||
|
<< "Input/Output"
|
||||||
|
<< "Connectivity"
|
||||||
|
<< "Networking"
|
||||||
|
<< "Positioning & Location"
|
||||||
|
<< "Internationalization"});
|
||||||
|
|
||||||
static bool sortByHighlightedAndName(ExampleItem *first, ExampleItem *second)
|
static bool sortByHighlightedAndName(ExampleItem *first, ExampleItem *second)
|
||||||
{
|
{
|
||||||
if (first->isHighlighted && !second->isHighlighted)
|
if (first->isHighlighted && !second->isHighlighted)
|
||||||
@@ -350,15 +365,20 @@ QList<std::pair<Core::Section, QList<ExampleItem *>>> getCategories(const QList<
|
|||||||
} else {
|
} else {
|
||||||
// All original items have been copied into a category or other, delete.
|
// All original items have been copied into a category or other, delete.
|
||||||
qDeleteAll(items);
|
qDeleteAll(items);
|
||||||
|
static const int defaultOrderSize = defaultOrder->size();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
const auto end = categoryMap.constKeyValueEnd();
|
const auto end = categoryMap.constKeyValueEnd();
|
||||||
for (auto it = categoryMap.constKeyValueBegin(); it != end; ++it) {
|
for (auto it = categoryMap.constKeyValueBegin(); it != end; ++it) {
|
||||||
categories.append({{it->first, index, /*maxRows=*/index == 0 ? 2 : 1}, it->second});
|
// order "known" categories as wanted, others come afterwards
|
||||||
|
const int defaultIndex = defaultOrder->indexOf(it->first);
|
||||||
|
const int priority = defaultIndex >= 0 ? defaultIndex : (index + defaultOrderSize);
|
||||||
|
categories.append({{it->first, priority, /*maxRows=*/index == 0 ? 2 : 1}, it->second});
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
if (!other.isEmpty())
|
if (!other.isEmpty())
|
||||||
categories.append({{otherDisplayName, index, /*maxRows=*/1}, other});
|
categories.append({{otherDisplayName, index + defaultOrderSize, /*maxRows=*/1}, other});
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto end = categories.end();
|
const auto end = categories.end();
|
||||||
for (auto it = categories.begin(); it != end; ++it)
|
for (auto it = categories.begin(); it != end; ++it)
|
||||||
sort(it->second, sortByHighlightedAndName);
|
sort(it->second, sortByHighlightedAndName);
|
||||||
|
|||||||
39
tests/auto/qml/codemodel/check/accessById.qml
Normal file
39
tests/auto/qml/codemodel/check/accessById.qml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Window
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: root
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
visible: true
|
||||||
|
title: qsTr("Hello World")
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rect
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: innerRect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: myText
|
||||||
|
width: 50
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: "a text string that is longer than 50 pixels"
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: innerText
|
||||||
|
}
|
||||||
|
states: State {
|
||||||
|
name: "widerText"
|
||||||
|
PropertyChanges { myText.width: undefined }
|
||||||
|
AnchorChanges { innerRect.width: undefined } // 16 29 37
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {rect.width: innerText.width}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user