Unified obtaining psi element for descriptor. Now code for finding effective descriptors of fake override and finding source element for original declarations are separated. Old method DescriptorToSourceUtils.descriptorToDeclaration is still there, because it has ~90 usages.

This commit is contained in:
Evgeny Gerashchenko
2015-03-03 12:38:31 +03:00
parent a56b1da11f
commit 7b6f83815c
15 changed files with 94 additions and 131 deletions
@@ -1817,7 +1817,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
PsiElement element = bindingContext.get(LABEL_TARGET, expression.getTargetLabel());
if (element != DescriptorToSourceUtils.callableDescriptorToDeclaration(context.getContextDescriptor())) {
if (element != DescriptorToSourceUtils.getSourceFromDescriptor(context.getContextDescriptor())) {
DeclarationDescriptor elementDescriptor = typeMapper.getBindingContext().get(DECLARATION_TO_DESCRIPTOR, element);
assert element != null : "Expression should be not null " + expression.getText();
assert elementDescriptor != null : "Descriptor should be not null: " + element.getText();
@@ -73,7 +73,7 @@ import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.isLocalNamedFun;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.OLD_JET_VALUE_PARAMETER_ANNOTATION;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.callableDescriptorToDeclaration;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTrait;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
@@ -498,7 +498,7 @@ public class FunctionCodegen {
);
if (!bridgesToGenerate.isEmpty()) {
PsiElement origin = descriptor.getKind() == DECLARATION ? callableDescriptorToDeclaration(descriptor) : null;
PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
for (Bridge<Method> bridge : bridgesToGenerate) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo());
}
@@ -628,12 +628,12 @@ public class FunctionCodegen {
if (this.owner instanceof PackageFacadeContext) {
mv.visitCode();
generatePackageDelegateMethodBody(mv, defaultMethod, (PackageFacadeContext) this.owner);
endVisit(mv, "default method delegation", callableDescriptorToDeclaration(functionDescriptor));
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else {
mv.visitCode();
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen);
endVisit(mv, "default method", callableDescriptorToDeclaration(functionDescriptor));
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
}
}
}
@@ -101,9 +101,9 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
if (member.getKind() != DELEGATION) {
// Delegates don't have declarations in the code
memberElement = origin.element ?: DescriptorToSourceUtils.callableDescriptorToDeclaration(member)
memberElement = origin.element ?: DescriptorToSourceUtils.descriptorToDeclaration(member)
if (memberElement == null && member is PropertyAccessorDescriptor) {
memberElement = DescriptorToSourceUtils.callableDescriptorToDeclaration(member.getCorrespondingProperty())
memberElement = DescriptorToSourceUtils.descriptorToDeclaration(member.getCorrespondingProperty())
}
}
}
@@ -619,7 +619,7 @@ public class JetTypeMapper {
return "invoke";
}
else if (descriptor instanceof AnonymousFunctionDescriptor) {
PsiElement element = DescriptorToSourceUtils.callableDescriptorToDeclaration(descriptor);
PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
if (element instanceof JetFunctionLiteral) {
PsiElement expression = element.getParent();
if (expression instanceof JetFunctionLiteralExpression) {
@@ -175,11 +175,11 @@ public class BindingContextUtils {
) {
FunctionDescriptor containingFunctionDescriptor = DescriptorUtils.getParentOfType(startDescriptor, FunctionDescriptor.class, strict);
PsiElement containingFunction =
containingFunctionDescriptor != null ? DescriptorToSourceUtils.callableDescriptorToDeclaration(containingFunctionDescriptor) : null;
containingFunctionDescriptor != null ? DescriptorToSourceUtils.getSourceFromDescriptor(containingFunctionDescriptor) : null;
while (containingFunction instanceof JetFunctionLiteral) {
containingFunctionDescriptor = DescriptorUtils.getParentOfType(containingFunctionDescriptor, FunctionDescriptor.class);
containingFunction = containingFunctionDescriptor != null ? DescriptorToSourceUtils
.callableDescriptorToDeclaration(containingFunctionDescriptor) : null;
.getSourceFromDescriptor(containingFunctionDescriptor) : null;
}
return new Pair<FunctionDescriptor, PsiElement>(containingFunctionDescriptor, containingFunction);
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.resolve;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -26,87 +25,58 @@ import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.resolve.source.SourcePackage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
public final class DescriptorToSourceUtils {
private static void collectEffectiveReferencedDescriptors(@NotNull List<DeclarationDescriptor> result, @NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor.Kind kind = ((CallableMemberDescriptor) descriptor).getKind();
if (kind != DECLARATION && kind != SYNTHESIZED) {
for (DeclarationDescriptor overridden: ((CallableMemberDescriptor) descriptor).getOverriddenDescriptors()) {
collectEffectiveReferencedDescriptors(result, overridden.getOriginal());
}
return;
}
}
result.add(descriptor);
}
@NotNull
public static Collection<DeclarationDescriptor> getEffectiveReferencedDescriptors(@NotNull DeclarationDescriptor descriptor) {
List<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>();
collectEffectiveReferencedDescriptors(result, descriptor.getOriginal());
return result;
}
@Nullable
private static PsiElement doGetDescriptorToDeclaration(@NotNull DeclarationDescriptor descriptor) {
DeclarationDescriptor original = descriptor.getOriginal();
if (!(original instanceof DeclarationDescriptorWithSource)) {
public static PsiElement getSourceFromDescriptor(@NotNull DeclarationDescriptor descriptor) {
if (!(descriptor instanceof DeclarationDescriptorWithSource)) {
return null;
}
return SourcePackage.getPsi(((DeclarationDescriptorWithSource) original).getSource());
return SourcePackage.getPsi(((DeclarationDescriptorWithSource) descriptor).getSource());
}
// NOTE this is also used by KDoc
@Nullable
public static PsiElement descriptorToDeclaration(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof CallableMemberDescriptor) {
return callableDescriptorToDeclaration((CallableMemberDescriptor) descriptor);
}
else if (descriptor instanceof ClassDescriptor) {
return classDescriptorToDeclaration((ClassDescriptor) descriptor);
}
else {
return doGetDescriptorToDeclaration(descriptor);
}
}
@NotNull
public static List<PsiElement> descriptorToDeclarations(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof CallableMemberDescriptor) {
return callableDescriptorToDeclarations((CallableMemberDescriptor) descriptor);
}
else {
PsiElement psiElement = descriptorToDeclaration(descriptor);
if (psiElement != null) {
return Lists.newArrayList(psiElement);
} else {
return Lists.newArrayList();
for (DeclarationDescriptor declarationDescriptor : getEffectiveReferencedDescriptors(descriptor.getOriginal())) {
PsiElement source = getSourceFromDescriptor(declarationDescriptor);
if (source != null) {
return source;
}
}
}
@Nullable
public static PsiElement callableDescriptorToDeclaration(@NotNull CallableMemberDescriptor callable) {
if (callable.getKind() == DECLARATION || callable.getKind() == SYNTHESIZED) {
return doGetDescriptorToDeclaration(callable);
}
//TODO: should not use this method for fake_override and delegation
Set<? extends CallableMemberDescriptor> overriddenDescriptors = callable.getOverriddenDescriptors();
if (overriddenDescriptors.size() == 1) {
return callableDescriptorToDeclaration(overriddenDescriptors.iterator().next());
}
return null;
}
@NotNull
public static List<PsiElement> callableDescriptorToDeclarations(@NotNull CallableMemberDescriptor callable) {
if (callable.getKind() == DECLARATION || callable.getKind() == SYNTHESIZED) {
PsiElement psiElement = doGetDescriptorToDeclaration(callable);
return psiElement != null ? Lists.newArrayList(psiElement) : Lists.<PsiElement>newArrayList();
}
List<PsiElement> r = new ArrayList<PsiElement>();
Set<? extends CallableMemberDescriptor> overriddenDescriptors = callable.getOverriddenDescriptors();
for (CallableMemberDescriptor overridden : overriddenDescriptors) {
r.addAll(callableDescriptorToDeclarations(overridden));
}
return r;
}
@Nullable
public static PsiElement classDescriptorToDeclaration(@NotNull ClassDescriptor clazz) {
return doGetDescriptorToDeclaration(clazz);
return getSourceFromDescriptor(clazz);
}
private DescriptorToSourceUtils() {}
@Nullable
public static JetFile getContainingFile(@NotNull DeclarationDescriptor declarationDescriptor) {
// declarationDescriptor may describe a synthesized element which doesn't have PSI
@@ -133,6 +103,6 @@ public final class DescriptorToSourceUtils {
}
return descriptor;
}
private DescriptorToSourceUtils() {}
}
@@ -21,8 +21,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.callableDescriptorToDeclaration
public object LibrarySourceHacks {
public val SKIP_TOP_LEVEL_MEMBERS: Key<Boolean> = Key.create<Boolean>("SKIP_TOP_LEVEL_MEMBERS") // used when analyzing library source
@@ -31,7 +29,7 @@ public object LibrarySourceHacks {
if (original.getContainingDeclaration() !is PackageFragmentDescriptor) return false
val declaration = callableDescriptorToDeclaration(original) ?: return false
val declaration = DescriptorToSourceUtils.getSourceFromDescriptor(original) ?: return false
val file = declaration.getContainingFile()
return file != null && (file.getUserData<Boolean>(SKIP_TOP_LEVEL_MEMBERS) ?: false)