You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/languages/pascal/pascalsupport_part.cpp

324 lines
10 KiB

/***************************************************************************
* 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 <tqdir.h>
#include <tqtimer.h>
#include <tqwhatsthis.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(TQObject *parent, const char *name, const TQStringList &)
: KDevLanguageSupport(&data, parent, name ? name : "KDevPascalSupport" ),
d( new PascalSupportPartData() )
{
setInstance(PascalSupportFactory::instance());
setXMLFile("kdevpascalsupport.rc");
d->problemReporter = new ProblemReporter( this );
connect( core(), TQT_SIGNAL(configWidget(KDialogBase*)),
d->problemReporter, TQT_SLOT(configWidget(KDialogBase*)) );
connect( core(), TQT_SIGNAL(projectOpened()), this, TQT_SLOT(projectOpened()) );
connect( core(), TQT_SIGNAL(projectClosed()), this, TQT_SLOT(projectClosed()) );
connect( partController(), TQT_SIGNAL(savedFile(const KURL&)),
this, TQT_SLOT(savedFile(const KURL&)) );
connect( core(), TQT_SIGNAL(contextMenu(TQPopupMenu *, const Context *)),
this, TQT_SLOT(contextMenu(TQPopupMenu *, const Context *)) );
connect( core(), TQT_SIGNAL(configWidget(KDialogBase*)),
this, TQT_SLOT(configWidget(KDialogBase*)) );
connect( core( ), TQT_SIGNAL( projectConfigWidget( KDialogBase* ) ), this,
TQT_SLOT( projectConfigWidget( KDialogBase* ) ) );
mainWindow()->embedOutputView( d->problemReporter, i18n("Problems"), i18n("problem reporter") );
TQWhatsThis::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(), TQT_SIGNAL(addedFilesToProject(const TQStringList &)),
this, TQT_SLOT(addedFilesToProject(const TQStringList &)));
connect(project(), TQT_SIGNAL(removedFilesFromProject(const TQStringList &)),
this, TQT_SLOT(removedFilesFromProject(const TQStringList &)));
connect(project(), TQT_SIGNAL(projectCompiled()),
this, TQT_SLOT(slotProjectCompiled()) );
m_projectFileList = project()->allFiles();
m_projectClosed = false;
TQTimer::singleShot(0, this, TQT_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(TQPopupMenu *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 TQStringList &fileList)
{
for (TQStringList::ConstIterator it = fileList.begin(); it != fileList.end() ;++it)
{
TQString fn = project()->projectDirectory() + "/" + *it;
maybeParse( fn );
kapp->processEvents( 500 );
emit addedSourceInfo(fn);
}
}
void PascalSupportPart::removedFilesFromProject(const TQStringList &fileList)
{
for (TQStringList::ConstIterator it = fileList.begin(); it != fileList.end() ;++it)
{
TQString 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!
TQStringList files = project()->allFiles();
for (TQStringList::Iterator it = files.begin(); it != files.end() ;++it){
TQString 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 TQString & 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 TQString & fileName )
{
kdDebug(9013) << "PascalSupportPart::parse() -- " << fileName << endl;
std::ifstream stream( TQFile::encodeName( fileName ).data() );
TQCString _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;
}
TQString PascalSupportPart::formatTag( const Tag & inputTag )
{
Tag tag = inputTag;
switch( tag.kind() )
{
case Tag::Kind_Namespace:
return TQString::fromLatin1("unit ") + tag.name();
case Tag::Kind_Class:
return TQString::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 TQString::fromLatin1("var ") + tag.name();
}
break;
}
return tag.name();
}
TQString PascalSupportPart::formatModelItem( const CodeModelItem * item, bool shortDescription )
{
if (item->isFunction() || item->isFunctionDefinition() )
{
const FunctionModel *model = static_cast<const FunctionModel*>(item);
TQString function;
TQString 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() ? TQString("virtual; ") : TQString("") ) + 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);
TQString arg;
arg += model->name();
arg += ": " + model->type();
if( !shortDescription )
arg += model->defaultValue().isEmpty() ? TQString("") : TQString(" = ") + model->defaultValue();
return arg.stripWhiteSpace();
}
else
return KDevLanguageSupport::formatModelItem( item, shortDescription );
}
#include "pascalsupport_part.moc"