From e65f1a1f0c72250fffdf4173be20e554ead10baf Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 14 Feb 2005 18:56:53 +0300 Subject: [PATCH] FindUsages API for custom languages. Implemented in javscript, reimplemented in HTML, CSS. --- openapi/src/com/intellij/lang/Language.java | 9 +- .../lang/findUsages/FindUsagesProvider.java | 19 ++++ .../codeInsight/TargetElementUtil.java | 9 +- .../findUsages/CommonFindUsagesDialog.java | 40 +++++++ .../find/findUsages/FindUsagesManager.java | 107 ++++-------------- source/com/intellij/lang/dtd/DTDLanguage.java | 6 + source/com/intellij/lang/xml/XMLLanguage.java | 6 + .../com/intellij/usageView/UsageViewUtil.java | 51 ++++----- 8 files changed, 125 insertions(+), 122 deletions(-) create mode 100644 openapi/src/com/intellij/lang/findUsages/FindUsagesProvider.java create mode 100644 source/com/intellij/find/findUsages/CommonFindUsagesDialog.java diff --git a/openapi/src/com/intellij/lang/Language.java b/openapi/src/com/intellij/lang/Language.java index bbffcd88665e..6553b25243f4 100644 --- a/openapi/src/com/intellij/lang/Language.java +++ b/openapi/src/com/intellij/lang/Language.java @@ -4,6 +4,7 @@ import com.intellij.codeFormatting.PseudoTextBuilder; import com.intellij.ide.structureView.StructureViewModel; import com.intellij.lang.annotation.Annotator; import com.intellij.lang.cacheBuilder.WordsScanner; +import com.intellij.lang.findUsages.FindUsagesProvider; import com.intellij.lang.folding.FoldingBuilder; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter; @@ -73,11 +74,15 @@ public abstract class Language { return null; } - public String toString() { - return "Language: " + myID; + public FindUsagesProvider getFindUsagesProvider() { + return null; } public StructureViewModel getStructureViewModel(final PsiElement psiElement) { return null; } + + public String toString() { + return "Language: " + myID; + } } diff --git a/openapi/src/com/intellij/lang/findUsages/FindUsagesProvider.java b/openapi/src/com/intellij/lang/findUsages/FindUsagesProvider.java new file mode 100644 index 000000000000..f376e62ac9d8 --- /dev/null +++ b/openapi/src/com/intellij/lang/findUsages/FindUsagesProvider.java @@ -0,0 +1,19 @@ +package com.intellij.lang.findUsages; + +import com.intellij.psi.PsiElement; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 14, 2005 + * Time: 5:48:12 PM + * To change this template use File | Settings | File Templates. + */ +public interface FindUsagesProvider { + boolean canFindUsagesFor(PsiElement psiElement); + String getHelpId(PsiElement psiElement); + + String getType(PsiElement element); + String getDescriptiveName(PsiElement element); + String getNodeText(PsiElement element, boolean useFullName); +} diff --git a/source/com/intellij/codeInsight/TargetElementUtil.java b/source/com/intellij/codeInsight/TargetElementUtil.java index dd44860e48a4..2e2cd3373d93 100644 --- a/source/com/intellij/codeInsight/TargetElementUtil.java +++ b/source/com/intellij/codeInsight/TargetElementUtil.java @@ -1,6 +1,5 @@ package com.intellij.codeInsight; -import com.intellij.ant.PsiAntElement; import com.intellij.aspects.psi.PsiPointcutDef; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.lookup.Lookup; @@ -14,6 +13,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; public class TargetElementUtil { @@ -83,8 +83,8 @@ public class TargetElementUtil { PsiElement element = file.findElementAt(offset); if ((flags & ELEMENT_NAME_ACCEPTED) != 0) { + PsiElement parent = element.getParent(); if (element instanceof PsiIdentifier) { - PsiElement parent = element.getParent(); if (parent instanceof PsiClass && element.equals(((PsiClass) parent).getNameIdentifier())) { return parent; } @@ -98,6 +98,11 @@ public class TargetElementUtil { return parent; } } + else if (parent instanceof PsiNamedElement) { // A bit hacky depends on navigation offset correctly overriden + if (parent.getTextOffset() == element.getTextOffset() && Comparing.equal(((PsiNamedElement)parent).getName(), element.getText())) { + return parent; + } + } } if (element instanceof PsiKeyword) { diff --git a/source/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/source/com/intellij/find/findUsages/CommonFindUsagesDialog.java new file mode 100644 index 000000000000..ee0373ed2c21 --- /dev/null +++ b/source/com/intellij/find/findUsages/CommonFindUsagesDialog.java @@ -0,0 +1,40 @@ +package com.intellij.find.findUsages; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.search.SearchScopeCache; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 14, 2005 + * Time: 5:40:05 PM + * To change this template use File | Settings | File Templates. + */ +public class CommonFindUsagesDialog extends FindUsagesDialog { + public CommonFindUsagesDialog(PsiElement element, + Project project, + FindUsagesOptions findUsagesOptions, + boolean toShowInNewTab, + boolean isShowInNewTabEnabled, + boolean isSingleFile) { + super(element, project, findUsagesOptions, toShowInNewTab, isShowInNewTabEnabled, isSingleFile); + } + + public FindUsagesOptions getShownOptions() { + return new FindUsagesOptions(myProject, SearchScopeCache.getInstance(myProject)); + } + + protected void update() { + } + + protected JPanel createFindWhatPanel() { + return null; + } + + protected JComponent getPreferredFocusedControl() { + return null; + } +} diff --git a/source/com/intellij/find/findUsages/FindUsagesManager.java b/source/com/intellij/find/findUsages/FindUsagesManager.java index 5de398e5e650..7259041e9586 100644 --- a/source/com/intellij/find/findUsages/FindUsagesManager.java +++ b/source/com/intellij/find/findUsages/FindUsagesManager.java @@ -6,6 +6,8 @@ import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.find.impl.HelpID; import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.lang.Language; +import com.intellij.lang.findUsages.FindUsagesProvider; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; @@ -17,8 +19,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorLocation; import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; @@ -37,9 +37,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.psi.xml.XmlAttributeDecl; import com.intellij.psi.xml.XmlElementDecl; import com.intellij.psi.xml.XmlTag; -import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.LightweightHint; -import com.intellij.ui.StateRestoringCheckBox; import com.intellij.ui.content.Content; import com.intellij.usageView.FindUsagesCommand; import com.intellij.usageView.UsageInfo; @@ -53,13 +51,14 @@ import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import javax.swing.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; public class FindUsagesManager { private static final Logger LOG = Logger.getInstance("#com.intellij.find.findParameterUsages.FindUsagesManager"); - private static HashMap findHandlers = new HashMap(); - public static final int FROM_START = 0; public static final int FROM_END = 3; public static final int AFTER_CARET = 1; @@ -80,24 +79,11 @@ public class FindUsagesManager { public FindUsagesOptions myLastOptions = null; } - public interface FindUsagesHandler extends UsageViewUtil.UsageViewHandler { - boolean canFindUsagesFor(PsiElement element); + static public class HtmlFindUsagesHandler implements FindUsagesProvider { + private FindUsagesProvider styleHandler; - FindUsagesDialog createFindUsagesDialog(PsiElement element, - Project project, - FindUsagesOptions findUsagesOptions, - boolean isSingleFile, - boolean isOpenInNewTab, - boolean isOpenInNewTabEnabled); - - String getHelpId(PsiElement element); - } - - static public class HtmlFindUsagesHandler implements FindUsagesHandler { - private FindUsagesHandler styleHandler; - - public void setStyleHandler(FindUsagesHandler handler) { - styleHandler = handler; + public void setStyleHandler(FindUsagesProvider provider) { + styleHandler = provider; } public boolean canFindUsagesFor(PsiElement element) { @@ -109,43 +95,6 @@ public class FindUsagesManager { return result; } - public FindUsagesDialog createFindUsagesDialog(final PsiElement element, - Project project, - FindUsagesOptions findUsagesOptions, - boolean isSingleFile, - boolean isOpenInNewTab, - boolean isOpenInNewTabEnabled) { - if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { - return styleHandler.createFindUsagesDialog(element, project, findUsagesOptions, isSingleFile, isOpenInNewTab, - isOpenInNewTabEnabled); - } - - return new FindUsagesDialog(element,project,findUsagesOptions,isOpenInNewTab,isOpenInNewTabEnabled,isSingleFile) { - private StateRestoringCheckBox myCbUsages; - - public FindUsagesOptions getShownOptions() { - return new FindUsagesOptions(element.getProject(), SearchScopeCache.getInstance(element.getProject())); - } - - protected void update() { - //To change body of implemented methods use File | Settings | File Templates. - } - - protected JPanel createFindWhatPanel() { - JPanel findWhatPanel = new JPanel(); - findWhatPanel.setBorder(IdeBorderFactory.createTitledBorder("Find")); - findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS)); - - myCbUsages = addCheckboxToPanel("Usages", myFindUsagesOptions.isUsages, findWhatPanel, true, 'U'); - return findWhatPanel; - } - - protected JComponent getPreferredFocusedControl() { - return myCbUsages; - } - }; - } - public String getType(PsiElement element) { if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { return styleHandler.getType(element); @@ -183,19 +132,6 @@ public class FindUsagesManager { } } - static { - HtmlFindUsagesHandler handler = new HtmlFindUsagesHandler(); - registerFindHandler(StdFileTypes.HTML, handler); - registerFindHandler(StdFileTypes.XHTML, handler); - registerFindHandler(StdFileTypes.DTD, handler); - registerFindHandler(StdFileTypes.XML, handler); - - UsageViewUtil.registerUsageViewHandler(StdFileTypes.HTML, handler); - UsageViewUtil.registerUsageViewHandler(StdFileTypes.XHTML, handler); - UsageViewUtil.registerUsageViewHandler(StdFileTypes.DTD, handler); - UsageViewUtil.registerUsageViewHandler(StdFileTypes.XML, handler); - } - private LastSearchData myLastSearchData = new LastSearchData(); public FindUsagesManager(Project project, SearchScopeCache searchScopeCache, com.intellij.usages.UsageViewManager anotherManager) { @@ -209,12 +145,9 @@ public class FindUsagesManager { myFindPointcutOptions = createFindUsagesOptions(searchScopeCache); } - public static void registerFindHandler(FileType fileType, FindUsagesHandler handler) { - findHandlers.put(fileType, handler); - } - - public static FindUsagesHandler getFindHandler(FileType fileType) { - return findHandlers.get(fileType); + public static FindUsagesProvider getFindHandler(PsiElement elt) { + final Language lang = elt.getLanguage(); + return lang != null ? lang.getFindUsagesProvider() : null; } private FindUsagesOptions createFindUsagesOptions(SearchScopeCache searchScopeCache) { @@ -241,9 +174,8 @@ public class FindUsagesManager { (element instanceof PsiPackage) || (ThrowSearchUtil.isSearchable(element)) || (element instanceof PsiMethod))) { - PsiFile containingFile = element.getContainingFile(); - FindUsagesHandler handler = (containingFile != null) ? getFindHandler(containingFile.getFileType()) : null; - if (handler != null && handler.canFindUsagesFor(element)) return true; + FindUsagesProvider provider = getFindHandler(element); + if (provider != null && provider.canFindUsagesFor(element)) return true; return false; } @@ -862,7 +794,7 @@ public class FindUsagesManager { helpID = HelpID.FIND_PARAMETER_USAGES; } else { - final FindUsagesHandler findHandler = getFindHandler(element.getContainingFile().getFileType()); + final FindUsagesProvider findHandler = getFindHandler(element); if (findHandler != null) { helpID = findHandler.getHelpId(element); } @@ -899,11 +831,10 @@ public class FindUsagesManager { isOpenInNewTabEnabled, isSingleFile); } else { - PsiFile containingFile = element.getContainingFile(); - FindUsagesHandler handler = (containingFile != null) ? getFindHandler(containingFile.getFileType()) : null; + FindUsagesProvider handler = getFindHandler(element); if (handler != null) { - return handler.createFindUsagesDialog(element, myProject, createFindUsagesOptions(SearchScopeCache.getInstance(myProject)), - isSingleFile, isOpenInNewTab, isOpenInNewTabEnabled); + return new CommonFindUsagesDialog(element, myProject, createFindUsagesOptions(SearchScopeCache.getInstance(myProject)), + isSingleFile, isOpenInNewTab, isOpenInNewTabEnabled); } return null; } diff --git a/source/com/intellij/lang/dtd/DTDLanguage.java b/source/com/intellij/lang/dtd/DTDLanguage.java index fc81663d0c7b..4c44c00b1d75 100644 --- a/source/com/intellij/lang/dtd/DTDLanguage.java +++ b/source/com/intellij/lang/dtd/DTDLanguage.java @@ -1,8 +1,10 @@ package com.intellij.lang.dtd; +import com.intellij.find.findUsages.FindUsagesManager; import com.intellij.ide.highlighter.XmlFileHighlighter; import com.intellij.lang.Language; import com.intellij.lang.ParserDefinition; +import com.intellij.lang.findUsages.FindUsagesProvider; import com.intellij.openapi.fileTypes.SyntaxHighlighter; import com.intellij.openapi.project.Project; @@ -26,4 +28,8 @@ public class DTDLanguage extends Language { public ParserDefinition getParserDefinition() { return new DTDParserDefinition(); } + + public FindUsagesProvider getFindUsagesProvider() { + return new FindUsagesManager.HtmlFindUsagesHandler(); + } } diff --git a/source/com/intellij/lang/xml/XMLLanguage.java b/source/com/intellij/lang/xml/XMLLanguage.java index bf9caede1380..69c88090694e 100644 --- a/source/com/intellij/lang/xml/XMLLanguage.java +++ b/source/com/intellij/lang/xml/XMLLanguage.java @@ -2,9 +2,11 @@ package com.intellij.lang.xml; import com.intellij.codeFormatting.PseudoTextBuilder; import com.intellij.codeFormatting.xml.xml.XmlPseudoTextBuilder; +import com.intellij.find.findUsages.FindUsagesManager; import com.intellij.ide.highlighter.XmlFileHighlighter; import com.intellij.lang.Language; import com.intellij.lang.ParserDefinition; +import com.intellij.lang.findUsages.FindUsagesProvider; import com.intellij.openapi.fileTypes.SyntaxHighlighter; import com.intellij.openapi.project.Project; import com.intellij.psi.impl.source.xml.XmlPsiPolicy; @@ -46,4 +48,8 @@ public class XMLLanguage extends Language { public ParserDefinition getParserDefinition() { return new XMLParserDefinition(); } + + public FindUsagesProvider getFindUsagesProvider() { + return new FindUsagesManager.HtmlFindUsagesHandler(); + } } diff --git a/source/com/intellij/usageView/UsageViewUtil.java b/source/com/intellij/usageView/UsageViewUtil.java index 7d69aee864c7..612d89352fc7 100644 --- a/source/com/intellij/usageView/UsageViewUtil.java +++ b/source/com/intellij/usageView/UsageViewUtil.java @@ -6,8 +6,9 @@ import com.intellij.aspects.psi.PsiPointcutDef; import com.intellij.aspects.psi.gen.PsiErrorIntroduction; import com.intellij.aspects.psi.gen.PsiVerificationIntroduction; import com.intellij.aspects.psi.gen.PsiWarningIntroduction; +import com.intellij.lang.Language; +import com.intellij.lang.findUsages.FindUsagesProvider; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; @@ -19,7 +20,6 @@ import com.intellij.psi.xml.XmlTag; import gnu.trove.THashSet; import java.util.Arrays; -import java.util.HashMap; import java.util.Set; /** @@ -29,15 +29,7 @@ public class UsageViewUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.usageView.UsageViewUtil"); public static final String DEFAULT_PACKAGE_NAME = ""; - public interface UsageViewHandler { - String getType(PsiElement element); - - String getDescriptiveName(PsiElement element); - - String getNodeText(PsiElement element, boolean useFullName); - } - - private static final HashMap usageViewHandlers = new HashMap(); + private UsageViewUtil() { } public static String createNodeText(PsiElement element, boolean useFullName) { if (element instanceof PsiDirectory) { @@ -49,9 +41,6 @@ public class UsageViewUtil { if (element instanceof PsiFile) { return useFullName ? ((PsiFile)element).getVirtualFile().getPresentableUrl() : ((PsiFile)element).getName(); } - if (element instanceof PsiFile) { - return useFullName ? ((PsiFile)element).getVirtualFile().getPresentableUrl() : ((PsiFile)element).getName(); - } if (ThrowSearchUtil.isSearchable(element)) { return ThrowSearchUtil.getSearchableTypeName(element); } @@ -150,20 +139,18 @@ public class UsageViewUtil { return ((XmlAttributeValue)element).getValue(); } else if (element != null) { - PsiFile containingFile = element.getContainingFile(); - UsageViewHandler handler = (containingFile != null) ? usageViewHandlers.get(containingFile.getFileType()) : null; - if (handler != null) { - return handler.getNodeText(element, useFullName); + final Language lang = element.getLanguage(); + if (lang != null) { + FindUsagesProvider provider = lang.getFindUsagesProvider(); + if (provider != null) { + return provider.getNodeText(element, useFullName); + } } } return ""; } - public static void registerUsageViewHandler(FileType fileType, UsageViewHandler handler) { - usageViewHandlers.put(fileType, handler); - } - public static String getPackageName(PsiDirectory directory, boolean includeRootDir) { PsiPackage aPackage = directory.getPackage(); if (aPackage == null) { @@ -370,10 +357,12 @@ public class UsageViewUtil { return ((PsiAntElement)psiElement).getRole().getName(); } - PsiFile containingFile = psiElement.getContainingFile(); - UsageViewHandler handler = (containingFile!=null)?usageViewHandlers.get(containingFile.getFileType()):null; - if (handler != null) { - return handler.getType(psiElement); + final Language lang = psiElement.getLanguage(); + if (lang != null) { + FindUsagesProvider provider = lang.getFindUsagesProvider(); + if (provider != null) { + return provider.getType(psiElement); + } } return ""; @@ -487,10 +476,12 @@ public class UsageViewUtil { ret = ((PsiLabeledStatement)psiElement).getName(); } else { - PsiFile containingFile = psiElement.getContainingFile(); - UsageViewHandler handler = (containingFile != null) ? usageViewHandlers.get(containingFile.getFileType()) : null; - if (handler != null) { - return handler.getDescriptiveName(psiElement); + final Language lang = psiElement.getLanguage(); + if (lang != null) { + FindUsagesProvider provider = lang.getFindUsagesProvider(); + if (provider != null) { + return provider.getDescriptiveName(psiElement); + } } }