KDevelop API Documentation

backgroundparser.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2002 by Roberto Raggi                                   *
00003  *   roberto@kdevelop.org                                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
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         //kdDebug(9013) << "-------> kapp is locked = " << kapp->locked() << endl;
00056         bool needToLock = kapp->locked() == false;
00057 
00058         if( needToLock )
00059         kapp->lock();
00060 
00061         //kdDebug(9013) << "-------> kapp locked" << endl;
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() ); // deep copy
00074 
00075         if( needToLock )
00076             kapp->unlock();
00077 
00078         //kdDebug(9013) << "-------> kapp unlocked" << endl;
00079 
00080         return contents;
00081         }
00082 
00083         if( needToLock )
00084         kapp->unlock();
00085         //kdDebug(9013) << "-------> kapp unlocked" << endl;
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     //disabled for now m_driver->setResolveDependencesEnabled( true );
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     // (void) m_javaSupport->codeCompletion()->repository()->getEntriesInScope( QStringList(), false );
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 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:27 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003