backgroundparser.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "backgroundparser.h"
00013 #include "javasupportpart.h"
00014 #include "javasupport_events.h"
00015 #include "driver.h"
00016 #include "kdevdeepcopy.h"
00017 #include "kdevdriver.h"
00018
00019 #if QT_VERSION < 0x030100
00020 #include <kdevmutex.h>
00021 #else
00022 #include <qmutex.h>
00023 #endif
00024
00025 #include <kparts/part.h>
00026 #include <ktexteditor/editinterface.h>
00027 #include <ktexteditor/document.h>
00028 #include <ktexteditor/view.h>
00029
00030 #include <kdevpartcontroller.h>
00031 #include <kdevproject.h>
00032
00033 #include <kurl.h>
00034 #include <kdebug.h>
00035 #include <kapplication.h>
00036
00037 #include <qfile.h>
00038 #include <qfileinfo.h>
00039 #include <qtextstream.h>
00040 #include <qprocess.h>
00041
00042 class KDevSourceProvider: public SourceProvider
00043 {
00044 public:
00045 KDevSourceProvider( JavaSupportPart* javaSupport )
00046 : m_javaSupport( javaSupport ),
00047 m_readFromDisk( false ) {}
00048
00049 void setReadFromDisk( bool b ) { m_readFromDisk = b; }
00050 bool readFromDisk() const { return m_readFromDisk; }
00051
00052 virtual QString contents( const QString& fileName )
00053 {
00054 if( !m_readFromDisk ){
00055
00056 bool needToLock = kapp->locked() == false;
00057
00058 if( needToLock )
00059 kapp->lock();
00060
00061
00062
00063 QPtrList<KParts::Part> parts( *m_javaSupport->partController()->parts() );
00064 QPtrListIterator<KParts::Part> it( parts );
00065 while( it.current() ){
00066 KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>( it.current() );
00067 ++it;
00068
00069 KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( doc );
00070 if( !doc || !editIface || doc->url().path() != fileName )
00071 continue;
00072
00073 QString contents = QString( editIface->text().ascii() );
00074
00075 if( needToLock )
00076 kapp->unlock();
00077
00078
00079
00080 return contents;
00081 }
00082
00083 if( needToLock )
00084 kapp->unlock();
00085
00086 }
00087
00088 QFile f( fileName );
00089 QTextStream stream( &f );
00090 if( f.open(IO_ReadOnly) ){
00091 QString contents = stream.read();
00092 f.close();
00093 return contents;
00094 }
00095
00096 return QString::null;
00097 }
00098
00099 virtual bool isModified( const QString& fileName )
00100 {
00101 Q_UNUSED( fileName );
00102 return true;
00103 }
00104
00105 private:
00106 JavaSupportPart* m_javaSupport;
00107 bool m_readFromDisk;
00108 private:
00109 KDevSourceProvider( const KDevSourceProvider& source );
00110 void operator = ( const KDevSourceProvider& source );
00111 };
00112
00113 class SynchronizedFileList
00114 {
00115 public:
00116 SynchronizedFileList() {}
00117
00118 bool isEmpty() const
00119 {
00120 QMutexLocker locker( &m_mutex );
00121 return m_fileList.isEmpty();
00122 }
00123
00124 uint count() const
00125 {
00126 QMutexLocker locker( &m_mutex );
00127 return m_fileList.count();
00128 }
00129
00130 QPair<QString, bool> front() const
00131 {
00132 QMutexLocker locker( &m_mutex );
00133 return m_fileList.front();
00134 }
00135
00136 void clear()
00137 {
00138 QMutexLocker locker( &m_mutex );
00139 m_fileList.clear();
00140 }
00141
00142 void push_back( const QString& fileName, bool readFromDisk=false )
00143 {
00144 QMutexLocker locker( &m_mutex );
00145 m_fileList.append( qMakePair(fileName, readFromDisk) );
00146 }
00147
00148 void pop_front()
00149 {
00150 QMutexLocker locker( &m_mutex );
00151 m_fileList.pop_front();
00152 }
00153
00154 bool contains( const QString& fileName ) const
00155 {
00156 QMutexLocker locker( &m_mutex );
00157 QValueList< QPair<QString, bool> >::ConstIterator it = m_fileList.begin();
00158 while( it != m_fileList.end() ){
00159 if( (*it).first == fileName )
00160 return true;
00161 ++it;
00162 }
00163 return false;
00164 }
00165
00166 void remove( const QString& fileName )
00167 {
00168 QMutexLocker locker( &m_mutex );
00169 QValueList< QPair<QString, bool> >::Iterator it = m_fileList.begin();
00170 while( it != m_fileList.end() ){
00171 if( (*it).first == fileName )
00172 m_fileList.remove( it );
00173 ++it;
00174 }
00175 }
00176
00177 private:
00178 mutable QMutex m_mutex;
00179 QValueList< QPair<QString, bool> > m_fileList;
00180 };
00181
00182 BackgroundParser::BackgroundParser( JavaSupportPart* part, QWaitCondition* consumed )
00183 : m_consumed( consumed ), m_javaSupport( part ), m_close( false )
00184 {
00185 m_fileList = new SynchronizedFileList();
00186 m_driver = new KDevDriver( m_javaSupport );
00187 m_driver->setSourceProvider( new KDevSourceProvider(m_javaSupport) );
00188
00189 }
00190
00191 BackgroundParser::~BackgroundParser()
00192 {
00193 removeAllFiles();
00194
00195 delete( m_driver );
00196 m_driver = 0;
00197
00198 delete m_fileList;
00199 m_fileList = 0;
00200 }
00201
00202 void BackgroundParser::addFile( const QString& fileName, bool readFromDisk )
00203 {
00204 QString fn = deepCopy( fileName );
00205
00206 bool added = false;
00207 if( !m_fileList->contains(fn) ){
00208 m_fileList->push_back( fn, readFromDisk );
00209 added = true;
00210 }
00211
00212 if( added )
00213 m_canParse.wakeAll();
00214 }
00215
00216 void BackgroundParser::removeAllFiles()
00217 {
00218 kdDebug(9013) << "BackgroundParser::removeAllFiles()" << endl;
00219 QMutexLocker locker( &m_mutex );
00220
00221 QMap<QString, Unit*>::Iterator it = m_unitDict.begin();
00222 while( it != m_unitDict.end() ){
00223 Unit* unit = it.data();
00224 ++it;
00225 delete( unit );
00226 unit = 0;
00227 }
00228 m_unitDict.clear();
00229 m_driver->reset();
00230 m_fileList->clear();
00231
00232 m_isEmpty.wakeAll();
00233 }
00234
00235 void BackgroundParser::removeFile( const QString& fileName )
00236 {
00237 QMutexLocker locker( &m_mutex );
00238
00239 if( Unit* unit = findUnit(fileName) ){
00240 m_driver->remove( fileName );
00241 m_unitDict.remove( fileName );
00242 delete( unit );
00243 unit = 0;
00244 }
00245
00246 if( m_fileList->isEmpty() )
00247 m_isEmpty.wakeAll();
00248 }
00249
00250 Unit* BackgroundParser::parseFile( const QString& fileName, bool readFromDisk )
00251 {
00252 static_cast<KDevSourceProvider*>( m_driver->sourceProvider() )->setReadFromDisk( readFromDisk );
00253
00254 m_driver->remove( fileName );
00255 m_driver->parseFile( fileName );
00256 RefJavaAST translationUnit = m_driver->takeTranslationUnit( fileName );
00257
00258 Unit* unit = new Unit;
00259 unit->fileName = fileName;
00260 unit->translationUnit = translationUnit;
00261 unit->problems = m_driver->problems( fileName );
00262
00263 static_cast<KDevSourceProvider*>( m_driver->sourceProvider() )->setReadFromDisk( false );
00264
00265 if( m_unitDict.find(fileName) != m_unitDict.end() ){
00266 Unit* u = m_unitDict[ fileName ];
00267 m_unitDict.remove( fileName );
00268 delete( u );
00269 u = 0;
00270 }
00271
00272 m_unitDict.insert( fileName, unit );
00273
00274 if( m_fileList->contains(fileName) ){
00275 kdDebug(9013) << "========================> FILE: " << fileName << " IN QUEUE <=============" << endl;
00276 } else {
00277 KApplication::postEvent( m_javaSupport, new FileParsedEvent(fileName, unit->problems) );
00278 }
00279
00280 m_currentFile = QString::null;
00281
00282 if( m_fileList->isEmpty() )
00283 m_isEmpty.wakeAll();
00284
00285 return unit;
00286 }
00287
00288 Unit* BackgroundParser::findUnit( const QString& fileName )
00289 {
00290 QMap<QString, Unit*>::Iterator it = m_unitDict.find( fileName );
00291 return it != m_unitDict.end() ? *it : 0;
00292 }
00293
00294 RefJavaAST BackgroundParser::translationUnit( const QString& fileName )
00295 {
00296 Unit* u = 0;
00297 if( (u = findUnit(fileName)) == 0 ){
00298 m_fileList->remove( fileName );
00299 u = parseFile( fileName, false );
00300 }
00301
00302 return u->translationUnit;
00303 }
00304
00305 QValueList<Problem> BackgroundParser::problems( const QString& fileName )
00306 {
00307 Unit* u = 0;
00308 if( (u = findUnit(fileName)) == 0 ){
00309 m_fileList->remove( fileName );
00310 u = parseFile( fileName, false );
00311 }
00312
00313 return u ? u->problems : QValueList<Problem>();
00314 }
00315
00316 void BackgroundParser::close()
00317 {
00318 QMutexLocker locker( &m_mutex );
00319 m_close = true;
00320 m_canParse.wakeAll();
00321 }
00322
00323 bool BackgroundParser::filesInQueue()
00324 {
00325 QMutexLocker locker( &m_mutex );
00326
00327 return m_fileList->count() || !m_currentFile.isEmpty();
00328 }
00329
00330 void BackgroundParser::run()
00331 {
00332
00333
00334 while( !m_close ){
00335
00336 m_mutex.lock();
00337 while( m_fileList->isEmpty() ){
00338 m_canParse.wait( &m_mutex );
00339
00340 if( m_close ){
00341 break;
00342 }
00343 }
00344
00345 if( m_close ){
00346 m_mutex.unlock();
00347 break;
00348 }
00349
00350 QPair<QString, bool> entry = m_fileList->front();
00351 QString fileName = entry.first;
00352 bool readFromDisk = entry.second;
00353 m_currentFile = fileName;
00354 m_fileList->pop_front();
00355
00356 (void) parseFile( fileName, readFromDisk );
00357 m_mutex.unlock();
00358 }
00359
00360 kdDebug(9013) << "!!!!!!!!!!!!!!!!!! BG PARSER DESTROYED !!!!!!!!!!!!" << endl;
00361
00362 QThread::exit();
00363 }
This file is part of the documentation for KDevelop Version 3.1.2.