diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java index 4c41659151c..677463f7927 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java @@ -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) { diff --git a/idea/testData/resolve/references/ClassInTypeConstraint.kt b/idea/testData/resolve/references/ClassInTypeConstraint.kt new file mode 100644 index 00000000000..5f960ed54f3 --- /dev/null +++ b/idea/testData/resolve/references/ClassInTypeConstraint.kt @@ -0,0 +1,6 @@ +package resolve + +open class AA {} +class BBAA> {} + +// REF: (resolve).AA \ No newline at end of file diff --git a/idea/testData/resolve/references/ReferenceInClassWhereConstraint.kt b/idea/testData/resolve/references/ReferenceInClassWhereConstraint.kt new file mode 100644 index 00000000000..ca73fff0dc3 --- /dev/null +++ b/idea/testData/resolve/references/ReferenceInClassWhereConstraint.kt @@ -0,0 +1,7 @@ +package test + +class A + +class Some where T: A + +// REF: (test).A \ No newline at end of file diff --git a/idea/testData/resolve/references/ReferenceInFunWhereConstraint.kt b/idea/testData/resolve/references/ReferenceInFunWhereConstraint.kt new file mode 100644 index 00000000000..e55be8d60ba --- /dev/null +++ b/idea/testData/resolve/references/ReferenceInFunWhereConstraint.kt @@ -0,0 +1,7 @@ +package test + +class A + +fun some() where T: A {} + +// REF: (test).A \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java index 2b7d5d78ac8..cbede45901f 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java @@ -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");