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<JetFile, LazyAnnotations> annotations;
|
||||
private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> fileAnnotations;
|
||||
private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> danglingAnnotations;
|
||||
|
||||
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
|
||||
public LazyAnnotations invoke(JetFile file) {
|
||||
JetScope scope = getScopeProvider().getFileScope(file);
|
||||
LazyAnnotationsContextImpl lazyAnnotationContext = new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope);
|
||||
return new LazyAnnotations(lazyAnnotationContext, file.getAnnotationEntries());
|
||||
return createAnnotations(file, 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
|
||||
@@ -448,7 +460,12 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
||||
|
||||
@NotNull
|
||||
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
|
||||
|
||||
+29
-14
@@ -85,6 +85,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
private final boolean isInner;
|
||||
|
||||
private final Annotations annotations;
|
||||
private final Annotations danglingAnnotations;
|
||||
private final NullableLazyValue<LazyClassDescriptor> classObjectDescriptor;
|
||||
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> scopeForPropertyInitializerResolution;
|
||||
|
||||
private final NullableLazyValue<Void> resolveDanglingAnnotations;
|
||||
|
||||
private final NullableLazyValue<Void> forceResolveAllContents;
|
||||
|
||||
public LazyClassDescriptor(
|
||||
@@ -144,7 +143,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
this.annotations = new LazyAnnotations(
|
||||
new LazyAnnotationsContext(
|
||||
resolveSession.getAnnotationResolver(),
|
||||
resolveSession.getStorageManager(),
|
||||
storageManager,
|
||||
resolveSession.getTrace()
|
||||
) {
|
||||
@NotNull
|
||||
@@ -162,6 +161,27 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
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>() {
|
||||
@Override
|
||||
public LazyClassDescriptor invoke() {
|
||||
@@ -192,15 +212,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
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>() {
|
||||
@Override
|
||||
public Void invoke() {
|
||||
@@ -431,6 +442,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Annotations getDanglingAnnotations() {
|
||||
return danglingAnnotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// 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
|
||||
public void resolveMemberHeaders() {
|
||||
ForceResolveUtil.forceResolveAllContents(getAnnotations());
|
||||
|
||||
resolveDanglingAnnotations.invoke();
|
||||
ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());
|
||||
|
||||
getClassObjectDescriptor();
|
||||
|
||||
|
||||
@@ -287,24 +287,25 @@ public abstract class ElementResolver {
|
||||
}
|
||||
|
||||
private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) {
|
||||
Annotations annotations = null;
|
||||
|
||||
JetModifierList modifierList = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetModifierList.class);
|
||||
JetDeclaration declaration = PsiTreeUtil.getParentOfType(modifierList, JetDeclaration.class);
|
||||
if (declaration != null) {
|
||||
annotations = getAnnotationsByDeclaration(resolveSession, modifierList, declaration);
|
||||
doResolveAnnotations(resolveSession, getAnnotationsByDeclaration(resolveSession, modifierList, declaration));
|
||||
}
|
||||
else {
|
||||
JetFileAnnotationList fileAnnotationList = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetFileAnnotationList.class);
|
||||
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) {
|
||||
AnnotationResolver.resolveAnnotationsArguments(annotations, resolveSession.getTrace());
|
||||
ForceResolveUtil.forceResolveAllContents(annotations);
|
||||
}
|
||||
private static void doResolveAnnotations(ResolveSession resolveSession, Annotations annotations) {
|
||||
AnnotationResolver.resolveAnnotationsArguments(annotations, resolveSession.getTrace());
|
||||
ForceResolveUtil.forceResolveAllContents(annotations);
|
||||
}
|
||||
|
||||
private static Annotations getAnnotationsByDeclaration(
|
||||
@@ -312,13 +313,21 @@ public abstract class ElementResolver {
|
||||
JetModifierList modifierList,
|
||||
JetDeclaration declaration
|
||||
) {
|
||||
Annotations annotations;Annotated descriptor = resolveSession.resolveToDescriptor(declaration);
|
||||
if (declaration instanceof JetClass && modifierList == ((JetClass) declaration).getPrimaryConstructorModifierList()) {
|
||||
descriptor = ((ClassDescriptor)descriptor).getUnsubstitutedPrimaryConstructor();
|
||||
assert descriptor != null : "No constructor found: " + declaration.getText();
|
||||
Annotated descriptor = resolveSession.resolveToDescriptor(declaration);
|
||||
if (declaration instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) declaration;
|
||||
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 annotations;
|
||||
return descriptor.getAnnotations();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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> {
|
||||
|
||||
Reference in New Issue
Block a user