Resolve dangling annotations in files and class bodies
This commit is contained in:
@@ -19,6 +19,8 @@ package org.jetbrains.jet.lang.psi;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
@@ -83,4 +85,19 @@ public class JetClassBody extends JetElementImplStub<KotlinPlaceHolderStub<JetCl
|
||||
ASTNode[] children = getNode().getChildren(TokenSet.create(JetTokens.LBRACE));
|
||||
return children.length == 1 ? children[0].getPsi() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return annotations that do not belong to any declaration due to incomplete code or syntax errors
|
||||
*/
|
||||
@NotNull
|
||||
public List<JetAnnotationEntry> getDanglingAnnotations() {
|
||||
return KotlinPackage.flatMap(
|
||||
findChildrenByClass(JetModifierList.class),
|
||||
new Function1<JetModifierList, Iterable<JetAnnotationEntry>>() {
|
||||
@Override
|
||||
public Iterable<JetAnnotationEntry> invoke(JetModifierList modifierList) {
|
||||
return modifierList.getAnnotationEntries();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import com.intellij.psi.PsiClassOwner;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
@@ -237,4 +239,19 @@ public class JetFile extends PsiFileBase implements JetDeclarationContainer, Jet
|
||||
|
||||
return fileAnnotationList.getAnnotationEntries();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return annotations that do not belong to any declaration due to incomplete code or syntax errors
|
||||
*/
|
||||
@NotNull
|
||||
public List<JetAnnotationEntry> getDanglingAnnotations() {
|
||||
return KotlinPackage.flatMap(
|
||||
findChildrenByClass(JetModifierList.class),
|
||||
new Function1<JetModifierList, Iterable<JetAnnotationEntry>>() {
|
||||
@Override
|
||||
public Iterable<JetAnnotationEntry> invoke(JetModifierList modifierList) {
|
||||
return modifierList.getAnnotationEntries();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,13 +51,9 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.REDECLARATION;
|
||||
import static org.jetbrains.jet.lang.resolve.ScriptHeaderResolver.resolveScriptDeclarations;
|
||||
|
||||
public class DeclarationResolver {
|
||||
@NotNull
|
||||
private AnnotationResolver annotationResolver;
|
||||
@NotNull
|
||||
private ImportsResolver importsResolver;
|
||||
@NotNull
|
||||
private DescriptorResolver descriptorResolver;
|
||||
@NotNull
|
||||
private BindingTrace trace;
|
||||
|
||||
|
||||
@@ -87,6 +83,7 @@ public class DeclarationResolver {
|
||||
resolveConstructorHeaders(c);
|
||||
resolveAnnotationStubsOnClassesAndConstructors(c);
|
||||
resolveFunctionAndPropertyHeaders(c);
|
||||
resolveDanglingAnnotationsInClasses(c);
|
||||
resolveAnnotationsOnFiles(c.getFileScopes());
|
||||
|
||||
// SCRIPT: Resolve script declarations
|
||||
@@ -115,6 +112,7 @@ public class DeclarationResolver {
|
||||
JetFile file = entry.getKey();
|
||||
JetScope fileScope = entry.getValue();
|
||||
annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getAnnotationEntries(), trace);
|
||||
annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getDanglingAnnotations(), trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +220,19 @@ public class DeclarationResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveDanglingAnnotationsInClasses(TopDownAnalysisContext c) {
|
||||
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
|
||||
JetClassBody body = entry.getKey().getBody();
|
||||
if (body != null) {
|
||||
annotationResolver.resolveAnnotationsWithArguments(
|
||||
entry.getValue().getScopeForMemberDeclarationResolution(),
|
||||
body.getDanglingAnnotations(),
|
||||
trace
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createFunctionsForDataClasses(@NotNull TopDownAnalysisContext c) {
|
||||
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
|
||||
JetClassOrObject klass = entry.getKey();
|
||||
|
||||
@@ -44,41 +44,23 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.MANY_CLASS_OBJECTS;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.UNSUPPORTED;
|
||||
|
||||
public class LazyTopDownAnalyzer {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private BindingTrace trace = null;
|
||||
private BindingTrace trace;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private DeclarationResolver declarationResolver = null;
|
||||
private DeclarationResolver declarationResolver;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private OverrideResolver overrideResolver = null;
|
||||
private OverrideResolver overrideResolver;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private OverloadResolver overloadResolver = null;
|
||||
private OverloadResolver overloadResolver;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private VarianceChecker varianceChecker = null;
|
||||
private VarianceChecker varianceChecker;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private ModuleDescriptor moduleDescriptor = null;
|
||||
private ModuleDescriptor moduleDescriptor;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private KotlinCodeAnalyzer resolveSession = null;
|
||||
private KotlinCodeAnalyzer resolveSession;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private BodyResolver bodyResolver = null;
|
||||
private BodyResolver bodyResolver;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NotNull
|
||||
private TopDownAnalyzer topDownAnalyzer = null;
|
||||
private TopDownAnalyzer topDownAnalyzer;
|
||||
|
||||
@Inject
|
||||
public void setKotlinCodeAnalyzer(@NotNull KotlinCodeAnalyzer kotlinCodeAnalyzer) {
|
||||
|
||||
@@ -57,4 +57,6 @@ public interface JetClassLikeInfo extends JetDeclarationContainer {
|
||||
@NotNull
|
||||
ClassKind getClassKind();
|
||||
|
||||
@NotNull
|
||||
List<JetAnnotationEntry> getDanglingAnnotations();
|
||||
}
|
||||
|
||||
+7
@@ -77,6 +77,13 @@ public abstract class JetClassOrObjectInfo<E extends JetClassOrObject> implement
|
||||
throw new IllegalArgumentException("Not in a JetFile: " + element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetAnnotationEntry> getDanglingAnnotations() {
|
||||
JetClassBody body = element.getBody();
|
||||
return body == null ? Collections.<JetAnnotationEntry>emptyList() : body.getDanglingAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "info for " + element.getText();
|
||||
|
||||
@@ -36,6 +36,7 @@ public class JetScriptInfo(
|
||||
override fun getClassKind() = ClassKind.CLASS
|
||||
override fun getDeclarations() = script.getDeclarations()
|
||||
.filter(::shouldBeScriptClassMember)
|
||||
override fun getDanglingAnnotations() = listOf<JetAnnotationEntry>()
|
||||
}
|
||||
|
||||
public fun shouldBeScriptClassMember(declaration: JetDeclaration): Boolean {
|
||||
|
||||
+6
@@ -96,6 +96,12 @@ public class SyntheticClassObjectInfo implements JetClassLikeInfo {
|
||||
return ClassKind.CLASS_OBJECT;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetAnnotationEntry> getDanglingAnnotations() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetDeclaration> getDeclarations() {
|
||||
|
||||
+13
@@ -95,6 +95,8 @@ 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(
|
||||
@@ -190,6 +192,15 @@ 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() {
|
||||
@@ -448,6 +459,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
public void resolveMemberHeaders() {
|
||||
ForceResolveUtil.forceResolveAllContents(getAnnotations());
|
||||
|
||||
resolveDanglingAnnotations.invoke();
|
||||
|
||||
getClassObjectDescriptor();
|
||||
|
||||
getDescriptorsForExtraClassObjects();
|
||||
|
||||
Reference in New Issue
Block a user