From d9cd4f0d749cb4695f10124893414bf119186fcb Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Sep 2012 16:37:37 +0400 Subject: [PATCH] KT-2725 No completion in properties initializers and accessors #KT-2725 Fixed --- .../jet/lang/resolve/BodyResolver.java | 4 +- .../resolve/lazy/ResolveSessionUtils.java | 43 ++++++++++++++++--- .../jet/lang/resolve/lazy/ScopeProvider.java | 3 ++ .../basic/InClassPropertyAccessor.kt | 9 ++++ .../basic/InGlobalPropertyInitializer.kt | 6 +++ .../basic/InInitializerInPropertyAccessor.kt | 11 +++++ .../completion/JetBasicCompletionTest.java | 12 ++++++ 7 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 idea/testData/completion/basic/InClassPropertyAccessor.kt create mode 100644 idea/testData/completion/basic/InGlobalPropertyInitializer.kt create mode 100644 idea/testData/completion/basic/InInitializerInPropertyAccessor.kt 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 34064c579ba..6cdf0f4fdae 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -425,7 +425,7 @@ public class BodyResolver { return accessorScope; } - private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor) { + public void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor) { ObservableBindingTrace fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor); JetPropertyAccessor getter = property.getGetter(); @@ -460,7 +460,7 @@ public class BodyResolver { }); } - private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) { + public void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) { //JetFlowInformationProvider flowInformationProvider = context.getDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15 JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScope(scope, propertyDescriptor.getTypeParameters(), ReceiverDescriptor.NO_RECEIVER, trace); 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 2863d7d2e15..06ff7988b27 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 @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.lazy; import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -42,6 +43,9 @@ public class ResolveSessionUtils { } private static class EmptyBodyResolveContext implements BodiesResolveContext { + + private Map declarationScopesMap = Collections.emptyMap(); + @Override public Map getClasses() { return Collections.emptyMap(); @@ -64,7 +68,11 @@ public class ResolveSessionUtils { @Override public Map getDeclaringScopes() { - return Collections.emptyMap(); + return declarationScopesMap; + } + + public void setDeclaringScopes(Map declarationScopes) { + declarationScopesMap = declarationScopes; } @Override @@ -87,17 +95,16 @@ public class ResolveSessionUtils { } } - public static - @NotNull - BindingContext resolveToExpression( + public static @NotNull BindingContext resolveToExpression( @NotNull final ResolveSession resolveSession, @NotNull JetExpression expression ) { final DelegatingBindingTrace trace = new DelegatingBindingTrace(resolveSession.getBindingContext()); JetFile file = (JetFile) expression.getContainingFile(); - @SuppressWarnings("unchecked") PsiElement topmostCandidateForAdditionalResolve = JetPsiUtil.getTopmostParentOfTypes(expression, - JetNamedFunction.class, JetClassInitializer.class); + @SuppressWarnings("unchecked") + PsiElement topmostCandidateForAdditionalResolve = JetPsiUtil.getTopmostParentOfTypes(expression, + JetNamedFunction.class, JetClassInitializer.class, JetProperty.class); if (topmostCandidateForAdditionalResolve != null) { if (topmostCandidateForAdditionalResolve instanceof JetNamedFunction) { @@ -106,6 +113,9 @@ public class ResolveSessionUtils { else if (topmostCandidateForAdditionalResolve instanceof JetClassInitializer) { initializerAdditionalResolve(resolveSession, (JetClassInitializer) topmostCandidateForAdditionalResolve, trace, file); } + else if (topmostCandidateForAdditionalResolve instanceof JetProperty) { + propertyAdditionalResolve(resolveSession, (JetProperty) topmostCandidateForAdditionalResolve, trace, file); + } else { assert false : "Invalid type of the topmost parent"; } @@ -124,6 +134,27 @@ public class ResolveSessionUtils { return trace.getBindingContext(); } + private static void propertyAdditionalResolve(final ResolveSession resolveSession, final JetProperty jetProperty, DelegatingBindingTrace trace, JetFile file) { + EmptyBodyResolveContext bodyResolveContext = new EmptyBodyResolveContext(); + BodyResolver bodyResolver = createBodyResolver(trace, file, bodyResolveContext); + PropertyDescriptor descriptor = (PropertyDescriptor) resolveSession.resolveToDescriptor(jetProperty); + + JetExpression propertyInitializer = jetProperty.getInitializer(); + + final JetScope propertyResolutionScope = resolveSession.getInjector().getScopeProvider().getResolutionScopeForDeclaration( + jetProperty); + + if (propertyInitializer != null) { + bodyResolver.resolvePropertyInitializer(jetProperty, descriptor, propertyInitializer, propertyResolutionScope); + } + + for (final JetPropertyAccessor propertyAccessor : jetProperty.getAccessors()) { + bodyResolveContext.setDeclaringScopes( + ImmutableMap.builder().put(propertyAccessor, propertyResolutionScope).build()); + bodyResolver.resolvePropertyAccessors(jetProperty, descriptor); + } + } + private static void functionAdditionalResolve( ResolveSession resolveSession, JetNamedFunction namedFunction, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index e8e5804147f..77c950e0614 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -90,6 +90,9 @@ public class ScopeProvider { if (parentDeclaration instanceof JetClassOrObject) { JetClassOrObject classOrObject = (JetClassOrObject) parentDeclaration; LazyClassDescriptor classDescriptor = (LazyClassDescriptor) resolveSession.getClassDescriptor(classOrObject); + if (jetDeclaration instanceof JetClassInitializer || jetDeclaration instanceof JetProperty) { + return classDescriptor.getScopeForPropertyInitializerResolution(); + } if (jetDeclaration instanceof JetEnumEntry) { return ((LazyClassDescriptor) classDescriptor.getClassObjectDescriptor()).getScopeForMemberDeclarationResolution(); } diff --git a/idea/testData/completion/basic/InClassPropertyAccessor.kt b/idea/testData/completion/basic/InClassPropertyAccessor.kt new file mode 100644 index 00000000000..459ab23103c --- /dev/null +++ b/idea/testData/completion/basic/InClassPropertyAccessor.kt @@ -0,0 +1,9 @@ +class Test(val testParam : Int) { + val x : Int get() { + val test = 12 + return te + } +} + +// EXIST: test +// EXIST: testParam diff --git a/idea/testData/completion/basic/InGlobalPropertyInitializer.kt b/idea/testData/completion/basic/InGlobalPropertyInitializer.kt new file mode 100644 index 00000000000..19d6982ba03 --- /dev/null +++ b/idea/testData/completion/basic/InGlobalPropertyInitializer.kt @@ -0,0 +1,6 @@ +val testing = 12 +val test = "Hello" + +val more = test + +// EXIST: test, testing diff --git a/idea/testData/completion/basic/InInitializerInPropertyAccessor.kt b/idea/testData/completion/basic/InInitializerInPropertyAccessor.kt new file mode 100644 index 00000000000..ca9fd584673 --- /dev/null +++ b/idea/testData/completion/basic/InInitializerInPropertyAccessor.kt @@ -0,0 +1,11 @@ +val testGlobal = 12 + +val test : Int get() { + class SomeMore(testParam : Int) { + { + tes + } + } +} + +// EXIST: testGlobal, test, testParam diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java index 8cec57bb2e2..75589fcfe21 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java @@ -92,6 +92,10 @@ public class JetBasicCompletionTest extends JetCompletionTestBase { doTest(); } + public void testInClassPropertyAccessor() { + doTest(); + } + public void testInEmptyImport() { doTest(); } @@ -100,10 +104,18 @@ public class JetBasicCompletionTest extends JetCompletionTestBase { doTest(); } + public void testInGlobalPropertyInitializer() { + doTest(); + } + public void testInImport() { doTest(); } + public void testInInitializerInPropertyAccessor() { + doTest(); + } + public void testInLocalObjectDeclaration() { doTest(); }