00001
00002 #include <qfileinfo.h>
00003 #include <qlistview.h>
00004 #include <qstringlist.h>
00005 #include <qtimer.h>
00006 #include <qvbox.h>
00007 #include <qprogressbar.h>
00008 #include <qwhatsthis.h>
00009
00010 #include <kgenericfactory.h>
00011 #include <kapp.h>
00012 #include <kdebug.h>
00013 #include <klocale.h>
00014 #include <kapplication.h>
00015 #include <kstatusbar.h>
00016 #include <kdialogbase.h>
00017 #include <kiconloader.h>
00018
00019 #include <fstream>
00020 #include <strstream>
00021
00022 #include "kdevgenericfactory.h"
00023 #include "kdevcore.h"
00024 #include "kdevproject.h"
00025 #include "kdevmainwindow.h"
00026 #include "kdevproject.h"
00027 #include "kdevpartcontroller.h"
00028 #include "codemodel.h"
00029 #include "adasupportpart.h"
00030 #include "problemreporter.h"
00031 #include "backgroundparser.h"
00032
00033 #include "AdaLexer.hpp"
00034 #include "AdaParser.hpp"
00035 #include "AdaStoreWalker.hpp"
00036 #include "AdaAST.hpp"
00037
00038 enum { KDEV_DB_VERSION = 3 };
00039 enum { KDEV_PCS_VERSION = 2 };
00040
00041 typedef KDevGenericFactory<AdaSupportPart> AdaSupportPartFactory;
00042
00043 static const KAboutData data("kdevadasupport", I18N_NOOP("Language"), "1.0");
00044 K_EXPORT_COMPONENT_FACTORY (libkdevadasupport, AdaSupportPartFactory (&data))
00045
00046
00047 struct AdaSupportPartData {
00048 ProblemReporter* problemReporter;
00049
00050 AdaSupportPartData () : problemReporter (0) {}
00051 };
00052
00053 AdaSupportPart::AdaSupportPart (QObject *parent, const char *name, const QStringList &)
00054 : KDevLanguageSupport ("AdaSupport", "ada", parent, name ? name : "AdaSupportPart"), d (new AdaSupportPartData())
00055 {
00056 setInstance (AdaSupportPartFactory::instance ());
00057
00058 d->problemReporter = new ProblemReporter (this);
00059 connect (core (), SIGNAL (configWidget (KDialogBase*)),
00060 d->problemReporter, SLOT (configWidget (KDialogBase*)));
00061 d->problemReporter->setIcon( SmallIcon("info") );
00062 mainWindow( )->embedOutputView( d->problemReporter, i18n("Problems"), i18n("Problem reporter"));
00063 QWhatsThis::add(d->problemReporter, i18n("<b>Problem reporter</b><p>This window shows various \"problems\" in your project. "
00064 "It displays errors reported by a language parser."));
00065
00066 setXMLFile ("adasupportpart.rc");
00067
00068 connect (core (), SIGNAL (projectOpened ()), this, SLOT (projectOpened ()));
00069 connect (core (), SIGNAL (projectClosed ()), this, SLOT (projectClosed ()));
00070
00071 connect (partController (), SIGNAL (savedFile (const KURL&)),
00072 this, SLOT (savedFile (const KURL&)));
00073
00074 connect (core (), SIGNAL (configWidget (KDialogBase*)), this, SLOT (configWidget (KDialogBase*)));
00075 connect( core(), SIGNAL(configWidget(KDialogBase*)),
00076 d->problemReporter, SLOT(configWidget(KDialogBase*)) );
00077
00078
00079
00080
00081
00082 }
00083
00084
00085 AdaSupportPart::~AdaSupportPart ()
00086 {
00087 mainWindow ()->removeView (d->problemReporter);
00088 delete (d->problemReporter);
00089 d->problemReporter = 0;
00090
00091 delete (d);
00092 d = 0;
00093 }
00094
00095
00096 KDevLanguageSupport::Features AdaSupportPart::features ()
00097 {
00098 return KDevLanguageSupport::Features
00099 (
00100 Functions | Namespaces);
00101 }
00102
00103 void AdaSupportPart::projectOpened ()
00104 {
00105 connect (project (), SIGNAL (addedFilesToProject (const QStringList &)),
00106 this, SLOT (addedFilesToProject (const QStringList &)));
00107 connect (project (), SIGNAL (removedFilesFromProject (const QStringList &)),
00108 this, SLOT (removedFilesFromProject (const QStringList &)));
00109 connect( project( ), SIGNAL( changedFilesInProject( const QStringList & ) ),
00110 this, SLOT( changedFilesInProject( const QStringList & ) ) );
00111
00112 QTimer::singleShot (0, this, SLOT (initialParse ()));
00113 }
00114
00115
00116 void AdaSupportPart::projectClosed ()
00117 {
00118 saveProjectSourceInfo();
00119 }
00120
00121
00122 void AdaSupportPart::initialParse ()
00123 {
00124 kdDebug () << "------------------------------------------> initialParse ()" << endl;
00125
00126 if (project ())
00127 {
00128 mainWindow()->statusBar()->message( i18n("Updating...") );
00129 kapp->processEvents( );
00130 kapp->setOverrideCursor (waitCursor);
00131
00132 int n = 0;
00133 QStringList files = project ()->allFiles ();
00134
00135 QProgressBar* bar = new QProgressBar( files.count( ), mainWindow( )->statusBar( ) );
00136 bar->setMinimumWidth( 120 );
00137 bar->setCenterIndicator( true );
00138 mainWindow( )->statusBar( )->addWidget( bar );
00139 bar->show( );
00140
00141 for (QStringList::Iterator it = files.begin (); it != files.end (); ++it) {
00142 bar->setProgress( n++ );
00143
00144 QString fn = project ()->projectDirectory () + "/" + *it;
00145 maybeParse (fn);
00146 kapp->processEvents (500);
00147 }
00148
00149 emit updatedSourceInfo();
00150
00151 mainWindow( )->statusBar( )->removeWidget( bar );
00152 delete bar;
00153
00154 kapp->restoreOverrideCursor ();
00155 mainWindow( )->statusBar( )->message( i18n( "Done" ), 2000 );
00156
00157
00158 }
00159 }
00160
00161 QStringList AdaSupportPart::fileExtensions ()
00162 {
00163 return QStringList () << "ads" << "adb";
00164 }
00165
00166 void AdaSupportPart::maybeParse (const QString &fileName)
00167 {
00168 kdDebug () << "AdaSupportPart::maybeParse: " << fileName << endl;
00169
00170 if (!fileExtensions ().contains (QFileInfo (fileName).extension ()))
00171 return;
00172
00173
00174 parse (fileName);
00175 }
00176
00177
00178 void AdaSupportPart::addedFilesToProject (const QStringList &fileList)
00179 {
00180 QStringList::ConstIterator it;
00181
00182 for (it = fileList.begin (); it != fileList.end (); ++it)
00183 {
00184 QString path = project ()->projectDirectory () + "/" + (*it);
00185 maybeParse (path);
00186 emit addedSourceInfo( path );
00187 }
00188 }
00189
00190
00191 void AdaSupportPart::removedFilesFromProject (const QStringList &fileList)
00192 {
00193 QStringList::ConstIterator it;
00194
00195 for (it = fileList.begin (); it != fileList.end (); ++it)
00196 {
00197 kdDebug () << "AdaSupportPart::removedFileFromProject () -- " << (*it) << endl;
00198 QString path = project ()->projectDirectory () + "/" + (*it);
00199
00200 if( codeModel()->hasFile(path) )
00201 {
00202 emit aboutToRemoveSourceInfo( path );
00203 codeModel()->removeFile( codeModel()->fileByName(path) );
00204 }
00205 }
00206
00207
00208 }
00209
00210
00211 void AdaSupportPart::parse (const QString &fileName)
00212 {
00213 kdDebug () << "AdaSupportPart::parse () -- " << fileName << endl;
00214
00215 std::ifstream stream (QFile::encodeName( fileName ).data());
00216 QCString _fn = fileName.utf8 ();
00217 std::string fn (_fn.data ());
00218
00219 AdaLexer lexer (stream);
00220 lexer.setFilename (fn);
00221 lexer.setProblemReporter (d->problemReporter);
00222
00223 AdaParser parser (lexer);
00224 parser.setFilename (fn);
00225 parser.setProblemReporter (d->problemReporter);
00226
00227
00228 antlr::ASTFactory ast_factory;
00229
00230 parser.initializeASTFactory (ast_factory);
00231 parser.setASTFactory (&ast_factory);
00232
00233
00234 try {
00235
00236 lexer.resetErrors ();
00237 parser.resetErrors ();
00238
00239 parser.compilation_unit ();
00240 int errors = lexer.numberOfErrors () + parser.numberOfErrors ();
00241 RefAdaAST ast = parser.getAST ();
00242
00243 if (errors == 0 && ast != antlr::nullAST) {
00244 kdDebug () << "-------------------> start StoreWalker" << endl;
00245 AdaStoreWalker walker;
00246 walker.setFileName (fileName);
00247 walker.setCodeModel (codeModel ());
00248 walker.compilation_unit (ast);
00249 }
00250 } catch (antlr::ANTLRException& ex) {
00251 kdDebug () << "*exception*: " << ex.toString ().c_str () << endl;
00252 d->problemReporter->reportError (QString::fromLatin1( ex.getMessage ().c_str() ),
00253 fileName,
00254 lexer.getLine (),
00255 lexer.getColumn ());
00256 }
00257 }
00258
00259 void AdaSupportPart::parseContents (const QString& contents, const QString& fileName)
00260 {
00261 kdDebug () << "AdaSupportPart::parseContents () -- " << fileName << endl;
00262
00263 QCString _fn = QFile::encodeName (fileName);
00264 std::string fn (_fn.data ());
00265
00266 QCString text = contents.utf8 ();
00267 std::istrstream stream (text);
00268
00269 AdaLexer lexer (stream);
00270 lexer.setFilename (fn);
00271 lexer.setProblemReporter (d->problemReporter);
00272
00273 AdaParser parser (lexer);
00274 parser.setFilename (fn);
00275 parser.setProblemReporter (d->problemReporter);
00276
00277 try {
00278 lexer.resetErrors ();
00279 parser.resetErrors ();
00280
00281 parser.compilation_unit ();
00282 int errors = lexer.numberOfErrors () + parser.numberOfErrors ();
00283 Q_UNUSED( errors );
00284
00285 } catch (antlr::ANTLRException& ex) {
00286 kdDebug () << "*exception*: " << ex.toString ().c_str () << endl;
00287 d->problemReporter->reportError (QString::fromLatin1( ex.getMessage().c_str() ),
00288 fileName,
00289 lexer.getLine (),
00290 lexer.getColumn ());
00291 }
00292 }
00293
00294
00295
00296 void AdaSupportPart::savedFile (const KURL& fileName)
00297 {
00298 kdDebug () << "AdaSupportPart::savedFile ()" << endl;
00299
00300 if (project ()->allFiles ().contains (fileName.path().mid (project ()->projectDirectory ().length () + 1))) {
00301 maybeParse (fileName.path());
00302 emit updatedSourceInfo();
00303 }
00304 }
00305
00306 KMimeType::List AdaSupportPart::mimeTypes( )
00307 {
00308 KMimeType::List list;
00309
00310 list << KMimeType::mimeType( "text/x-adasrc" );
00311
00312 return list;
00313 }
00314
00315
00316
00317
00318 void AdaSupportPart::saveProjectSourceInfo( )
00319 {
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 }
00360
00361 void AdaSupportPart::changedFilesInProject( const QStringList & fileList )
00362 {
00363 QStringList files = fileList;
00364
00365 for ( QStringList::ConstIterator it = files.begin(); it != files.end(); ++it )
00366 {
00367 QString path = project ()->projectDirectory () + "/" + *it ;
00368
00369 maybeParse( path );
00370 emit addedSourceInfo( path );
00371 }
00372 }
00373
00374
00375 #include "adasupportpart.moc"