Problem with ChooseByNameContributor

Hi everyone,

I'm developing a custom language plugin for 7.0+, and I'm having a problem with my ChooseByNameContributor. When I run in debug mode, it looks like I get the right stuff coming out of getNames and getItemsByName, and yet when I fill in some letters in the "Enter class name:" popup, I get the following stack trace, repeated many times:

No message
java.lang.NullPointerException
at com.intellij.ide.util.NavigationItemListCellRenderer$LeftRenderer.customizeCellRenderer(NavigationItemListCellRenderer.java:18)
at com.intellij.ui.ColoredListCellRenderer.getListCellRendererComponent(ColoredListCellRenderer.java:65)
at com.intellij.ide.util.NavigationItemListCellRenderer.getListCellRendererComponent(NavigationItemListCellRenderer.java:15)
at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1155)
at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1105)
at javax.swing.plaf.basic.BasicListUI.locationToIndex(BasicListUI.java:721)
at javax.swing.JList.locationToIndex(JList.java:1144)
at javax.swing.JList.getLastVisibleIndex(JList.java:898)
at com.intellij.ui.ListScrollingUtil.getVisibleRowCount(ListScrollingUtil.java:172)
at com.intellij.ui.ListScrollingUtil.ensureIndexIsVisible(ListScrollingUtil.java:144)
at com.intellij.ui.ListScrollingUtil.selectItem(ListScrollingUtil.java:50)
at com.intellij.ide.util.gotoByName.ChooseByNameBase$ListUpdater$1.run(ChooseByNameBase.java:5)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:9)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at com.intellij.ide.IdeEventQueue.c(IdeEventQueue.java:179)
at com.intellij.ide.IdeEventQueue.b(IdeEventQueue.java:37)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:119)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:176)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)


Here is my contributor implementation:

public class ArcChooser implements ChooseByNameContributor {
....private Map> map; ....public String[] getNames(Project project, boolean includeNonProjectItems) { ........map = new HashMap>(); ........List names = new ArrayList(); ........// TODO - Distinguish between project and non-project Arc files ........findNames(project, project.getBaseDir(), names); ........return names.toArray(new String[names.size()]); ....} ....private void findNames(Project project, VirtualFile baseDir, List names) { ........if (baseDir != null) { ............for (VirtualFile file : baseDir.getChildren()) { ................if (file.isDirectory()) { ....................findNames(project, file, names); ................} else if ("arc".equalsIgnoreCase(file.getExtension())) { ....................findNamesInFile(project, file, names); ................} ............} ........} ....} ....private void findNamesInFile(Project project, VirtualFile file, List names) { ........PsiFile psiFile = PsiManager.getInstance(project).findFile(file); ........if (psiFile != null) { ............for (PsiElement child : psiFile.getChildren()) { ................if (child instanceof VariableAssignment) { ....................String name = ((VariableAssignment) child).getName(); ....................List navItems = map.get(name); ....................if (navItems == null) { ........................navItems = new ArrayList(); ........................map.put(name, navItems); ....................} ....................navItems.add((VariableAssignment) child); ....................names.add(name); ................} ............} ........} ....} ....public NavigationItem[] getItemsByName(String name, Project project, boolean includeNonProjectItems) { ........// TODO - Distinguish between project and non-project Arc files ........List navItems = map.get(name); ........return (NavigationItem[]) navItems.toArray(new NavigationItem[navItems.size()]); ....} } ...and this is what I have in plugin.xml: ]]>


Any help would be greatly appreciated!

Thanks,
Kurt Christensen

Edited by: Kurt Christensen on May 13, 2008 12:44 PM

2 comments
Comment actions Permalink

Hello Kurt,

If you ran your plugin with assertions enabled (-ea), you would see a more
helpful error message in this case. :) Your PSI elements must return a non-null
value from the getPresentation() method.

I'm developing a custom language plugin for 7.0+, and I'm having a
problem with my ChooseByNameContributor. When I run in debug mode, it
looks like I get the right stuff coming out of getNames and
getItemsByName, and yet when I fill in some letters in the "Enter
class name:" popup, I get the following stack trace, repeated many
times:

No message
java.lang.NullPointerException
at
com.intellij.ide.util.NavigationItemListCellRenderer$LeftRenderer.cust
omizeCellRenderer(NavigationItemListCellRenderer.java:18)
at
com.intellij.ui.ColoredListCellRenderer.getListCellRendererComponent(C
oloredListCellRenderer.java:65)
at
com.intellij.ide.util.NavigationItemListCellRenderer.getListCellRender
erComponent(NavigationItemListCellRenderer.java:15)
at
javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:
1155)
at
javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.
java:1105)
at
javax.swing.plaf.basic.BasicListUI.locationToIndex(BasicListUI.java:72
1)
at javax.swing.JList.locationToIndex(JList.java:1144)
at javax.swing.JList.getLastVisibleIndex(JList.java:898)
at
com.intellij.ui.ListScrollingUtil.getVisibleRowCount(ListScrollingUtil
.java:172)
at
com.intellij.ui.ListScrollingUtil.ensureIndexIsVisible(ListScrollingUt
il.java:144)
at
com.intellij.ui.ListScrollingUtil.selectItem(ListScrollingUtil.java:50
)
at
com.intellij.ide.util.gotoByName.ChooseByNameBase$ListUpdater$1.run(Ch
ooseByNameBase.java:5)
at
com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(La
terInvocator.java:9)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at com.intellij.ide.IdeEventQueue.c(IdeEventQueue.java:179)
at com.intellij.ide.IdeEventQueue.b(IdeEventQueue.java:37)
at
com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:119)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThr
ead.java:269)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThrea
d.java:190)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:184)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:176)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Here is my contributor implementation:

