mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-26 20:03:10 +00:00
302 lines
11 KiB
C++
302 lines
11 KiB
C++
/* This file is part of KDevelop
|
|
Copyright 2012 Olivier de Gaalon <olivier.jg@gmail.com>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef KDEVPLATFORM_JSONDECLARATIONTESTS_H
|
|
#define KDEVPLATFORM_JSONDECLARATIONTESTS_H
|
|
|
|
#include "language/duchain/ducontext.h"
|
|
#include "language/duchain/declaration.h"
|
|
#include "language/duchain/indexeddeclaration.h"
|
|
#include "language/duchain/identifier.h"
|
|
#include "language/duchain/abstractfunctiondeclaration.h"
|
|
#include "language/duchain/types/typeutils.h"
|
|
#include "language/duchain/types/identifiedtype.h"
|
|
#include <language/duchain/types/functiontype.h>
|
|
#include "language/duchain/duchain.h"
|
|
#include "language/duchain/functiondefinition.h"
|
|
#include "language/duchain/definitions.h"
|
|
#include <language/duchain/classmemberdeclaration.h>
|
|
#include "jsontesthelpers.h"
|
|
|
|
/**
|
|
* JSON Object Specification:
|
|
* DeclTestObject: Mapping of (string) declaration test names to values
|
|
* TypeTestObject: Mapping of (string) type test names to values
|
|
* CtxtTestObject: Mapping of (string) context test names to values
|
|
*
|
|
* Quick Reference:
|
|
* useCount : int
|
|
* useRanges : string array
|
|
* identifier : string
|
|
* qualifiedIdentifier : string
|
|
* internalContext : CtxtTestObject
|
|
* internalFunctionContext : CtxtTestObject
|
|
* type : TypeTestObject
|
|
* unaliasedType : TypeTestObject
|
|
* targetType : TypeTestObject
|
|
* returnType : TypeTestObject
|
|
* identifiedTypeQid : string
|
|
* isVirtual : bool
|
|
* isStatic : bool
|
|
* declaration : DeclTestObject
|
|
* definition : DeclTestObject
|
|
* null : bool
|
|
* defaultParameter : string
|
|
* toString : string
|
|
* range : string
|
|
* kind : string
|
|
*/
|
|
|
|
namespace KDevelop
|
|
{
|
|
template<>
|
|
QString TestSuite<Declaration*>::objectInformation(Declaration *decl)
|
|
{
|
|
if (!decl)
|
|
return "(null declaration)";
|
|
return QString("(Declaration on line %1 in %2)")
|
|
.arg(decl->range().start.line + 1)
|
|
.arg(decl->topContext()->url().str());
|
|
}
|
|
|
|
namespace DeclarationTests
|
|
{
|
|
|
|
using namespace JsonTestHelpers;
|
|
|
|
///JSON type: int
|
|
///@returns whether the declaration's number of uses matches the given value
|
|
DeclarationTest(useCount)
|
|
{
|
|
int uses = 0;
|
|
foreach(const QList<RangeInRevision>& useRanges, decl->uses()) {
|
|
uses += useRanges.size();
|
|
}
|
|
return compareValues(uses, value, "Declaration's use count ");
|
|
}
|
|
///JSON type: string array
|
|
///@returns whether the declaration's ranges match the given value
|
|
DeclarationTest(useRanges)
|
|
{
|
|
QStringList ranges;
|
|
foreach(const QList<RangeInRevision>& useRanges, decl->uses()) {
|
|
foreach(const RangeInRevision &range, useRanges) {
|
|
ranges << rangeStr(range);
|
|
}
|
|
}
|
|
const QStringList testValues = value.toStringList();
|
|
return ranges == testValues ? SUCCESS
|
|
: QString("Declaration's use ranges (\"%1\") don't match test data (\"%2\").").arg(ranges.join(", ")).arg(testValues.join(", "));
|
|
}
|
|
///JSON type: string
|
|
///@returns whether the declaration's identifier matches the given value
|
|
DeclarationTest(identifier)
|
|
{
|
|
return compareValues(decl->identifier().toString(), value, "Declaration's identifier");
|
|
}
|
|
///JSON type: string
|
|
///@returns whether the declaration's qualified identifier matches the given value
|
|
DeclarationTest(qualifiedIdentifier)
|
|
{
|
|
return compareValues(decl->qualifiedIdentifier().toString(), value, "Declaration's qualified identifier");
|
|
}
|
|
///JSON type: CtxtTestObject
|
|
///@returns whether the tests for the declaration's internal context pass
|
|
DeclarationTest(internalContext)
|
|
{
|
|
return testObject(decl->internalContext(), value, "Declaration's internal context");
|
|
}
|
|
///JSON type: CtxtTestObject
|
|
///@returns whether the tests for the declaration's internal function context pass
|
|
DeclarationTest(internalFunctionContext)
|
|
{
|
|
const QString NO_INTERNAL_CTXT = "%1 has no internal function context.";
|
|
AbstractFunctionDeclaration *absFuncDecl = dynamic_cast<AbstractFunctionDeclaration*>(decl);
|
|
if (!absFuncDecl || !absFuncDecl->internalFunctionContext())
|
|
return NO_INTERNAL_CTXT.arg(decl->qualifiedIdentifier().toString());
|
|
return testObject(absFuncDecl->internalFunctionContext(), value, "Declaration's internal function context");
|
|
}
|
|
/*FIXME: The type functions need some renaming and moving around
|
|
* Some (all?) functions from cpp's TypeUtils should be moved to the kdevplatform type utils
|
|
* targetType is exactly like realType except it also tosses pointers
|
|
* shortenTypeForViewing should go to type utils (and it's broken, it places const to the left of all *'s when it should be left or right of the type)
|
|
* UnaliasedType seems to be unable to understand aliases involving templates, perhaps a cpp version is in order
|
|
*/
|
|
///JSON type: TypeTestObject
|
|
///@returns whether the tests for the declaration's type pass
|
|
DeclarationTest(type)
|
|
{
|
|
return testObject(decl->abstractType(), value, "Declaration's type");
|
|
}
|
|
///JSON type: TypeTestObject
|
|
///@returns whether the tests for the declaration's unaliased type pass (TypeUtils::unaliasedType)
|
|
DeclarationTest(unaliasedType)
|
|
{
|
|
return testObject(TypeUtils::unAliasedType(decl->abstractType()), value, "Declaration's unaliased type");
|
|
}
|
|
///JSON type: TypeTestObject
|
|
///@returns whether the tests for the declaration's target type pass (TypeUtils::targetType)
|
|
DeclarationTest(targetType)
|
|
{
|
|
return testObject(TypeUtils::targetType(decl->abstractType(), decl->topContext()), value, "Declaration's target type");
|
|
}
|
|
///JSON type: TestTypeObject
|
|
///@returns the
|
|
DeclarationTest(returnType)
|
|
{
|
|
FunctionType::Ptr functionType = decl->abstractType().cast<FunctionType>();
|
|
AbstractType::Ptr returnType;
|
|
if (functionType) {
|
|
returnType = functionType->returnType();
|
|
}
|
|
return testObject(returnType, value, "Declaration's return type");
|
|
}
|
|
///JSON type: string
|
|
///@returns whether the declaration's type's declaration can be identified and if it's qualified identifier matches the given value
|
|
DeclarationTest(identifiedTypeQid)
|
|
{
|
|
VERIFY_TYPE(QString);
|
|
const QString UN_ID_ERROR = "Unable to identify declaration of type \"%1\".";
|
|
AbstractType::Ptr type = decl->abstractType();
|
|
IdentifiedType* idType = dynamic_cast<IdentifiedType*>(type.unsafeData());
|
|
Declaration* idDecl = idType ? idType->declaration(decl->topContext()) : 0;
|
|
if (!idDecl)
|
|
return UN_ID_ERROR.arg(type->toString());
|
|
|
|
return compareValues(idDecl->qualifiedIdentifier().toString(), value, "Declaration's identified type");
|
|
}
|
|
///JSON type: bool
|
|
///@returns whether the (function) declaration's isVirtual matches the given value
|
|
DeclarationTest(isVirtual)
|
|
{
|
|
const QString NOT_A_FUNCTION = "Non-function declaration cannot be virtual.";
|
|
AbstractFunctionDeclaration *absFuncDecl = dynamic_cast<AbstractFunctionDeclaration*>(decl);
|
|
if (!absFuncDecl)
|
|
return NOT_A_FUNCTION;
|
|
|
|
return compareValues(absFuncDecl->isVirtual(), value, "Declaration's isVirtual");
|
|
}
|
|
///JSON type: bool
|
|
///@returns whether the (class-member) declaration's isStatic matches the given value
|
|
DeclarationTest(isStatic)
|
|
{
|
|
const QString NOT_A_MEMBER = "Non-class-member declaration cannot be static.";
|
|
auto memberDecl = dynamic_cast<ClassMemberDeclaration*>(decl);
|
|
if (!memberDecl)
|
|
return NOT_A_MEMBER;
|
|
|
|
return compareValues(memberDecl->isStatic(), value, "Declaration's isStatic");
|
|
}
|
|
///JSON type: DeclTestObject
|
|
///@returns whether the tests for the function declaration's definition pass
|
|
DeclarationTest(definition)
|
|
{
|
|
KDevVarLengthArray<IndexedDeclaration> definitions = DUChain::definitions()->definitions(decl->id());
|
|
Declaration *declDef = 0;
|
|
if (definitions.size())
|
|
declDef = definitions.at(0).declaration();
|
|
return testObject(declDef, value, "Declaration's definition");
|
|
}
|
|
///JSON type: DeclTestObject
|
|
///@returns whether the tests for the function definition's declaration pass
|
|
DeclarationTest(declaration)
|
|
{
|
|
FunctionDefinition *def = dynamic_cast<FunctionDefinition*>(decl);
|
|
Declaration *defDecl = nullptr;
|
|
if (def)
|
|
defDecl = def->declaration(decl->topContext());
|
|
return testObject(defDecl, value, "Definition's declaration");
|
|
}
|
|
///JSON type: bool
|
|
///@returns whether the declaration's nullity matches the given value
|
|
DeclarationTest(null)
|
|
{
|
|
return compareValues(decl == 0, value, "Declaration's nullity");
|
|
}
|
|
///JSON type: bool
|
|
///@returns whether the declaration's default parameter matches the given value
|
|
DeclarationTest(defaultParameter)
|
|
{
|
|
const QString NOT_IN_FUNC_CTXT = "Asked for a default parameter for a declaration outside of a function context.";
|
|
const QString OWNER_NOT_FUNC = "Function context not owned by function declaration (what on earth did you do?).";
|
|
DUContext *context = decl->context();
|
|
if (!context || context->type() != DUContext::Function)
|
|
return NOT_IN_FUNC_CTXT;
|
|
AbstractFunctionDeclaration *funcDecl = dynamic_cast<AbstractFunctionDeclaration*>(context->owner());
|
|
if (!funcDecl)
|
|
return OWNER_NOT_FUNC;
|
|
int argIndex = context->localDeclarations().indexOf(decl);
|
|
return compareValues(funcDecl->defaultParameterForArgument(argIndex).str(), value, "Declaration's default parameter");
|
|
}
|
|
|
|
///JSON type: string
|
|
///@returns stringified declaration
|
|
DeclarationTest(toString)
|
|
{
|
|
if (!decl) {
|
|
return "Invalid Declaration";
|
|
}
|
|
return compareValues(decl->toString(), value, "Declaration's toString");
|
|
}
|
|
|
|
///JSON type: string
|
|
///@returns stringified declaration range
|
|
DeclarationTest(range)
|
|
{
|
|
if (!decl) {
|
|
return "Invalid Declaration";
|
|
}
|
|
return compareValues(rangeStr(decl->range()), value, "Declaration's range");
|
|
}
|
|
|
|
///JSON type: string
|
|
///@returns stringified declaration kind
|
|
DeclarationTest(kind)
|
|
{
|
|
if (!decl) {
|
|
return "Invalid Declaration";
|
|
}
|
|
QString kind;
|
|
switch (decl->kind()) {
|
|
case KDevelop::Declaration::Alias:
|
|
kind = "Alias";
|
|
break;
|
|
case KDevelop::Declaration::Import:
|
|
kind = "Import";
|
|
break;
|
|
case KDevelop::Declaration::Instance:
|
|
kind = "Instance";
|
|
break;
|
|
case KDevelop::Declaration::Namespace:
|
|
kind = "Namespace";
|
|
break;
|
|
case KDevelop::Declaration::NamespaceAlias:
|
|
kind = "NamespaceAlias";
|
|
break;
|
|
case KDevelop::Declaration::Type:
|
|
kind = "Type";
|
|
break;
|
|
}
|
|
return compareValues(kind, value, "Declaration's kind");
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif //KDEVPLATFORM_JSONDECLARATIONTESTS_H
|