diff --git a/CMakeLists.txt b/CMakeLists.txt index 82036a7..9fb71c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,80 +1,80 @@ cmake_minimum_required(VERSION 3.0) project(php) set(KDEVPHP_VERSION_MAJOR 5) -set(KDEVPHP_VERSION_MINOR 1) -set(KDEVPHP_VERSION_PATCH 40) +set(KDEVPHP_VERSION_MINOR 2) +set(KDEVPHP_VERSION_PATCH 0) # KDevplatform dependency version set( KDEVPLATFORM_VERSION "${KDEVPHP_VERSION_MAJOR}.${KDEVPHP_VERSION_MINOR}.${KDEVPHP_VERSION_PATCH}" ) configure_file( "${php_SOURCE_DIR}/kdevphpversion.h.cmake" "${php_BINARY_DIR}/kdevphpversion.h" @ONLY ) find_package (ECM "5.14.0" REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMAddTests) include(ECMQtDeclareLoggingCategory) include(KDEInstallDirs) include(KDECMakeSettings) include(GenerateExportHeader) include(FeatureSummary) set(QT_MIN_VERSION "5.5.0") find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Core Widgets Test) set(KF5_DEP_VERSION "5.15.0") find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS Archive ThreadWeaver TextEditor I18n ItemModels KCMUtils) find_package(KDevPlatform ${KDEVPLATFORM_VERSION} REQUIRED) find_package(KDevelop-PG-Qt REQUIRED) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdocumentation") endif() add_definitions( -DKDE_DEFAULT_DEBUG_AREA=9043 ) add_definitions( -DTRANSLATION_DOMAIN=\"kdevphp\" ) include_directories( ${KDEVPGQT_INCLUDE_DIR} ) add_subdirectory(app_templates) add_subdirectory(parser) add_subdirectory(duchain) add_subdirectory(completion) add_subdirectory(testprovider) add_subdirectory(docs) set(kdevphplanguagesupport_PART_SRCS phplanguagesupport.cpp phpparsejob.cpp phphighlighting.cpp codegen/refactoring.cpp ) ecm_qt_declare_logging_category(kdevphplanguagesupport_PART_SRCS HEADER phpdebug.h IDENTIFIER PHP CATEGORY_NAME "kdevelop.languages.php" ) kdevplatform_add_plugin(kdevphplanguagesupport JSON kdevphpsupport.json SOURCES ${kdevphplanguagesupport_PART_SRCS}) target_link_libraries(kdevphplanguagesupport KDev::Interfaces KDev::Language kdevphpduchain kdevphpparser kdevphpcompletion KF5::I18n KF5::TextEditor ) # not writeable so that the refactoring actions get hidden install(FILES phpfunctions.php DESTINATION ${DATA_INSTALL_DIR}/kdevphpsupport PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) # kdebugsettings file install(FILES kdevphpsupport.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/duchain/navigation/declarationnavigationcontext.cpp b/duchain/navigation/declarationnavigationcontext.cpp index d811d30..02a0f4d 100644 --- a/duchain/navigation/declarationnavigationcontext.cpp +++ b/duchain/navigation/declarationnavigationcontext.cpp @@ -1,258 +1,258 @@ /* Copyright 2007 David Nolden Copyright 2008 Niko Sams 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. */ #include "declarationnavigationcontext.h" #include #include #include #include #include #include #include #include #include #include "../types/indexedcontainer.h" #include "../declarations/classdeclaration.h" #include #include #include #include #include "helper.h" namespace Php { using namespace KDevelop; DeclarationNavigationContext::DeclarationNavigationContext(DeclarationPointer decl, KDevelop::TopDUContextPointer topContext, AbstractNavigationContext* previousContext) : AbstractDeclarationNavigationContext(decl, topContext, previousContext) { } NavigationContextPointer DeclarationNavigationContext::registerChild(DeclarationPointer declaration) { return AbstractDeclarationNavigationContext::registerChild(new DeclarationNavigationContext(declaration, topContext(), this)); } void DeclarationNavigationContext::htmlClass() { StructureType::Ptr klass = declaration()->abstractType().cast(); Q_ASSERT(klass); ClassDeclaration* classDecl = dynamic_cast(klass->declaration(topContext().data())); if (classDecl) { // write class modifier switch (classDecl->classModifier()) { case ClassDeclarationData::Abstract: modifyHtml() += QStringLiteral("abstract "); break; case ClassDeclarationData::Final: modifyHtml() += QStringLiteral("final "); break; default: //nothing break; } // write class type if (classDecl->classType() == ClassDeclarationData::Interface) { modifyHtml() += QStringLiteral("interface "); } else if (classDecl->classType() == ClassDeclarationData::Trait) { modifyHtml() += QStringLiteral("trait "); } else { modifyHtml() += QStringLiteral("class "); } // write class identifier eventuallyMakeTypeLinks(declaration()->abstractType()); // write inheritance if (classDecl->baseClassesSize() > 0) { AbstractType::Ptr extends; QList implements; FOREACH_FUNCTION(const BaseClassInstance& base, classDecl->baseClasses) { StructureType::Ptr stype = base.baseClass.type(); if (stype) { ClassDeclaration *classDecl = dynamic_cast(stype->declaration(topContext().data())); if (classDecl) { if (classDecl->classType() == ClassDeclarationData::Interface) { implements.append(base.baseClass.abstractType()); } else { extends = base.baseClass.abstractType(); } } } } // write parent class if (extends) { modifyHtml() += QStringLiteral(" extends "); eventuallyMakeTypeLinks(extends); } // write implemented interfaces if (!implements.isEmpty()) { modifyHtml() += QStringLiteral(" implements "); for (QList::iterator i = implements.begin(); ;) { eventuallyMakeTypeLinks(*i); ++i; if (i != implements.end()) { modifyHtml() += QStringLiteral(", "); } else { break; } } } } modifyHtml() += QStringLiteral(" "); } } void DeclarationNavigationContext::htmlAdditionalNavigation() { if (auto member = dynamic_cast(declaration().data())) { Declaration *dec = member->aliasedDeclaration().data(); if (dec && dec->context() && dec->context()->owner()) { modifyHtml() += i18n("Use of %1 from %2
") .arg(createLink(prettyQualifiedIdentifier(DeclarationPointer(dec)).toString(), QStringLiteral("jump_to_used"), NavigationAction(DeclarationPointer(dec), KDevelop::NavigationAction::NavigateDeclaration))) .arg(createLink(prettyQualifiedIdentifier(DeclarationPointer(dec->context()->owner())).toString(), QStringLiteral("jump_to_used_container"), NavigationAction(DeclarationPointer(dec->context()->owner()), KDevelop::NavigationAction::NavigateDeclaration))); } } else if (auto member = dynamic_cast(declaration().data())) { Declaration *dec = member->aliasedDeclaration().data(); if (dec && dec->context() && dec->context()->owner()) { modifyHtml() += i18n("Use of %1 from %2
") .arg(createLink(prettyQualifiedIdentifier(DeclarationPointer(dec)).toString(), QStringLiteral("jump_to_used"), NavigationAction(DeclarationPointer(dec), KDevelop::NavigationAction::NavigateDeclaration))) .arg(createLink(prettyQualifiedIdentifier(DeclarationPointer(dec->context()->owner())).toString(), QStringLiteral("jump_to_used_container"), NavigationAction(DeclarationPointer(dec->context()->owner()), KDevelop::NavigationAction::NavigateDeclaration))); } else { modifyHtml() += i18n("Broken member alias trait."); } } KDevelop::AbstractDeclarationNavigationContext::htmlAdditionalNavigation(); } void DeclarationNavigationContext::htmlFunction() { const AbstractFunctionDeclaration* function = dynamic_cast(declaration().data()); Q_ASSERT(function); const ClassFunctionDeclaration* classFunDecl = dynamic_cast(declaration().data()); const FunctionType::Ptr type = declaration()->abstractType().cast(); if( !type ) { modifyHtml() += errorHighlight(QStringLiteral("Invalid type
")); return; } if( !classFunDecl || (!classFunDecl->isConstructor() && !classFunDecl->isDestructor()) ) { // only print return type for global functions and non-ctor/dtor methods eventuallyMakeTypeLinks( type->returnType() ); } modifyHtml() += ' ' + identifierHighlight(prettyIdentifier(declaration()).toString().toHtmlEscaped(), declaration()); if( type->indexedArgumentsSize() == 0 ) { modifyHtml() += QStringLiteral("()"); } else { modifyHtml() += QStringLiteral("( "); bool first = true; int firstDefaultParam = type->indexedArgumentsSize() - function->defaultParametersSize(); int currentArgNum = 0; QVector decls; if (DUContext* argumentContext = DUChainUtils::getArgumentContext(declaration().data())) { decls = argumentContext->localDeclarations(topContext().data()); } foreach(const AbstractType::Ptr& argType, type->arguments()) { if( !first ) modifyHtml() += QStringLiteral(", "); first = false; VariableDeclaration *argDec = dynamic_cast(decls[currentArgNum]); - if (argDec->isVariadic()) { + if (argDec && argDec->isVariadic()) { AbstractType::Ptr variadicType; const auto indexed = argType.cast(); if (indexed && indexed->typesCount() == 1) { variadicType = indexed->typeAt(0).abstractType(); } else { variadicType = AbstractType::Ptr(new IntegralType(IntegralType::TypeMixed)); } modifyHtml() += QStringLiteral("["); eventuallyMakeTypeLinks( variadicType ); if (currentArgNum < decls.size()) { modifyHtml() += QStringLiteral(" ...") + identifierHighlight(decls[currentArgNum]->identifier().toString().toHtmlEscaped(), declaration()); } modifyHtml() += QStringLiteral("]"); } else { eventuallyMakeTypeLinks( argType ); if (currentArgNum < decls.size()) { modifyHtml() += ' ' + identifierHighlight(decls[currentArgNum]->identifier().toString().toHtmlEscaped(), declaration()); } if (currentArgNum >= firstDefaultParam) { IndexedString defaultStr = function->defaultParameters()[currentArgNum - firstDefaultParam]; if (!defaultStr.isEmpty()) { modifyHtml() += " = " + defaultStr.str().toHtmlEscaped(); } } } ++currentArgNum; } modifyHtml() += QStringLiteral(" )"); } modifyHtml() += QStringLiteral("
"); } QualifiedIdentifier DeclarationNavigationContext::prettyQualifiedIdentifier( DeclarationPointer decl ) const { return QualifiedIdentifier(prettyName(decl.data())); } void DeclarationNavigationContext::makeLink(const QString& name, DeclarationPointer declaration, NavigationAction::Type actionType) { if ( actionType == NavigationAction::JumpToSource && declaration->url() == internalFunctionFile() ) { modifyHtml() += i18n("PHP internal"); return; } AbstractDeclarationNavigationContext::makeLink(name, declaration, actionType); } QString DeclarationNavigationContext::declarationKind(DeclarationPointer decl) { if ( decl->kind() == Declaration::Instance && decl->abstractType() && decl->abstractType()->modifiers() & AbstractType::ConstModifier ) { return i18nc("kind of a php-constant, as shown in the declaration tooltip", "Constant"); } return AbstractDeclarationNavigationContext::declarationKind(decl); } }