public class ArcChooser implements ChooseByNameContributor {
...private Map<String, List<VariableAssignment>> map;

...public String[] getNames(Project project, boolean
includeNonProjectItems) {
.......map = new HashMap<String, List<VariableAssignment>>();
.......List<String> names = new ArrayList<String>();
.......// TODO - Distinguish between project and non-project Arc files
.......findNames(project, project.getBaseDir(), names);
.......return names.toArray(new String[names.size()]);
...}
...private void findNames(Project project, VirtualFile baseDir,
List<String> names) {
.......if (baseDir != null) {
...........for (VirtualFile file : baseDir.getChildren()) {
...............if (file.isDirectory()) {
...................findNames(project, file, names);
...............} else if ("arc".equalsIgnoreCase(file.getExtension()))
{
...................findNamesInFile(project, file, names);
...............}
...........}
.......}
...}
...private void findNamesInFile(Project project, VirtualFile file,
List<String> names) {
.......PsiFile psiFile =
PsiManager.getInstance(project).findFile(file);
.......if (psiFile != null) {
...........for (PsiElement child : psiFile.getChildren()) {
...............if (child instanceof VariableAssignment) {
...................String name = ((VariableAssignment)
child).getName();
...................List<VariableAssignment> navItems = map.get(name);
...................if (navItems == null) {
.......................navItems = new ArrayList<VariableAssignment>();
.......................map.put(name, navItems);
...................}
...................navItems.add((VariableAssignment) child);
...................names.add(name);
...............}
...........}
.......}
...}
...public NavigationItem[] getItemsByName(String name, Project
project, boolean includeNonProjectItems) {

.......// TODO - Distinguish between project and non-project Arc files

.......List navItems = map.get(name);

.......return (NavigationItem[]) navItems.toArray(new
NavigationItem[navItems.size()]);

...}

}

..and this is what I have in plugin.xml:

<extensions defaultExtensionNs="com.intellij">
<!-- <errorHandler
implementation="com.intellij.diagnostic.ITNReporter"/> -->
<fileTypeFactory
implementation="com.bitbakery.plugin.arc.ArcSupportLoader"/>
<colorSettingsPage
implementation="com.bitbakery.plugin.arc.ArcColorsPage"/>
<gotoClassContributor
implementation="com.bitbakery.plugin.arc.nav.ArcChooser"/>
</extensions>
Any help would be greatly appreciated!

Thanks,
Kurt Christensen

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Thanks Dmitri - As always, your help is spot-on: I was returning a null ItemPresentation from my PsiElement. Everything works fine now. Thanks also for the -ea tip!

Cheers,
KurtC

0

Please sign in to leave a comment.