goto type declaration: place aware (IDEA-85106)

This commit is contained in:
anna
2012-04-25 17:19:03 +02:00
parent 736a74a221
commit f1fcd7ccd8
3 changed files with 59 additions and 8 deletions
@@ -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};
}
@@ -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<PsiElement> types = new THashSet<PsiElement>();
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;
}
@@ -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);
}