more descriptorToDeclaration utils
* custom versions * normalization code moved out of norializer * hide DESCRIPTOR_TO_DECLARATION (make package local)
This commit is contained in:
@@ -88,7 +88,7 @@ public interface BindingContext {
|
||||
backingFieldRequired = valueNotFound ? false : backingFieldRequired;
|
||||
assert backingFieldRequired != null;
|
||||
// TODO: user BindingContextAccessors
|
||||
PsiElement declarationPsiElement = map.get(DESCRIPTOR_TO_DECLARATION, propertyDescriptor);
|
||||
PsiElement declarationPsiElement = map.get(BindingContextUtils.DESCRIPTOR_TO_DECLARATION, propertyDescriptor);
|
||||
if (declarationPsiElement instanceof JetParameter) {
|
||||
JetParameter jetParameter = (JetParameter) declarationPsiElement;
|
||||
return jetParameter.getValOrVarNode() != null ||
|
||||
@@ -123,43 +123,19 @@ public interface BindingContext {
|
||||
}
|
||||
};
|
||||
|
||||
Slices.KeyNormalizer<DeclarationDescriptor> DECLARATION_DESCRIPTOR_NORMALIZER = new Slices.KeyNormalizer<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public DeclarationDescriptor normalize(DeclarationDescriptor declarationDescriptor) {
|
||||
if (declarationDescriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor callable = (CallableMemberDescriptor) declarationDescriptor;
|
||||
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
Set<? extends CallableMemberDescriptor> overriddenDescriptors = callable.getOverriddenDescriptors();
|
||||
if (overriddenDescriptors.size() != 1) {
|
||||
throw new IllegalStateException(
|
||||
"cannot find declaration: fake descriptor" +
|
||||
" has more then one overriden descriptor: " + declarationDescriptor);
|
||||
}
|
||||
return normalize(overriddenDescriptors.iterator().next());
|
||||
}
|
||||
}
|
||||
if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
|
||||
VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
|
||||
return descriptor.getVariableDescriptor().getOriginal();
|
||||
}
|
||||
return declarationDescriptor.getOriginal();
|
||||
}
|
||||
};
|
||||
|
||||
ReadOnlySlice<DeclarationDescriptor, PsiElement> DESCRIPTOR_TO_DECLARATION = Slices.<DeclarationDescriptor, PsiElement>sliceBuilder().setKeyNormalizer(DECLARATION_DESCRIPTOR_NORMALIZER).build();
|
||||
|
||||
WritableSlice<PsiElement, NamespaceDescriptor> NAMESPACE = Slices.<PsiElement, NamespaceDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, ClassDescriptor> CLASS = Slices.<PsiElement, ClassDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetTypeParameter, TypeParameterDescriptor> TYPE_PARAMETER = Slices.<JetTypeParameter, TypeParameterDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, SimpleFunctionDescriptor> FUNCTION = Slices.<PsiElement, SimpleFunctionDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, ConstructorDescriptor> CONSTRUCTOR = Slices.<PsiElement, ConstructorDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, VariableDescriptor> VARIABLE = Slices.<PsiElement, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetParameter, VariableDescriptor> VALUE_PARAMETER = Slices.<JetParameter, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR = Slices.<JetPropertyAccessor, PropertyAccessorDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, NamespaceDescriptor> NAMESPACE = Slices.<PsiElement, NamespaceDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, ClassDescriptor> CLASS = Slices.<PsiElement, ClassDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetTypeParameter, TypeParameterDescriptor> TYPE_PARAMETER = Slices.<JetTypeParameter, TypeParameterDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
/** @see BindingContextUtils#recordFunctionDeclarationToDescriptor(BindingTrace, PsiElement, SimpleFunctionDescriptor)} */
|
||||
WritableSlice<PsiElement, SimpleFunctionDescriptor> FUNCTION = Slices.<PsiElement, SimpleFunctionDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, ConstructorDescriptor> CONSTRUCTOR = Slices.<PsiElement, ConstructorDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, VariableDescriptor> VARIABLE = Slices.<PsiElement, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetParameter, VariableDescriptor> VALUE_PARAMETER = Slices.<JetParameter, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR = Slices.<JetPropertyAccessor, PropertyAccessorDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
|
||||
// normalize value to getOriginal(value)
|
||||
WritableSlice<PsiElement, PropertyDescriptor> PRIMARY_CONSTRUCTOR_PARAMETER = Slices.<PsiElement, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetObjectDeclarationName, PropertyDescriptor> OBJECT_DECLARATION = Slices.<JetObjectDeclarationName, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<PsiElement, PropertyDescriptor> PRIMARY_CONSTRUCTOR_PARAMETER = Slices.<PsiElement, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
WritableSlice<JetObjectDeclarationName, PropertyDescriptor> OBJECT_DECLARATION = Slices.<JetObjectDeclarationName, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||
|
||||
WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] {
|
||||
NAMESPACE, CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR, PRIMARY_CONSTRUCTOR_PARAMETER, OBJECT_DECLARATION
|
||||
|
||||
@@ -19,12 +19,19 @@ package org.jetbrains.jet.lang.resolve;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableAsFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
||||
import org.jetbrains.jet.util.slicedmap.Slices;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -34,6 +41,28 @@ public class BindingContextUtils {
|
||||
private BindingContextUtils() {
|
||||
}
|
||||
|
||||
private static final Slices.KeyNormalizer<DeclarationDescriptor> DECLARATION_DESCRIPTOR_NORMALIZER = new Slices.KeyNormalizer<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public DeclarationDescriptor normalize(DeclarationDescriptor declarationDescriptor) {
|
||||
if (declarationDescriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor callable = (CallableMemberDescriptor) declarationDescriptor;
|
||||
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
throw new IllegalStateException("non-declaration descriptors should be filtered out earler: " + callable);
|
||||
}
|
||||
}
|
||||
if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
|
||||
VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
|
||||
if (descriptor.getOriginal() != descriptor) {
|
||||
throw new IllegalStateException("original should be resolved earlier: " + descriptor);
|
||||
}
|
||||
}
|
||||
return declarationDescriptor.getOriginal();
|
||||
}
|
||||
};
|
||||
|
||||
static final ReadOnlySlice<DeclarationDescriptor, PsiElement> DESCRIPTOR_TO_DECLARATION =
|
||||
Slices.<DeclarationDescriptor, PsiElement>sliceBuilder().setKeyNormalizer(DECLARATION_DESCRIPTOR_NORMALIZER).build();
|
||||
|
||||
@Nullable
|
||||
public static PsiElement resolveToDeclarationPsiElement(@NotNull BindingContext bindingContext, @Nullable JetReferenceExpression referenceExpression) {
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression);
|
||||
@@ -83,10 +112,54 @@ public class BindingContextUtils {
|
||||
return context.get(BindingContext.FILE_TO_NAMESPACE, source);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement doGetDescriptorToDeclaration(@NotNull BindingContext context, @NotNull DeclarationDescriptor descriptor) {
|
||||
return context.get(DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
}
|
||||
|
||||
// NOTE this is also used by KDoc
|
||||
@Nullable
|
||||
public static PsiElement descriptorToDeclaration(@NotNull BindingContext context, @NotNull DeclarationDescriptor descriptor) {
|
||||
return context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
return callableDescriptorToDeclaration(context, (CallableMemberDescriptor) descriptor);
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
return classDescriptorToDeclaration(context, (ClassDescriptor) descriptor);
|
||||
}
|
||||
else {
|
||||
return doGetDescriptorToDeclaration(context, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement callableDescriptorToDeclaration(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) {
|
||||
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
Set<? extends CallableMemberDescriptor> overriddenDescriptors = callable.getOverriddenDescriptors();
|
||||
if (overriddenDescriptors.size() != 1) {
|
||||
// TODO evil code
|
||||
throw new IllegalStateException(
|
||||
"cannot find declaration: fake descriptor" +
|
||||
" has more then one overriden descriptor: " + callable);
|
||||
}
|
||||
|
||||
return callableDescriptorToDeclaration(context, overriddenDescriptors.iterator().next());
|
||||
}
|
||||
|
||||
return doGetDescriptorToDeclaration(context, callable.getOriginal());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement classDescriptorToDeclaration(@NotNull BindingContext context, @NotNull ClassDescriptor clazz) {
|
||||
return doGetDescriptorToDeclaration(context, clazz);
|
||||
}
|
||||
|
||||
public static void recordFunctionDeclarationToDescriptor(@NotNull BindingTrace trace,
|
||||
@NotNull PsiElement psiElement, @NotNull SimpleFunctionDescriptor function) {
|
||||
|
||||
if (function.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
throw new IllegalArgumentException("function of kind " + function.getKind() + " cannot have declaration");
|
||||
}
|
||||
|
||||
trace.record(BindingContext.FUNCTION, psiElement, function);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,10 +179,9 @@ public class DeclarationsChecker {
|
||||
return;
|
||||
}
|
||||
if (!(classDescriptor.getModality() == Modality.ABSTRACT) && classDescriptor.getKind() != ClassKind.ENUM_CLASS) {
|
||||
PsiElement classElement = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), classDescriptor);
|
||||
assert classElement instanceof JetClass;
|
||||
JetClass classElement = (JetClass) BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
|
||||
String name = property.getName();
|
||||
trace.report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(property, name != null ? name : "", classDescriptor, (JetClass) classElement));
|
||||
trace.report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(property, name != null ? name : "", classDescriptor, classElement));
|
||||
return;
|
||||
}
|
||||
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
||||
@@ -252,9 +251,8 @@ public class DeclarationsChecker {
|
||||
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
|
||||
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
|
||||
if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) {
|
||||
PsiElement classElement = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), classDescriptor);
|
||||
assert classElement instanceof JetClass;
|
||||
trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName(), classDescriptor, (JetClass) classElement));
|
||||
JetClass classElement = (JetClass) BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
|
||||
trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName(), classDescriptor, classElement));
|
||||
}
|
||||
if (hasAbstractModifier && inTrait) {
|
||||
trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(function));
|
||||
|
||||
@@ -230,7 +230,7 @@ public class DescriptorResolver {
|
||||
visibility,
|
||||
isInline);
|
||||
|
||||
trace.record(BindingContext.FUNCTION, function, functionDescriptor);
|
||||
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.DESCRIPTOR_TO_DECLARATION;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
|
||||
@@ -350,7 +350,7 @@ public class TypeHierarchyResolver {
|
||||
if (!found) continue;
|
||||
|
||||
ClassDescriptor superclass = (i < size - 1) ? currentPath.get(i + 1) : current;
|
||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), classDescriptor);
|
||||
PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
|
||||
|
||||
PsiElement elementToMark = null;
|
||||
if (psiElement instanceof JetClassOrObject) {
|
||||
@@ -410,10 +410,8 @@ public class TypeHierarchyResolver {
|
||||
if (conflictingTypes.size() > 1) {
|
||||
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
||||
assert containingDeclaration instanceof ClassDescriptor : containingDeclaration;
|
||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), mutableClassDescriptor);
|
||||
assert psiElement instanceof JetClassOrObject : psiElement;
|
||||
JetClassOrObject declaration = (JetClassOrObject) psiElement;
|
||||
JetDelegationSpecifierList delegationSpecifierList = declaration.getDelegationSpecifierList();
|
||||
JetClassOrObject psiElement = (JetClassOrObject) BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), mutableClassDescriptor);
|
||||
JetDelegationSpecifierList delegationSpecifierList = psiElement.getDelegationSpecifierList();
|
||||
assert delegationSpecifierList != null;
|
||||
// trace.getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + " has inconsistent values: " + conflictingTypes);
|
||||
trace.report(INCONSISTENT_TYPE_PARAMETER_VALUES.on(delegationSpecifierList, typeParameterDescriptor, (ClassDescriptor) containingDeclaration, conflictingTypes));
|
||||
|
||||
+2
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
@@ -155,6 +156,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
|
||||
/*isInline = */ false
|
||||
);
|
||||
context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor);
|
||||
BindingContextUtils.recordFunctionDeclarationToDescriptor(context.trace, expression, functionDescriptor);
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -473,12 +473,12 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
if (expression.getTargetLabel() == null) {
|
||||
if (containingFunctionDescriptor != null) {
|
||||
PsiElement containingFunction = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), containingFunctionDescriptor);
|
||||
PsiElement containingFunction = BindingContextUtils.callableDescriptorToDeclaration(context.trace.getBindingContext(), containingFunctionDescriptor);
|
||||
assert containingFunction != null;
|
||||
if (containingFunction instanceof JetFunctionLiteralExpression) {
|
||||
do {
|
||||
containingFunctionDescriptor = DescriptorUtils.getParentOfType(containingFunctionDescriptor, FunctionDescriptor.class);
|
||||
containingFunction = containingFunctionDescriptor != null ? BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), containingFunctionDescriptor) : null;
|
||||
containingFunction = containingFunctionDescriptor != null ? BindingContextUtils.callableDescriptorToDeclaration(context.trace.getBindingContext(), containingFunctionDescriptor) : null;
|
||||
} while (containingFunction instanceof JetFunctionLiteralExpression);
|
||||
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
|
||||
}
|
||||
|
||||
-1
@@ -45,7 +45,6 @@ import java.util.Collection;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.DESCRIPTOR_TO_DECLARATION;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE_REASSIGNMENT;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user