File indexing completed on 2024-05-12 04:38:04

0001 /*
0002     SPDX-FileCopyrightText: 2008 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "specializationstore.h"
0008 #include "declarationid.h"
0009 #include "ducontext.h"
0010 #include "declaration.h"
0011 
0012 namespace KDevelop {
0013 SpecializationStore::SpecializationStore()
0014 {
0015 }
0016 
0017 SpecializationStore::~SpecializationStore()
0018 {
0019 }
0020 
0021 SpecializationStore& SpecializationStore::self()
0022 {
0023     static SpecializationStore store;
0024     return store;
0025 }
0026 
0027 void SpecializationStore::set(const DeclarationId& declaration,
0028                               const IndexedInstantiationInformation& specialization)
0029 {
0030     Q_ASSERT(specialization.index() >> 16);
0031     m_specializations[declaration] = specialization;
0032 }
0033 
0034 IndexedInstantiationInformation SpecializationStore::get(const DeclarationId& declaration)
0035 {
0036     QHash<DeclarationId, IndexedInstantiationInformation>::const_iterator it = m_specializations.constFind(declaration);
0037     if (it != m_specializations.constEnd())
0038         return *it;
0039     else
0040         return IndexedInstantiationInformation();
0041 }
0042 
0043 void SpecializationStore::clear(const DeclarationId& declaration)
0044 {
0045     QHash<DeclarationId, IndexedInstantiationInformation>::iterator it = m_specializations.find(declaration);
0046     if (it != m_specializations.end())
0047         m_specializations.erase(it);
0048 }
0049 
0050 void SpecializationStore::clear()
0051 {
0052     m_specializations.clear();
0053 }
0054 
0055 Declaration* SpecializationStore::applySpecialization(Declaration* declaration, TopDUContext* source,
0056                                                       bool recursive)
0057 {
0058     if (!declaration)
0059         return nullptr;
0060 
0061     IndexedInstantiationInformation specialization = get(declaration->id());
0062     if (specialization.index())
0063         return declaration->specialize(specialization, source);
0064 
0065     if (declaration->context() && recursive) {
0066         //Find a parent that has a specialization, and specialize this with the info and required depth
0067         int depth = 0;
0068         DUContext* ctx = declaration->context();
0069         IndexedInstantiationInformation specialization;
0070         while (ctx && !specialization.index()) {
0071             if (ctx->owner())
0072                 specialization = get(ctx->owner()->id());
0073             ++depth;
0074             ctx = ctx->parentContext();
0075         }
0076 
0077         if (specialization.index())
0078             return declaration->specialize(specialization, source, depth);
0079     }
0080 
0081     return declaration;
0082 }
0083 
0084 DUContext* SpecializationStore::applySpecialization(DUContext* context, TopDUContext* source,
0085                                                     bool recursive)
0086 {
0087     if (!context)
0088         return nullptr;
0089 
0090     if (Declaration* declaration = context->owner())
0091         return applySpecialization(declaration, source, recursive)->internalContext();
0092 
0093     if (context->parentContext() && recursive) {
0094         //Find a parent that has a specialization, and specialize this with the info and required depth
0095         int depth = 0;
0096         DUContext* ctx = context->parentContext();
0097         IndexedInstantiationInformation specialization;
0098         while (ctx && !specialization.index()) {
0099             if (ctx->owner())
0100                 specialization = get(ctx->owner()->id());
0101             ++depth;
0102             ctx = ctx->parentContext();
0103         }
0104 
0105         if (specialization.index())
0106             return context->specialize(specialization, source, depth);
0107     }
0108 
0109     return context;
0110 }
0111 }