7#include <QtCore/qfileinfo.h>
8#include <QtCore/qdir.h>
9#include <QtCore/qthreadpool.h>
10#include <QtCore/qlibraryinfo.h>
11#include <QtQmlDom/private/qqmldomtop_p.h>
98 m_state = State::Stopping;
99 m_openDocumentsToUpdate.
clear();
100 shouldWait = m_nIndexInProgress != 0 || m_nUpdateInProgress != 0;
113int QQmlCodeModel::indexEvalProgress()
const
116 const int dirCost = 10;
119 costToDo += dirCost *
el.leftDepth;
120 costToDo += m_indexInProgressCost;
121 return m_indexDoneCost * 100 / (costToDo + m_indexDoneCost);
124void QQmlCodeModel::indexStart()
127 qCDebug(codeModelLog) <<
"indexStart";
130void QQmlCodeModel::indexEnd()
133 qCDebug(codeModelLog) <<
"indexEnd";
134 m_lastIndexProgress = 0;
135 m_nIndexInProgress = 0;
137 m_indexInProgressCost = 0;
141void QQmlCodeModel::indexSendProgress(
int progress)
143 if (progress <= m_lastIndexProgress)
145 m_lastIndexProgress = progress;
149bool QQmlCodeModel::indexCancelled()
152 if (m_state == State::Stopping)
157void QQmlCodeModel::indexDirectory(
const QString &
path,
int depthLeft)
159 if (indexCancelled())
166 addDirectory(
dir.filePath(
child), --depthLeft);
173 m_indexInProgressCost += qmljs.size();
174 progress = indexEvalProgress();
176 indexSendProgress(progress);
181 if (indexCancelled())
184 DomCreationOptions options;
185 options.setFlag(DomCreationOption::WithScriptExpressions);
186 options.setFlag(DomCreationOption::WithSemanticAnalysis);
190 newCurrent.loadBuiltins();
192 newCurrent.loadPendingDependencies();
198 --m_indexInProgressCost;
199 progress = indexEvalProgress();
201 indexSendProgress(progress);
209 const int maxDepth = 5;
211 addDirectory(
path, maxDepth);
215void QQmlCodeModel::addDirectory(
const QString &
path,
int depthLeft)
221 for (
auto it = m_toIndex.begin();
it != m_toIndex.end();) {
222 if (
it->path.startsWith(
path)) {
225 if (
it->path.at(
path.size()) == u
'/') {
226 it = m_toIndex.erase(
it);
233 m_toIndex.append({
path, depthLeft });
242 return p.startsWith(
path) && (
p.size() ==
path.size() ||
p.at(
path.size()) == u
'/');
244 auto it = m_toIndex.begin();
245 auto end = m_toIndex.end();
247 if (toRemove(
it->path))
248 it = m_toIndex.erase(
it);
254 validEnvPtr->removePath(
path);
256 currentEnvPtr->removePath(
path);
270 QString cPath =
f.canonicalFilePath();
272 cPath =
f.filePath();
275 if (!
res.isEmpty() &&
res != cPath)
287 auto &openDoc = m_openDocuments[
url];
288 if (!openDoc.textDocument)
289 openDoc.textDocument = std::make_shared<Utils::TextDocument>();
291 openDoc.textDocument->setVersion(version);
292 openDoc.textDocument->setPlainText(docText);
301 return m_openDocuments.value(
url);
306 const int maxIndexThreads = 1;
309 if (m_toIndex.isEmpty() || m_nIndexInProgress >= maxIndexThreads)
311 if (++m_nIndexInProgress == 1)
315 while (indexSome()) { }
319bool QQmlCodeModel::indexSome()
321 qCDebug(codeModelLog) <<
"indexSome";
325 if (m_toIndex.isEmpty()) {
326 if (--m_nIndexInProgress == 0)
331 m_toIndex.removeLast();
333 bool hasMore =
false;
337 if (m_toIndex.isEmpty()) {
338 if (--m_nIndexInProgress == 0)
352 qCDebug(codeModelLog) <<
"openNeedUpdate";
353 const int maxIndexThreads = 1;
356 if (m_openDocumentsToUpdate.
isEmpty() || m_nUpdateInProgress >= maxIndexThreads)
358 if (++m_nUpdateInProgress == 1)
362 while (openUpdateSome()) { }
366bool QQmlCodeModel::openUpdateSome()
368 qCDebug(codeModelLog) <<
"openUpdateSome start";
372 if (m_openDocumentsToUpdate.
isEmpty()) {
373 if (--m_nUpdateInProgress == 0)
377 auto it = m_openDocumentsToUpdate.
find(m_lastOpenDocumentUpdated);
378 auto end = m_openDocumentsToUpdate.
end();
380 it = m_openDocumentsToUpdate.
begin();
381 else if (++
it ==
end)
382 it = m_openDocumentsToUpdate.
begin();
384 m_openDocumentsToUpdate.
erase(
it);
386 bool hasMore =
false;
390 if (m_openDocumentsToUpdate.
isEmpty()) {
391 if (--m_nUpdateInProgress == 0)
398 openUpdate(toUpdate);
403void QQmlCodeModel::openUpdateStart()
405 qCDebug(codeModelLog) <<
"openUpdateStart";
408void QQmlCodeModel::openUpdateEnd()
410 qCDebug(codeModelLog) <<
"openUpdateEnd";
415 qCDebug(codeModelLog) <<
"updating doc" <<
url <<
"to version" << version <<
"("
416 << docText.
size() <<
"chars)";
421 newCurrentPtr->setLoadPaths(loadPaths);
425 DomCreationOptions options;
426 options.setFlag(DomCreationOption::WithScriptExpressions);
427 options.setFlag(DomCreationOption::WithSemanticAnalysis);
447 <<
"docUpdate: version" << version <<
"of document"
456 qCWarning(lspServerLog) <<
"skipping update of current doc to obsolete version"
459 if (
item.field(Fields::isValid).value().toBool(
false)) {
465 qCWarning(lspServerLog) <<
"skippig update of valid doc to obsolete version"
470 <<
"avoid update of validDoc to " << version <<
"of document"
475 if (codeModelLog().isDebugEnabled()) {
476 qCDebug(codeModelLog) <<
"finished update doc of " <<
url <<
"to version" << version;
487 m_openDocuments.remove(
url);
521 return m_buildPathsForRootUrl.
value(
url);
534 roots = m_buildPathsForRootUrl.
keys();
538 if (el1.size() > el2.size())
540 if (el1.size() < el2.size())
562 if (buildPaths.isEmpty()) {
567 if (buildPaths.isEmpty()) {
570 buildPaths += envPaths;
575 if (buildPaths.isEmpty() && m_settings) {
578 if (m_settings->
isSet(buildDir))
584 if (buildPaths.isEmpty()) {
587 const int maxDirDepth = 8;
588 int iDir = maxDirDepth;
591 while (
d.cdUp() && --iDir > 0) {
593 if (fInfo.completeBaseName() == u
"build"
594 || fInfo.completeBaseName().startsWith(u
"build-%1"_s.arg(dirName))) {
597 if (!lastModified.
isValid() || lastModified < fInfo.lastModified()) {
599 buildPaths.append(fInfo.absoluteFilePath());
607 std::reverse(buildPaths.begin(), buildPaths.end());
608 const int maxDeps = 4;
609 while (!buildPaths.isEmpty()) {
610 QString bPath = buildPaths.last();
611 buildPaths.removeLast();
614 QDir d(bPath + u
"/_deps");
616 buildPaths.append(fInfo.absoluteFilePath());
635 bool updateDoc =
false;
636 bool updateScope =
false;
637 std::optional<int> rNow = 0;
640 std::shared_ptr<Utils::TextDocument> document;
649 rNow = document->version();
684 dbg.noquote().nospace() <<
"{";
688 dbg <<
" doc: ------------\n"
696 dbg <<
" validDocVersion:"
699 dbg <<
" validDoc: ------------\n"
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
bool startsWith(QByteArrayView bv) const
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString toString(const QString &defaultValue={}) const
Returns the string value stored in this QCborValue, if it is of the string type.
\inmodule QtCore\reentrant
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
static constexpr QChar listSeparator() noexcept
\inmodule QtCore \reentrant
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool remove(const Key &key)
Removes the item that has the key from the hash.
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
T value(const Key &key) const noexcept
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Implements a server for the language server protocol.
static QString path(LibraryPath p)
bool isEmpty() const noexcept
bool removeOne(const AT &t)
void removeLast() noexcept
void append(parameter_type t)
bool tryLock(int timeout=0) noexcept
Attempts to lock the mutex.
Represents a consistent set of types organized in modules, it is the top level of the DOM.
std::shared_ptr< T > ownerAs()
MutableDomItem makeCopy(CopyOption option=CopyOption::EnvConnected)
void loadPendingDependencies()
bool commitToBase(std::shared_ptr< DomEnvironment > validPtr=nullptr)
DomItem path(Path p, ErrorHandler h=&defaultErrorHandler)
void loadFile(const FileToLoad &file, std::function< void(Path, DomItem &, DomItem &)> callback, LoadOptions loadOptions, std::optional< DomType > fileType=std::optional< DomType >())
DomItem field(QStringView name)
QString canonicalPath() const
static FileToLoad fromMemory(const std::weak_ptr< DomEnvironment > &environment, const QString &path, const QString &data, DomCreationOptions options=None)
static FileToLoad fromFileSystem(const std::weak_ptr< DomEnvironment > &environment, const QString &canonicalPath, DomCreationOptions options=None)
iterator erase(const_iterator i)
iterator find(const T &value)
iterator insert(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
qsizetype size() const
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void start(QRunnable *runnable, int priority=0)
Reserves a thread and uses it to run runnable, unless this thread will make the current thread count ...
static QThreadPool * globalInstance()
Returns the global QThreadPool instance.
static void yieldCurrentThread()
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool scopeDependenciesChanged
std::optional< int > scopeVersion
QDateTime scopeDependenciesLoadTime
std::optional< int > docVersion
std::optional< int > validDocVersion
QDebug dump(QDebug dbg, DumpOptions dump=DumpOption::NoCode)
QQmlJS::Dom::DomItem validDoc
std::shared_ptr< Utils::TextDocument > textDocument
OpenDocumentSnapshot snapshot
void newOpenFile(const QByteArray &url, int version, const QString &docText)
void addRootUrls(const QList< QByteArray > &urls)
QList< QByteArray > rootUrls() const
QQmlCodeModel(QObject *parent=nullptr, QQmlToolingSettings *settings=nullptr)
void setBuildPathsForRootUrl(QByteArray url, const QStringList &paths)
OpenDocumentSnapshot snapshotByUrl(const QByteArray &url)
void addOpenToUpdate(const QByteArray &)
QString url2Path(const QByteArray &url, UrlLookup options=UrlLookup::Caching)
OpenDocument openDocumentByUrl(const QByteArray &url)
QStringList buildPathsForFileUrl(const QByteArray &url)
void setRootUrls(const QList< QByteArray > &urls)
void removeDirectory(const QString &path)
void removeRootUrls(const QList< QByteArray > &urls)
void addDirectoriesToIndex(const QStringList &paths, QLanguageServer *server)
void newDocForOpenFile(const QByteArray &url, int version, const QString &docText)
void updatedSnapshot(const QByteArray &url)
QStringList buildPathsForRootUrl(const QByteArray &url)
void closeOpenFile(const QByteArray &url)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
static bool isNotSeparator(char c)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall DBusPendingCall return DBusPendingCall return dbus_int32_t return DBusServer * server
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLsizei const GLuint * paths
GLsizei const GLchar *const * path
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
#define QStringLiteral(str)
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
static uint toIndex(ExecutionEngine *e, const Value &v)
QSettings settings("MySoft", "Star Runner")
[0]
QUrl url("example.com")
[constructor-url-reference]
bool contains(const AT &t) const noexcept
IUIAutomation __RPC__in_opt IUIAutomationElement * el2
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent