diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 99e8fb35b56..1bb366edf63 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -152,12 +152,21 @@ public class BodyResolver { } } - private void resolveDelegationSpecifierList(final JetClassOrObject jetClass, final MutableClassDescriptor descriptor) { + private void resolveDelegationSpecifierList(JetClassOrObject jetClass, final MutableClassDescriptor descriptor) { + resolveDelegationSpecifierList(jetClass, descriptor, + descriptor.getUnsubstitutedPrimaryConstructor(), + descriptor.getScopeForSupertypeResolution(), + descriptor.getScopeForMemberResolution()); + } + + public void resolveDelegationSpecifierList(@NotNull final JetClassOrObject jetClass, @NotNull final ClassDescriptor descriptor, + @Nullable final ConstructorDescriptor primaryConstructor, + @NotNull JetScope scopeForSupertypeResolution, + @NotNull final JetScope scopeForMemberResolution) { if (!context.completeAnalysisNeeded(jetClass)) return; - final ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor(); final JetScope scopeForConstructor = primaryConstructor == null ? null - : FunctionDescriptorUtil.getFunctionInnerScope(descriptor.getScopeForSupertypeResolution(), primaryConstructor, trace); + : FunctionDescriptorUtil.getFunctionInnerScope(scopeForSupertypeResolution, primaryConstructor, trace); final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow final Map supertypes = Maps.newLinkedHashMap(); @@ -186,7 +195,7 @@ public class BodyResolver { JetExpression delegateExpression = specifier.getDelegateExpression(); if (delegateExpression != null) { JetScope scope = scopeForConstructor == null - ? descriptor.getScopeForMemberResolution() + ? scopeForMemberResolution : scopeForConstructor; JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, trace); if (type != null && supertype != null && !JetTypeChecker.INSTANCE.isSubtypeOf(type, supertype)) { @@ -204,7 +213,7 @@ public class BodyResolver { } JetTypeReference typeReference = call.getTypeReference(); if (typeReference == null) return; - if (descriptor.getUnsubstitutedPrimaryConstructor() == null) { + if (primaryConstructor == null) { assert descriptor.getKind() == ClassKind.TRAIT; recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference)); return; @@ -277,7 +286,11 @@ public class BodyResolver { } // allowedFinalSupertypes typically contains a enum type of which supertypeOwner is an entry - private void checkSupertypeList(@NotNull MutableClassDescriptor supertypeOwner, @NotNull Map supertypes, Set allowedFinalSupertypes) { + private void checkSupertypeList( + @NotNull ClassDescriptor supertypeOwner, + @NotNull Map supertypes, + @NotNull Set allowedFinalSupertypes + ) { Set typeConstructors = Sets.newHashSet(); boolean classAppeared = false; for (Map.Entry entry : supertypes.entrySet()) { 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 9575e09b90d..1ee8fc80d8f 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 @@ -105,7 +105,7 @@ public class ResolveSessionUtils { @SuppressWarnings("unchecked") PsiElement topmostCandidateForAdditionalResolve = JetPsiUtil.getTopmostParentOfTypes(expression, - JetNamedFunction.class, JetClassInitializer.class, JetProperty.class); + JetNamedFunction.class, JetClassInitializer.class, JetProperty.class, JetDelegationSpecifierList.class); if (topmostCandidateForAdditionalResolve != null) { if (topmostCandidateForAdditionalResolve instanceof JetNamedFunction) { @@ -117,6 +117,10 @@ public class ResolveSessionUtils { else if (topmostCandidateForAdditionalResolve instanceof JetProperty) { propertyAdditionalResolve(resolveSession, (JetProperty) topmostCandidateForAdditionalResolve, trace, file); } + else if (topmostCandidateForAdditionalResolve instanceof JetDelegationSpecifierList) { + delegationSpecifierAdditionalResolve(resolveSession, (JetDelegationSpecifierList) topmostCandidateForAdditionalResolve, + trace, file); + } else { assert false : "Invalid type of the topmost parent"; } @@ -135,6 +139,22 @@ public class ResolveSessionUtils { return trace.getBindingContext(); } + private static void delegationSpecifierAdditionalResolve(final ResolveSession resolveSession, + final JetDelegationSpecifierList specifier, DelegatingBindingTrace trace, JetFile file) { + BodyResolver bodyResolver = createBodyResolver(trace, file, resolveSession.getModuleConfiguration()); + + JetClassOrObject classOrObject = (JetClassOrObject) specifier.getParent(); + LazyClassDescriptor descriptor = (LazyClassDescriptor) resolveSession.resolveToDescriptor(classOrObject); + + // Activate resolving of supertypes + descriptor.getTypeConstructor().getSupertypes(); + + bodyResolver.resolveDelegationSpecifierList(classOrObject, descriptor, + descriptor.getUnsubstitutedPrimaryConstructor(), + descriptor.getScopeForClassHeaderResolution(), + descriptor.getScopeForMemberDeclarationResolution()); + } + private static void propertyAdditionalResolve(final ResolveSession resolveSession, final JetProperty jetProperty, DelegatingBindingTrace trace, JetFile file) { EmptyBodyResolveContext bodyResolveContext = new EmptyBodyResolveContext(); BodyResolver bodyResolver = createBodyResolver(trace, file, bodyResolveContext, resolveSession.getModuleConfiguration()); diff --git a/idea/testData/completion/basic/InObjectInDelegationSpecifier.kt b/idea/testData/completion/basic/InObjectInDelegationSpecifier.kt new file mode 100644 index 00000000000..99b6abf2a2c --- /dev/null +++ b/idea/testData/completion/basic/InObjectInDelegationSpecifier.kt @@ -0,0 +1,11 @@ +open class PageManager(a: Runnable) +class Tab + +class ChromePageManager(): PageManager(object : Runnable { + public override fun run() { + val ab : Ta = null + } +}) { +} + +// EXIST: Tab \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java index 75589fcfe21..cd666e4dbed 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java @@ -128,6 +128,10 @@ public class JetBasicCompletionTest extends JetCompletionTestBase { doTest(); } + public void testInObjectInDelegationSpecifier() { + doTest(); + } + public void testInPackage() { doTest(); }