| 941 | } // namespace |
| 942 | |
| 943 | ClangCodeCompletionContext::ClangCodeCompletionContext(const DUContextPointer& context, |
| 944 | const ParseSessionData::Ptr& sessionData, |
| 945 | const QUrl& url, |
| 946 | const KTextEditor::Cursor& position, |
| 947 | const QString& text, |
| 948 | const QString& followingText |
| 949 | ) |
| 950 | : CodeCompletionContext(context, text + followingText, CursorInRevision::castFromSimpleCursor(position), 0) |
| 951 | , m_results(nullptr, clang_disposeCodeCompleteResults) |
| 952 | , m_parseSessionData(sessionData) |
| 953 | { |
| 954 | qRegisterMetaType<MemberAccessReplacer::Type>(); |
| 955 | const QByteArray file = url.toLocalFile().toUtf8(); |
| 956 | ParseSession session(m_parseSessionData); |
| 957 | |
| 958 | QVector<UnsavedFile> otherUnsavedFiles; |
| 959 | { |
| 960 | ForegroundLock lock; |
| 961 | otherUnsavedFiles = ClangUtils::unsavedFiles(); |
| 962 | } |
| 963 | QVector<CXUnsavedFile> allUnsaved; |
| 964 | |
| 965 | { |
| 966 | const unsigned int completeOptions = clang_defaultCodeCompleteOptions(); |
| 967 | |
| 968 | CXUnsavedFile unsaved; |
| 969 | unsaved.Filename = file.constData(); |
| 970 | const QByteArray content = m_text.toUtf8(); |
| 971 | unsaved.Contents = content.constData(); |
| 972 | unsaved.Length = content.size(); |
| 973 | |
| 974 | allUnsaved.reserve(otherUnsavedFiles.size() + 1); |
| 975 | for (const auto& f : std::as_const(otherUnsavedFiles)) { |
| 976 | allUnsaved.append(f.toClangApi()); |
| 977 | } |
| 978 | allUnsaved.append(unsaved); |
| 979 | |
| 980 | m_results.reset(clang_codeCompleteAt(session.unit(), file.constData(), |
| 981 | position.line() + 1, position.column() + 1, |
| 982 | allUnsaved.data(), allUnsaved.size(), |
| 983 | completeOptions)); |
| 984 | |
| 985 | if (!m_results) { |
| 986 | qCWarning(KDEV_CLANG) << "Something went wrong during 'clang_codeCompleteAt' for file" << file; |
| 987 | return; |
| 988 | } |
| 989 | |
| 990 | auto numDiagnostics = clang_codeCompleteGetNumDiagnostics(m_results.get()); |
| 991 | for (uint i = 0; i < numDiagnostics; i++) { |
| 992 | auto diagnostic = clang_codeCompleteGetDiagnostic(m_results.get(), i); |
| 993 | auto diagnosticType = ClangDiagnosticEvaluator::diagnosticType(diagnostic); |
| 994 | clang_disposeDiagnostic(diagnostic); |
| 995 | if (diagnosticType == ClangDiagnosticEvaluator::ReplaceWithArrowProblem || diagnosticType == ClangDiagnosticEvaluator::ReplaceWithDotProblem) { |
| 996 | MemberAccessReplacer::Type replacementType; |
| 997 | if (diagnosticType == ClangDiagnosticEvaluator::ReplaceWithDotProblem) { |
| 998 | replacementType = MemberAccessReplacer::ArrowToDot; |
| 999 | } else { |
| 1000 | replacementType = MemberAccessReplacer::DotToArrow; |
nothing calls this directly
no test coverage detected