Resolve codeFragments with context of JetClass
This commit is contained in:
@@ -203,31 +203,44 @@ public abstract class ElementResolver {
|
|||||||
if (!(codeFragmentExpression instanceof JetExpression)) return;
|
if (!(codeFragmentExpression instanceof JetExpression)) return;
|
||||||
|
|
||||||
PsiElement contextElement = codeFragment.getContext();
|
PsiElement contextElement = codeFragment.getContext();
|
||||||
if (!(contextElement instanceof JetExpression)) return;
|
|
||||||
|
|
||||||
JetExpression contextExpression = (JetExpression) contextElement;
|
JetScope scopeForContextElement;
|
||||||
BindingContext contextForElement = resolveToElement(contextExpression);
|
DataFlowInfo dataFlowInfoForContextElement;
|
||||||
|
|
||||||
JetScope scopeForContextElement = contextForElement.get(BindingContext.RESOLUTION_SCOPE, contextExpression);
|
if (contextElement instanceof JetClassOrObject) {
|
||||||
if (scopeForContextElement != null) {
|
LazyClassDescriptor descriptor = (LazyClassDescriptor) resolveSession.resolveToDescriptor((JetClassOrObject) contextElement);
|
||||||
JetScope codeFragmentScope = resolveSession.getScopeProvider().getFileScope(codeFragment);
|
|
||||||
ChainedScope chainedScope = new ChainedScope(
|
|
||||||
scopeForContextElement.getContainingDeclaration(),
|
|
||||||
"Scope for resolve code fragment",
|
|
||||||
scopeForContextElement,
|
|
||||||
codeFragmentScope
|
|
||||||
);
|
|
||||||
|
|
||||||
DataFlowInfo dataFlowInfoForContextElement = getDataFlowInfo(contextForElement, contextExpression);
|
scopeForContextElement = descriptor.getScopeForMemberDeclarationResolution();
|
||||||
AnalyzerPackage.computeTypeInContext(
|
dataFlowInfoForContextElement = DataFlowInfo.EMPTY;
|
||||||
(JetExpression) codeFragmentExpression,
|
|
||||||
chainedScope,
|
|
||||||
trace,
|
|
||||||
dataFlowInfoForContextElement,
|
|
||||||
TypeUtils.NO_EXPECTED_TYPE,
|
|
||||||
resolveSession.getModuleDescriptor()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
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) {
|
private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) {
|
||||||
|
|||||||
+19
-4
@@ -61,6 +61,9 @@ import org.jetbrains.jet.lang.resolve.BindingTraceContext
|
|||||||
import org.jetbrains.jet.lang.types.TypeUtils
|
import org.jetbrains.jet.lang.types.TypeUtils
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope
|
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope
|
||||||
import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo
|
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<T> {
|
public trait CacheExtension<T> {
|
||||||
public val platform: TargetPlatform
|
public val platform: TargetPlatform
|
||||||
@@ -272,11 +275,24 @@ private object KotlinResolveDataProvider {
|
|||||||
if (codeFragmentExpression !is JetExpression) return BindingContext.EMPTY
|
if (codeFragmentExpression !is JetExpression) return BindingContext.EMPTY
|
||||||
|
|
||||||
val contextElement = codeFragment.getContext()
|
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
|
if (scopeForContextElement == null) return BindingContext.EMPTY
|
||||||
|
|
||||||
val codeFragmentScope = resolveSession.getScopeProvider().getFileScope(codeFragment)
|
val codeFragmentScope = resolveSession.getScopeProvider().getFileScope(codeFragment)
|
||||||
@@ -285,7 +301,6 @@ private object KotlinResolveDataProvider {
|
|||||||
"Scope for resolve code fragment",
|
"Scope for resolve code fragment",
|
||||||
scopeForContextElement, codeFragmentScope)
|
scopeForContextElement, codeFragmentScope)
|
||||||
|
|
||||||
val dataFlowInfo = contextForElement.getDataFlowInfo(contextElement)
|
|
||||||
return codeFragmentExpression.analyzeInContext(
|
return codeFragmentExpression.analyzeInContext(
|
||||||
chainedScope,
|
chainedScope,
|
||||||
BindingTraceContext(),
|
BindingTraceContext(),
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import org.jetbrains.jet.lang.psi.JetExpression
|
import org.jetbrains.jet.lang.psi.JetExpression
|
||||||
import org.jetbrains.jet.lang.psi.JetBlockExpression
|
import org.jetbrains.jet.lang.psi.JetBlockExpression
|
||||||
import org.jetbrains.jet.lang.psi.JetBlockCodeFragment
|
import org.jetbrains.jet.lang.psi.JetBlockCodeFragment
|
||||||
|
import org.jetbrains.jet.asJava.KotlinLightClass
|
||||||
|
|
||||||
class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
||||||
override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment {
|
override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment {
|
||||||
@@ -68,6 +69,10 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
return getContextElement(elementAt.getContext()?.getContext())
|
return getContextElement(elementAt.getContext()?.getContext())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elementAt is KotlinLightClass) {
|
||||||
|
return getContextElement(elementAt.origin)
|
||||||
|
}
|
||||||
|
|
||||||
val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass<JetExpression>(), false)
|
val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass<JetExpression>(), false)
|
||||||
if (expressionAtOffset != null) {
|
if (expressionAtOffset != null) {
|
||||||
return expressionAtOffset
|
return expressionAtOffset
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class <caret>A(aaabbbccc: Int) {
|
||||||
|
val aabbcc = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"" + <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: aaabbbccc">aaabbbccc</error> + aabbcc + this.toString()
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class <caret>A(aaabbbccc: Int) {
|
||||||
|
val aabbcc = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 1
|
||||||
|
// EXIST: aabbcc
|
||||||
|
// ABSENT: aaabbbccc
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
aa<caret>
|
||||||
+6
@@ -42,6 +42,12 @@ public class CodeFragmentCompletionTestGenerated extends AbstractCodeFragmentCom
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("localVal.kt")
|
||||||
public void testLocalVal() throws Exception {
|
public void testLocalVal() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/codeFragments/localVal.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/codeFragments/localVal.kt");
|
||||||
|
|||||||
+6
@@ -57,6 +57,12 @@ public class CodeFragmentHighlightingTestGenerated extends AbstractCodeFragmentH
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("contextElementAsStatement.kt")
|
||||||
public void testContextElementAsStatement() throws Exception {
|
public void testContextElementAsStatement() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/codeFragments/contextElementAsStatement.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/codeFragments/contextElementAsStatement.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user