5#ifndef QQMLJSLOGGER_P_H
6#define QQMLJSLOGGER_P_H
19#include <qtqmlcompilerexports.h>
24#include <private/qqmljsdiagnosticmessage_p.h>
26#include <QtCore/qhash.h>
27#include <QtCore/qmap.h>
28#include <QtCore/qstring.h>
29#include <QtCore/qlist.h>
30#include <QtCore/qset.h>
31#include <QtCore/QLoggingCategory>
38
39
40
45
46
47
48
49 IssueLocationWithContext(QStringView code,
const QQmlJS::SourceLocation &location) {
50 quint32 before = qMax(0, code.lastIndexOf(QLatin1Char(
'\n'), location.offset));
52 if (before != 0 && before < location.offset)
55 m_beforeText = code.mid(before, location.offset - before);
56 m_issueText = code.mid(location.offset, location.length);
57 int after = code.indexOf(QLatin1Char(
'\n'), location.offset + location.length);
58 m_afterText = code.mid(location.offset + location.length,
59 after - (location.offset+location.length));
63 QStringView beforeText()
const {
return m_beforeText; }
65 QStringView issueText()
const {
return m_issueText; }
67 QStringView afterText()
const {
return m_afterText; }
70 QStringView m_beforeText;
71 QStringView m_issueText;
72 QStringView m_afterText;
77 Q_DECLARE_EQUALITY_COMPARABLE(QQmlJSDocumentEdit)
84 const QQmlJSDocumentEdit &other)
noexcept
86 return self.m_filename == other.m_filename && self.m_location == other.m_location
87 && self.m_replacement == other.m_replacement;
94 QQmlJSFixSuggestion() =
default;
95 QQmlJSFixSuggestion(
const QString &description,
const QQmlJS::SourceLocation &location,
96 const QQmlJSDocumentEdit &);
97 QQmlJSFixSuggestion(
const QString &description,
const QQmlJS::SourceLocation &location,
98 const QList<QQmlJSDocumentEdit> & = {});
100 QString description()
const {
return m_description; }
101 QQmlJS::SourceLocation location()
const {
return m_location; }
103 void addDocumentEdit(
const QQmlJSDocumentEdit &documentEdit);
104 void setDocumentEdits(
const QList<QQmlJSDocumentEdit> &documentEdits);
105 QList<QQmlJSDocumentEdit> documentEdits()
const {
return m_documentEdits; }
107 void setFilename(
const QString &filename) { m_filename = filename; }
108 QString filename()
const {
return m_filename; }
110 void setAutoApplicable(
bool autoApply =
true) { m_autoApplicable = autoApply; }
111 bool isAutoApplicable()
const {
return m_autoApplicable; }
113 bool operator==(
const QQmlJSFixSuggestion &)
const;
114 bool operator!=(
const QQmlJSFixSuggestion &)
const;
117 QString m_description;
119 QQmlJS::SourceLocation m_location;
120 QList<QQmlJSDocumentEdit> m_documentEdits;
121 bool m_autoApplicable =
false;
140 Q_DISABLE_COPY_MOVE(QQmlJSLogger)
142 QList<QQmlJS::LoggerCategory> categories()
const;
148 ~QQmlJSLogger() =
default;
159 for (
const Message &msg : m_currentFunctionMessages)
166 for (
const Message &msg : m_archivedMessages)
169 for (
const Message &msg : m_currentFunctionMessages)
175 return m_categorySeverities[id.name().toString()];
179 m_categorySeverities[id.name().toString()] = severity;
180 m_categoryChanged[id.name().toString()] =
true;
185 return m_categoryChanged[id.name().toString()];
198
199
200
201
202
203
204 void log(
const QString &message, QQmlJS::LoggerWarningId id,
205 const QQmlJS::SourceLocation &srcLocation,
bool showContext =
true,
206 bool showFileName =
true,
const std::optional<QQmlJSFixSuggestion> &suggestion = {},
207 std::optional<quint32> customLineForDisabling =
std::nullopt)
209 const auto &severityForCategory = m_categorySeverities[id.name().toString()];
214 QQmlJS::DiagnosticMessage {
216 QtMsgType(severityForCategory),
221 Message::CompilationStatus::Normal,
222 customLineForDisabling
223 }, showContext, showFileName);
226 void logCompileError(
const QString &message,
const QQmlJS::SourceLocation &srcLocation)
228 if (m_compileErrorSeverity == QQmlJS::WarningSeverity::Disable)
232 m_hasPendingCompileError =
true;
234 m_hasCompileError =
true;
237 QQmlJS::DiagnosticMessage {
238 m_compileErrorPrefix + message,
239 QtMsgType(m_compileErrorSeverity),
244 Message::CompilationStatus::Error
249 void logCompileSkip(
const QString &message,
const QQmlJS::SourceLocation &srcLocation)
251 if (m_compileSkipSeverity == QQmlJS::WarningSeverity::Disable)
254 m_hasCompileSkip =
true;
256 QQmlJS::DiagnosticMessage {
257 m_compileSkipPrefix + message,
258 QtMsgType(m_compileSkipSeverity),
263 Message::CompilationStatus::Skip
268 const QQmlJS::LoggerWarningId id,
273 m_ignoredWarnings[line] = categories;
276 void setSilent(
bool silent) { m_output.setSilent(silent); }
277 bool isSilent()
const {
return m_output.isSilent(); }
280
281
282
283
284
285
286
287
291 void setCode(
const QString &code) { m_code = code; }
294 void setFilePath(
const QString &filePath) { m_filePath = filePath; }
299 return m_hasCompileError || m_hasPendingCompileError;
304 return m_hasCompileSkip;
314 for (
const Message &message : m_currentFunctionMessages) {
315 if (message.compilationStatus == Message::CompilationStatus::Error)
316 return message.message;
324 for (
const Message &message : m_currentFunctionMessages) {
325 if (message.compilationStatus == Message::CompilationStatus::Skip)
326 return message.message;
339 QMap<QString, QQmlJS::LoggerCategory> m_categories;
341 void printContext(
const QQmlJS::SourceLocation &location);
342 void printFix(
const QQmlJSFixSuggestion &fix);
344 void log(
Message &&diagMsg,
bool showContext =
false,
bool showFileName =
true);
346 void countMessage(
const Message &message);
351 QColorOutput m_output;
353 QHash<QString, QQmlJS::WarningSeverity> m_categorySeverities;
354 QHash<QString,
bool> m_categoryChanged;
356 QList<Message> m_pendingMessages;
357 QList<Message> m_currentFunctionMessages;
358 QList<Message> m_archivedMessages;
359 QHash<uint32_t, QSet<QString>> m_ignoredWarnings;
361 QString m_compileErrorPrefix;
362 QString m_compileSkipPrefix;
364 qsizetype m_numWarnings = 0;
365 qsizetype m_numErrors = 0;
366 bool m_inTransaction =
false;
367 bool m_hasCompileError =
false;
368 bool m_hasPendingCompileError =
false;
369 bool m_hasCompileSkip =
false;
370 bool m_isDisabled =
false;
std::optional< QQmlJSFixSuggestion > fixSuggestion
CompilationStatus compilationStatus
quint32 lineForDisabling() const
std::optional< quint32 > customLineForDisabling
friend bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are equal, otherwise returns false.
friend bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are different, otherwise returns false.
QString fileName() const
If the currently assigned device is a QFile, or if setFileName() has been called, this function retur...
void setFileName(const QString &fileName)
Sets the file name of QImageReader to fileName.
virtual Type type() const =0
Reimplement this function to return the paint engine \l{Type}.
virtual bool isValid() const
void logCompileSkip(const QString &message, const QQmlJS::SourceLocation &srcLocation)
bool currentFunctionWasSkipped() const
QString compileSkipPrefix() const
qsizetype numErrors() const
QQmlJS::WarningSeverity compileErrorSeverity() const
void setCode(const QString &code)
bool currentFunctionHasErrorOrSkip() const
void setFilePath(const QString &filePath)
void setCategorySeverity(QQmlJS::LoggerWarningId id, QQmlJS::WarningSeverity severity)
bool currentFunctionHasCompileError() const
void log(const QString &message, QQmlJS::LoggerWarningId id, const QQmlJS::SourceLocation &srcLocation, bool showContext=true, bool showFileName=true, const std::optional< QQmlJSFixSuggestion > &suggestion={}, std::optional< quint32 > customLineForDisabling=std::nullopt)
void logCompileError(const QString &message, const QQmlJS::SourceLocation &srcLocation)
void setSilent(bool silent)
QQmlJS::WarningSeverity categorySeverity(QQmlJS::LoggerWarningId id) const
bool wasCategoryChanged(QQmlJS::LoggerWarningId id) const
void processMessages(QSpan< const QQmlJS::DiagnosticMessage > messages, const QQmlJS::LoggerWarningId id, const QQmlJS::SourceLocation &sourceLocation=QQmlJS::SourceLocation{})
QString currentFunctionCompileErrorMessage() const
void iterateCurrentFunctionMessages(F &&f) const
QString compileErrorPrefix() const
void iterateAllMessages(F &&f) const
qsizetype numWarnings() const
void setIsDisabled(bool isDisabled)
void setCompileErrorPrefix(const QString &prefix)
QString currentFunctionCompileSkipMessage() const
static const QList< QQmlJS::LoggerCategory > & builtinCategories()
void setCompileErrorSeverity(QQmlJS::WarningSeverity severity)
void setCompileSkipPrefix(const QString &prefix)
void registerCategory(const QQmlJS::LoggerCategory &category)
void ignoreWarnings(uint32_t line, const QSet< QString > &categories)
QQmlJSRegisterContent createMethod(const QList< QQmlJSMetaMethod > &methods, const QQmlJSScope::ConstPtr &methodType, ContentVariant variant, QQmlJSRegisterContent scope)
QQmlJSRegisterContent createImportNamespace(uint importNamespaceStringId, const QQmlJSScope::ConstPtr &importNamespaceType, ContentVariant variant, QQmlJSRegisterContent scope)
QQmlJSRegisterContent createProperty(const QQmlJSMetaProperty &property, int baseLookupIndex, int resultLookupIndex, ContentVariant variant, QQmlJSRegisterContent scope)
void adjustType(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &adjusted)
void generalizeType(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &generalized)
void storeType(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &stored)
QQmlJSRegisterContent castTo(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &newContainedType)
QQmlJSRegisterContent createEnumeration(const QQmlJSMetaEnum &enumeration, const QString &enumMember, ContentVariant variant, QQmlJSRegisterContent scope)
void setAllocationMode(AllocationMode mode)
QQmlJSRegisterContent storedIn(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &newStoredType)
QQmlJSRegisterContent clone(QQmlJSRegisterContent from)
QQmlJSRegisterContentPool()
QQmlJSRegisterContent createType(const QQmlJSScope::ConstPtr &type, int resultLookupIndex, ContentVariant variant, QQmlJSRegisterContent scope={})
QQmlJSRegisterContent createConversion(const QList< QQmlJSRegisterContent > &origins, const QQmlJSScope::ConstPtr &conversion, QQmlJSRegisterContent conversionScope, ContentVariant variant, QQmlJSRegisterContent scope)
QQmlJSRegisterContent createMethodCall(const QQmlJSMetaMethod &method, const QQmlJSScope::ConstPtr &returnType, QQmlJSRegisterContent scope)
Tracks the types for the QmlCompiler.
QTypeRevision revision() const
QTypeRevision version() const
Export(QString package, QString type, QTypeRevision version, QTypeRevision revision)
virtual QQmlSourceLocation sourceLocation() const
static BindingPrivate * get(Binding *binding)
static QQmlJSMetaPropertyBinding binding(QQmlSA::Binding &binding)
Element bindingScope() const
void setPropertyName(QString name)
static QQmlSA::Binding createBinding(const QQmlJSMetaPropertyBinding &)
static const QQmlJSMetaPropertyBinding binding(const QQmlSA::Binding &binding)
void setIsAttached(bool isAttached)
BindingPrivate(Binding *, const BindingPrivate &)
void setBindingScope(Element bindingScope)
static const BindingPrivate * get(const Binding *binding)
Element attachedType() const
Returns the attached type if the content type of this binding is AttachedProperty,...
BindingType bindingType() const
Returns the type of this binding.
Element bindingScope() const
Returns the Element scope in which the binding is defined.
friend bool operator!=(const Binding &lhs, const Binding &rhs)
Returns true if lhs and rhs are not equal, and false otherwise.
bool hasUndefinedScriptValue() const
Returns whether this binding has script value type undefined like when it is assigned undefined.
Binding(const Binding &)
Creates a copy of other.
Binding & operator=(const Binding &)
Assigns other to this Binding instance.
bool isAttached() const
Returns true if this type is attached to another one, false otherwise.
bool hasObject() const
Returns true if this binding has an objects, otherwise returns false.
friend bool operator==(const Binding &lhs, const Binding &rhs)
Returns true if lhs and rhs are equal, and false otherwise.
static bool isLiteralBinding(BindingType)
Returns true if bindingType is a literal type, and false otherwise.
QString propertyName() const
Returns the name of the property bound with this binding.
Binding()
Constructs a new Binding object.
QString stringValue() const
Returns the associated string literal if the content type of this binding is StringLiteral,...
Element objectType() const
Returns the type of the associated object if the content type of this binding is Object,...
Binding & operator=(Binding &&) noexcept
Move-assigns other to this Binding instance.
QQmlSA::SourceLocation sourceLocation() const
Returns the location in the QML code where this binding is defined.
ScriptBindingKind scriptKind() const
Returns the kind of the associated script if the content type of this binding is Script,...
double numberValue() const
Returns the associated number if the content type of this binding is NumberLiteral,...
Element groupType() const
Returns the type of the property of this binding if it is a group property, otherwise returns an inva...
bool hasFunctionScriptValue() const
Returns whether this binding has script value type function like when it is assigned a (lambda) metho...
~BindingsPrivate()=default
QMultiHash< QString, Binding >::const_iterator constBegin() const
BindingsPrivate(QQmlSA::Binding::Bindings *, const BindingsPrivate &)
friend class QT_PREPEND_NAMESPACE(QQmlJSMetaPropertyBinding)
QMultiHash< QString, Binding >::const_iterator constEnd() const
DocumentEditPrivate(DocumentEdit *, DocumentEditPrivate &&)
static QQmlJSDocumentEdit documentEdit(const DocumentEdit &edit)
QString replacement() const
DocumentEditPrivate(DocumentEdit *, const DocumentEditPrivate &)
SourceLocation location() const
static QList< QQmlJSDocumentEdit > documentEdits(const QList< DocumentEdit > &edits)
static DocumentEdit createQQmlSADocumentEdit(const QQmlJSDocumentEdit &edit)
~DocumentEditPrivate()=default
QString replacement() const
Returns the replacement string of the edit.
QString filename() const
Returns the file this edit applies to.
DocumentEdit(const DocumentEdit &)
Creates a copy of other.
QList< DocumentEdit > documentEdits() const
SourceLocation location() const
QString description() const
static FixSuggestion createQQmlSAFixSuggestion(const QQmlJSFixSuggestion &)
FixSuggestionPrivate(FixSuggestion *, const QString &description, const SourceLocation &location, const QList< DocumentEdit > &documentEdits={})
void setFileName(const QString &)
void addDocumentEdit(const DocumentEdit &)
FixSuggestionPrivate(FixSuggestion *)
bool isAutoApplicable() const
void setAutoApplicable(bool autoApplicable=true)
static const QQmlJSFixSuggestion & fixSuggestion(const QQmlSA::FixSuggestion &)
FixSuggestionPrivate(FixSuggestion *, FixSuggestionPrivate &&)
~FixSuggestionPrivate()=default
static QQmlJSFixSuggestion & fixSuggestion(QQmlSA::FixSuggestion &)
FixSuggestionPrivate(FixSuggestion *, const FixSuggestionPrivate &)
FixSuggestion(const QString &description, const QQmlSA::SourceLocation &location, const QList< DocumentEdit > &documentEdits={})
Creates a FixSuggestion object.
void addDocumentEdit(const DocumentEdit &)
Adds a document edit to the list of edits for this fix.
FixSuggestion(const FixSuggestion &)
Creates a copy of other.
QString description() const
Returns the description of the fix.
bool isAutoApplicable() const
Returns whether this suggested fix can be applied automatically.
void setAutoApplicable(bool autoApplicable=true)
Sets autoApplicable to determine whether this suggested fix can be applied automatically.
QList< DocumentEdit > documentEdits() const
Returns the list of document edits that applying this fix would make.
void emitWarning(QAnyStringView diagnostic, LoggerWarningId id)
Emits a warning message diagnostic about an issue of type id.
Element resolveLiteralType(const Binding &binding)
Returns the element representing the type of literal in binding.
void emitWarning(QAnyStringView diagnostic, LoggerWarningId id, QQmlSA::SourceLocation srcLocation, const QQmlSA::FixSuggestion &fix)
Emits a warning message diagnostic about an issue of type id located at srcLocation and with suggeste...
void emitWarning(QAnyStringView diagnostic, LoggerWarningId id, QQmlSA::SourceLocation srcLocation)
Emits warning message diagnostic about an issue of type id located at srcLocation.
Element resolveBuiltinType(QAnyStringView typeName) const
Returns the type of the built-in type identified by typeName.
Element resolveAttached(QAnyStringView moduleName, QAnyStringView typeName)
Returns the attached type of typeName defined in module moduleName.
QString resolveElementToId(const Element &element, const Element &context)
Returns the id of element in a given context.
Element resolveTypeInFileScope(QAnyStringView typeName)
Returns the type corresponding to typeName inside the currently analysed file.
QString sourceCode(QQmlSA::SourceLocation location)
Returns the source code located within location.
Element resolveAttachedInFileScope(QAnyStringView typeName)
Returns the attached type corresponding to typeName used inside the currently analysed file.
Element resolveIdToElement(QAnyStringView id, const Element &context)
Returns the element in context that has id id.
Element resolveType(QAnyStringView moduleName, QAnyStringView typeName)
Returns the type of typeName defined in module moduleName.
MethodPrivate(Method *, const MethodPrivate &)
QQmlSA::SourceLocation sourceLocation() const
static QQmlSA::Method createMethod(const QQmlJSMetaMethod &)
MethodType methodType() const
static QQmlJSMetaMethod method(const QQmlSA::Method &)
QString methodName() const
Method & operator=(Method &&) noexcept
Move-assigns other to this Method instance.
MethodType methodType() const
Returns the type of this method.
Method(const Method &)
Creates a copy of other.
Method()
Constructs a new Method object.
Method & operator=(const Method &)
Assigns other to this Method instance.
QString methodName() const
Returns the name of the this method.
MethodsPrivate(QQmlSA::Method::Methods *, MethodsPrivate &&)
static QQmlSA::Method::Methods createMethods(const QMultiHash< QString, QQmlJSMetaMethod > &)
QMultiHash< QString, Method >::const_iterator constEnd() const
~MethodsPrivate()=default
MethodsPrivate(QQmlSA::Method::Methods *, const MethodsPrivate &)
QMultiHash< QString, Method >::const_iterator constBegin() const
void analyze(const Element &root)
Runs the element passes over root and all its children.
bool isCategoryEnabled(LoggerWarningId category) const
Returns true if warnings of category are enabled, false otherwise.
bool registerPropertyPass(std::shared_ptr< PropertyPass > pass, QAnyStringView moduleName, QAnyStringView typeName, QAnyStringView propertyName=QAnyStringView(), bool allowInheritance=true)
Registers a static analysis pass for properties.
std::unordered_map< quint32, Binding > bindingsByLocation() const
Returns bindings by their source location.
bool hasImportedModule(QAnyStringView name) const
Returns true if the module named module has been imported by the QML to be analyzed,...
PropertyPassBuilder(PassManager *passManager)
PropertyPassBuilder()=delete
Property(const Property &)
Creates a copy of other.
QString typeName() const
Returns the name of the type of this property.
bool isReadonly() const
Returns true if this property is read-only, false otherwise.
QQmlSA::WarningSeverity WarningSeverity
Q_QMLCOMPILER_EXPORT void emitWarningWithOptionalFix(GenericPass &pass, QAnyStringView diagnostic, const LoggerWarningId &id, const QQmlSA::SourceLocation &srcLocation, const std::optional< QQmlJSFixSuggestion > &fixSuggestion)
@ SignalHandlerFunctionScope
bool isRegularBindingType(BindingType type)
constexpr bool isFunctionScope(ScopeType type)
@ WrappedInImplicitComponent
Combined button and popup list for selecting options.
static auto getQQmlJSScopeFromSmartPtr(const From &p) -> From
Q_DECLARE_TYPEINFO(QDateTime::Data, Q_RELOCATABLE_TYPE)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
Q_DECLARE_INTERFACE(QNetworkAccessBackendFactory, QNetworkAccessBackendFactory_iid)
static QString toNumericString(double value)
static QString messageTypeForMethod(const QString &method)
static QString derefContentPointer(const QString &contentPointer)
static bool canTypeBeAffectedBySideEffects(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &baseType)
#define BYTECODE_UNIMPLEMENTED()
#define INJECT_TRACE_INFO(function)
static QString registerName(int registerIndex, int offset)
static QString minExpression(int argc)
static QString maxExpression(int argc)
static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type)
static void resetFactory(QDeferredSharedPointer< T > &pointer, QQmlJSImporter *importer, const typename QDeferredFactory< std::remove_const_t< T > >::TypeReader &typeReader, const QString &filePath)
void resetFactoryImpl(QDeferredSharedPointer< T > &pointer, U &&factory)
#define QmlLintPluginInterface_iid
static void onWriteDefault(PropertyPass *, const Element &, const QString &, const Element &, const Element &, SourceLocation)
static void onBindingDefault(PropertyPass *, const Element &, const QString &, const Binding &, const Element &, const Element &)
void onRead(const Element &element, const QString &propertyName, const Element &readScope, SourceLocation location) override
Executes whenever a property is read.
static void onCallDefault(PropertyPass *, const Element &, const QString &, const Element &, SourceLocation)
void onBinding(const Element &element, const QString &propertyName, const Binding &binding, const Element &bindingScope, const Element &value) override
Executes whenever a property gets bound to a value.
void onCall(const Element &element, const QString &propertyName, const Element &readScope, SourceLocation location) override
Executes whenever a property or method is called.
static void onReadDefault(PropertyPass *, const Element &, const QString &, const Element &, SourceLocation)
void onWrite(const Element &element, const QString &propertyName, const Element &value, const Element &writeScope, SourceLocation location) override
Executes whenever a property is written to.
std::shared_ptr< QQmlSA::PropertyPass > pass