| 80 | |
| 81 | private: |
| 82 | void run() |
| 83 | { |
| 84 | aborting() = false; |
| 85 | |
| 86 | DUChainReadLocker lock; |
| 87 | if (aborting()) { |
| 88 | failed(); |
| 89 | return; |
| 90 | } |
| 91 | |
| 92 | auto top = DUChainUtils::standardContextForUrl(m_url); |
| 93 | if (!top) { |
| 94 | qCWarning(KDEV_CLANG) << "No context found for" << m_url; |
| 95 | return; |
| 96 | } |
| 97 | |
| 98 | ParseSessionData::Ptr sessionData(ClangIntegration::DUChainUtils::findParseSessionData(top->url(), m_index->translationUnitForUrl(top->url()))); |
| 99 | |
| 100 | if (!sessionData) { |
| 101 | // TODO: trigger reparse and re-request code completion |
| 102 | qCWarning(KDEV_CLANG) << "No parse session / AST attached to context for url" << m_url; |
| 103 | return; |
| 104 | } |
| 105 | |
| 106 | if (aborting()) { |
| 107 | failed(); |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | // We hold DUChain lock, and ask for ParseSession, but TUDUChain indirectly holds ParseSession lock. |
| 112 | lock.unlock(); |
| 113 | |
| 114 | auto completionContext = ::createCompletionContext(DUContextPointer(top), sessionData, m_url, |
| 115 | m_position, m_text, m_followingText); |
| 116 | |
| 117 | lock.lock(); |
| 118 | if (aborting()) { |
| 119 | failed(); |
| 120 | return; |
| 121 | } |
| 122 | |
| 123 | bool abort = false; |
| 124 | // NOTE: cursor might be wrong here, but shouldn't matter much I hope... |
| 125 | // when the document changed significantly, then the cache is off anyways and we don't get anything sensible |
| 126 | // the position here is just a "optimization" to only search up to that position |
| 127 | const auto& items = completionContext->completionItems(abort); |
| 128 | |
| 129 | if (aborting()) { |
| 130 | failed(); |
| 131 | return; |
| 132 | } |
| 133 | |
| 134 | auto tree = computeGroups( items, {} ); |
| 135 | |
| 136 | if (aborting()) { |
| 137 | failed(); |
| 138 | return; |
| 139 | } |
nothing calls this directly
no test coverage detected