2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2011-09-28 15:16:00 +02:00
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-09-28 15:16:00 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2011-09-28 15:16:00 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:58:39 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2011-09-28 15:16:00 +02:00
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2011-09-28 15:16:00 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2011-09-28 15:16:00 +02:00
|
|
|
|
|
|
|
|
#include "qmljsstaticanalysismessage.h"
|
2013-10-16 14:59:28 +02:00
|
|
|
#include "qmljsconstants.h"
|
2015-03-04 16:46:23 +01:00
|
|
|
#include "parser/qmljsengine_p.h"
|
2011-09-28 15:16:00 +02:00
|
|
|
|
|
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QCoreApplication>
|
2015-03-04 16:46:23 +01:00
|
|
|
#include <QRegExp>
|
2011-09-28 15:16:00 +02:00
|
|
|
|
|
|
|
|
using namespace QmlJS;
|
|
|
|
|
using namespace QmlJS::StaticAnalysis;
|
2013-10-16 14:59:28 +02:00
|
|
|
using namespace QmlJS::Severity;
|
2011-09-28 15:16:00 +02:00
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
class StaticAnalysisMessages
|
|
|
|
|
{
|
2013-01-28 17:29:33 +01:00
|
|
|
Q_DECLARE_TR_FUNCTIONS(QmlJS::StaticAnalysisMessages)
|
2011-09-28 15:16:00 +02:00
|
|
|
|
|
|
|
|
public:
|
2013-10-16 14:59:28 +02:00
|
|
|
void newMsg(Type type, Enum severity, const QString &message, int placeholders = 0)
|
2011-09-28 15:16:00 +02:00
|
|
|
{
|
|
|
|
|
PrototypeMessageData prototype;
|
|
|
|
|
prototype.type = type;
|
|
|
|
|
prototype.severity = severity;
|
|
|
|
|
prototype.message = message;
|
|
|
|
|
prototype.placeholders = placeholders;
|
|
|
|
|
QTC_CHECK(placeholders <= 2);
|
|
|
|
|
QTC_ASSERT(!messages.contains(type), return);
|
|
|
|
|
messages[type] = prototype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StaticAnalysisMessages();
|
|
|
|
|
QHash<Type, PrototypeMessageData> messages;
|
|
|
|
|
};
|
|
|
|
|
|
2011-12-13 16:17:43 +01:00
|
|
|
static inline QString msgInvalidConstructor(const char *what)
|
|
|
|
|
{
|
2016-08-26 09:17:27 +02:00
|
|
|
return StaticAnalysisMessages::tr("Do not use \"%1\" as a constructor."
|
|
|
|
|
"\n\nFor more information, see the"
|
|
|
|
|
" \"Checking Code Syntax\" documentation.")
|
|
|
|
|
.arg(QLatin1String(what));
|
2011-12-13 16:17:43 +01:00
|
|
|
}
|
|
|
|
|
|
2011-09-28 15:16:00 +02:00
|
|
|
StaticAnalysisMessages::StaticAnalysisMessages()
|
|
|
|
|
{
|
2011-12-07 15:04:23 +01:00
|
|
|
// When changing a message or severity, update the documentation, currently
|
|
|
|
|
// in creator-editors.qdoc, accordingly.
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidEnumValue, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Invalid value for enum."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrEnumValueMustBeStringOrNumber, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Enum value must be a string or a number."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrNumberValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Number value expected."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrBooleanValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Boolean value expected."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrStringValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("String value expected."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidUrl, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Invalid URL."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnFileOrDirectoryDoesNotExist, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("File or directory does not exist."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidColor, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Invalid color."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrAnchorLineExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Anchor line expected."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrPropertiesCanOnlyHaveOneBinding, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Duplicate property binding."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrIdExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Id expected."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidId, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Invalid id."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrDuplicateId, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Duplicate id."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidPropertyName, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Invalid property name \"%1\"."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrDoesNotHaveMembers, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("\"%1\" does not have members."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidMember, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("\"%1\" is not a member of \"%2\"."), 2);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnAssignmentInCondition, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Assignment in condition."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnCaseWithoutFlowControl, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Unterminated non-empty case block."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnEval, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Do not use 'eval'."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnUnreachable, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Unreachable."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnWith, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Do not use 'with'."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnComma, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Do not use comma expressions."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnAlreadyFormalParameter, Warning,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("\"%1\" already is a formal parameter."), 1);
|
2011-10-20 09:45:29 +02:00
|
|
|
newMsg(WarnUnnecessaryMessageSuppression, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Unnecessary message suppression."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnAlreadyFunction, Warning,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("\"%1\" already is a function."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnVarUsedBeforeDeclaration, Warning,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("var \"%1\" is used before its declaration."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnAlreadyVar, Warning,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("\"%1\" already is a var."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnDuplicateDeclaration, Warning,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("\"%1\" is declared more than once."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnFunctionUsedBeforeDeclaration, Warning,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Function \"%1\" is used before its declaration."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnBooleanConstructor, Warning,
|
2011-12-13 16:17:43 +01:00
|
|
|
msgInvalidConstructor("Boolean"));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnStringConstructor, Warning,
|
2011-12-13 16:17:43 +01:00
|
|
|
msgInvalidConstructor("String"));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnObjectConstructor, Warning,
|
2011-12-13 16:17:43 +01:00
|
|
|
msgInvalidConstructor("Object"));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnArrayConstructor, Warning,
|
2011-12-13 16:17:43 +01:00
|
|
|
msgInvalidConstructor("Array"));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnFunctionConstructor, Warning,
|
2011-12-13 16:17:43 +01:00
|
|
|
msgInvalidConstructor("Function"));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(HintAnonymousFunctionSpacing, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("The 'function' keyword and the opening parenthesis should be separated by a single space."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnBlock, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Do not use stand-alone blocks."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnVoid, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Do not use void expressions."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnConfusingPluses, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Confusing pluses."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(WarnConfusingMinuses, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Confusing minuses."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(HintDeclareVarsInOneLine, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Declare all function vars on a single line."));
|
2011-10-04 09:49:30 +02:00
|
|
|
newMsg(HintExtraParentheses, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Unnecessary parentheses."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(MaybeWarnEqualityTypeCoercion, MaybeWarning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("== and != may perform type coercion, use === or !== to avoid it."));
|
2013-10-16 14:59:28 +02:00
|
|
|
newMsg(WarnConfusingExpressionStatement, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Expression statements should be assignments, calls or delete expressions only."));
|
2011-10-28 15:56:56 +02:00
|
|
|
newMsg(HintDeclarationsShouldBeAtStartOfFunction, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Place var declarations at the start of a function."));
|
2011-10-28 15:56:56 +02:00
|
|
|
newMsg(HintOneStatementPerLine, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Use only one statement per line."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrUnknownComponent, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Unknown component."));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrCouldNotResolvePrototypeOf, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Could not resolve the prototype \"%1\" of \"%2\"."), 2);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrCouldNotResolvePrototype, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Could not resolve the prototype \"%1\"."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrPrototypeCycle, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Prototype cycle, the last non-repeated component is \"%1\"."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(ErrInvalidPropertyType, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Invalid property type \"%1\"."), 1);
|
2013-10-16 14:59:28 +02:00
|
|
|
newMsg(WarnEqualityTypeCoercion, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("== and != perform type coercion, use === or !== to avoid it."));
|
2013-10-16 14:59:28 +02:00
|
|
|
newMsg(WarnExpectedNewWithUppercaseFunction, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Calls of functions that start with an uppercase letter should use 'new'."));
|
2013-10-16 14:59:28 +02:00
|
|
|
newMsg(WarnNewWithLowercaseFunction, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Use 'new' only with functions that start with an uppercase letter."));
|
2013-10-16 14:59:28 +02:00
|
|
|
newMsg(WarnNumberConstructor, Error,
|
2011-12-13 16:17:43 +01:00
|
|
|
msgInvalidConstructor("Function"));
|
2011-09-28 15:16:00 +02:00
|
|
|
newMsg(HintBinaryOperatorSpacing, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Use spaces around binary operators."));
|
2013-10-16 14:59:28 +02:00
|
|
|
newMsg(WarnUnintentinalEmptyBlock, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Unintentional empty block, use ({}) for empty object literal."));
|
2011-10-19 14:09:15 +02:00
|
|
|
newMsg(HintPreferNonVarPropertyType, Hint,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Use %1 instead of 'var' or 'variant' to improve performance."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrMissingRequiredProperty, Error,
|
2014-04-17 14:09:47 +02:00
|
|
|
tr("Missing property \"%1\"."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrObjectValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Object value expected."));
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrArrayValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Array value expected."));
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrDifferentValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("%1 value expected."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrSmallerNumberValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Maximum number value is %1."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrLargerNumberValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Minimum number value is %1."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrMaximumNumberValueIsExclusive, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Maximum number value is exclusive."));
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrMinimumNumberValueIsExclusive, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Minimum number value is exclusive."));
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrInvalidStringValuePattern, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("String value does not match required pattern."));
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrLongerStringValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Minimum string value length is %1."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrShorterStringValueExpected, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Maximum string value length is %1."), 1);
|
2012-02-07 15:30:33 +01:00
|
|
|
newMsg(ErrInvalidArrayValueLength, Error,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("%1 elements expected in array value."), 1);
|
2014-02-17 11:21:10 +01:00
|
|
|
newMsg(WarnImperativeCodeNotEditableInVisualDesigner, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Imperative code is not supported in the Qt Quick Designer."));
|
2013-11-25 12:37:04 +01:00
|
|
|
newMsg(WarnUnsupportedTypeInVisualDesigner, Warning,
|
2014-10-14 16:48:39 +02:00
|
|
|
tr("This type (%1) is not supported in the Qt Quick Designer."), 1);
|
2014-02-17 11:21:10 +01:00
|
|
|
newMsg(WarnReferenceToParentItemNotSupportedByVisualDesigner, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Reference to parent item cannot be resolved correctly by the Qt Quick Designer."));
|
2013-11-25 12:37:04 +01:00
|
|
|
newMsg(WarnUndefinedValueForVisualDesigner, Warning,
|
2013-01-29 15:12:14 +01:00
|
|
|
tr("This visual property binding cannot be evaluated in the local context "
|
2013-02-12 15:28:38 +01:00
|
|
|
"and might not show up in Qt Quick Designer as expected."));
|
2013-11-25 12:37:04 +01:00
|
|
|
newMsg(WarnStatesOnlyInRootItemForVisualDesigner, Warning,
|
2013-02-12 15:28:38 +01:00
|
|
|
tr("Qt Quick Designer only supports states in the root item."));
|
2013-11-13 17:20:01 +01:00
|
|
|
newMsg(WarnAboutQtQuick1InsteadQtQuick2, Warning,
|
|
|
|
|
tr("Using Qt Quick 1 code model instead of Qt Quick 2."));
|
2014-09-10 09:49:51 +02:00
|
|
|
newMsg(ErrUnsupportedRootTypeInVisualDesigner, Error,
|
2014-10-14 16:48:39 +02:00
|
|
|
tr("This type (%1) is not supported as a root element by Qt Quick Designer."), 1);
|
|
|
|
|
newMsg(ErrUnsupportedRootTypeInQmlUi, Error,
|
2014-11-03 15:47:39 +01:00
|
|
|
tr("This type (%1) is not supported as a root element of a Qt Quick UI form."), 1);
|
2014-10-14 16:48:39 +02:00
|
|
|
newMsg(ErrUnsupportedTypeInQmlUi, Error,
|
2014-11-03 15:47:39 +01:00
|
|
|
tr("This type (%1) is not supported in a Qt Quick UI form."), 1);
|
2014-10-14 16:48:39 +02:00
|
|
|
newMsg(ErrFunctionsNotSupportedInQmlUi, Error,
|
2014-11-03 15:47:39 +01:00
|
|
|
tr("Functions are not supported in a Qt Quick UI form."));
|
2014-10-14 16:48:39 +02:00
|
|
|
newMsg(ErrBlocksNotSupportedInQmlUi, Error,
|
2015-01-05 14:21:59 +01:00
|
|
|
tr("JavaScript blocks are not supported in a Qt Quick UI form."));
|
2014-10-14 16:48:39 +02:00
|
|
|
newMsg(ErrBehavioursNotSupportedInQmlUi, Error,
|
2014-11-03 15:47:39 +01:00
|
|
|
tr("Behavior type is not supported in a Qt Quick UI form."));
|
2014-10-15 12:32:26 +02:00
|
|
|
newMsg(ErrStatesOnlyInRootItemInQmlUi, Error,
|
2014-11-03 15:47:39 +01:00
|
|
|
tr("States are only supported in the root item in a Qt Quick UI form."));
|
2014-10-15 12:32:26 +02:00
|
|
|
newMsg(ErrReferenceToParentItemNotSupportedInQmlUi, Error,
|
2014-11-03 15:47:39 +01:00
|
|
|
tr("Referencing the parent of the root item is not supported in a Qt Quick UI form."));
|
2016-06-21 18:33:15 +02:00
|
|
|
newMsg(StateCannotHaveChildItem, Error,
|
|
|
|
|
tr("A State cannot have a child item (%1)."), 1);
|
2011-09-28 15:16:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
|
Q_GLOBAL_STATIC(StaticAnalysisMessages, messages)
|
|
|
|
|
|
|
|
|
|
QList<Type> Message::allMessageTypes()
|
|
|
|
|
{
|
|
|
|
|
return messages()->messages.keys();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Message::Message()
|
|
|
|
|
: type(UnknownType), severity(Hint)
|
|
|
|
|
{}
|
|
|
|
|
|
2012-02-07 15:30:33 +01:00
|
|
|
Message::Message(Type type,
|
|
|
|
|
AST::SourceLocation location,
|
|
|
|
|
const QString &arg1,
|
|
|
|
|
const QString &arg2,
|
|
|
|
|
bool appendTypeId)
|
2011-09-28 15:16:00 +02:00
|
|
|
: location(location), type(type)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(messages()->messages.contains(type), return);
|
2013-04-10 14:38:08 +02:00
|
|
|
const PrototypeMessageData &prototype = prototypeForMessageType(type);
|
2011-09-28 15:16:00 +02:00
|
|
|
severity = prototype.severity;
|
|
|
|
|
message = prototype.message;
|
|
|
|
|
if (prototype.placeholders == 0) {
|
|
|
|
|
if (!arg1.isEmpty() || !arg2.isEmpty())
|
|
|
|
|
qWarning() << "StaticAnalysis message" << type << "expects no arguments";
|
|
|
|
|
} else if (prototype.placeholders == 1) {
|
|
|
|
|
if (arg1.isEmpty() || !arg2.isEmpty())
|
|
|
|
|
qWarning() << "StaticAnalysis message" << type << "expects exactly one argument";
|
|
|
|
|
message = message.arg(arg1);
|
|
|
|
|
} else if (prototype.placeholders == 2) {
|
|
|
|
|
if (arg1.isEmpty() || arg2.isEmpty())
|
|
|
|
|
qWarning() << "StaticAnalysis message" << type << "expects exactly two arguments";
|
|
|
|
|
message = message.arg(arg1, arg2);
|
|
|
|
|
}
|
2012-02-07 15:30:33 +01:00
|
|
|
if (appendTypeId)
|
2012-11-27 20:20:02 +02:00
|
|
|
message.append(QString::fromLatin1(" (M%1)").arg(QString::number(prototype.type)));
|
2011-09-28 15:16:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Message::isValid() const
|
|
|
|
|
{
|
|
|
|
|
return type != UnknownType && location.isValid() && !message.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DiagnosticMessage Message::toDiagnosticMessage() const
|
|
|
|
|
{
|
|
|
|
|
DiagnosticMessage diagnostic;
|
|
|
|
|
switch (severity) {
|
|
|
|
|
case Hint:
|
|
|
|
|
case MaybeWarning:
|
|
|
|
|
case Warning:
|
2013-10-16 14:59:28 +02:00
|
|
|
diagnostic.kind = Warning;
|
2011-09-28 15:16:00 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2013-10-16 14:59:28 +02:00
|
|
|
diagnostic.kind = Error;
|
2011-09-28 15:16:00 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
diagnostic.loc = location;
|
|
|
|
|
diagnostic.message = message;
|
|
|
|
|
return diagnostic;
|
|
|
|
|
}
|
2011-10-19 14:27:40 +02:00
|
|
|
|
|
|
|
|
QString Message::suppressionString() const
|
|
|
|
|
{
|
2012-11-27 20:20:02 +02:00
|
|
|
return QString::fromLatin1("@disable-check M%1").arg(QString::number(type));
|
2011-10-28 12:27:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QRegExp Message::suppressionPattern()
|
|
|
|
|
{
|
|
|
|
|
return QRegExp(QLatin1String("@disable-check M(\\d+)"));
|
2011-10-19 14:27:40 +02:00
|
|
|
}
|
2013-04-10 14:38:08 +02:00
|
|
|
|
|
|
|
|
const PrototypeMessageData Message::prototypeForMessageType(Type type)
|
|
|
|
|
{
|
|
|
|
|
QTC_CHECK(messages()->messages.contains(type));
|
|
|
|
|
const PrototypeMessageData &prototype = messages()->messages.value(type);
|
|
|
|
|
|
|
|
|
|
return prototype;
|
|
|
|
|
}
|