File indexing completed on 2024-05-05 16:41:06

0001 /*
0002     SPDX-FileCopyrightText: 2008 Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "predeclarationbuilder.h"
0008 
0009 #include <QByteArray>
0010 
0011 #include <language/duchain/stringhelpers.h>
0012 #include <language/duchain/types/functiontype.h>
0013 
0014 #include <klocalizedstring.h>
0015 
0016 #include "phpast.h"
0017 #include "parsesession.h"
0018 #include "helper.h"
0019 #include "../declarations/classdeclaration.h"
0020 #include "../declarations/functiondeclaration.h"
0021 #include "../declarations/variabledeclaration.h"
0022 #include "../declarations/namespacedeclaration.h"
0023 #include "../types/structuretype.h"
0024 #include <duchaindebug.h>
0025 
0026 using namespace KDevelop;
0027 
0028 namespace Php
0029 {
0030 
0031 PreDeclarationBuilder::~PreDeclarationBuilder()
0032 {
0033 }
0034 
0035 void PreDeclarationBuilder::visitClassDeclarationStatement(ClassDeclarationStatementAst * node)
0036 {
0037     setComment(formatComment(node, m_editor));
0038     {
0039         IdentifierPair ids = identifierPairForNode(node->className);
0040         DUChainWriteLocker lock(DUChain::lock());
0041         ClassDeclaration* dec = openDefinition<ClassDeclaration>(ids.second, editorFindRange(node->className, node->className));
0042         dec->setPrettyName(ids.first);
0043         dec->setKind(KDevelop::Declaration::Type);
0044         dec->clearBaseClasses();
0045         dec->setClassType(ClassDeclarationData::Class);
0046         if (node->modifier) {
0047             switch (node->modifier->modifier) {
0048             case NormalClass:
0049                 dec->setClassModifier(ClassDeclarationData::None);
0050                 break;
0051             case FinalClass:
0052                 dec->setClassModifier(ClassDeclarationData::Final);
0053                 break;
0054             case AbstractClass:
0055                 dec->setClassModifier(ClassDeclarationData::Abstract);
0056                 break;
0057             }
0058         } else {
0059             dec->setClassModifier(ClassDeclarationData::None);
0060         }
0061 
0062         // build the type as well, to make this declaration usable
0063         StructureType::Ptr type(new StructureType());
0064         type->setPrettyName(ids.first);
0065         type->setDeclaration(dec);
0066         dec->setType(type);
0067 
0068         m_types->insert(node->className->string, dec);
0069     }
0070 
0071     PreDeclarationBuilderBase::visitClassDeclarationStatement(node);
0072 
0073     closeDeclaration();
0074 }
0075 
0076 void PreDeclarationBuilder::visitInterfaceDeclarationStatement(InterfaceDeclarationStatementAst *node)
0077 {
0078     setComment(formatComment(node, m_editor));
0079     {
0080         IdentifierPair ids = identifierPairForNode(node->interfaceName);
0081         DUChainWriteLocker lock(DUChain::lock());
0082         ClassDeclaration* dec = openDefinition<ClassDeclaration>(ids.second, editorFindRange(node->interfaceName, node->interfaceName));
0083         dec->setPrettyName(ids.first);
0084         dec->setKind(KDevelop::Declaration::Type);
0085         dec->clearBaseClasses();
0086         dec->setClassType(ClassDeclarationData::Interface);
0087 
0088         // build the type as well, to make this declaration usable
0089         StructureType::Ptr type(new StructureType());
0090         type->setPrettyName(ids.first);
0091         type->setDeclaration(dec);
0092         dec->setType(type);
0093 
0094         m_types->insert(node->interfaceName->string, dec);
0095     }
0096 
0097     PreDeclarationBuilderBase::visitInterfaceDeclarationStatement(node);
0098 
0099     closeDeclaration();
0100 }
0101 
0102 void PreDeclarationBuilder::visitTraitDeclarationStatement(TraitDeclarationStatementAst *node)
0103 {
0104     setComment(formatComment(node, m_editor));
0105     {
0106         IdentifierPair ids = identifierPairForNode(node->traitName);
0107         StructureType::Ptr type(new StructureType());
0108         type->setPrettyName(ids.first);
0109 
0110         DUChainWriteLocker lock;
0111 
0112         ClassDeclaration* dec = openDefinition<ClassDeclaration>(ids.second, editorFindRange(node->traitName, node->traitName));
0113         dec->setPrettyName(ids.first);
0114         dec->setKind(KDevelop::Declaration::Type);
0115         dec->clearBaseClasses();
0116         dec->setClassType(ClassDeclarationData::Trait);
0117 
0118         type->setDeclaration(dec);
0119         dec->setType(type);
0120 
0121         m_types->insert(node->traitName->string, dec);
0122     }
0123 
0124     PreDeclarationBuilderBase::visitTraitDeclarationStatement(node);
0125 
0126     closeDeclaration();
0127 }
0128 
0129 void PreDeclarationBuilder::visitClassVariable(ClassVariableAst* node)
0130 {
0131     m_upcomingClassVariables->append(identifierForNode(node->variable));
0132 }
0133 
0134 void PreDeclarationBuilder::visitFunctionDeclarationStatement(FunctionDeclarationStatementAst* node)
0135 {
0136     setComment(formatComment(node, m_editor));
0137     {
0138         IdentifierPair ids = identifierPairForNode(node->functionName);
0139         DUChainWriteLocker lock(DUChain::lock());
0140         FunctionDeclaration *dec = openDefinition<FunctionDeclaration>(ids.second, editorFindRange(node->functionName, node->functionName));
0141         dec->setPrettyName(ids.first);
0142         dec->setKind(Declaration::Type);
0143         dec->clearDefaultParameters();
0144 
0145         FunctionType::Ptr type = FunctionType::Ptr(new FunctionType());
0146 
0147         dec->setType(type);
0148 
0149         m_functions->insert(node->functionName->string, dec);
0150     }
0151 
0152     PreDeclarationBuilderBase::visitFunctionDeclarationStatement(node);
0153 
0154     closeDeclaration();
0155 }
0156 
0157 void PreDeclarationBuilder::openNamespace(NamespaceDeclarationStatementAst* parent, IdentifierAst* node, const IdentifierPair& identifier, const RangeInRevision& range)
0158 {
0159     if ( node == parent->namespaceNameSequence->back()->element ) {
0160         setComment(formatComment(parent, m_editor));
0161     }
0162 
0163     {
0164     DUChainWriteLocker lock;
0165     NamespaceDeclaration *dec = openDefinition<NamespaceDeclaration>(identifier.second, editorFindRange(node, node) );
0166     dec->setKind(Declaration::Namespace);
0167     dec->setPrettyName(identifier.first);
0168     m_namespaces->insert(node->string, dec);
0169     }
0170 
0171     PreDeclarationBuilderBase::openNamespace(parent, node, identifier, range);
0172 }
0173 
0174 void PreDeclarationBuilder::closeNamespace(NamespaceDeclarationStatementAst* parent, IdentifierAst* node, const IdentifierPair& identifier)
0175 {
0176     PreDeclarationBuilderBase::closeNamespace(parent, node, identifier);
0177 
0178     closeDeclaration();
0179 }
0180 
0181 void PreDeclarationBuilder::closeDeclaration()
0182 {
0183     eventuallyAssignInternalContext();
0184     PreDeclarationBuilderBase::closeDeclaration();
0185 }
0186 
0187 void PreDeclarationBuilder::closeContext()
0188 {
0189     // we don't want to cleanup here, see DeclarationBuilder::closeContext()
0190     setCompilingContexts(false);
0191     PreDeclarationBuilderBase::closeContext();
0192     setCompilingContexts(true);
0193 }
0194 
0195 }