aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-04 11:29:58 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-04 14:42:20 +0000
commit009c7413952c01c7ba4722aa73c968e07dc17e04 (patch)
treeb172946d8d7011c3a95827d6c3f0f27b217e1b12
parent7de80955ccb5383d07183c119b834d12cecedd0c (diff)
shiboken: Allow for include paths with relative directories
Resolve the absolute file paths of the code model items against the include paths of shiboken to reconstruct the relative paths. Change-Id: Id0f793315b01c0fc65a4cfb26b3372f9c6688872 Fixes: PYSIDE-975 Reviewed-by: Volker Aßmann <volker.assmann@gmail.com> Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp50
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h2
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h2
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.cpp1
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp14
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h11
-rw-r--r--sources/shiboken2/generator/main.cpp6
7 files changed, 71 insertions, 15 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 655d44833..685cbb78d 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -3197,16 +3197,60 @@ void AbstractMetaBuilder::setGlobalHeader(const QString& globalHeader)
d->m_globalHeader = QFileInfo(globalHeader);
}
+void AbstractMetaBuilder::setHeaderPaths(const HeaderPaths &hp)
+{
+ for (const auto & h: hp) {
+ if (h.type != HeaderType::Framework && h.type != HeaderType::FrameworkSystem)
+ d->m_headerPaths.append(QFile::decodeName(h.path));
+ }
+}
+
void AbstractMetaBuilder::setSkipDeprecated(bool value)
{
d->m_skipDeprecated = value;
}
+// PYSIDE-975: When receiving an absolute path name from the code model, try
+// to resolve it against the include paths set on shiboken in order to recreate
+// relative paths like #include <foo/bar.h>.
+
+static inline bool isFileSystemSlash(QChar c)
+{
+ return c == QLatin1Char('/') || c == QLatin1Char('\\');
+}
+
+static bool matchHeader(const QString &headerPath, const QString &fileName)
+{
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN)
+ static const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
+#else
+ static const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
+#endif
+ const int pathSize = headerPath.size();
+ return fileName.size() > pathSize
+ && isFileSystemSlash(fileName.at(pathSize))
+ && fileName.startsWith(headerPath, caseSensitivity);
+}
+
void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &fileName) const
{
- QFileInfo info(fileName);
- if (m_globalHeader.fileName() != info.fileName())
- te->setInclude(Include(Include::IncludePath, info.fileName()));
+ auto it = m_resolveIncludeHash.find(fileName);
+ if (it == m_resolveIncludeHash.end()) {
+ QFileInfo info(fileName);
+ if (m_globalHeader.fileName() == info.fileName())
+ return;
+
+ int bestMatchLength = 0;
+ for (const auto &headerPath : m_headerPaths) {
+ if (headerPath.size() > bestMatchLength && matchHeader(headerPath, fileName))
+ bestMatchLength = headerPath.size();
+ }
+ const QString include = bestMatchLength > 0
+ ? fileName.right(fileName.size() - bestMatchLength - 1)
+ : info.fileName();
+ it = m_resolveIncludeHash.insert(fileName, {Include::IncludePath, include});
+ }
+ te->setInclude(it.value());
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index ed89060ac..1789ca2aa 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -30,6 +30,7 @@
#define ABSTRACTMETABUILDER_H
#include "abstractmetalang_typedefs.h"
+#include "header_paths.h"
#include "dependency.h"
#include "clangparser/compilersupport.h"
@@ -85,6 +86,7 @@ public:
* filled.
*/
void setGlobalHeader(const QString& globalHeader);
+ void setHeaderPaths(const HeaderPaths &h);
void setSkipDeprecated(bool value);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 8466fd50a..8d5b924dd 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -183,6 +183,8 @@ public:
QString m_logDirectory;
QFileInfo m_globalHeader;
+ QStringList m_headerPaths;
+ mutable QHash<QString, Include> m_resolveIncludeHash;
bool m_skipDeprecated;
};
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp
index e301d891f..fbe7664e9 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp
@@ -224,6 +224,7 @@ bool ApiExtractor::run()
m_builder->setLogDirectory(m_logDirectory);
m_builder->setGlobalHeader(m_cppFileName);
m_builder->setSkipDeprecated(m_skipDeprecated);
+ m_builder->setHeaderPaths(m_includePaths);
QByteArrayList arguments;
arguments.reserve(m_includePaths.size() + 1);
for (const HeaderPath &headerPath : qAsConst(m_includePaths))
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index ad97e40ee..3bb2f0efa 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -3483,6 +3483,20 @@ static const QSet<QString> &primitiveCppTypes()
return result;
}
+void TypeEntry::setInclude(const Include &inc)
+{
+ // This is a workaround for preventing double inclusion of the QSharedPointer implementation
+ // header, which does not use header guards. In the previous parser this was not a problem
+ // because the Q_QDOC define was set, and the implementation header was never included.
+ if (inc.name().endsWith(QLatin1String("qsharedpointer_impl.h"))) {
+ QString path = inc.name();
+ path.remove(QLatin1String("_impl"));
+ m_include = Include(inc.type(), path);
+ } else {
+ m_include = inc;
+ }
+}
+
bool TypeEntry::isCppPrimitive() const
{
if (!isPrimitive())
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 96d0bb5fd..1e1b04136 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -835,16 +835,7 @@ public:
{
return m_include;
}
- void setInclude(const Include &inc)
- {
- // This is a workaround for preventing double inclusion of the QSharedPointer implementation
- // header, which does not use header guards. In the previous parser this was not a problem
- // because the Q_QDOC define was set, and the implementation header was never included.
- if (inc.name() == QLatin1String("qsharedpointer_impl.h"))
- m_include = Include(inc.type(), QLatin1String("qsharedpointer.h"));
- else
- m_include = inc;
- }
+ void setInclude(const Include &inc);
// Replace conversionRule arg to CodeSnip in future version
/// Set the type convertion rule
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 094990b64..1817f6b03 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -373,8 +373,10 @@ static void parseIncludePathOption(const QString &option, HeaderType headerType,
const QStringList includePathListList =
it.value().split(pathSplitter, QString::SkipEmptyParts);
args.erase(it);
- for (const QString &s : includePathListList)
- extractor.addIncludePath(HeaderPath{QFile::encodeName(s), headerType});
+ for (const QString &s : includePathListList) {
+ auto path = QFile::encodeName(QDir::cleanPath(s));
+ extractor.addIncludePath(HeaderPath{path, headerType});
+ }
}
}