File indexing completed on 2024-05-19 15:42:36

0001 /*
0002     SPDX-FileCopyrightText: 2012 Sven Brauch svenbrauch @googlemail.com
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef CODEHELPERS_H
0008 #define CODEHELPERS_H
0009 #include <QString>
0010 #include <QStringList>
0011 #include <KTextEditor/Document>
0012 #include "parserexport.h"
0013 
0014 namespace Python {
0015     
0016 // helper class that lazy fetches lines from a document, for performance gain
0017 class KDEVPYTHONPARSER_EXPORT LazyLineFetcher {
0018 public:
0019     virtual QString fetchLine(int lineno) = 0;
0020     virtual ~LazyLineFetcher() { };
0021 };
0022 
0023 class KDEVPYTHONPARSER_EXPORT TrivialLazyLineFetcher : public LazyLineFetcher {
0024 public:
0025     TrivialLazyLineFetcher(QStringList lines) : m_lines(lines) { }
0026     QString fetchLine(int lineno) override {
0027         return m_lines.at(lineno);
0028     };
0029 private:
0030     QStringList m_lines;
0031 };
0032 
0033 class KDEVPYTHONPARSER_EXPORT TextDocumentLazyLineFetcher : public LazyLineFetcher {
0034 public:
0035     TextDocumentLazyLineFetcher(KTextEditor::Document* d) :
0036       m_document(d) { };
0037     QString fetchLine(int lineno) override {
0038         return m_document->line(lineno);
0039     };
0040 private:
0041     KTextEditor::Document* m_document;
0042 };
0043 
0044 class KDEVPYTHONPARSER_EXPORT FileIndentInformation {
0045 public:
0046     FileIndentInformation(const QStringList& lines);
0047     FileIndentInformation(KTextEditor::Document* document);
0048     FileIndentInformation(const QByteArray& data);
0049     FileIndentInformation(const QString& data);
0050     
0051     enum ScanDirection {
0052         Forward,
0053         Backward
0054     };
0055     
0056     enum ChangeTypes {
0057         Indent,
0058         Dedent,
0059         AnyChange
0060     };
0061     
0062     int indentForLine(int line) const;
0063     int linesCount() const;
0064     int nextChange(int line, ChangeTypes type, ScanDirection direction = Forward) const;
0065 private:
0066     QList<int> m_indents;
0067     void initialize(const QStringList& lines);
0068 };
0069 
0070 class KDEVPYTHONPARSER_EXPORT CodeHelpers
0071 {
0072     public:
0073         enum EndLocation {
0074             Code,
0075             String,
0076             Comment
0077         };
0078 
0079         CodeHelpers();
0080         /**
0081          * @brief Get the python expression at the specified cursor.
0082          *
0083          * @param lineFetcher An object which is used to get lines from the document
0084          * @param cursor where to search for the expression
0085          * @param forceScanExpression Start scanning even if the first char is non-alphanumeric. Defaults to false.
0086          * @return QString the expression which was found, as string.
0087          **/
0088         static QString expressionUnderCursor(LazyLineFetcher& lineFetcher, KTextEditor::Cursor cursor,
0089                                              KTextEditor::Cursor& start, bool forceScanExpression = false);
0090         
0091         /**
0092          * @brief Replaces all quoted strings with "S" in the given expression.
0093          * TODO this does not work correctly, I think.
0094          * 
0095          * @param stringWithStrings some python code which may contain strings
0096          * @return QString the input code, with all strings replaced by "S", so 'foo("fancy\"\"\"''__/string")' -> 'foo("S")'
0097          **/
0098         static QString killStrings(QString stringWithStrings);
0099         
0100         /**
0101          * @brief Check whether the given code ends inside a comment.
0102          **/
0103         static EndLocation endsInside(const QString &code);
0104 
0105         /**
0106          * @brief Extracts the string which is under the cursor, if one is present
0107          *
0108          * @param code the code, which to scan
0109          * @param range the range in the document, which contains this code
0110          * @param cursor the location of the cursor in the document
0111          * @param cursorPositionInString optional return value, which is set to
0112          *        the relative position of the cursor inside the string
0113          * @return The string under the cursor, or an empty string if none is available.
0114          */
0115         static QString extractStringUnderCursor(const QString &code, KTextEditor::Range range, KTextEditor::Cursor cursor, int *cursorPositionInString);
0116 
0117         /**
0118          * @brief Splits the given code, which is assumed to be contained in
0119          *        the range provided range, in two pieces: before and after the
0120          *        cursor.
0121          * @param code some code to split
0122          * @param range the range in the document, which contains this code
0123          * @param cursor the location of the cursor in the document
0124          * @return A pair of strings, containing the code and the code after
0125          *         the cursor
0126          */
0127         static QPair<QString, QString> splitCodeByCursor(const QString &code, KTextEditor::Range range, KTextEditor::Cursor cursor);
0128 };
0129 }
0130 
0131 #endif // CODEHELPERS_H
0132 
0133 class C;