Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit e01b1978 authored by David Nolden's avatar David Nolden

Implement storing/loading of EnvironmentFile. Not all of its data can be...

Implement storing/loading of EnvironmentFile. Not all of its data can be stored in a copyable format atm, for that reason some items are copied from the data to another format on loading, and copied back on aboutToSave().
parent 90673f7b
......@@ -93,6 +93,10 @@ public:
Set operator -(const Set& rhs) const;
Set& operator -=(const Set& rhs);
uint setIndex() const {
return m_tree;
}
///Returns a pointer to the repository this set belongs to. Returns zero when this set is not initialized yet.
BasicSetRepository* repository() const;
private:
......
......@@ -22,6 +22,8 @@
#include <language/editor/modificationrevision.h>
#include "parser/rpp/macrorepository.h"
#include "cppdebughelper.h"
#include <arrayhelpers.h>
#include <duchainregister.h>
bool Cpp::EnvironmentManager::m_simplifiedMatching = false;
......@@ -55,6 +57,13 @@ inline bool debugging() {
using namespace Cpp;
using namespace KDevelop;
namespace Cpp {
DEFINE_LIST_MEMBER_HASH(EnvironmentFileData, m_includePaths, KDevelop::IndexedString);
DEFINE_LIST_MEMBER_HASH(EnvironmentFileData, m_allModificationTimes, StringModificationPair);
}
REGISTER_DUCHAIN_ITEM(EnvironmentFile);
//Repository that contains the actual macros, and maps them to indices
MacroDataRepository Cpp::EnvironmentManager::macroDataRepository("macro repository");
//Set-repository that contains the string-sets
......@@ -199,20 +208,54 @@ bool EnvironmentFile::needsUpdate() const {
return false;
}
EnvironmentFile::EnvironmentFile( const IndexedString& fileName, EnvironmentManager* manager ) : m_identityOffset(0), m_url( fileName ), m_includeFiles(&EnvironmentManager::stringSetRepository), m_missingIncludeFiles(&EnvironmentManager::stringSetRepository), m_usedMacros(&EnvironmentManager::macroSetRepository), m_usedMacroNames(&EnvironmentManager::stringSetRepository), m_definedMacros(&EnvironmentManager::macroSetRepository), m_definedMacroNames(&EnvironmentManager::stringSetRepository), m_unDefinedMacroNames(&EnvironmentManager::stringSetRepository),m_contentStartLine(0) {
QFileInfo fileInfo( KUrl(fileName.str()).path() ); ///@todo care about remote documents
m_modificationTime = fileInfo.lastModified();
EnvironmentFile::EnvironmentFile( const IndexedString& fileName, EnvironmentManager* manager ) : ParsingEnvironmentFile(*new EnvironmentFileData()), m_includeFiles(&EnvironmentManager::stringSetRepository), m_missingIncludeFiles(&EnvironmentManager::stringSetRepository), m_usedMacros(&EnvironmentManager::macroSetRepository), m_usedMacroNames(&EnvironmentManager::stringSetRepository), m_definedMacros(&EnvironmentManager::macroSetRepository), m_definedMacroNames(&EnvironmentManager::stringSetRepository), m_unDefinedMacroNames(&EnvironmentManager::stringSetRepository) {
ifDebug( kDebug(9007) << "created for" << fileName.str() << "modification-time:" << m_modificationTime );
d_func_dynamic()->m_url = fileName;
QFileInfo fileInfo( KUrl(fileName.str()).path() );
d_func_dynamic()->m_modificationTime = fileInfo.lastModified();
addIncludeFile( m_url, m_modificationTime );
clearModificationTimes();
}
EnvironmentFile::EnvironmentFile( EnvironmentFileData& data ) : ParsingEnvironmentFile(data)
, m_includeFiles(&EnvironmentManager::stringSetRepository, 0, Utils::Set(data.m_includeFiles, &EnvironmentManager::stringSetRepository))
, m_missingIncludeFiles(&EnvironmentManager::stringSetRepository, 0, Utils::Set(data.m_missingIncludeFiles, &EnvironmentManager::stringSetRepository))
, m_usedMacros(&EnvironmentManager::macroSetRepository, 0, Utils::Set(data.m_usedMacros, &EnvironmentManager::macroSetRepository))
, m_usedMacroNames(&EnvironmentManager::stringSetRepository, 0, Utils::Set(data.m_usedMacroNames, &EnvironmentManager::stringSetRepository))
, m_definedMacros(&EnvironmentManager::macroSetRepository, 0, Utils::Set(data.m_definedMacros, &EnvironmentManager::macroSetRepository))
, m_definedMacroNames(&EnvironmentManager::stringSetRepository, 0, Utils::Set(data.m_definedMacroNames, &EnvironmentManager::stringSetRepository))
, m_unDefinedMacroNames(&EnvironmentManager::stringSetRepository, 0, Utils::Set(data.m_unDefinedMacroNames, &EnvironmentManager::stringSetRepository))
{
//Copy data from "data" to temporary items
FOREACH_FUNCTION(const StringModificationPair& pair, data.m_allModificationTimes)
m_allModificationTimes[pair.first] = pair.second;
}
void EnvironmentFile::aboutToSave() {
ParsingEnvironmentFile::aboutToSave();
///@todo Get rid of this. Instead, automatically create LazySet's like done with lists in appendedlist code.
//Copy data from temporary items to "data"
d_func_dynamic()->m_includeFiles = m_includeFiles.set().setIndex();
d_func_dynamic()->m_missingIncludeFiles = m_missingIncludeFiles.set().setIndex();
d_func_dynamic()->m_usedMacros = m_usedMacros.set().setIndex();
d_func_dynamic()->m_usedMacroNames = m_usedMacroNames.set().setIndex();
d_func_dynamic()->m_definedMacros = m_definedMacros.set().setIndex();
d_func_dynamic()->m_definedMacroNames = m_definedMacroNames.set().setIndex();
d_func_dynamic()->m_unDefinedMacroNames = m_unDefinedMacroNames.set().setIndex();
d_func_dynamic()->m_allModificationTimesList().clear();
for(QMap<KDevelop::IndexedString, KDevelop::ModificationRevision>::const_iterator it = m_allModificationTimes.begin(); it != m_allModificationTimes.end(); ++it)
d_func_dynamic()->m_allModificationTimesList().append( qMakePair(it.key(), it.value()) );
}
void EnvironmentFile::setContentStartLine(int line) {
m_contentStartLine = line;
d_func_dynamic()->m_contentStartLine = line;
}
int EnvironmentFile::contentStartLine() const {
return m_contentStartLine;
return d_func()->m_contentStartLine;
}
void EnvironmentFile::addDefinedMacro( const rpp::pp_macro& macro, const rpp::pp_macro* previousOfSameName ) {
......@@ -265,7 +308,7 @@ void EnvironmentFile::usingMacro( const rpp::pp_macro& macro ) {
// }
Utils::Set EnvironmentFile::strings() const {
return m_strings;
return Utils::Set(d_func()->m_strings, &EnvironmentManager::stringSetRepository);
}
......@@ -293,12 +336,17 @@ const LazyMacroSet& EnvironmentFile::usedMacros() const {
return m_usedMacros;
}
const QList<IndexedString>& EnvironmentFile::includePaths() const {
return m_includePaths;
const QList<IndexedString> EnvironmentFile::includePaths() const {
QList<IndexedString> ret;
FOREACH_FUNCTION(IndexedString include, d_func()->m_includePaths)
ret << include;
return ret;
}
void EnvironmentFile::setIncludePaths( const QList<IndexedString>& paths ) {
m_includePaths = paths;
d_func_dynamic()->m_includePathsList().clear();
foreach(IndexedString include, paths)
d_func_dynamic()->m_includePathsList().append(include);
}
///Should contain a modification-time for each included-file
......@@ -308,11 +356,11 @@ const QMap<IndexedString, KDevelop::ModificationRevision>& EnvironmentFile::allM
void EnvironmentFile::clearModificationTimes() {
m_allModificationTimes.clear();
m_allModificationTimes[m_url] = m_modificationTime;
m_allModificationTimes[d_func()->m_url] = d_func()->m_modificationTime;
}
IndexedString EnvironmentFile::url() const {
return m_url;
return d_func()->m_url;
}
void EnvironmentFile::addMissingIncludeFile(const IndexedString& file)
......@@ -341,21 +389,21 @@ void EnvironmentFile::setModificationRevision( const KDevelop::ModificationRevis
kDebug( 9007 ) << id(this) << "setting modification-revision" << rev.toString();
}
#endif
m_modificationTime = rev;
d_func_dynamic()->m_modificationTime = rev;
#ifdef LEXERCACHE_DEBUG
if(debugging()) {
kDebug( 9007 ) << id(this) << "new modification-revision" << m_modificationTime;
}
#endif
m_allModificationTimes[m_url] = rev;
m_allModificationTimes[d_func()->m_url] = rev;
}
KDevelop::ModificationRevision EnvironmentFile::modificationRevision() const {
return m_modificationTime;
return d_func()->m_modificationTime;
}
void EnvironmentFile::addStrings( const std::set<Utils::BasicSetRepository::Index>& strings ) {
m_strings += EnvironmentManager::stringSetRepository.createSet(strings);
d_func_dynamic()->m_strings = (this->strings() + EnvironmentManager::stringSetRepository.createSet(strings)).setIndex();
}
//The parameter should be a EnvironmentFile that was lexed AFTER the content of this file
......@@ -365,7 +413,7 @@ void EnvironmentFile::merge( const EnvironmentFile& file ) {
kDebug( 9007 ) << id(this) << ": merging" << id(&file) << "defined in macros this:" << print(m_definedMacroNames) << "defined macros in other:" << print(file.m_definedMacroNames) << "undefined macros in other:" << print(file.m_unDefinedMacroNames) << "strings in other:" << print(file.m_strings);
}
#endif
m_strings += (file.m_strings - m_definedMacroNames.set()) - m_unDefinedMacroNames.set();
d_func_dynamic()->m_strings = (strings() + (file.strings() - m_definedMacroNames.set()) - m_unDefinedMacroNames.set()).setIndex();
///@todo Probably it's more efficient having 2 sets m_changedMacroNames and m_unDefinedMacroNames, where m_unDefinedMacroNames is a subset of m_changedMacroNames.
//Only add macros to the usedMacros-set that were not defined locally
m_usedMacroNames += (file.m_usedMacroNames.set() - m_definedMacroNames.set()) - m_unDefinedMacroNames.set();
......@@ -420,15 +468,15 @@ size_t EnvironmentFile::hash() const {
}
uint EnvironmentFile::identityOffset() const {
return m_identityOffset;
return d_func()->m_identityOffset;
}
void EnvironmentFile::setIdentityOffset(uint offset) {
m_identityOffset = offset;
d_func_dynamic()->m_identityOffset = offset;
}
IdentifiedFile EnvironmentFile::identity() const {
return IdentifiedFile(m_url, (uint)hash() + m_identityOffset);
return IdentifiedFile(d_func()->m_url, (uint)hash() + d_func()->m_identityOffset);
}
int EnvironmentFile::type() const {
......
......@@ -142,12 +142,72 @@ typedef Utils::LazySet<rpp::pp_macro, MacroIndexConversion> LazyMacroSet;
class EnvironmentManager;
class MacroSet;
typedef QPair<KDevelop::IndexedString, KDevelop::ModificationRevision> StringModificationPair;
DECLARE_LIST_MEMBER_HASH(EnvironmentFileData, m_includePaths, KDevelop::IndexedString);
DECLARE_LIST_MEMBER_HASH(EnvironmentFileData, m_allModificationTimes, StringModificationPair);
struct EnvironmentFileData : public KDevelop::DUChainBaseData {
EnvironmentFileData() {
initializeAppendedLists();
m_contentStartLine = 0;
m_identityOffset = 0;
m_strings = 0;
m_includeFiles = 0;
m_missingIncludeFiles = 0;
m_usedMacros = 0;
m_usedMacroNames = 0;
m_definedMacros = 0;
m_definedMacroNames = 0;
m_unDefinedMacroNames = 0;
}
EnvironmentFileData(const EnvironmentFileData& rhs) : KDevelop::DUChainBaseData(rhs) {
initializeAppendedLists();
copyListsFrom(rhs);
m_identityOffset = rhs.m_identityOffset;
m_url = rhs.m_url;
m_modificationTime = rhs.m_modificationTime;
m_strings = rhs.m_strings; //String-set
m_includeFiles = rhs.m_includeFiles; //String-set
m_missingIncludeFiles = rhs.m_missingIncludeFiles; //String-set
m_usedMacros = rhs.m_usedMacros; //Macro-set
m_usedMacroNames = rhs.m_usedMacroNames; //String-set
m_definedMacros = rhs.m_definedMacros; //Macro-set
m_definedMacroNames = rhs.m_definedMacroNames; //String-set
m_unDefinedMacroNames = rhs.m_unDefinedMacroNames; //String-set
m_contentStartLine = rhs.m_contentStartLine;
}
~EnvironmentFileData() {
freeAppendedLists();
}
uint m_identityOffset;
KDevelop::IndexedString m_url;
KDevelop::ModificationRevision m_modificationTime;
//Set of all strings that can be affected by macros from outside
uint m_strings; //String-set
uint m_includeFiles; //String-set
uint m_missingIncludeFiles; //String-set
uint m_usedMacros; //Macro-set
uint m_usedMacroNames; //String-set
uint m_definedMacros; //Macro-set
uint m_definedMacroNames; //String-set
uint m_unDefinedMacroNames; //String-set
int m_contentStartLine;
START_APPENDED_LISTS_BASE(EnvironmentFileData, KDevelop::DUChainBaseData);
APPENDED_LIST_FIRST(EnvironmentFileData, KDevelop::IndexedString, m_includePaths);
APPENDED_LIST(EnvironmentFileData, StringModificationPair, m_allModificationTimes, m_includePaths);
END_APPENDED_LISTS(EnvironmentFileData, m_allModificationTimes);
};
class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmentFile {
public:
///@todo Respect changing include-paths: Check if the included files are still the same(maybe new files are found that were not found before)
EnvironmentFile( const KDevelop::IndexedString& url, EnvironmentManager* manager );
EnvironmentFile( EnvironmentFileData& data );
void addStrings( const std::set<Utils::BasicSetRepository::Index>& strings );
///If there previously was a macro defined of the same name, it must be given through previousOfSameName, else it can be zero.
......@@ -169,7 +229,7 @@ class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmen
void merge( const EnvironmentFile& file );
bool operator < ( const EnvironmentFile& rhs ) const {
return m_url < rhs.m_url;
return url() < rhs.url();
}
size_t hash() const;
......@@ -215,7 +275,7 @@ class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmen
void clearModificationTimes();
///Should return the include-paths that were used while parsing this file(as used/found in CppLanguageSupport)
const QList<KDevelop::IndexedString>& includePaths() const;
const QList<KDevelop::IndexedString> includePaths() const;
void setIncludePaths( const QList<KDevelop::IndexedString>& paths );
/**
......@@ -233,15 +293,18 @@ class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmen
virtual bool needsUpdate() const;
enum {
Identity = 73
};
typedef EnvironmentFileData Data;
private:
virtual void aboutToSave();
virtual int type() const;
friend class EnvironmentManager;
uint m_identityOffset;
QList<KDevelop::IndexedString> m_includePaths;
KDevelop::IndexedString m_url;
KDevelop::ModificationRevision m_modificationTime;
Utils::Set m_strings; //Set of all strings that can be affected by macros from outside
Cpp::LazyStringSet m_includeFiles; //Set of all files with absolute paths
Cpp::LazyStringSet m_missingIncludeFiles; //Set of relative file-names of missing includes
Cpp::LazyMacroSet m_usedMacros; //Set of all macros that were used, and were defined outside of this file
......@@ -250,7 +313,8 @@ class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmen
Cpp::LazyStringSet m_definedMacroNames;
Cpp::LazyStringSet m_unDefinedMacroNames; //Set of all macros that were undefined in this file, from outside perspective(not changed ones)
QMap<KDevelop::IndexedString, KDevelop::ModificationRevision> m_allModificationTimes;
mutable int m_contentStartLine; //Line-number where the actual content starts. Needs to be kept current when edited
DUCHAIN_DECLARE_DATA(EnvironmentFile);
/*
Needed data:
1. Set of all strings that appear in this file(For memory-reasons they should be taken from a global string-repository, because many will be the same)
......@@ -264,12 +328,6 @@ class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmen
typedef KSharedPtr<EnvironmentFile> EnvironmentFilePointer;
struct KDEVCPPDUCHAIN_EXPORT EnvironmentFilePointerCompare {
bool operator() ( const EnvironmentFilePointer& lhs, const EnvironmentFilePointer& rhs ) const {
return (*lhs) < (*rhs );
}
};
class KDEVCPPDUCHAIN_EXPORT EnvironmentManager {
public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment