mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-26 20:03:10 +00:00
252 lines
7.2 KiB
C
252 lines
7.2 KiB
C
![]() |
/*
|
||
|
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.
|
||
|
*/
|
||
|
|
||
|
#ifndef KDEVPLATFORM_CODEGENERATOR_H
|
||
|
#define KDEVPLATFORM_CODEGENERATOR_H
|
||
|
|
||
|
#include "language/editor/documentrange.h"
|
||
|
#include "../duchain/indexedstring.h"
|
||
|
#include "../duchain/topducontext.h"
|
||
|
#include "../duchain/duchain.h"
|
||
|
|
||
|
#include "language/interfaces/iastcontainer.h"
|
||
|
|
||
|
namespace KDevelop
|
||
|
{
|
||
|
template<class AstNode >
|
||
|
class AstChangeSet;
|
||
|
|
||
|
class DUContext;
|
||
|
class DUChainChangeSet;
|
||
|
class DocumentChangeSet;
|
||
|
|
||
|
/**
|
||
|
* \short Base class for generic code generators
|
||
|
*
|
||
|
* CodeGeneratorBase provides an api for a step-by-step process to
|
||
|
* create and/or refactor code.
|
||
|
*
|
||
|
* This class should be used as a superclass only when du-chain level
|
||
|
* changes are made, since this level knows nothing about the
|
||
|
* language-specific AST. For more complex changes that require knowledge
|
||
|
* about the language AST, use CodeGenerator
|
||
|
*
|
||
|
* \see Refactoring
|
||
|
* \see CodeGenerator
|
||
|
* \author Hamish Rodda <rodda@kde.org>
|
||
|
*/
|
||
|
class KDEVPLATFORMLANGUAGE_EXPORT CodeGeneratorBase
|
||
|
{
|
||
|
public:
|
||
|
CodeGeneratorBase();
|
||
|
virtual ~CodeGeneratorBase();
|
||
|
|
||
|
enum State {
|
||
|
Precondition,
|
||
|
UserInput,
|
||
|
Processing,
|
||
|
Review,
|
||
|
Finished
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Check whether the preconditions of this generation are met at the given \a context and
|
||
|
* \a position.
|
||
|
* \returns true if conditions are met and the generator can progress, otherwise false if
|
||
|
* the conditions are not met. Use setErrorText to specify the nature of the Error.
|
||
|
*/
|
||
|
virtual bool checkPreconditions(DUContext* context, const DocumentRange& position) = 0;
|
||
|
|
||
|
/**
|
||
|
* Gather information required from the user for this generator.
|
||
|
*
|
||
|
* \returns true if all of the information is retrieved, otherwise false, Use setErrorText
|
||
|
* to specify the nature of the Error.
|
||
|
*/
|
||
|
virtual bool gatherInformation() = 0;
|
||
|
|
||
|
/**
|
||
|
* Do final condition checking and perform the code generation.
|
||
|
*
|
||
|
* \returns true if code generation was successful, false otherwise. Use setErrorText to
|
||
|
* specify the nature of the Error.
|
||
|
*/
|
||
|
virtual bool process() = 0;
|
||
|
|
||
|
const QString & errorText() const;
|
||
|
|
||
|
// Implementation from kJob
|
||
|
bool execute();
|
||
|
|
||
|
/**
|
||
|
* @brief Indicates that this generation should not expect interaction with the user/
|
||
|
* Most probable scenarios are: Testing, and a generator that is being used by another one
|
||
|
* @param context If not NULL, the custom context to use, instead of user selection
|
||
|
* @param position If not NULL, the cursom range to use instead of user selection
|
||
|
* @note If this function is called, then gather information will not be called.
|
||
|
* Derived classes should provide an alternative way of setting up the generator.
|
||
|
*/
|
||
|
void autoGenerate(DUContext * context, const DocumentRange * range);
|
||
|
|
||
|
/**
|
||
|
* \return The Document Change set to add a single Change, it is more addicient than creating a local DocumentChangeSet and merging it
|
||
|
*/
|
||
|
DocumentChangeSet & documentChangeSet();
|
||
|
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/**
|
||
|
* Generate text edits from duchain change set.
|
||
|
* This generator now owns the changeset, and will delete it.
|
||
|
*
|
||
|
* You may call this method multiple times to edit different files.
|
||
|
*/
|
||
|
void addChangeSet(DUChainChangeSet* duChainChange);
|
||
|
|
||
|
void addChangeSet(DocumentChangeSet & docChangeSet);
|
||
|
|
||
|
/**
|
||
|
* Accessor for KJob's KJob::setErrorText.
|
||
|
*/
|
||
|
void setErrorText(const QString & error);
|
||
|
|
||
|
/**
|
||
|
* Inform the derived class if this generation is being performed without user interaction
|
||
|
*/
|
||
|
bool autoGeneration() const;
|
||
|
|
||
|
/**
|
||
|
* Clean up all the change sets that this generator is in charge of
|
||
|
*/
|
||
|
void clearChangeSets();
|
||
|
|
||
|
private:
|
||
|
class CodeGeneratorPrivate * const d;
|
||
|
|
||
|
bool displayChanges();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* \brief Base class for Ast aware code generators
|
||
|
*
|
||
|
* This class provides convenience for adding AstChangeSet, storing
|
||
|
* the IAstContainer from the TopDUContext, and in general managing
|
||
|
* Code generators that manipulate the AST
|
||
|
*
|
||
|
* \see CodeGeneratorBase
|
||
|
* \author Ramón Zarazúa <killerfox512+kde@gmail.com>
|
||
|
*/
|
||
|
template <typename AstContainer>
|
||
|
class CodeGenerator : public CodeGeneratorBase
|
||
|
{
|
||
|
public:
|
||
|
~CodeGenerator()
|
||
|
{
|
||
|
clearChangeSets();
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/// Convenience definition of the TopAstNode that is contained by this AstContainer
|
||
|
typedef typename AstContainer::TopAstNode TopAstNode;
|
||
|
typedef AstChangeSet<TopAstNode> LanguageChangeSet;
|
||
|
|
||
|
/**
|
||
|
* Query an AST of a particular file
|
||
|
*/
|
||
|
TopAstNode * ast(const IndexedString & file)
|
||
|
{
|
||
|
return astContainer(file)->topAstNode();
|
||
|
}
|
||
|
|
||
|
TopAstNode * ast(const TopDUContext & context)
|
||
|
{
|
||
|
return astContainer(context)->topAstNode();
|
||
|
}
|
||
|
|
||
|
typename AstContainer::Ptr astContainer(const IndexedString & file)
|
||
|
{
|
||
|
if(!m_AstContainers.contains(file))
|
||
|
{
|
||
|
kDebug() << "Ast requested for: " << file.str();
|
||
|
|
||
|
TopDUContext * context = DUChain::self()->waitForUpdate(file, KDevelop::TopDUContext::AST).data();
|
||
|
|
||
|
Q_ASSERT(context);
|
||
|
m_AstContainers[file] = AstContainer::Ptr::template staticCast<IAstContainer>( context->ast() );
|
||
|
}
|
||
|
|
||
|
return m_AstContainers[file];
|
||
|
}
|
||
|
|
||
|
typename AstContainer::Ptr astContainer(const TopDUContext & context)
|
||
|
{
|
||
|
return astContainer(context.url());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate text edits from duchain / ast change set.
|
||
|
*
|
||
|
* You may call this method multiple times to edit different files.
|
||
|
*/
|
||
|
void addChangeSet(DUChainChangeSet * duChainChange)
|
||
|
{
|
||
|
CodeGeneratorBase::addChangeSet(duChainChange);
|
||
|
}
|
||
|
|
||
|
void addChangeSet(DocumentChangeSet & doc)
|
||
|
{
|
||
|
CodeGeneratorBase::addChangeSet(doc);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate text edits from duchain / ast change set.
|
||
|
*
|
||
|
* You may call this method multiple times to edit different files.
|
||
|
*/
|
||
|
void addChangeSet(LanguageChangeSet * astChange);
|
||
|
|
||
|
void clearChangeSets()
|
||
|
{
|
||
|
CodeGeneratorBase::clearChangeSets();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Inform the derived class if this generation is being performed without user interaction
|
||
|
*/
|
||
|
bool autoGeneration() const
|
||
|
{
|
||
|
return CodeGeneratorBase::autoGeneration();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Accessor for KJob's KJob::setErrorText.
|
||
|
*/
|
||
|
void setErrorText(const QString & error)
|
||
|
{
|
||
|
CodeGeneratorBase::setErrorText(error);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
typedef QMap<IndexedString, typename AstContainer::Ptr> AstContainerMap;
|
||
|
AstContainerMap m_AstContainers;
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif // KDEVPLATFORM_CODEGENERATOR_H
|