6#ifdef QDOC_TEMPLATE_GENERATOR_ENABLED
9#include "inclusionfilter.h"
10#include "qmltypenode.h"
14#include <QtCore/qfileinfo.h>
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
38
39
40
41
42
43
44
46HrefResolver::HrefResolver(
const HrefResolverConfig &config)
52
53
54
55
56
57
58QString HrefResolver::fileBase(
const Node *node)
const
60 if (!node->isPageNode() && !node->isCollectionNode()) {
61 node = node->parent();
66 if (node->hasFileNameBase())
67 return node->fileNameBase();
69 auto it = m_fileBaseCache.constFind(node);
70 if (it != m_fileBaseCache.constEnd())
73 QString result = Utilities::computeFileBase(
74 node, m_config.project,
75 m_config.outputPrefixFn,
76 m_config.outputSuffixFn);
78 m_fileBaseCache.insert(node, result);
83
84
85
86
87
88
89
90QString HrefResolver::fileName(
const Node *node)
const
92 if (!node->url().isEmpty())
95 const auto base = fileBase(node);
99 if (node->isTextPageNode() && !node->isCollectionNode()) {
100 QFileInfo originalName(node->name());
101 QString suffix = originalName.suffix();
102 if (!suffix.isEmpty() && suffix !=
"html"_L1)
103 return base +
'.'_L1 + suffix;
106 return base +
'.'_L1 + m_config.fileExtension;
110
111
112
113
114
115
116
117
118
119QString HrefResolver::anchorForNode(
const Node *node)
const
121 const QString ref = computeAnchorId(node);
124 return m_config.cleanRefFn ? m_config.cleanRefFn(ref) : ref;
128
129
130
131
132
133
134
135
136
137HrefResult HrefResolver::hrefForNode(
const Node *node,
const Node *relative)
const
140 return HrefSuppressReason::NullNode;
141 if (!node->url().isEmpty())
144 QString fn = fileName(node);
146 return HrefSuppressReason::NoFileBase;
148 const NodeContext context = node->createContext();
149 if (!InclusionFilter::isIncluded(m_config.inclusionPolicy, context))
150 return HrefSuppressReason::ExcludedByPolicy;
152 if (node->parent() && node->parent()->isQmlType() && node->parent()->isAbstract()) {
153 const QmlTypeNode *qmlContext = m_config.qmlTypeContextFn
154 ? m_config.qmlTypeContextFn() :
nullptr;
156 if (qmlContext->inherits(node->parent())) {
157 fn = fileName(qmlContext);
158 }
else if (node->parent()->isInternal() && !m_config.noLinkErrors) {
159 node->doc().location().warning(
160 u"Cannot link to property in internal type '%1'"_s
161 .arg(node->parent()->name()));
162 return HrefSuppressReason::InternalAbstractQml;
169 if (!node->isPageNode() || node->isPropertyGroup()) {
170 QString ref = anchorForNode(node);
171 if (relative && fn == fileName(relative) && ref == anchorForNode(relative))
172 return HrefSuppressReason::SameFileAnchor;
178 if (relative && (node != relative)) {
179 if (m_config.useOutputSubdirs && !node->isExternalPage()
180 && (node->isIndexNode() || node->tree() != relative->tree()))
181 link.prepend(
"../%1/"_L1.arg(node->tree()->physicalModuleName()));