diff options
Diffstat (limited to 'languages/pascal/pascalsupport_part.cpp')
-rw-r--r-- | languages/pascal/pascalsupport_part.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/languages/pascal/pascalsupport_part.cpp b/languages/pascal/pascalsupport_part.cpp new file mode 100644 index 00000000..0c5f96f2 --- /dev/null +++ b/languages/pascal/pascalsupport_part.cpp @@ -0,0 +1,323 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 <fstream> + +#include <qdir.h> +#include <qtimer.h> +#include <qwhatsthis.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kdevgenericfactory.h> +#include <kdebug.h> +#include <kapplication.h> +#include <kstatusbar.h> + +#include <antlr/ASTFactory.hpp> + +#include "catalog.h" +#include <kdevcore.h> +#include <kdevmainwindow.h> +#include <kdevpartcontroller.h> +#include <kdevproject.h> +#include <kdevplugininfo.h> + +#include "pascalsupport_part.h" +#include "problemreporter.h" +#include "PascalLexer.hpp" +#include "PascalParser.hpp" +#include "PascalStoreWalker.hpp" + +struct PascalSupportPartData{ + ProblemReporter* problemReporter; + + PascalSupportPartData() + : problemReporter( 0 ) + {} +}; + +typedef KDevGenericFactory<PascalSupportPart> PascalSupportFactory; +static const KDevPluginInfo data("kdevpascalsupport"); +K_EXPORT_COMPONENT_FACTORY( libkdevpascalsupport, PascalSupportFactory( data ) ) + +PascalSupportPart::PascalSupportPart(QObject *parent, const char *name, const QStringList &) + : KDevLanguageSupport(&data, parent, name ? name : "KDevPascalSupport" ), + d( new PascalSupportPartData() ) +{ + setInstance(PascalSupportFactory::instance()); + setXMLFile("kdevpascalsupport.rc"); + + d->problemReporter = new ProblemReporter( this ); + connect( core(), SIGNAL(configWidget(KDialogBase*)), + d->problemReporter, SLOT(configWidget(KDialogBase*)) ); + + connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) ); + connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) ); + connect( partController(), SIGNAL(savedFile(const KURL&)), + this, SLOT(savedFile(const KURL&)) ); + connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), + this, SLOT(contextMenu(QPopupMenu *, const Context *)) ); + connect( core(), SIGNAL(configWidget(KDialogBase*)), + this, SLOT(configWidget(KDialogBase*)) ); + connect( core( ), SIGNAL( projectConfigWidget( KDialogBase* ) ), this, + SLOT( projectConfigWidget( KDialogBase* ) ) ); + + mainWindow()->embedOutputView( d->problemReporter, i18n("Problems"), i18n("problem reporter") ); + QWhatsThis::add(d->problemReporter, i18n("<b>Problem reporter</b><p>This window shows various \"problems\" in your project. " + "It displays errors reported by a language parser.")); +} + +PascalSupportPart::~PascalSupportPart() +{ + mainWindow()->removeView( d->problemReporter ); + delete( d->problemReporter ); + + delete( d ); +} + +PascalSupportPart::Features PascalSupportPart::features() +{ + return Features(Classes | Structs | Functions | Variables | Declarations); +} + +void PascalSupportPart::projectOpened() +{ + connect(project(), SIGNAL(addedFilesToProject(const QStringList &)), + this, SLOT(addedFilesToProject(const QStringList &))); + connect(project(), SIGNAL(removedFilesFromProject(const QStringList &)), + this, SLOT(removedFilesFromProject(const QStringList &))); + connect(project(), SIGNAL(projectCompiled()), + this, SLOT(slotProjectCompiled()) ); + + m_projectFileList = project()->allFiles(); + m_projectClosed = false; + + QTimer::singleShot(0, this, SLOT(initialParse())); +} + +void PascalSupportPart::projectClosed() +{ + m_projectClosed = true; +} + +void PascalSupportPart::configWidget(KDialogBase *dlg) +{ + Q_UNUSED( dlg ); + return; +} + +void PascalSupportPart::projectConfigWidget(KDialogBase *dlg) +{ + Q_UNUSED( dlg ); + return; +} + +void PascalSupportPart::contextMenu(QPopupMenu *popup, const Context *context) +{ + Q_UNUSED( popup ); + Q_UNUSED( context ); + return; +} + +void PascalSupportPart::savedFile(const KURL &fileName) +{ + maybeParse(fileName.path()); + emit updatedSourceInfo(); +} + +void PascalSupportPart::addedFilesToProject(const QStringList &fileList) +{ + for (QStringList::ConstIterator it = fileList.begin(); it != fileList.end() ;++it) + { + QString fn = project()->projectDirectory() + "/" + *it; + maybeParse( fn ); + kapp->processEvents( 500 ); + emit addedSourceInfo(fn); + } +} + +void PascalSupportPart::removedFilesFromProject(const QStringList &fileList) +{ + for (QStringList::ConstIterator it = fileList.begin(); it != fileList.end() ;++it) + { + QString fn = project()->projectDirectory() + "/" + *it; + + emit aboutToRemoveSourceInfo(fn); + codeModel()->removeFile( codeModel()->fileByName(fn) ); + } +} + +void PascalSupportPart::slotProjectCompiled() +{ + return; +} + +void PascalSupportPart::initialParse( ) +{ + kdDebug(9013) << "------------------------------------------> initialParse()" << endl; + + if (project()) + { + kapp->setOverrideCursor(waitCursor); + + /// @todo Progress indicator! + + QStringList files = project()->allFiles(); + for (QStringList::Iterator it = files.begin(); it != files.end() ;++it){ + QString fn = project()->projectDirectory() + "/" + *it; + maybeParse( fn ); + kapp->processEvents( 500 ); + } + + emit updatedSourceInfo(); + + kapp->restoreOverrideCursor(); + mainWindow()->statusBar()->message( i18n("Found 1 problem", "Found %n problems", d->problemReporter->childCount()) ); + } +} + +void PascalSupportPart::maybeParse( const QString & fileName ) +{ + kdDebug(9013) << "Maybe parse: " << fileName << endl; + + KMimeType::Ptr mime = KMimeType::findByURL( KURL( fileName ) ); + if( !mime || mime->name() != "text/x-pascal" ) + return; + + mainWindow()->statusBar()->message( i18n("Parsing file: %1").arg(fileName) ); + parse( fileName ); +} + +void PascalSupportPart::parse( const QString & fileName ) +{ + kdDebug(9013) << "PascalSupportPart::parse() -- " << fileName << endl; + + std::ifstream stream( QFile::encodeName( fileName ).data() ); + QCString _fn = fileName.utf8(); + std::string fn( _fn.data() ); + + PascalLexer lexer( stream ); + lexer.setFilename( fn ); + lexer.setProblemReporter( d->problemReporter ); + + PascalParser parser( lexer ); + parser.setFilename( fn ); + parser.setProblemReporter( d->problemReporter ); + + try{ + antlr::ASTFactory my_factory( "PascalAST", PascalAST::factory ); + parser.initializeASTFactory(my_factory); + parser.setASTFactory( &my_factory ); + + lexer.resetErrors(); + parser.resetErrors(); + + parser.compilationUnit(); + int errors = lexer.numberOfErrors() + parser.numberOfErrors(); + RefPascalAST ast = RefPascalAST( parser.getAST() ); + + if( errors == 0 && ast != antlr::nullAST ){ + kdDebug(9013) << "-------------------> start StoreWalker" << endl; +/* PascalStoreWalker walker; + walker.setFileName( fileName ); + walker.setCodeModel( codeModel() ); + walker.compilationUnit( ast );*/ + } + + } catch( antlr::ANTLRException& ex ){ + kdDebug() << "*exception*: " << ex.toString().c_str() << endl; + d->problemReporter->reportError( ex.getMessage().c_str(), + fileName, + lexer.getLine(), + lexer.getColumn() ); + } +} + +KMimeType::List PascalSupportPart::mimeTypes( ) +{ + KMimeType::List list; + KMimeType::Ptr mime = KMimeType::mimeType( "text/x-pascal" ); + if( mime ) + list << mime; + return list; +} + +QString PascalSupportPart::formatTag( const Tag & inputTag ) +{ + Tag tag = inputTag; + + switch( tag.kind() ) + { + case Tag::Kind_Namespace: + return QString::fromLatin1("unit ") + tag.name(); + + case Tag::Kind_Class: + return QString::fromLatin1("class ") + tag.name(); + + case Tag::Kind_Function: + case Tag::Kind_FunctionDeclaration: + { + return tag.name() + "()"; + } + break; + + case Tag::Kind_Variable: + case Tag::Kind_VariableDeclaration: + { + return QString::fromLatin1("var ") + tag.name(); + } + break; + } + return tag.name(); +} + +QString PascalSupportPart::formatModelItem( const CodeModelItem * item, bool shortDescription ) +{ + if (item->isFunction() || item->isFunctionDefinition() ) + { + const FunctionModel *model = static_cast<const FunctionModel*>(item); + QString function; + QString args; + ArgumentList argumentList = model->argumentList(); + for (ArgumentList::const_iterator it = argumentList.begin(); it != argumentList.end(); ++it) + { + args.isEmpty() ? args += "" : args += ", " ; + args += formatModelItem((*it).data()); + } + + function += model->name() + "(" + args + ")"; + + if( !shortDescription ) + function += (model->isVirtual() ? QString("virtual; ") : QString("") ) + model->resultType() + " "; + + return function; + } + else if (item->isVariable()) + { + const VariableModel *model = static_cast<const VariableModel*>(item); + if( shortDescription ) + return model->name(); + return model->name() + ": " + model->type(); + } + else if (item->isArgument()) + { + const ArgumentModel *model = static_cast<const ArgumentModel*>(item); + QString arg; + arg += model->name(); + arg += ": " + model->type(); + if( !shortDescription ) + arg += model->defaultValue().isEmpty() ? QString("") : QString(" = ") + model->defaultValue(); + return arg.stripWhiteSpace(); + } + else + return KDevLanguageSupport::formatModelItem( item, shortDescription ); +} + +#include "pascalsupport_part.moc" |