Make resolve session be able to resolve class constructor parameters

This commit is contained in:
Nikolay Krasko
2013-07-11 17:17:41 +04:00
parent 27efc3b202
commit 9167e4f1ee
5 changed files with 83 additions and 18 deletions
@@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.util.QualifiedNamesUtil;
import java.util.*;
@@ -118,41 +119,49 @@ public class ResolveSessionUtils {
@NotNull ResolveSession resolveSession,
@NotNull JetElement jetElement
) {
DelegatingBindingTrace trace = new DelegatingBindingTrace(
resolveSession.getBindingContext(), "trace to resolve jetElement", jetElement);
// All additional resolve should be done to separate trace
DelegatingBindingTrace trace = new DelegatingBindingTrace(resolveSession.getBindingContext(), "trace to resolve element", jetElement);
@SuppressWarnings("unchecked")
PsiElement topmostCandidateForAdditionalResolve = JetPsiUtil.getTopmostParentOfTypes(jetElement,
PsiElement resolveElement = JetPsiUtil.getTopmostParentOfTypes(jetElement,
JetNamedFunction.class, JetClassInitializer.class,
JetProperty.class, JetDelegationSpecifierList.class,
JetImportDirective.class, JetAnnotationEntry.class);
JetImportDirective.class, JetAnnotationEntry.class,
JetTypeParameter.class, JetTypeConstraint.class);
if (topmostCandidateForAdditionalResolve != null) {
if (resolveElement != null) {
JetFile file = (JetFile) jetElement.getContainingFile();
if (topmostCandidateForAdditionalResolve instanceof JetNamedFunction) {
functionAdditionalResolve(resolveSession, (JetNamedFunction) topmostCandidateForAdditionalResolve, trace, file);
if (resolveElement instanceof JetNamedFunction) {
functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file);
}
else if (topmostCandidateForAdditionalResolve instanceof JetClassInitializer) {
initializerAdditionalResolve(resolveSession, (JetClassInitializer) topmostCandidateForAdditionalResolve, trace, file);
else if (resolveElement instanceof JetClassInitializer) {
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file);
}
else if (topmostCandidateForAdditionalResolve instanceof JetProperty) {
propertyAdditionalResolve(resolveSession, (JetProperty) topmostCandidateForAdditionalResolve, trace, file);
else if (resolveElement instanceof JetProperty) {
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file);
}
else if (topmostCandidateForAdditionalResolve instanceof JetDelegationSpecifierList) {
delegationSpecifierAdditionalResolve(resolveSession, (JetDelegationSpecifierList) topmostCandidateForAdditionalResolve,
else if (resolveElement instanceof JetDelegationSpecifierList) {
delegationSpecifierAdditionalResolve(resolveSession, (JetDelegationSpecifierList) resolveElement,
trace, file);
}
else if (topmostCandidateForAdditionalResolve instanceof JetImportDirective) {
JetImportDirective importDirective = (JetImportDirective) topmostCandidateForAdditionalResolve;
else if (resolveElement instanceof JetImportDirective) {
JetImportDirective importDirective = (JetImportDirective) resolveElement;
JetScope scope = resolveSession.getInjector().getScopeProvider().getFileScope((JetFile) importDirective.getContainingFile());
// Get all descriptors to force resolving all imports
scope.getAllDescriptors();
}
else if (topmostCandidateForAdditionalResolve instanceof JetAnnotationEntry) {
annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) topmostCandidateForAdditionalResolve);
else if (resolveElement instanceof JetAnnotationEntry) {
annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) resolveElement);
return resolveSession.getBindingContext();
}
else if (resolveElement instanceof JetTypeParameter) {
typeParameterAdditionalResolve(resolveSession, (JetTypeParameter) resolveElement);
return resolveSession.getBindingContext();
}
else if (resolveElement instanceof JetTypeConstraint) {
typeConstraintAdditionalResolve(resolveSession, jetElement);
return resolveSession.getBindingContext();
}
else {
@@ -176,6 +185,19 @@ public class ResolveSessionUtils {
return trace.getBindingContext();
}
private static void typeConstraintAdditionalResolve(KotlinCodeAnalyzer analyzer, JetElement jetElement) {
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetElement, JetDeclaration.class);
DeclarationDescriptor descriptor = analyzer.resolveToDescriptor(declaration);
assert (descriptor instanceof ClassDescriptor);
TypeConstructor constructor = ((ClassDescriptor) descriptor).getTypeConstructor();
for (TypeParameterDescriptor parameterDescriptor : constructor.getParameters()) {
LazyDescriptor lazyDescriptor = (LazyDescriptor) parameterDescriptor;
lazyDescriptor.forceResolveAllContents();
}
}
private static void annotationAdditionalResolve(KotlinCodeAnalyzer analyzer, JetAnnotationEntry jetAnnotationEntry) {
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetDeclaration.class);
if (declaration != null) {
@@ -186,6 +208,14 @@ public class ResolveSessionUtils {
}
}
private static void typeParameterAdditionalResolve(KotlinCodeAnalyzer analyzer, JetTypeParameter typeParameter) {
DeclarationDescriptor descriptor = analyzer.resolveToDescriptor(typeParameter);
assert descriptor instanceof LazyDescriptor;
LazyDescriptor parameterDescriptor = (LazyDescriptor) descriptor;
parameterDescriptor.forceResolveAllContents();
}
private static void delegationSpecifierAdditionalResolve(
KotlinCodeAnalyzer analyzer,
JetDelegationSpecifierList specifier, DelegatingBindingTrace trace, JetFile file) {
@@ -0,0 +1,6 @@
package resolve
open class AA {}
class BB<T : <caret>AA> {}
// REF: (resolve).AA
@@ -0,0 +1,7 @@
package test
class A
class Some<T> where T: <caret>A
// REF: (test).A
@@ -0,0 +1,7 @@
package test
class A
fun <T> some() where T: <caret>A {}
// REF: (test).A
@@ -56,6 +56,11 @@ public class ReferenceResolveTestGenerated extends AbstractResolveBaseTest {
doTest("idea/testData/resolve/references/AnnotationTypeParameter.kt");
}
@TestMetadata("ClassInTypeConstraint.kt")
public void testClassInTypeConstraint() throws Exception {
doTest("idea/testData/resolve/references/ClassInTypeConstraint.kt");
}
@TestMetadata("ClassReferenceInImport.kt")
public void testClassReferenceInImport() throws Exception {
doTest("idea/testData/resolve/references/ClassReferenceInImport.kt");
@@ -71,6 +76,16 @@ public class ReferenceResolveTestGenerated extends AbstractResolveBaseTest {
doTest("idea/testData/resolve/references/PackageReferenceInImport.kt");
}
@TestMetadata("ReferenceInClassWhereConstraint.kt")
public void testReferenceInClassWhereConstraint() throws Exception {
doTest("idea/testData/resolve/references/ReferenceInClassWhereConstraint.kt");
}
@TestMetadata("ReferenceInFunWhereConstraint.kt")
public void testReferenceInFunWhereConstraint() throws Exception {
doTest("idea/testData/resolve/references/ReferenceInFunWhereConstraint.kt");
}
@TestMetadata("ResolveClass.kt")
public void testResolveClass() throws Exception {
doTest("idea/testData/resolve/references/ResolveClass.kt");