diff options
Diffstat (limited to 'sources/shiboken6/ApiExtractor/codesniphelpers.cpp')
-rw-r--r-- | sources/shiboken6/ApiExtractor/codesniphelpers.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/codesniphelpers.cpp b/sources/shiboken6/ApiExtractor/codesniphelpers.cpp new file mode 100644 index 000000000..775cf10af --- /dev/null +++ b/sources/shiboken6/ApiExtractor/codesniphelpers.cpp @@ -0,0 +1,77 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "codesniphelpers.h" + +#include <QtCore/QStringList> + +#include <algorithm> + +static inline int firstNonBlank(QStringView s) +{ + const auto it = std::find_if(s.cbegin(), s.cend(), + [] (QChar c) { return !c.isSpace(); }); + return int(it - s.cbegin()); +} + +static inline bool isEmpty(QStringView s) +{ + return s.isEmpty() + || std::all_of(s.cbegin(), s.cend(), + [] (QChar c) { return c.isSpace(); }); +} + +QString CodeSnipHelpers::dedent(const QString &code) +{ + if (code.isEmpty()) + return code; + // Right trim if indent=0, or trim if single line + if (!code.at(0).isSpace() || !code.contains(u'\n')) + return code.trimmed(); + const auto lines = QStringView{code}.split(u'\n'); + int spacesToRemove = std::numeric_limits<int>::max(); + for (const auto &line : lines) { + if (!isEmpty(line)) { + const int nonSpacePos = firstNonBlank(line); + if (nonSpacePos < spacesToRemove) + spacesToRemove = nonSpacePos; + if (spacesToRemove == 0) + return code; + } + } + QString result; + for (const auto &line : lines) { + if (!isEmpty(line) && spacesToRemove < line.size()) + result += line.mid(spacesToRemove).toString(); + result += u'\n'; + } + return result; +} + +QString CodeSnipHelpers::fixSpaces(QString code) +{ + code.remove(u'\r'); + // Check for XML <tag>\n<space>bla... + if (code.startsWith(u"\n ")) + code.remove(0, 1); + while (!code.isEmpty() && code.back().isSpace()) + code.chop(1); + code = dedent(code); + if (!code.isEmpty() && !code.endsWith(u'\n')) + code.append(u'\n'); + return code; +} + +// Prepend a line to the code, observing indentation +void CodeSnipHelpers::prependCode(QString *code, QString firstLine) +{ + while (!code->isEmpty() && code->front() == u'\n') + code->remove(0, 1); + if (!code->isEmpty() && code->front().isSpace()) { + const int indent = firstNonBlank(*code); + firstLine.prepend(QString(indent, u' ')); + } + if (!firstLine.endsWith(u'\n')) + firstLine += u'\n'; + code->prepend(firstLine); +} |