Support navigation to dangling annotations in the IDE
This commit is contained in:
@@ -62,7 +62,8 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
|
|
||||||
private final MemoizedFunctionToNotNull<JetScript, LazyScriptDescriptor> scriptDescriptors;
|
private final MemoizedFunctionToNotNull<JetScript, LazyScriptDescriptor> scriptDescriptors;
|
||||||
|
|
||||||
private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> annotations;
|
private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> fileAnnotations;
|
||||||
|
private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> danglingAnnotations;
|
||||||
|
|
||||||
private ScopeProvider scopeProvider;
|
private ScopeProvider scopeProvider;
|
||||||
|
|
||||||
@@ -168,14 +169,25 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
annotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() {
|
fileAnnotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() {
|
||||||
@Override
|
@Override
|
||||||
public LazyAnnotations invoke(JetFile file) {
|
public LazyAnnotations invoke(JetFile file) {
|
||||||
JetScope scope = getScopeProvider().getFileScope(file);
|
return createAnnotations(file, file.getAnnotationEntries());
|
||||||
LazyAnnotationsContextImpl lazyAnnotationContext = new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope);
|
|
||||||
return new LazyAnnotations(lazyAnnotationContext, file.getAnnotationEntries());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
danglingAnnotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() {
|
||||||
|
@Override
|
||||||
|
public LazyAnnotations invoke(JetFile file) {
|
||||||
|
return createAnnotations(file, file.getDanglingAnnotations());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private LazyAnnotations createAnnotations(JetFile file, List<JetAnnotationEntry> annotationEntries) {
|
||||||
|
JetScope scope = getScopeProvider().getFileScope(file);
|
||||||
|
LazyAnnotationsContextImpl lazyAnnotationContext = new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope);
|
||||||
|
return new LazyAnnotations(lazyAnnotationContext, annotationEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -448,7 +460,12 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Annotations getFileAnnotations(@NotNull JetFile file) {
|
public Annotations getFileAnnotations(@NotNull JetFile file) {
|
||||||
return annotations.invoke(file);
|
return fileAnnotations.invoke(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Annotations getDanglingAnnotations(@NotNull JetFile file) {
|
||||||
|
return danglingAnnotations.invoke(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+29
-14
@@ -85,6 +85,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
private final boolean isInner;
|
private final boolean isInner;
|
||||||
|
|
||||||
private final Annotations annotations;
|
private final Annotations annotations;
|
||||||
|
private final Annotations danglingAnnotations;
|
||||||
private final NullableLazyValue<LazyClassDescriptor> classObjectDescriptor;
|
private final NullableLazyValue<LazyClassDescriptor> classObjectDescriptor;
|
||||||
private final MemoizedFunctionToNotNull<JetClassObject, ClassDescriptor> extraClassObjectDescriptors;
|
private final MemoizedFunctionToNotNull<JetClassObject, ClassDescriptor> extraClassObjectDescriptors;
|
||||||
|
|
||||||
@@ -95,8 +96,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
private final NotNullLazyValue<JetScope> scopeForMemberDeclarationResolution;
|
private final NotNullLazyValue<JetScope> scopeForMemberDeclarationResolution;
|
||||||
private final NotNullLazyValue<JetScope> scopeForPropertyInitializerResolution;
|
private final NotNullLazyValue<JetScope> scopeForPropertyInitializerResolution;
|
||||||
|
|
||||||
private final NullableLazyValue<Void> resolveDanglingAnnotations;
|
|
||||||
|
|
||||||
private final NullableLazyValue<Void> forceResolveAllContents;
|
private final NullableLazyValue<Void> forceResolveAllContents;
|
||||||
|
|
||||||
public LazyClassDescriptor(
|
public LazyClassDescriptor(
|
||||||
@@ -144,7 +143,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
this.annotations = new LazyAnnotations(
|
this.annotations = new LazyAnnotations(
|
||||||
new LazyAnnotationsContext(
|
new LazyAnnotationsContext(
|
||||||
resolveSession.getAnnotationResolver(),
|
resolveSession.getAnnotationResolver(),
|
||||||
resolveSession.getStorageManager(),
|
storageManager,
|
||||||
resolveSession.getTrace()
|
resolveSession.getTrace()
|
||||||
) {
|
) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -162,6 +161,27 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
this.annotations = Annotations.EMPTY;
|
this.annotations = Annotations.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<JetAnnotationEntry> jetDanglingAnnotations = classLikeInfo.getDanglingAnnotations();
|
||||||
|
if (jetDanglingAnnotations.isEmpty()) {
|
||||||
|
this.danglingAnnotations = Annotations.EMPTY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.danglingAnnotations = new LazyAnnotations(
|
||||||
|
new LazyAnnotationsContext(
|
||||||
|
resolveSession.getAnnotationResolver(),
|
||||||
|
storageManager,
|
||||||
|
resolveSession.getTrace()
|
||||||
|
) {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetScope getScope() {
|
||||||
|
return getScopeForMemberDeclarationResolution();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jetDanglingAnnotations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.classObjectDescriptor = storageManager.createNullableLazyValue(new Function0<LazyClassDescriptor>() {
|
this.classObjectDescriptor = storageManager.createNullableLazyValue(new Function0<LazyClassDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public LazyClassDescriptor invoke() {
|
public LazyClassDescriptor invoke() {
|
||||||
@@ -192,15 +212,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
return computeScopeForPropertyInitializerResolution();
|
return computeScopeForPropertyInitializerResolution();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.resolveDanglingAnnotations = storageManager.createNullableLazyValue(new Function0<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void invoke() {
|
|
||||||
resolveSession.getAnnotationResolver().resolveAnnotationsWithArguments(
|
|
||||||
getScopeForMemberDeclarationResolution(), originalClassInfo.getDanglingAnnotations(), resolveSession.getTrace()
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(new Function0<Void>() {
|
this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(new Function0<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void invoke() {
|
public Void invoke() {
|
||||||
@@ -431,6 +442,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Annotations getDanglingAnnotations() {
|
||||||
|
return danglingAnnotations;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
// not using descriptor render to preserve laziness
|
// not using descriptor render to preserve laziness
|
||||||
@@ -458,8 +474,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
// Note: headers of member classes' members are not resolved
|
// Note: headers of member classes' members are not resolved
|
||||||
public void resolveMemberHeaders() {
|
public void resolveMemberHeaders() {
|
||||||
ForceResolveUtil.forceResolveAllContents(getAnnotations());
|
ForceResolveUtil.forceResolveAllContents(getAnnotations());
|
||||||
|
ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());
|
||||||
resolveDanglingAnnotations.invoke();
|
|
||||||
|
|
||||||
getClassObjectDescriptor();
|
getClassObjectDescriptor();
|
||||||
|
|
||||||
|
|||||||
@@ -287,24 +287,25 @@ public abstract class ElementResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) {
|
private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) {
|
||||||
Annotations annotations = null;
|
|
||||||
|
|
||||||
JetModifierList modifierList = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetModifierList.class);
|
JetModifierList modifierList = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetModifierList.class);
|
||||||
JetDeclaration declaration = PsiTreeUtil.getParentOfType(modifierList, JetDeclaration.class);
|
JetDeclaration declaration = PsiTreeUtil.getParentOfType(modifierList, JetDeclaration.class);
|
||||||
if (declaration != null) {
|
if (declaration != null) {
|
||||||
annotations = getAnnotationsByDeclaration(resolveSession, modifierList, declaration);
|
doResolveAnnotations(resolveSession, getAnnotationsByDeclaration(resolveSession, modifierList, declaration));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetFileAnnotationList fileAnnotationList = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetFileAnnotationList.class);
|
JetFileAnnotationList fileAnnotationList = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetFileAnnotationList.class);
|
||||||
if (fileAnnotationList != null) {
|
if (fileAnnotationList != null) {
|
||||||
annotations = resolveSession.getFileAnnotations(fileAnnotationList.getContainingJetFile());
|
doResolveAnnotations(resolveSession, resolveSession.getFileAnnotations(fileAnnotationList.getContainingJetFile()));
|
||||||
|
}
|
||||||
|
if (modifierList != null && modifierList.getParent() instanceof JetFile) {
|
||||||
|
doResolveAnnotations(resolveSession, resolveSession.getDanglingAnnotations(modifierList.getContainingJetFile()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (annotations != null) {
|
private static void doResolveAnnotations(ResolveSession resolveSession, Annotations annotations) {
|
||||||
AnnotationResolver.resolveAnnotationsArguments(annotations, resolveSession.getTrace());
|
AnnotationResolver.resolveAnnotationsArguments(annotations, resolveSession.getTrace());
|
||||||
ForceResolveUtil.forceResolveAllContents(annotations);
|
ForceResolveUtil.forceResolveAllContents(annotations);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Annotations getAnnotationsByDeclaration(
|
private static Annotations getAnnotationsByDeclaration(
|
||||||
@@ -312,13 +313,21 @@ public abstract class ElementResolver {
|
|||||||
JetModifierList modifierList,
|
JetModifierList modifierList,
|
||||||
JetDeclaration declaration
|
JetDeclaration declaration
|
||||||
) {
|
) {
|
||||||
Annotations annotations;Annotated descriptor = resolveSession.resolveToDescriptor(declaration);
|
Annotated descriptor = resolveSession.resolveToDescriptor(declaration);
|
||||||
if (declaration instanceof JetClass && modifierList == ((JetClass) declaration).getPrimaryConstructorModifierList()) {
|
if (declaration instanceof JetClass) {
|
||||||
descriptor = ((ClassDescriptor)descriptor).getUnsubstitutedPrimaryConstructor();
|
JetClass jetClass = (JetClass) declaration;
|
||||||
assert descriptor != null : "No constructor found: " + declaration.getText();
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||||
|
if (modifierList == jetClass.getPrimaryConstructorModifierList()) {
|
||||||
|
descriptor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
|
assert descriptor != null : "No constructor found: " + declaration.getText();
|
||||||
|
}
|
||||||
|
else if (modifierList.getParent() == jetClass.getBody()) {
|
||||||
|
if (classDescriptor instanceof LazyClassDescriptor) {
|
||||||
|
return ((LazyClassDescriptor) classDescriptor).getDanglingAnnotations();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
annotations = descriptor.getAnnotations();
|
return descriptor.getAnnotations();
|
||||||
return annotations;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void typeParameterAdditionalResolve(KotlinCodeAnalyzer analyzer, JetTypeParameter typeParameter) {
|
private static void typeParameterAdditionalResolve(KotlinCodeAnalyzer analyzer, JetTypeParameter typeParameter) {
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ public abstract class AbstractJetReference<T : JetElement>(element: T)
|
|||||||
override fun isSoft(): Boolean = false
|
override fun isSoft(): Boolean = false
|
||||||
|
|
||||||
private fun resolveToPsiElements(): Collection<PsiElement> {
|
private fun resolveToPsiElements(): Collection<PsiElement> {
|
||||||
return resolveToPsiElements(expression.analyze(), getTargetDescriptors(expression.analyze()))
|
val bindingContext = expression.analyze()
|
||||||
|
return resolveToPsiElements(bindingContext, getTargetDescriptors(bindingContext))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resolveToDescriptors(): Collection<DeclarationDescriptor> {
|
override fun resolveToDescriptors(): Collection<DeclarationDescriptor> {
|
||||||
|
|||||||
Reference in New Issue
Block a user