summaryrefslogtreecommitdiffstats
path: root/languages/java/backgroundparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'languages/java/backgroundparser.cpp')
-rw-r--r--languages/java/backgroundparser.cpp363
1 files changed, 363 insertions, 0 deletions
diff --git a/languages/java/backgroundparser.cpp b/languages/java/backgroundparser.cpp
new file mode 100644
index 00000000..4081949c
--- /dev/null
+++ b/languages/java/backgroundparser.cpp
@@ -0,0 +1,363 @@
+/***************************************************************************
+ * Copyright (C) 2002 by Roberto Raggi *
+ * roberto@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "backgroundparser.h"
+#include "javasupportpart.h"
+#include "javasupport_events.h"
+#include "driver.h"
+#include "kdevdeepcopy.h"
+#include "kdevdriver.h"
+
+#if QT_VERSION < 0x030100
+#include <kdevmutex.h>
+#else
+#include <qmutex.h>
+#endif
+
+#include <kparts/part.h>
+#include <ktexteditor/editinterface.h>
+#include <ktexteditor/document.h>
+#include <ktexteditor/view.h>
+
+#include <kdevpartcontroller.h>
+#include <kdevproject.h>
+
+#include <kurl.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+
+class KDevSourceProvider: public SourceProvider
+{
+public:
+ KDevSourceProvider( JavaSupportPart* javaSupport )
+ : m_javaSupport( javaSupport ),
+ m_readFromDisk( false ) {}
+
+ void setReadFromDisk( bool b ) { m_readFromDisk = b; }
+ bool readFromDisk() const { return m_readFromDisk; }
+
+ virtual QString contents( const QString& fileName )
+ {
+ if( !m_readFromDisk ){
+ //kdDebug(9013) << "-------> kapp is locked = " << kapp->locked() << endl;
+ bool needToLock = kapp->locked() == false;
+
+ if( needToLock )
+ kapp->lock();
+
+ //kdDebug(9013) << "-------> kapp locked" << endl;
+
+ QPtrList<KParts::Part> parts( *m_javaSupport->partController()->parts() );
+ QPtrListIterator<KParts::Part> it( parts );
+ while( it.current() ){
+ KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>( it.current() );
+ ++it;
+
+ KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( doc );
+ if( !doc || !editIface || doc->url().path() != fileName )
+ continue;
+
+ QString contents = QString( editIface->text().ascii() ); // deep copy
+
+ if( needToLock )
+ kapp->unlock();
+
+ //kdDebug(9013) << "-------> kapp unlocked" << endl;
+
+ return contents;
+ }
+
+ if( needToLock )
+ kapp->unlock();
+ //kdDebug(9013) << "-------> kapp unlocked" << endl;
+ }
+
+ QFile f( fileName );
+ QTextStream stream( &f );
+ if( f.open(IO_ReadOnly) ){
+ QString contents = stream.read();
+ f.close();
+ return contents;
+ }
+
+ return QString::null;
+ }
+
+ virtual bool isModified( const QString& fileName )
+ {
+ Q_UNUSED( fileName );
+ return true;
+ }
+
+private:
+ JavaSupportPart* m_javaSupport;
+ bool m_readFromDisk;
+private:
+ KDevSourceProvider( const KDevSourceProvider& source );
+ void operator = ( const KDevSourceProvider& source );
+};
+
+class SynchronizedFileList
+{
+public:
+ SynchronizedFileList() {}
+
+ bool isEmpty() const
+ {
+ QMutexLocker locker( &m_mutex );
+ return m_fileList.isEmpty();
+ }
+
+ uint count() const
+ {
+ QMutexLocker locker( &m_mutex );
+ return m_fileList.count();
+ }
+
+ QPair<QString, bool> front() const
+ {
+ QMutexLocker locker( &m_mutex );
+ return m_fileList.front();
+ }
+
+ void clear()
+ {
+ QMutexLocker locker( &m_mutex );
+ m_fileList.clear();
+ }
+
+ void push_back( const QString& fileName, bool readFromDisk=false )
+ {
+ QMutexLocker locker( &m_mutex );
+ m_fileList.append( qMakePair(fileName, readFromDisk) ); /// \FIXME ROBE deepcopy?!
+ }
+
+ void pop_front()
+ {
+ QMutexLocker locker( &m_mutex );
+ m_fileList.pop_front();
+ }
+
+ bool contains( const QString& fileName ) const
+ {
+ QMutexLocker locker( &m_mutex );
+ QValueList< QPair<QString, bool> >::ConstIterator it = m_fileList.begin();
+ while( it != m_fileList.end() ){
+ if( (*it).first == fileName )
+ return true;
+ ++it;
+ }
+ return false;
+ }
+
+ void remove( const QString& fileName )
+ {
+ QMutexLocker locker( &m_mutex );
+ QValueList< QPair<QString, bool> >::Iterator it = m_fileList.begin();
+ while( it != m_fileList.end() ){
+ if( (*it).first == fileName )
+ m_fileList.remove( it );
+ ++it;
+ }
+ }
+
+private:
+ mutable QMutex m_mutex;
+ QValueList< QPair<QString, bool> > m_fileList;
+};
+
+BackgroundParser::BackgroundParser( JavaSupportPart* part, QWaitCondition* consumed )
+ : m_consumed( consumed ), m_javaSupport( part ), m_close( false )
+{
+ m_fileList = new SynchronizedFileList();
+ m_driver = new KDevDriver( m_javaSupport );
+ m_driver->setSourceProvider( new KDevSourceProvider(m_javaSupport) );
+ //disabled for now m_driver->setResolveDependencesEnabled( true );
+}
+
+BackgroundParser::~BackgroundParser()
+{
+ removeAllFiles();
+
+ delete( m_driver );
+ m_driver = 0;
+
+ delete m_fileList;
+ m_fileList = 0;
+}
+
+void BackgroundParser::addFile( const QString& fileName, bool readFromDisk )
+{
+ QString fn = deepCopy( fileName );
+
+ bool added = false;
+ if( !m_fileList->contains(fn) ){
+ m_fileList->push_back( fn, readFromDisk );
+ added = true;
+ }
+
+ if( added )
+ m_canParse.wakeAll();
+}
+
+void BackgroundParser::removeAllFiles()
+{
+ kdDebug(9013) << "BackgroundParser::removeAllFiles()" << endl;
+ QMutexLocker locker( &m_mutex );
+
+ QMap<QString, Unit*>::Iterator it = m_unitDict.begin();
+ while( it != m_unitDict.end() ){
+ Unit* unit = it.data();
+ ++it;
+ delete( unit );
+ unit = 0;
+ }
+ m_unitDict.clear();
+ m_driver->reset();
+ m_fileList->clear();
+
+ m_isEmpty.wakeAll();
+}
+
+void BackgroundParser::removeFile( const QString& fileName )
+{
+ QMutexLocker locker( &m_mutex );
+
+ if( Unit* unit = findUnit(fileName) ){
+ m_driver->remove( fileName );
+ m_unitDict.remove( fileName );
+ delete( unit );
+ unit = 0;
+ }
+
+ if( m_fileList->isEmpty() )
+ m_isEmpty.wakeAll();
+}
+
+Unit* BackgroundParser::parseFile( const QString& fileName, bool readFromDisk )
+{
+ static_cast<KDevSourceProvider*>( m_driver->sourceProvider() )->setReadFromDisk( readFromDisk );
+
+ m_driver->remove( fileName );
+ m_driver->parseFile( fileName );
+ RefJavaAST translationUnit = m_driver->takeTranslationUnit( fileName );
+
+ Unit* unit = new Unit;
+ unit->fileName = fileName;
+ unit->translationUnit = translationUnit;
+ unit->problems = m_driver->problems( fileName );
+
+ static_cast<KDevSourceProvider*>( m_driver->sourceProvider() )->setReadFromDisk( false );
+
+ if( m_unitDict.find(fileName) != m_unitDict.end() ){
+ Unit* u = m_unitDict[ fileName ];
+ m_unitDict.remove( fileName );
+ delete( u );
+ u = 0;
+ }
+
+ m_unitDict.insert( fileName, unit );
+
+ if( m_fileList->contains(fileName) ){
+ kdDebug(9013) << "========================> FILE: " << fileName << " IN QUEUE <=============" << endl;
+ } else {
+ KApplication::postEvent( m_javaSupport, new FileParsedEvent(fileName, unit->problems) );
+ }
+
+ m_currentFile = QString::null;
+
+ if( m_fileList->isEmpty() )
+ m_isEmpty.wakeAll();
+
+ return unit;
+}
+
+Unit* BackgroundParser::findUnit( const QString& fileName )
+{
+ QMap<QString, Unit*>::Iterator it = m_unitDict.find( fileName );
+ return it != m_unitDict.end() ? *it : 0;
+}
+
+RefJavaAST BackgroundParser::translationUnit( const QString& fileName )
+{
+ Unit* u = 0;
+ if( (u = findUnit(fileName)) == 0 ){
+ m_fileList->remove( fileName );
+ u = parseFile( fileName, false );
+ }
+
+ return u->translationUnit;
+}
+
+QValueList<Problem> BackgroundParser::problems( const QString& fileName )
+{
+ Unit* u = 0;
+ if( (u = findUnit(fileName)) == 0 ){
+ m_fileList->remove( fileName );
+ u = parseFile( fileName, false );
+ }
+
+ return u ? u->problems : QValueList<Problem>();
+}
+
+void BackgroundParser::close()
+{
+ QMutexLocker locker( &m_mutex );
+ m_close = true;
+ m_canParse.wakeAll();
+}
+
+bool BackgroundParser::filesInQueue()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_fileList->count() || !m_currentFile.isEmpty();
+}
+
+void BackgroundParser::run()
+{
+ // (void) m_javaSupport->codeCompletion()->repository()->getEntriesInScope( QStringList(), false );
+
+ while( !m_close ){
+
+ m_mutex.lock();
+ while( m_fileList->isEmpty() ){
+ m_canParse.wait( &m_mutex );
+
+ if( m_close ){
+ break;
+ }
+ }
+
+ if( m_close ){
+ m_mutex.unlock();
+ break;
+ }
+
+ QPair<QString, bool> entry = m_fileList->front();
+ QString fileName = entry.first;
+ bool readFromDisk = entry.second;
+ m_currentFile = fileName;
+ m_fileList->pop_front();
+
+ (void) parseFile( fileName, readFromDisk );
+ m_mutex.unlock();
+ }
+
+ kdDebug(9013) << "!!!!!!!!!!!!!!!!!! BG PARSER DESTROYED !!!!!!!!!!!!" << endl;
+
+ //commented to fix #83352
+ //QThread::exit();
+}