diff --git a/java/java-impl/src/com/intellij/codeInsight/navigation/actions/JavaTypeDeclarationProvider.java b/java/java-impl/src/com/intellij/codeInsight/navigation/actions/JavaTypeDeclarationProvider.java index 6f26795cf510..9ee0920a3174 100644 --- a/java/java-impl/src/com/intellij/codeInsight/navigation/actions/JavaTypeDeclarationProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/navigation/actions/JavaTypeDeclarationProvider.java @@ -15,6 +15,8 @@ */ package com.intellij.codeInsight.navigation.actions; +import com.intellij.codeInsight.TargetElementUtilBase; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.Nullable; @@ -22,9 +24,15 @@ import org.jetbrains.annotations.Nullable; /** * @author yole */ -public class JavaTypeDeclarationProvider implements TypeDeclarationProvider { +public class JavaTypeDeclarationProvider implements TypeDeclarationPlaceAwareProvider { + @Override + public PsiElement[] getSymbolTypeDeclarations(PsiElement symbol) { + return getSymbolTypeDeclarations(symbol, null, -1); + } + @Nullable - public PsiElement[] getSymbolTypeDeclarations(final PsiElement targetElement) { + @Override + public PsiElement[] getSymbolTypeDeclarations(PsiElement targetElement, Editor editor, int offset) { PsiType type; if (targetElement instanceof PsiVariable){ type = ((PsiVariable)targetElement).getType(); @@ -36,6 +44,13 @@ public class JavaTypeDeclarationProvider implements TypeDeclarationProvider { return null; } if (type == null) return null; + if (editor != null) { + final PsiReference reference = TargetElementUtilBase.findReference(editor, offset); + if (reference instanceof PsiJavaReference) { + final JavaResolveResult resolveResult = ((PsiJavaReference)reference).advancedResolve(true); + type = resolveResult.getSubstitutor().substitute(type); + } + } PsiClass psiClass = PsiUtil.resolveClassInType(type); return psiClass == null ? null : new PsiElement[] {psiClass}; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java index 76a4180302f9..d63921bf2cf8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java @@ -32,7 +32,7 @@ import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.util.PsiUtilCore; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -107,16 +107,17 @@ public class GotoTypeDeclarationAction extends BaseCodeInsightAction implements offset); if (targetElement != null) { - final PsiElement[] symbolType = getSymbolTypeDeclarations(targetElement); + final PsiElement[] symbolType = getSymbolTypeDeclarations(targetElement, editor, offset); return symbolType == null ? PsiElement.EMPTY_ARRAY : symbolType; } + final PsiReference psiReference = TargetElementUtilBase.findReference(editor, offset); if (psiReference instanceof PsiPolyVariantReference) { final ResolveResult[] results = ((PsiPolyVariantReference)psiReference).multiResolve(false); Set types = new THashSet(); for(ResolveResult r: results) { - final PsiElement[] declarations = getSymbolTypeDeclarations(r.getElement()); + final PsiElement[] declarations = getSymbolTypeDeclarations(r.getElement(), editor, offset); if (declarations != null) { for (PsiElement declaration : declarations) { assert declaration != null; @@ -125,16 +126,22 @@ public class GotoTypeDeclarationAction extends BaseCodeInsightAction implements } } - if (!types.isEmpty()) return PsiUtilBase.toPsiElementArray(types); + if (!types.isEmpty()) return PsiUtilCore.toPsiElementArray(types); } return null; } @Nullable - private static PsiElement[] getSymbolTypeDeclarations(final PsiElement targetElement) { + private static PsiElement[] getSymbolTypeDeclarations(final PsiElement targetElement, Editor editor, int offset) { for(TypeDeclarationProvider provider: Extensions.getExtensions(TypeDeclarationProvider.EP_NAME)) { - PsiElement[] result = provider.getSymbolTypeDeclarations(targetElement); + PsiElement[] result; + if (provider instanceof TypeDeclarationPlaceAwareProvider) { + result = ((TypeDeclarationPlaceAwareProvider)provider).getSymbolTypeDeclarations(targetElement, editor, offset); + } + else { + result = provider.getSymbolTypeDeclarations(targetElement); + } if (result != null) return result; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/TypeDeclarationPlaceAwareProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/TypeDeclarationPlaceAwareProvider.java new file mode 100644 index 000000000000..bb262d9b2914 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/TypeDeclarationPlaceAwareProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; + +/** + * User: anna + * Date: 4/25/12 + */ +public interface TypeDeclarationPlaceAwareProvider extends TypeDeclarationProvider { + @Nullable + PsiElement[] getSymbolTypeDeclarations(PsiElement symbol, Editor editor, int offset); +}