You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
461 lines
14 KiB
461 lines
14 KiB
/* 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., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, 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
|