diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java index c2db24492a1..408235f90b9 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java @@ -203,31 +203,44 @@ public abstract class ElementResolver { if (!(codeFragmentExpression instanceof JetExpression)) return; PsiElement contextElement = codeFragment.getContext(); - if (!(contextElement instanceof JetExpression)) return; - JetExpression contextExpression = (JetExpression) contextElement; - BindingContext contextForElement = resolveToElement(contextExpression); + JetScope scopeForContextElement; + DataFlowInfo dataFlowInfoForContextElement; - JetScope scopeForContextElement = contextForElement.get(BindingContext.RESOLUTION_SCOPE, contextExpression); - if (scopeForContextElement != null) { - JetScope codeFragmentScope = resolveSession.getScopeProvider().getFileScope(codeFragment); - ChainedScope chainedScope = new ChainedScope( - scopeForContextElement.getContainingDeclaration(), - "Scope for resolve code fragment", - scopeForContextElement, - codeFragmentScope - ); + if (contextElement instanceof JetClassOrObject) { + LazyClassDescriptor descriptor = (LazyClassDescriptor) resolveSession.resolveToDescriptor((JetClassOrObject) contextElement); - DataFlowInfo dataFlowInfoForContextElement = getDataFlowInfo(contextForElement, contextExpression); - AnalyzerPackage.computeTypeInContext( - (JetExpression) codeFragmentExpression, - chainedScope, - trace, - dataFlowInfoForContextElement, - TypeUtils.NO_EXPECTED_TYPE, - resolveSession.getModuleDescriptor() - ); + scopeForContextElement = descriptor.getScopeForMemberDeclarationResolution(); + dataFlowInfoForContextElement = DataFlowInfo.EMPTY; } + else { + if (!(contextElement instanceof JetExpression)) return; + + JetExpression contextExpression = (JetExpression) contextElement; + BindingContext contextForElement = resolveToElement((JetElement) contextElement); + + scopeForContextElement = contextForElement.get(BindingContext.RESOLUTION_SCOPE, contextExpression); + dataFlowInfoForContextElement = getDataFlowInfo(contextForElement, contextExpression); + } + + if (scopeForContextElement == null) return; + + JetScope codeFragmentScope = resolveSession.getScopeProvider().getFileScope(codeFragment); + ChainedScope chainedScope = new ChainedScope( + scopeForContextElement.getContainingDeclaration(), + "Scope for resolve code fragment", + scopeForContextElement, + codeFragmentScope + ); + + AnalyzerPackage.computeTypeInContext( + (JetExpression) codeFragmentExpression, + chainedScope, + trace, + dataFlowInfoForContextElement, + TypeUtils.NO_EXPECTED_TYPE, + resolveSession.getModuleDescriptor() + ); } private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) { diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt index 74508f03406..74429005ba3 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt @@ -61,6 +61,9 @@ import org.jetbrains.jet.lang.resolve.BindingTraceContext import org.jetbrains.jet.lang.types.TypeUtils import org.jetbrains.jet.lang.resolve.scopes.ChainedScope import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo +import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor +import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo +import org.jetbrains.jet.lang.resolve.scopes.JetScope public trait CacheExtension { public val platform: TargetPlatform @@ -272,11 +275,24 @@ private object KotlinResolveDataProvider { if (codeFragmentExpression !is JetExpression) return BindingContext.EMPTY val contextElement = codeFragment.getContext() - if (contextElement !is JetExpression) return BindingContext.EMPTY - val contextForElement = contextElement.getBindingContext() + val scopeForContextElement: JetScope? + val dataFlowInfo: DataFlowInfo + if (contextElement is JetClassOrObject) { + val descriptor = resolveSession.resolveToDescriptor(contextElement) as LazyClassDescriptor + + scopeForContextElement = descriptor.getScopeForMemberDeclarationResolution() + dataFlowInfo = DataFlowInfo.EMPTY + } + else { + if (contextElement !is JetExpression) return BindingContext.EMPTY + + val contextForElement = contextElement.getBindingContext() + + scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, contextElement] + dataFlowInfo = contextForElement.getDataFlowInfo(contextElement) + } - val scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, contextElement] if (scopeForContextElement == null) return BindingContext.EMPTY val codeFragmentScope = resolveSession.getScopeProvider().getFileScope(codeFragment) @@ -285,7 +301,6 @@ private object KotlinResolveDataProvider { "Scope for resolve code fragment", scopeForContextElement, codeFragmentScope) - val dataFlowInfo = contextForElement.getDataFlowInfo(contextElement) return codeFragmentExpression.analyzeInContext( chainedScope, BindingTraceContext(), diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt b/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt index 494d37143f2..09872f905ce 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt +++ b/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt @@ -31,6 +31,7 @@ import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.jet.lang.psi.JetExpression import org.jetbrains.jet.lang.psi.JetBlockExpression import org.jetbrains.jet.lang.psi.JetBlockCodeFragment +import org.jetbrains.jet.asJava.KotlinLightClass class KotlinCodeFragmentFactory: CodeFragmentFactory() { override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { @@ -68,6 +69,10 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { return getContextElement(elementAt.getContext()?.getContext()) } + if (elementAt is KotlinLightClass) { + return getContextElement(elementAt.origin) + } + val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass(), false) if (expressionAtOffset != null) { return expressionAtOffset diff --git a/idea/testData/checker/codeFragments/classHeader.kt b/idea/testData/checker/codeFragments/classHeader.kt new file mode 100644 index 00000000000..b251f688b5f --- /dev/null +++ b/idea/testData/checker/codeFragments/classHeader.kt @@ -0,0 +1,3 @@ +class A(aaabbbccc: Int) { + val aabbcc = 1 +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/classHeader.kt.fragment b/idea/testData/checker/codeFragments/classHeader.kt.fragment new file mode 100644 index 00000000000..5af343d36d1 --- /dev/null +++ b/idea/testData/checker/codeFragments/classHeader.kt.fragment @@ -0,0 +1 @@ +"" + aaabbbccc + aabbcc + this.toString() \ No newline at end of file diff --git a/idea/testData/completion/basic/codeFragments/classHeader.kt b/idea/testData/completion/basic/codeFragments/classHeader.kt new file mode 100644 index 00000000000..e1be55b2efa --- /dev/null +++ b/idea/testData/completion/basic/codeFragments/classHeader.kt @@ -0,0 +1,7 @@ +class A(aaabbbccc: Int) { + val aabbcc = 1 +} + +// INVOCATION_COUNT: 1 +// EXIST: aabbcc +// ABSENT: aaabbbccc \ No newline at end of file diff --git a/idea/testData/completion/basic/codeFragments/classHeader.kt.fragment b/idea/testData/completion/basic/codeFragments/classHeader.kt.fragment new file mode 100644 index 00000000000..673089a370f --- /dev/null +++ b/idea/testData/completion/basic/codeFragments/classHeader.kt.fragment @@ -0,0 +1 @@ +aa diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java index 8333e541474..89342c594fb 100644 --- a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java @@ -42,6 +42,12 @@ public class CodeFragmentCompletionTestGenerated extends AbstractCodeFragmentCom doTest(fileName); } + @TestMetadata("classHeader.kt") + public void testClassHeader() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/codeFragments/classHeader.kt"); + doTest(fileName); + } + @TestMetadata("localVal.kt") public void testLocalVal() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/codeFragments/localVal.kt"); diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java index 55c22e4e8df..10fad56f551 100644 --- a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java @@ -57,6 +57,12 @@ public class CodeFragmentHighlightingTestGenerated extends AbstractCodeFragmentH doTest(fileName); } + @TestMetadata("classHeader.kt") + public void testClassHeader() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/codeFragments/classHeader.kt"); + doTest(fileName); + } + @TestMetadata("contextElementAsStatement.kt") public void testContextElementAsStatement() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/codeFragments/contextElementAsStatement.kt");