File indexing completed on 2024-05-05 04:39:35

0001 /*
0002     SPDX-FileCopyrightText: 2014 Sergey Kalinichev <kalinichev.so.0@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef IDEFINESANDINCLUDES_H
0008 #define IDEFINESANDINCLUDES_H
0009 
0010 #include <QHash>
0011 #include <QPointer>
0012 #include <QString>
0013 
0014 #include <interfaces/icore.h>
0015 #include <interfaces/iplugincontroller.h>
0016 
0017 #include <util/path.h>
0018 
0019 namespace KDevelop
0020 {
0021 class ProjectBaseItem;
0022 class IProject;
0023 
0024 using Defines = QHash<QString, QString>;
0025 
0026 /** An interface that provides language plugins with include directories/files and defines.
0027 * Call IDefinesAndIncludesManager::manager() to get the instance of the plugin.
0028 **/
0029 class IDefinesAndIncludesManager
0030 {
0031 public:
0032     /// The type of includes/defines
0033     enum Type {
0034         CompilerSpecific = 1, ///< Those that compiler provides
0035         ProjectSpecific = 2, ///< Those that project manager provides
0036         UserDefined = 4,    ///< Those that user defines
0037         All = CompilerSpecific | ProjectSpecific | UserDefined
0038      };
0039 
0040     /**
0041      * Class that actually does all the work of calculating i/d.
0042      *
0043      * Implement one in e.g. project manager and register it with @see registerProvider
0044      * To unregister it use @see unregisterProvider
0045      *
0046      * @sa BackgroundProvider
0047     **/
0048     class Provider
0049     {
0050     public:
0051         virtual ~Provider() = default;
0052 
0053         virtual Defines defines( const QString& path ) const = 0;
0054         virtual Defines defines( ProjectBaseItem* item ) const = 0;
0055 
0056         virtual Path::List includes( const QString& path ) const = 0;
0057         virtual Path::List includes( ProjectBaseItem* item ) const = 0;
0058 
0059         virtual Path::List frameworkDirectories( const QString& path ) const = 0;
0060         virtual Path::List frameworkDirectories( ProjectBaseItem* item ) const = 0;
0061 
0062         /// @return the type of i/d this provider provides
0063         virtual Type type() const = 0;
0064     };
0065 
0066     /**
0067      * Use this as base class for provider, if computing includes/defines can takes a long time (e.g. parsing Makefile by running make).
0068      *
0069      * This provider will be queried for includes/defines in a background thread.
0070      *
0071      * @sa Provider
0072     **/
0073     class BackgroundProvider
0074     {
0075     public:
0076         virtual ~BackgroundProvider() = default;
0077 
0078         virtual Path::List includesInBackground( const QString& path ) const = 0;
0079 
0080         virtual Path::List frameworkDirectoriesInBackground( const QString& path ) const = 0;
0081 
0082         virtual Defines definesInBackground( const QString& path ) const = 0;
0083 
0084         virtual QString parserArgumentsInBackground(const QString& path) const = 0;
0085 
0086         /// @return the type of i/d this provider provides
0087         virtual Type type() const = 0;
0088     };
0089 
0090     ///@param item project item
0091     ///@param type Data sources to be used.
0092     ///@return list of defines for @p item
0093     ///NOTE: call it from the foreground thread only.
0094     virtual Defines defines( ProjectBaseItem* item, Type type = All ) const = 0;
0095 
0096     ///@param item project item
0097     ///@param type Data sources to be used.
0098     ///@return list of include directories/files for @p item
0099     ///NOTE: call it from the foreground thread only.
0100     virtual Path::List includes( ProjectBaseItem* item, Type type = All ) const = 0;
0101 
0102     ///@param item project item
0103     ///@param type Data sources to be used.
0104     ///@return list of framework directories for @p item
0105     ///NOTE: call it from the foreground thread only.
0106     virtual Path::List frameworkDirectories( ProjectBaseItem* item, Type type = All ) const = 0;
0107 
0108     ///@param path path to an out-of-project file.
0109     ///@param type Data sources to be used.
0110     ///@return list of defines for @p path
0111     ///NOTE: call it from the foreground thread only.
0112     virtual Defines defines( const QString& path, Type type = All ) const = 0;
0113 
0114     ///@param path path to an out-of-project file.
0115     ///@param type Data sources to be used.
0116     ///@return list of include directories/files for @p path
0117     ///NOTE: call it from the foreground thread only.
0118     virtual Path::List includes( const QString& path, Type type = All ) const = 0;
0119 
0120     ///@param path path to an out-of-project file.
0121     ///@param type Data sources to be used.
0122     ///@return list of framework directories for @p path
0123     ///NOTE: call it from the foreground thread only.
0124     virtual Path::List frameworkDirectories( const QString& path, Type type = All ) const = 0;
0125 
0126     /**
0127      * Computes include directories in background thread.
0128      *
0129      * This is especially useful for CustomMake projects.
0130      *
0131      * Call it from background thread if possible.
0132     **/
0133     virtual Path::List includesInBackground( const QString& path ) const = 0;
0134 
0135     /**
0136      * Computes framework directories in background thread.
0137      *
0138      * This is especially useful for CustomMake projects.
0139      *
0140      * Call it from background thread if possible.
0141     **/
0142     virtual Path::List frameworkDirectoriesInBackground( const QString& path ) const = 0;
0143 
0144     /**
0145      * Computes defined macros in background thread.
0146      *
0147      * Call it from background thread if possible.
0148     **/
0149     virtual Defines definesInBackground( const QString& path ) const = 0;
0150 
0151     /**
0152      * @param item project item. Use nullptr to get default arguments
0153      * @return The parser command-line arguments used to parse the @p item
0154      */
0155     virtual QString parserArguments(ProjectBaseItem* item) const = 0;
0156 
0157     virtual QString parserArguments(const QString& path) const = 0;
0158     virtual QString parserArgumentsInBackground(const QString& path) const = 0;
0159 
0160     ///@return the instance of the plugin.
0161     inline static IDefinesAndIncludesManager* manager();
0162 
0163     virtual ~IDefinesAndIncludesManager() = default;
0164 
0165     /**
0166      * Register the @p provider
0167      */
0168     virtual void registerProvider(Provider* provider) = 0;
0169 
0170     /**
0171      * Unregister the provider
0172      *
0173      * @return true on success, false otherwise (e.g. if not registered)
0174      */
0175     virtual bool unregisterProvider(Provider* provider) = 0;
0176 
0177     /**
0178      * Use this to register the background provider
0179      *
0180      * This provider will be queried for includes/defines in a background thread.
0181      */
0182     virtual void registerBackgroundProvider(BackgroundProvider* provider) = 0;
0183 
0184     /**
0185      * Unregister the background provider.
0186      *
0187      * @sa registerBackgroundProvider
0188      */
0189     virtual bool unregisterBackgroundProvider(BackgroundProvider* provider) = 0;
0190 
0191     /// Opens a configuration dialog for @p pathToFile to modify include directories/files and defined macros.
0192     virtual void openConfigurationDialog(const QString& pathToFile) = 0;
0193 };
0194 
0195 inline IDefinesAndIncludesManager* IDefinesAndIncludesManager::manager()
0196 {
0197     static QPointer<IPlugin> manager;
0198     if (!manager) {
0199         manager = ICore::self()->pluginController()->pluginForExtension( QStringLiteral("org.kdevelop.IDefinesAndIncludesManager") );
0200     }
0201     Q_ASSERT(manager);
0202 
0203     auto extension = manager->extension<IDefinesAndIncludesManager>();
0204     return extension;
0205 }
0206 
0207 }
0208 
0209 Q_DECLARE_INTERFACE( KDevelop::IDefinesAndIncludesManager, "org.kdevelop.IDefinesAndIncludesManager" )
0210 
0211 #endif