LanguageController has possibly recursive loop

Andreas Pakulat apaku at gmx.de
Sun Nov 2 12:56:23 UTC 2008


Hi,

due to one of Matt's last commits I had a closer look at LanguageController
and how it loads a language. I see a possible problem there. The code
currently looks like this:

,----
| ILanguage *LanguageController::language(const QString &name) const
| {
|     if(d->languages.contains(name))
|         return d->languages[name];
|     else{
|         ILanguage* ret = 0;
|         QStringList constraints;
|         constraints << QString("'%1' in [X-KDevelop-Language]").arg(name);
|         QList<IPlugin*> supports = Core::self()->pluginController()->
|             allPluginsForExtension("ILanguageSupport", constraints);
|         if(!supports.isEmpty()) {
|             ILanguageSupport *languageSupport = supports[0]->extension<ILanguageSupport>();
|             ret = languageSupport->language();
|         }
|         return ret;
|     }
| }
| 
| QList<ILanguage*> LanguageController::languagesForUrl(const KUrl &url)
| {
|     KMimeType::Ptr mimeType = KMimeType::findByUrl(url);
| 
|     QList<ILanguage*> languages;
|     LanguageCache::iterator it = d->languageCache.find(mimeType->name());
|     if (it != d->languageCache.constEnd()) {
|         languages = it.value();
|     } else {
|         QStringList constraints;
|         constraints << QString("'%1' in [X-KDevelop-SupportedMimeTypes]").arg(mimeType->name());
|         QList<IPlugin*> supports = Core::self()->pluginController()->
|             allPluginsForExtension("ILanguageSupport", constraints);
| 
|         foreach (IPlugin *support, supports) {
|             ILanguageSupport *languageSupport = support->extension<ILanguageSupport>();
|             if (ILanguage *lang = language(languageSupport->name())) {
|                 languages << lang;
|             } else {
|                 Language *_lang = new Language(languageSupport, this);
|                 d->languages.insert(languageSupport->name(), _lang);
|                 languages << _lang;
|             }
|         }
|         d->languageCache.insert(mimeType->name(), languages);
|     }
| 
|     return languages;
| }
`----

The problem I see is that languagesForUrl tries to load a plugin - lets say
C++ support - then tries to create a Language instance from that plugin's
name() function. This goes into the upper "language" method, where it would
go into the else branch as the new ILanguage instance hasn't been created.
Now in the else branch it again looks for plugins that provide C++ support
and then asks the plugin for its ILanguage instance by calling its
language() member function. In C++ support this member function reads:

core()->languageController()->language( name() )

Which is the same call as done from languagesForUrl(). So actually I
currently don't understand why loading a language part for a url works at
all, it should go into an endless loop - unless I'm missing something.

Even if I do, this code looks strange/wrong, would it be ok to remove the
"if(ILanguage* lang = language(languageSupport->name()))" part from
languagesForUrl? I mean if we didn't load the language plugin yet, its
quite clear that the language hasn't been created either, so we should go
into the else-branch there.

Andreas

-- 
You will gain money by an illegal action.




More information about the KDevelop-devel mailing list