aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/typesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/typesystem.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp84
1 files changed, 83 insertions, 1 deletions
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 920da9e10..729e6b32b 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -34,6 +34,7 @@
#include <QtCore/QSet>
#include <algorithm>
+#include <limits>
static QString strings_Object = QLatin1String("Object");
static QString strings_String = QLatin1String("String");
@@ -212,7 +213,7 @@ QString TemplateInstance::expandCode() const
if (!code.startsWith(QLatin1Char('\n')))
result += QLatin1Char('\n');
result += code;
- result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END");
+ result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END\n");
return result;
}
@@ -226,6 +227,82 @@ QString CodeSnipAbstract::code() const
return res;
}
+void CodeSnipAbstract::addCode(const QString &code)
+{
+ codeList.append(CodeSnipFragment(fixSpaces(code)));
+}
+
+template <class String> // QString, QStringRef
+static inline int firstNonBlank(const String &s)
+{
+ const auto it = std::find_if(s.cbegin(), s.cend(),
+ [] (QChar c) { return !c.isSpace(); });
+ return int(it - s.cbegin());
+}
+
+template <class String> // QString, QStringRef
+static inline bool isEmpty(const String &s)
+{
+ return s.isEmpty()
+ || std::all_of(s.cbegin(), s.cend(),
+ [] (QChar c) { return c.isSpace(); });
+}
+
+QString CodeSnipAbstract::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(QLatin1Char('\n')))
+ return code.trimmed();
+ const auto lines = code.splitRef(QLatin1Char('\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 += QLatin1Char('\n');
+ }
+ return result;
+}
+
+QString CodeSnipAbstract::fixSpaces(QString code)
+{
+ code.remove(QLatin1Char('\r'));
+ // Check for XML <tag>\n<space>bla...
+ if (code.startsWith(QLatin1String("\n ")))
+ code.remove(0, 1);
+ while (!code.isEmpty() && code.back().isSpace())
+ code.chop(1);
+ code = dedent(code);
+ if (!code.isEmpty() && !code.endsWith(QLatin1Char('\n')))
+ code.append(QLatin1Char('\n'));
+ return code;
+}
+
+// Prepend a line to the code, observing indentation
+void CodeSnipAbstract::prependCode(QString *code, QString firstLine)
+{
+ while (!code->isEmpty() && code->front() == QLatin1Char('\n'))
+ code->remove(0, 1);
+ if (!code->isEmpty() && code->front().isSpace()) {
+ const int indent = firstNonBlank(*code);
+ firstLine.prepend(QString(indent, QLatin1Char(' ')));
+ }
+ if (!firstLine.endsWith(QLatin1Char('\n')))
+ firstLine += QLatin1Char('\n');
+ code->prepend(firstLine);
+}
+
QString CodeSnipFragment::code() const
{
return m_instance ? m_instance->expandCode() : m_code;
@@ -1184,3 +1261,8 @@ TypeEntry *ObjectTypeEntry::clone() const
}
ObjectTypeEntry::ObjectTypeEntry(const ObjectTypeEntry &) = default;
+
+void DocModification::setCode(const QString &code)
+{
+ m_code = CodeSnipAbstract::fixSpaces(code);
+}