File indexing completed on 2024-05-12 04:39:19

0001 /*
0002     SPDX-FileCopyrightText: 2013 Olivier de Gaalon <olivier.jg@gmail.com>
0003     SPDX-FileCopyrightText: 2013 Milian Wolff <mail@milianw.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "clangtypes.h"
0009 
0010 #include <QReadLocker>
0011 
0012 #include <language/editor/rangeinrevision.h>
0013 #include <language/editor/documentcursor.h>
0014 #include <language/editor/documentrange.h>
0015 #include <util/path.h>
0016 
0017 using namespace KDevelop;
0018 
0019 namespace {
0020 
0021 template<typename T>
0022 inline T cursorForCXSrcLoc(CXSourceLocation loc)
0023 {
0024     uint line = 0;
0025     uint column = 0;
0026     clang_getFileLocation(loc, nullptr, &line, &column, nullptr);
0027     return {static_cast<int>(line-1), static_cast<int>(column-1)};
0028 }
0029 
0030 }
0031 
0032 ClangString::ClangString(CXString string)
0033     : string(string)
0034 {
0035 }
0036 
0037 ClangString::~ClangString()
0038 {
0039     clang_disposeString(string);
0040 }
0041 
0042 const char* ClangString::c_str() const
0043 {
0044     return clang_getCString(string);
0045 }
0046 
0047 bool ClangString::isEmpty() const
0048 {
0049     auto str = c_str();
0050     return !str || !str[0];
0051 }
0052 
0053 QString ClangString::toString() const
0054 {
0055     return QString::fromUtf8(c_str());
0056 }
0057 
0058 QByteArray ClangString::toByteArray() const
0059 {
0060     return QByteArray(c_str());
0061 }
0062 
0063 IndexedString ClangString::toIndexed() const
0064 {
0065     return IndexedString(c_str());
0066 }
0067 
0068 QTextStream& operator<<(QTextStream& stream, const ClangString& str)
0069 {
0070     return stream << str.toString();
0071 }
0072 
0073 QDebug operator<<(QDebug stream, const ClangString& str)
0074 {
0075     return stream << str.toString();
0076 }
0077 
0078 ClangLocation::ClangLocation(CXSourceLocation location)
0079     : location(location)
0080 {
0081 
0082 }
0083 
0084 ClangLocation::operator DocumentCursor() const
0085 {
0086     uint line = 0;
0087     uint column = 0;
0088     CXFile file;
0089     clang_getFileLocation(location, &file, &line, &column, nullptr);
0090     ClangString fileName(clang_getFileName(file));
0091     return {IndexedString(fileName.c_str()), {static_cast<int>(line-1), static_cast<int>(column-1)}};
0092 }
0093 
0094 ClangLocation::operator KTextEditor::Cursor() const
0095 {
0096     return cursorForCXSrcLoc<KTextEditor::Cursor>(location);
0097 }
0098 
0099 ClangLocation::operator CursorInRevision() const
0100 {
0101     return cursorForCXSrcLoc<CursorInRevision>(location);
0102 }
0103 
0104 ClangLocation::operator CXSourceLocation() const
0105 {
0106     return location;
0107 }
0108 
0109 ClangLocation::~ClangLocation()
0110 {
0111 }
0112 
0113 QDebug operator<<(QDebug stream, const ClangLocation& location)
0114 {
0115     return stream << static_cast<DocumentCursor>(location);
0116 }
0117 
0118 ClangRange::ClangRange(CXSourceRange range)
0119     : m_range(range)
0120 {
0121 
0122 }
0123 
0124 ClangLocation ClangRange::start() const
0125 {
0126     return ClangLocation(clang_getRangeStart(m_range));
0127 }
0128 
0129 ClangLocation ClangRange::end() const
0130 {
0131     return ClangLocation(clang_getRangeEnd(m_range));
0132 }
0133 
0134 CXSourceRange ClangRange::range() const
0135 {
0136     return m_range;
0137 }
0138 
0139 DocumentRange ClangRange::toDocumentRange() const
0140 {
0141     auto start = clang_getRangeStart(m_range);
0142     CXFile file;
0143     clang_getFileLocation(start, &file, nullptr, nullptr, nullptr);
0144     ClangString fileName(clang_getFileName(file));
0145     return {IndexedString(QUrl::fromLocalFile(fileName.toString()).adjusted(QUrl::NormalizePathSegments)), toRange()};
0146 }
0147 
0148 KTextEditor::Range ClangRange::toRange() const
0149 {
0150     return {start(), end()};
0151 }
0152 
0153 RangeInRevision ClangRange::toRangeInRevision() const
0154 {
0155     return {start(), end()};
0156 }
0157 
0158 ClangRange::~ClangRange()
0159 {
0160 }
0161 
0162 QDebug operator<<(QDebug stream, const ClangRange& range)
0163 {
0164     return stream << range.toDocumentRange();
0165 }
0166 
0167 ClangTokens::ClangTokens(CXTranslationUnit unit, CXSourceRange range)
0168     : m_unit(unit)
0169 {
0170     clang_tokenize(m_unit, range, &m_tokens, &m_numTokens);
0171 }
0172 ClangTokens::~ClangTokens()
0173 {
0174     clang_disposeTokens(m_unit, m_tokens, m_numTokens);
0175 }
0176 CXToken* ClangTokens::begin() const
0177 {
0178     return m_tokens;
0179 }
0180 CXToken* ClangTokens::end() const
0181 {
0182     return m_tokens + m_numTokens;
0183 }
0184 std::reverse_iterator<CXToken*> ClangTokens::rbegin() const
0185 {
0186     return std::reverse_iterator<CXToken*>(end());
0187 }
0188 std::reverse_iterator<CXToken*> ClangTokens::rend() const
0189 {
0190     return std::reverse_iterator<CXToken*>(begin());
0191 }
0192 uint ClangTokens::size() const
0193 {
0194     return m_numTokens;
0195 }
0196 CXToken ClangTokens::at(uint index) const {
0197     Q_ASSERT(index < m_numTokens);
0198     return m_tokens[index];
0199 }
0200 
0201 CXTranslationUnit ClangTokens::unit() const
0202 {
0203     return m_unit;
0204 }
0205 
0206 QDebug operator<<(QDebug stream, const ClangTokens& tokens)
0207 {
0208     stream << "ClangTokens {";
0209     for (uint i = 0; i < tokens.size(); ++i) {
0210         stream << i << tokens.at(i) << ClangString(clang_getTokenSpelling(tokens.unit(), tokens.at(i))) << ",";
0211     }
0212     return stream << "}";
0213 }
0214 
0215 QDebug operator<<(QDebug stream, const CXToken& token)
0216 {
0217     return stream << clang_getTokenKind(token);
0218 }