diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp index fcb67d7..8d057f8 100644 --- a/duchain/declarationbuilder.cpp +++ b/duchain/declarationbuilder.cpp @@ -1,141 +1,160 @@ #include "declarationbuilder.h" #include #include #include "types/declarationtypes.h" #include "nodetraits.h" #include "rustdebug.h" namespace Rust { using namespace KDevelop; RSVisitResult DeclarationBuilder::visitNode(RustNode *node, RustNode *parent) { RSNodeKind kind = node_get_kind(node->data()); switch (kind) { case Module: return buildDeclaration(node, parent); case StructDecl: return buildDeclaration(node, parent); case EnumDecl: return buildDeclaration(node, parent); case FunctionDecl: return buildDeclaration(node, parent); case ImplDecl: return buildDeclaration(node, parent); case TraitDecl: return buildDeclaration(node, parent); case TypeAliasDecl: return buildDeclaration(node, parent); case EnumVariantDecl: return buildDeclaration(node, parent); case FieldDecl: return buildDeclaration(node, parent); case VarDecl: return buildDeclaration(node, parent); default: return ContextBuilder::visitNode(node, parent); } } template RSVisitResult DeclarationBuilder::buildDeclaration(RustNode *node, RustNode *parent) { Q_UNUSED(parent); constexpr bool hasContext = NodeTraits::hasContext(Kind); RustPath name(node); createDeclaration(node, &name, hasContext); RSVisitResult ret = buildContext(node, parent); if (hasContext) eventuallyAssignInternalContext(); closeDeclaration(); return ret; } template Declaration *DeclarationBuilder::createDeclaration(RustNode *node, RustPath *name, bool hasContext) { auto range = editorFindSpellingRange(node, name->value); Declaration *decl = openDeclaration::Type>(Identifier(name->value), range, hasContext ? DeclarationIsDefinition : NoFlags); auto type = createType(node); openType(type); if (Kind == TypeAliasDecl) { decl->setIsTypeAlias(true); } if (NodeTraits::isTypeDeclaration(Kind)) { decl->setKind(Declaration::Type); } setDeclData(decl); setType(decl, type.data()); closeType(); return decl; } template > typename IdType::Type::Ptr DeclarationBuilder::createType(RustNode *node) { Q_UNUSED(node); return typename IdType::Type::Ptr(new typename IdType::Type); } template > FunctionType::Ptr DeclarationBuilder::createType(RustNode *node) { Q_UNUSED(node); return FunctionType::Ptr(new FunctionType); } template > AbstractType::Ptr DeclarationBuilder::createType(RustNode *node) { Q_UNUSED(node); return AbstractType::Ptr(nullptr); } template void DeclarationBuilder::setType(Declaration *decl, typename IdType::Type *type) { setType(decl, static_cast(type)); setType(decl, static_cast(type)); } template void DeclarationBuilder::setType(Declaration *decl, IdentifiedType *type) { type->setDeclaration(decl); } template void DeclarationBuilder::setType(Declaration *decl, AbstractType *type) { decl->setAbstractType(AbstractType::Ptr(type)); } template> void DeclarationBuilder::setDeclData(ClassDeclaration *decl) { if (Kind == StructDecl || Kind == ImplDecl) { decl->setClassType(ClassDeclarationData::Struct); } else if (Kind == TraitDecl) { decl->setClassType(ClassDeclarationData::Trait); } } -template +template> +void DeclarationBuilder::setDeclData(Declaration *decl) +{ + decl->setKind(Declaration::Namespace); +} + +template> +void DeclarationBuilder::setDeclData(Declaration *decl) +{ + decl->setKind(Declaration::Instance); +} + +template> +void DeclarationBuilder::setDeclData(AliasDeclaration *decl) +{ + decl->setKind(Declaration::Alias); +} + +template> void DeclarationBuilder::setDeclData(Declaration *decl) { + Q_UNUSED(decl); } } diff --git a/duchain/declarationbuilder.h b/duchain/declarationbuilder.h index 8961c1a..4347562 100644 --- a/duchain/declarationbuilder.h +++ b/duchain/declarationbuilder.h @@ -1,70 +1,79 @@ #ifndef DECLARATIONBUILDER_H #define DECLARATIONBUILDER_H #include #include #include #include #include "duchain/types/declarationtypes.h" #include "duchain/contextbuilder.h" #include "duchain/nodetraits.h" #include "duchain/rustnode.h" #include "duchain/astredux.h" namespace Rust { using TypeBuilderBase = KDevelop::AbstractTypeBuilder; using DeclarationBuilderBase = KDevelop::AbstractDeclarationBuilder; namespace detail { enum class enabler {}; } constexpr detail::enabler dummy = {}; template using EnableIf = typename std::enable_if::type; class DeclarationBuilder : public DeclarationBuilderBase { public: DeclarationBuilder() = default; ~DeclarationBuilder() override = default; protected: RSVisitResult visitNode(RustNode *node, RustNode *parent) override; private: template RSVisitResult buildDeclaration(RustNode *node, RustNode *parent); template KDevelop::Declaration *createDeclaration(RustNode *node, RustPath *name, bool hasContext); template = dummy> typename IdType::Type::Ptr createType(RustNode *node); template = dummy> KDevelop::FunctionType::Ptr createType(RustNode *node); template = dummy> KDevelop::AbstractType::Ptr createType(RustNode *node); - template + template = dummy> + void setDeclData(KDevelop::Declaration *decl); + + template = dummy> void setDeclData(KDevelop::Declaration *decl); + template = dummy> + void setDeclData(KDevelop::Declaration *decl); + + template = dummy> + void setDeclData(KDevelop::AliasDeclaration *decl); + template = dummy> void setDeclData(KDevelop::ClassDeclaration *decl); template void setType(KDevelop::Declaration *decl, typename IdType::Type *type); template void setType(KDevelop::Declaration *decl, KDevelop::IdentifiedType *type); template void setType(KDevelop::Declaration *decl, KDevelop::AbstractType *type); }; } #endif // DECLARATIONBUILDER_H diff --git a/duchain/nodetraits.h b/duchain/nodetraits.h index 1927c05..3710237 100644 --- a/duchain/nodetraits.h +++ b/duchain/nodetraits.h @@ -1,51 +1,50 @@ #ifndef NODETRAITS_H #define NODETRAITS_H #include #include "astredux.h" namespace Rust { namespace NodeTraits { constexpr bool hasContext(RSNodeKind kind) { return kind == Crate || kind == Module || kind == StructDecl || kind == EnumDecl || kind == TraitDecl || kind == ImplDecl || kind == FunctionDecl || kind == Block; } constexpr KDevelop::DUContext::ContextType contextType(RSNodeKind kind) { using namespace KDevelop; return kind == Crate ? DUContext::Global : kind == Module ? DUContext::Namespace : kind == StructDecl ? DUContext::Class : kind == EnumDecl ? DUContext::Enum : kind == TraitDecl ? DUContext::Class : kind == ImplDecl ? DUContext::Class : kind == FunctionDecl ? DUContext::Function : kind == Block ? DUContext::Other : static_cast(-1); } constexpr bool isKDevDeclaration(RSNodeKind kind) { - return kind == EnumDecl || kind == TypeAliasDecl || kind == EnumVariantDecl + return kind == EnumDecl || kind == EnumVariantDecl || kind == ParmDecl || kind == VarDecl || kind == Module; } constexpr bool isTypeDeclaration(RSNodeKind kind) { return kind == EnumDecl || kind == EnumVariantDecl - || kind == TypeAliasDecl || kind == StructDecl - || kind == ImplDecl || kind == TraitDecl; + || kind == StructDecl || kind == ImplDecl || kind == TraitDecl; } } } #endif // NODETRAITS_H diff --git a/duchain/types/declarationtypes.h b/duchain/types/declarationtypes.h index 6502432..8e74597 100644 --- a/duchain/types/declarationtypes.h +++ b/duchain/types/declarationtypes.h @@ -1,81 +1,88 @@ #ifndef DECLARATIONTYPES_H #define DECLARATIONTYPES_H #include #include #include #include #include #include +#include #include "duchain/astredux.h" #include "duchain/nodetraits.h" namespace Rust { template struct IdType; template struct IdType::type> { typedef KDevelop::StructureType Type; }; template struct IdType::type> { typedef KDevelop::TypeAliasType Type; }; template struct IdType::type> { typedef KDevelop::EnumerationType Type; }; template struct IdType::type> { typedef KDevelop::EnumeratorType Type; }; template struct DeclType; template struct DeclType::type> { typedef KDevelop::Declaration Type; }; template struct DeclType::type> { typedef KDevelop::ClassDeclaration Type; }; +template +struct DeclType::type> +{ + typedef KDevelop::AliasDeclaration Type; +}; + // FIXME: specialize //template //struct DeclType::type> //{ // typedef KDevelop::ClassFunctionDeclaration Type; //}; template struct DeclType::type> { typedef KDevelop::FunctionDeclaration Type; }; template struct DeclType::type> { typedef KDevelop::ClassMemberDeclaration Type; }; } #endif // DECLARATIONTYPES_H