File indexing completed on 2024-05-12 04:38:06

0001 /*
0002     SPDX-FileCopyrightText: 2010 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KDEVPLATFORM_RANGEINREVISION_H
0008 #define KDEVPLATFORM_RANGEINREVISION_H
0009 
0010 #include <language/languageexport.h>
0011 #include "cursorinrevision.h"
0012 
0013 #include <KTextEditor/Range>
0014 
0015 namespace KDevelop {
0016 /**
0017  * Represents a range (start- and end cursor) within a text document.
0018  *
0019  * In KDevelop, this object is used when referencing a ranges that do _not_ point into the
0020  * most current document revision. Therefore, before applying such a range in the text
0021  * documents, it has to be translated into the current document revision explicitly, thereby replaying
0022  * eventual changes (see DUChainBase::translate...)
0023  */
0024 
0025 class KDEVPLATFORMLANGUAGE_EXPORT RangeInRevision
0026 {
0027 public:
0028 
0029     CursorInRevision start, end;
0030 
0031     RangeInRevision(const CursorInRevision& _start, const CursorInRevision& _end) : start(_start)
0032         , end(_end)
0033     {
0034     }
0035 
0036     RangeInRevision(const CursorInRevision& _start, int length) : start(_start)
0037         , end(_start.line, _start.column + length)
0038     {
0039     }
0040 
0041     RangeInRevision()
0042     {
0043     }
0044 
0045     RangeInRevision(int sLine, int sCol, int eLine, int eCol) : start(sLine, sCol)
0046         , end(eLine, eCol)
0047     {
0048     }
0049 
0050     static RangeInRevision invalid()
0051     {
0052         return RangeInRevision(-1, -1, -1, -1);
0053     }
0054 
0055     bool isValid() const
0056     {
0057         return start.column != -1 || start.line != -1 || end.column != -1 || end.line != -1;
0058     }
0059 
0060     bool isEmpty() const
0061     {
0062         return start == end;
0063     }
0064 
0065     enum ContainsBehavior {
0066         Default = 0,
0067         IncludeBackEdge = 1
0068     };
0069     /**
0070      * Checks if @p position is contained within this range (i.e. >= start and < end)
0071      * If @p cb is IncludeBackEdge, also checks that @p position == end
0072      */
0073     bool contains(const CursorInRevision& position, ContainsBehavior cb = Default) const
0074     {
0075         return (position >= start && position < end) || (cb == IncludeBackEdge && position == end);
0076     }
0077 
0078     bool contains(const RangeInRevision& range) const
0079     {
0080         return range.start >= start && range.end <= end;
0081     }
0082 
0083     bool operator ==(const RangeInRevision& rhs) const
0084     {
0085         return start == rhs.start && end == rhs.end;
0086     }
0087 
0088     bool operator !=(const RangeInRevision& rhs) const
0089     {
0090         return !(*this == rhs);
0091     }
0092 
0093     bool operator <(const RangeInRevision& rhs) const
0094     {
0095         return start < rhs.start;
0096     }
0097 
0098     /// @warning Using this is wrong in most cases! If you want
0099     ///  to transform this range to the current revision, you should do a proper
0100     ///  mapping instead through @ref KDevelop::DUChainBase or @ref KDevelop::RevisionReference
0101     ///  or @ref KDevelop::DocumentChangeTracker
0102     KTextEditor::Range castToSimpleRange() const
0103     {
0104         return KTextEditor::Range(start.castToSimpleCursor(), end.castToSimpleCursor());
0105     }
0106 
0107     /// @warning Using this is wrong in most cases! If you want
0108     ///  to transform this range to the current revision, you should do a proper
0109     ///  mapping instead through @ref KDevelop::DUChainBase or @ref KDevelop::RevisionReference
0110     ///  or @ref KDevelop::DocumentChangeTracker
0111     static RangeInRevision castFromSimpleRange(const KTextEditor::Range& range)
0112     {
0113         return RangeInRevision(range.start().line(), range.start().column(), range.end().line(), range.end().column());
0114     }
0115     ///qDebug() stream operator.  Writes this range to the debug output in a nicely formatted way.
0116     inline friend QDebug operator<<(QDebug s, const RangeInRevision& range)
0117     {
0118         s.nospace() << '[' << range.start << ", " << range.end << ']';
0119         return s.space();
0120     }
0121 };
0122 
0123 inline uint qHash(const KDevelop::RangeInRevision& range)
0124 {
0125     return qHash(range.start) + qHash(range.end) * 41;
0126 }
0127 } // namespace KDevelop
0128 
0129 Q_DECLARE_TYPEINFO(KDevelop::RangeInRevision, Q_MOVABLE_TYPE);
0130 Q_DECLARE_METATYPE(KDevelop::RangeInRevision)
0131 
0132 #endif