Made navigation to member properties aware of properties which are defined as constructor parameters.

This commit is contained in:
Evgeny Gerashchenko
2012-03-14 18:14:50 +04:00
parent 76a5a10ac1
commit 9d0fae9650
2 changed files with 27 additions and 18 deletions
@@ -48,7 +48,7 @@ public class JetClsNavigationPolicy implements ClsCustomNavigationPolicy {
public PsiElement getNavigationElement(@NotNull ClsMethodImpl clsMethod) { public PsiElement getNavigationElement(@NotNull ClsMethodImpl clsMethod) {
JetDeclaration jetDeclaration = getJetDeclarationByClsElement(clsMethod); JetDeclaration jetDeclaration = getJetDeclarationByClsElement(clsMethod);
if (jetDeclaration instanceof JetProperty) { if (jetDeclaration instanceof JetProperty) {
JetProperty sourceProperty = JetSourceNavigationHelper.getSourceProperty((JetProperty) jetDeclaration); JetDeclaration sourceProperty = JetSourceNavigationHelper.getSourceProperty((JetProperty) jetDeclaration);
if (sourceProperty != null) { if (sourceProperty != null) {
return sourceProperty; return sourceProperty;
} }
@@ -27,13 +27,13 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager; import com.intellij.psi.PsiManager;
import com.intellij.util.Processor; import com.intellij.util.Processor;
import jet.Tuple0; import jet.Tuple2;
import jet.Tuple1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -52,19 +52,26 @@ public class JetSourceNavigationHelper {
} }
@Nullable @Nullable
public static JetClass getSourceClass(final @NotNull JetClass decompiledClass) { private static Tuple2<BindingContext, ClassDescriptor> getBindingContextAndClassDescriptor(@NotNull JetClass decompiledClass) {
for (VirtualFile sourceDir : getAllSourceDirs(decompiledClass)) { for (VirtualFile sourceDir : getAllSourceDirs(decompiledClass)) {
BindingContext bindingContext = analyzeLibrary(sourceDir, decompiledClass.getProject()); BindingContext bindingContext = analyzeLibrary(sourceDir, decompiledClass.getProject());
ClassDescriptor cd = bindingContext.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(decompiledClass)); ClassDescriptor cd = bindingContext.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(decompiledClass));
if (cd != null) { if (cd != null) {
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, cd); return new Tuple2<BindingContext, ClassDescriptor>(bindingContext, cd);
assert declaration instanceof JetClass;
return (JetClass) declaration;
} }
} }
return null; return null;
} }
@Nullable
public static JetClass getSourceClass(@NotNull JetClass decompiledClass) {
Tuple2<BindingContext, ClassDescriptor> bindingContextAndClassDescriptor = getBindingContextAndClassDescriptor(decompiledClass);
if (bindingContextAndClassDescriptor == null) return null;
PsiElement declaration = bindingContextAndClassDescriptor._1.get(BindingContext.DESCRIPTOR_TO_DECLARATION, bindingContextAndClassDescriptor._2);
assert declaration instanceof JetClass;
return (JetClass) declaration;
}
private static BindingContext analyzeLibrary(VirtualFile sourceDir, final Project project) { private static BindingContext analyzeLibrary(VirtualFile sourceDir, final Project project) {
final List<JetFile> libraryFiles = new ArrayList<JetFile>(); final List<JetFile> libraryFiles = new ArrayList<JetFile>();
VfsUtil.processFilesRecursively(sourceDir, new Processor<VirtualFile>() { VfsUtil.processFilesRecursively(sourceDir, new Processor<VirtualFile>() {
@@ -100,7 +107,7 @@ public class JetSourceNavigationHelper {
} }
@Nullable @Nullable
public static JetProperty getSourceProperty(final @NotNull JetProperty decompiledProperty) { public static JetDeclaration getSourceProperty(final @NotNull JetProperty decompiledProperty) {
String propertyName = decompiledProperty.getName(); String propertyName = decompiledProperty.getName();
if (propertyName == null) { if (propertyName == null) {
return null; return null;
@@ -108,19 +115,21 @@ public class JetSourceNavigationHelper {
PsiElement propertyContainer = decompiledProperty.getParent(); PsiElement propertyContainer = decompiledProperty.getParent();
if (propertyContainer instanceof JetFile) { if (propertyContainer instanceof JetFile) {
// TODO global property // TODO global property, may be extension
return null; return null;
} else if (propertyContainer instanceof JetClassBody) { }
JetClass sourceClass = getSourceClass((JetClass) propertyContainer.getParent()); else if (propertyContainer instanceof JetClassBody) {
if (sourceClass != null) { Tuple2<BindingContext, ClassDescriptor> bindingContextAndClassDescriptor = getBindingContextAndClassDescriptor((JetClass) propertyContainer.getParent());
JetClassBody sourceClassBody = sourceClass.getBody(); if (bindingContextAndClassDescriptor != null) {
if (sourceClassBody != null) { BindingContext bindingContext = bindingContextAndClassDescriptor._1;
for (JetProperty p : sourceClassBody.getProperties()) { ClassDescriptor classDescriptor = bindingContextAndClassDescriptor._2;
if (propertyName.equals(p.getName())) { for (VariableDescriptor vd : classDescriptor.getDefaultType().getMemberScope().getProperties(propertyName)) {
return p; if (vd.getContainingDeclaration() == classDescriptor) {
JetDeclaration property = (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, vd);
if (property != null) {
return property;
} }
} }
} }
} }
} }