diff options
Diffstat (limited to 'lib/cppparser/driver.h')
-rw-r--r-- | lib/cppparser/driver.h | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/lib/cppparser/driver.h b/lib/cppparser/driver.h new file mode 100644 index 00000000..31f62443 --- /dev/null +++ b/lib/cppparser/driver.h @@ -0,0 +1,460 @@ +/* This file is part of KDevelop + Copyright (C) 2002,2003 Roberto Raggi <roberto@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef DRIVER_H +#define DRIVER_H + +#include "ast.h" + +#include "macro.h" +#include <qpair.h> +#include <qvaluestack.h> +#include <qstringlist.h> +#include <qcstring.h> +#include <qdatastream.h> +#include <qmap.h> +#include <qdatetime.h> +#include <qvaluelist.h> +#include <map> +#include <set> +#include <hashedstring.h> +#include <ksharedptr.h> +#include <codemodel.h> +#include <ext/hash_map> +#include "lexercache.h" + + +class Lexer; +class Parser; + +enum +{ + Dep_Global, + Dep_Local +}; + +typedef QPair<QString, int> Dependence; + +class ParsedFile; +typedef KSharedPtr< ParsedFile > ParsedFilePointer; + +class ParsedFile : public AbstractParseResult { + public: + struct IncludeDesc { + bool local; //Whether it is a local include(#include "local.h", not #include <global.h>) + QString includePath; + ParsedFilePointer parsed; //May be zero! + }; +// ParsedFile() { +// } + ParsedFile( QDataStream& s ) { + read( s ); + } + + ParsedFile( const QString& fileName, const QDateTime& timeStamp ); + + ///Deserializes the ParsedFile from a previous call to serialize(). AST will always be zero after a call to this. + ParsedFile( const QByteArray& array ); + + /** + * @return All Macros that were used while processing this translation-unit. May be modified. + */ + MacroSet& usedMacros(); + const MacroSet& usedMacros() const; + + /** + * @return the count of lines that were skipped while preprocessing the file + * */ + int skippedLines() const; + + void setSkippedLines( int lines ); + /** + * @return Absolutely all files included by this one(no matter through how many other files they were included) + */ +// HashedStringSet& includeFiles(); + + const HashedStringSet& includeFiles() const; + + void addIncludeFiles( const HashedStringSet& includeFiles ); + + void addIncludeFile( const QString& includePath, const ParsedFilePointer& parsed, bool localInclude ); + + ///If this file was parsed while resolving the dependencies of another file, this returns the file this one was included from. Else returns an empty string. + QString includedFrom() const; + + void setIncludedFrom( const QString& str ); + /** + * @return Reference to the internal list of all directly included files(without those included indirectly) + */ + const QValueList<IncludeDesc>& directIncludeFiles() const; + + operator TranslationUnitAST* () const; //May be zero! + + TranslationUnitAST* operator -> () const { + if( !this ) return 0; + return m_translationUnit; + } + + void setTranslationUnit( const TranslationUnitAST::Node& trans ); + + QString fileName() const; + + QDateTime timeStamp() const; + + ///Serializes the content of this class into a byte-array. Note that this does not serialize the AST. + QByteArray serialize() const; + + /*void read( QDataStream& stream ); + void write( QDataStream& stream ) const;*/ + + virtual void read( QDataStream& stream ) { + int directIncludeFilesCount; + stream >> directIncludeFilesCount; + m_directIncludeFiles.clear(); + for( int a = 0; a < directIncludeFilesCount; a++ ) { + IncludeDesc i; + Q_INT8 in; + stream >> in; + i.local = in; + stream >> i.includePath; + //"parsed" will not be reconstructed + m_directIncludeFiles.push_back( i ); + } + stream >> m_skippedLines; + stream >> m_fileName; + stream >> m_timeStamp; + stream >> m_includedFrom; + m_usedMacros.read( stream ); + m_translationUnit = 0; + m_includeFiles.read( stream ); + } + + virtual void write( QDataStream& stream ) const { + int i = m_directIncludeFiles.size(); + stream << i; + for( QValueList<IncludeDesc>::const_iterator it = m_directIncludeFiles.begin(); it != m_directIncludeFiles.end(); ++it ) { + Q_INT8 i = (*it).local; + stream << i; + stream << (*it).includePath; + } + stream << m_skippedLines; + stream << m_fileName; + stream << m_timeStamp; + stream << m_includedFrom; + m_usedMacros.write( stream ); + m_includeFiles.write( stream ); + } + + virtual ParsedFileType type() const { + return CppParsedFile; + } + + private: + QValueList<IncludeDesc> m_directIncludeFiles; + MacroSet m_usedMacros; + TranslationUnitAST::Node m_translationUnit; + HashedStringSet m_includeFiles; + int m_skippedLines; + QString m_fileName; + QDateTime m_timeStamp; + QString m_includedFrom; +}; + +/** + * An interface that provides source code to the Driver + */ +class SourceProvider { + public: + SourceProvider() {} + virtual ~SourceProvider() {} + + /** + * Get the contents of a file + * \param fileName The name of the file to get the contents for. An absolute + * path should be used. + * \return A QString that contains the contents of the file + */ + virtual QString contents( const QString& fileName ) = 0; + + /** + * Check to see if a file has been modified + * \param fileName The name of hte file to get the modification state of. An + * absolute path should be used. + * \return true if the file has been modified + * \return false if the file has not been modified + */ + virtual bool isModified( const QString& fileName ) = 0; + + private: + SourceProvider( const SourceProvider& source ); + void operator = ( const SourceProvider& source ); +}; + +class Driver { + public: + Driver(); + virtual ~Driver(); + + typedef std::multimap< HashedString, Macro > MacroMap; + + /** + * Get the source provider for this driver. This would be useful for + * getting the text the driver is working with. + */ + SourceProvider* sourceProvider(); + /** + * Sets the source provider the driver will use + * @param sourceProvider the SourceProvider the driver will use + */ + void setSourceProvider( SourceProvider* sourceProvider ); + + /** + * @brief Resets the driver + * + * Clears the driver of all problems, dependencies, macros, and include paths and + * removes any translation units that have been parsed + */ + virtual void reset(); + + /** + * Tells the driver to start parsing a file + * @param fileName The name of the file to parse + * @param onlyPreProcesss Tells the driver to only run the file through the preprocessor. Defaults to false + * @param force Force the parsing of the file. Defaults to false + * @param macrosGlobal Should the macros be global? (Global macros are not deleted once a new translation-unit is parsed) + */ + virtual void parseFile( const QString& fileName, bool onlyPreProcesss = false, bool force = false, bool macrosGlobal = false ); + + /** + * Indicates that the file has been parsed + * @param fileName The name of the file parsed. It is legal to create a ParsedFilePointer on the given item. + */ + virtual void fileParsed( ParsedFile& fileName ); + + /** + * Removes the file specified by @p fileName from the driver + * @param fileName The name of the file to remove + */ + virtual void remove + ( const QString& fileName ); + + /** + * Add a dependency on another header file for @p fileName + * @param fileName The file name to add the dependency for + * @param dep The dependency to add + */ + virtual void addDependence( const QString& fileName, const Dependence& dep ); + + /** + * Add a macro to the driver + * @param macro The macro to add to the driver + */ + virtual void addMacro( const Macro& macro ); + + /** + * Add a problem to the driver + * @param fileName The file name to add the problem for + * @param problem The problem to add + */ + virtual void addProblem( const QString& fileName, const Problem& problem ); + + /** + * The current file name the driver is working with + */ + QString currentFileName() const { + return m_currentFileName; + } + ParsedFilePointer takeTranslationUnit( const QString& fileName ); + + void takeTranslationUnit( const ParsedFile& file ); + /** + * Get the translation unit contained in the driver for @p fileName. + * @param fileName The name of the file to get the translation unit for + * @return The TranslationUnitAST pointer that represents the translation unit + * @return 0 if no translation unit exists for the file + */ + ParsedFilePointer translationUnit( const QString& fileName ) const; + /** + * Get the dependencies for a file + * @param fileName The file name to get dependencies for + * @return The dependencies for the file + */ + QMap<QString, Dependence> dependences( const QString& fileName ) const; + /** + * Get all the macros the driver contains + * @return The macros + */ + const MacroMap& macros() const; + + /** + * Take all macros from the given map(forgetting own macros) */ + void insertMacros( const MacroSet& macros ); + /** + * Get the list of problem areas the driver contains + * @param fileName The filename to get problems for + * @return The list of problems for @p fileName + */ + QValueList<Problem> problems( const QString& fileName ) const; + + void usingString( const HashedString& str ); + /** + * Check if we have a macro in the driver + * If the last stacked macro of that name is an undef-macro, false is returned. + * @param name The name of the macro to check for + * @return true if we have the macro in the driver + * @return false if we don't have the macro in the driver + */ + bool hasMacro( const HashedString& name ) ; + /** + * Get the macro identified by @p name + * @param name The name of the macro to get + * @return A const reference of the macro object represented by @p name + */ + const Macro& macro( const HashedString& name ) const; + /** + * Get the last inserted macro identified by @p name + * @override + * @param name The name of the macro to get + * @return A non-const reference of the macro object represented by @p name + * + */ + Macro& macro( const HashedString& name ); + + /** + * Remove the last inserted Macro of that name + * @param macroName The name of the macro to remove + */ + virtual void removeMacro( const HashedString& macroName ); + + /** + * Remove all macros from the driver for a certain file + * @param fileName The file name + */ + virtual void removeAllMacrosInFile( const QString& fileName ); ///Check when this is called. It may be wrong. + + QStringList includePaths() const { + return m_includePaths; + } + + virtual QStringList getCustomIncludePath( const QString& ); + + + virtual void addIncludePath( const QString &path ); + + virtual void clearIncludePaths(); + + /// @todo remove + const QMap<QString, ParsedFilePointer> &parsedUnits() const { + return m_parsedUnits; + } + + /** + * Set whether or not to enable dependency resolving for files added to the driver + */ + virtual void setResolveDependencesEnabled( bool enabled ); + /** + * Check if dependency resolving is enabled + * \return true if dependency resolving is enabled + * \return false if dependency resolving is disabled + */ + bool isResolveDependencesEnabled() const { + return depresolv; + } + + void setMaxDependenceDepth( int depth ); + + /** + * Used by the Lexer to indicate that a Macro was used + * @param macro The used macro + * */ + void usingMacro( const Macro& macro ); + + /** + * Returns the local instance of the lexer-cache, can be used from outside to control the cache-behavior. + * */ + LexerCache* lexerCache(); + + ///This uses getCustomIncludePath(..) to resolve the include-path internally + QString findIncludeFile( const Dependence& dep, const QString& fromFile ); + + protected: + ///This uses the state of the parser to find the include-file + QString findIncludeFile( const Dependence& dep ) const; + + /** + * Set up the lexer. + */ + virtual void setupLexer( Lexer* lexer ); + /** + * Setup the parser + */ + virtual void setupParser( Parser* parser ); + /** + * Set up the preprocessor + */ + virtual void setupPreProcessor(); + + /** + * Is code-information for this file already available? If false is returned, the file will be parsed. + * Code-model and static repository should be checked to find out whether the file is already available. + * This function is only used when dependency-resolving is activated. + * @arg file absolute path to the file + */ + virtual bool shouldParseIncludedFile( const ParsedFilePointer& /*file*/ ); + + void clearMacros(); + + void clearParsedMacros(); + + private: + QMap<QString, Dependence>& findOrInsertDependenceList( const QString& fileName ); + QValueList<Problem>& findOrInsertProblemList( const QString& fileName ); + + + private: + QString m_currentFileName; + QString m_currentMasterFileName; + typedef QMap<QString, Dependence> DependenceMap; + typedef QMap< QString, DependenceMap> DependencesMap; + DependencesMap m_dependences; + MacroMap m_macros; + QMap< QString, QValueList<Problem> > m_problems; + QMap<QString, ParsedFilePointer> m_parsedUnits; + QStringList m_includePaths; + uint depresolv : + 1; + Lexer *lexer; + SourceProvider* m_sourceProvider; + + ParsedFilePointer m_currentParsedFile; + CachedLexedFilePointer m_currentLexerCache; + LexerCache m_lexerCache; + + int m_dependenceDepth; + int m_maxDependenceDepth; + + class ParseHelper; + friend class ParseHelper; + + private: + Driver( const Driver& source ); + void operator = ( const Driver& source ); +}; + +#endif |