diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java index 0689a8deded..27ef2fe57e9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; @@ -145,10 +146,7 @@ public class BindingContextUtils { @Nullable public static JetTypeInfo getRecordedTypeInfo(@NotNull JetExpression expression, @NotNull BindingContext context) { if (!context.get(BindingContext.PROCESSED, expression)) return null; - DataFlowInfo dataFlowInfo = context.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression); - if (dataFlowInfo == null) { - dataFlowInfo = DataFlowInfo.EMPTY; - } + DataFlowInfo dataFlowInfo = BindingContextUtilPackage.getDataFlowInfo(context, expression); JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); return JetTypeInfo.create(type, dataFlowInfo); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.kt index 44d59df7da9..93ac0feb426 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.kt @@ -54,3 +54,6 @@ public fun > ResolutionContext.recordScopeAndDataFlo trace.record(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression, dataFlowInfo) } } + +public fun BindingContext.getDataFlowInfo(expression: JetExpression?): DataFlowInfo = + expression?.let { this[BindingContext.EXPRESSION_DATA_FLOW_INFO, it] } ?: DataFlowInfo.EMPTY diff --git a/idea/ide-lazy-resolve/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java b/idea/ide-lazy-resolve/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java index 5057b65ecc0..60e70ef123d 100644 --- a/idea/ide-lazy-resolve/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java +++ b/idea/ide-lazy-resolve/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java @@ -46,6 +46,8 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; +import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getDataFlowInfo; + public class ElementResolver { protected final ResolveSession resolveSession; @@ -216,12 +218,12 @@ public class ElementResolver { codeFragmentScope ); - DataFlowInfo dataFlowInfoForContextElement = contextForElement.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, contextExpression); + DataFlowInfo dataFlowInfoForContextElement = getDataFlowInfo(contextForElement, contextExpression); AnalyzerPackage.computeTypeInContext( (JetExpression) codeFragmentExpression, chainedScope, trace, - dataFlowInfoForContextElement == null ? DataFlowInfo.EMPTY : dataFlowInfoForContextElement, + dataFlowInfoForContextElement, TypeUtils.NO_EXPECTED_TYPE, resolveSession.getModuleDescriptor() ); 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 6c69661a246..f4deee773e1 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 @@ -63,6 +63,7 @@ import org.jetbrains.jet.analyzer.analyzeInContext 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.descriptors.ModuleDescriptor public trait CacheExtension { @@ -289,8 +290,7 @@ private object KotlinResolveDataProvider { "Scope for resolve code fragment", scopeForContextElement, codeFragmentScope) - val dataFlowInfoForContextElement = contextForElement[BindingContext.EXPRESSION_DATA_FLOW_INFO, contextElement] - val dataFlowInfo = dataFlowInfoForContextElement ?: DataFlowInfo.EMPTY + val dataFlowInfo = contextForElement.getDataFlowInfo(contextElement) return codeFragmentExpression.analyzeInContext( chainedScope, BindingTraceContext(), diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/intentions/RemoveExplicitTypeArguments.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/intentions/RemoveExplicitTypeArguments.kt index 163262ab2b6..e78acc06b2a 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/intentions/RemoveExplicitTypeArguments.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/intentions/RemoveExplicitTypeArguments.kt @@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.psi.JetReturnExpression import org.jetbrains.jet.lang.psi.JetDeclarationWithBody import org.jetbrains.jet.lang.resolve.calls.callUtil.getResolvedCall import org.jetbrains.jet.lang.psi.psiUtil.getTextWithLocation +import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo public class RemoveExplicitTypeArguments : JetSelfTargetingIntention( "remove.explicit.type.arguments", javaClass()) { @@ -72,7 +73,7 @@ public class RemoveExplicitTypeArguments : JetSelfTargetingIntention variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info); for (JetType variant : variantsForExplicitReceiver) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt b/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt index 04674955a29..3401099d388 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt @@ -58,6 +58,7 @@ import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace import org.jetbrains.jet.lang.psi.JetPrefixExpression import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall import org.jetbrains.jet.lang.psi.JetFunctionLiteralArgument +import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo enum class Tail { COMMA @@ -128,7 +129,7 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, calleeExpression] ?: return null //TODO: discuss it val expectedType = (callElement as? JetExpression)?.let { bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, it] } ?: TypeUtils.NO_EXPECTED_TYPE - val dataFlowInfo = (callElement as? JetExpression)?.let { bindingContext[BindingContext.EXPRESSION_DATA_FLOW_INFO, it] } ?: DataFlowInfo.EMPTY + val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression) val callResolutionContext = BasicCallResolutionContext.create( DelegatingBindingTrace(bindingContext, "Temporary trace for completion"), resolutionScope, diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt index bf14eb60c63..95c85813f3c 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt @@ -35,10 +35,11 @@ import java.util.HashSet import org.jetbrains.jet.lang.resolve.BindingContext import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver import org.jetbrains.jet.plugin.util.makeNotNullable +import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo class TypesWithAutoCasts(val bindingContext: BindingContext) { public fun calculate(expression: JetExpression, receiver: JetExpression?): (DeclarationDescriptor) -> Iterable { - val dataFlowInfo = bindingContext[BindingContext.EXPRESSION_DATA_FLOW_INFO, expression] + val dataFlowInfo = bindingContext.getDataFlowInfo(expression) val (variableToTypes: Map>, notNullVariables: Set) = processDataFlowInfo(dataFlowInfo, receiver) @@ -77,8 +78,8 @@ class TypesWithAutoCasts(val bindingContext: BindingContext) { val notNullVariables: Set = Collections.emptySet() ) - private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo?, receiver: JetExpression?): ProcessDataFlowInfoResult { - if (dataFlowInfo == null) return ProcessDataFlowInfoResult() + private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo, receiver: JetExpression?): ProcessDataFlowInfoResult { + if (dataFlowInfo == DataFlowInfo.EMPTY) return ProcessDataFlowInfoResult() val dataFlowValueToVariable: (DataFlowValue) -> VariableDescriptor? if (receiver != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java b/idea/src/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java index 103bdf2c718..f856b055e49 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java @@ -40,6 +40,7 @@ import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.ObservableBindingTrace; +import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -124,10 +125,7 @@ public class KotlinIntroduceVariableHandler extends KotlinIntroduceHandlerBase { final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); //can be null or error type JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expression); if (scope != null) { - DataFlowInfo dataFlowInfo = bindingContext.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression); - if (dataFlowInfo == null) { - dataFlowInfo = DataFlowInfo.EMPTY; - } + DataFlowInfo dataFlowInfo = BindingContextUtilPackage.getDataFlowInfo(bindingContext, expression); ObservableBindingTrace bindingTrace = new ObservableBindingTrace(new BindingTraceContext()); JetType typeNoExpectedType = AnalyzerPackage.computeTypeInfoInContext( diff --git a/idea/tests/org/jetbrains/jet/completion/DataFlowValueRenderingTest.kt b/idea/tests/org/jetbrains/jet/completion/DataFlowValueRenderingTest.kt index 75a4f38c33d..1b11415e5d8 100644 --- a/idea/tests/org/jetbrains/jet/completion/DataFlowValueRenderingTest.kt +++ b/idea/tests/org/jetbrains/jet/completion/DataFlowValueRenderingTest.kt @@ -29,6 +29,7 @@ import java.io.File import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo public abstract class AbstractDataFlowValueRenderingTest: JetLightCodeInsightFixtureTestCase() { override fun getTestDataPath() : String { @@ -46,7 +47,7 @@ public abstract class AbstractDataFlowValueRenderingTest: JetLightCodeInsightFix val jetFile = fixture.getFile() as JetFile val element = jetFile.findElementAt(fixture.getCaretOffset()) val expression = PsiTreeUtil.getParentOfType(element, javaClass())!! - val info = AnalyzerFacadeWithCache.getContextForElement(expression)[BindingContext.EXPRESSION_DATA_FLOW_INFO, expression]!! + val info = AnalyzerFacadeWithCache.getContextForElement(expression).getDataFlowInfo(expression) val allValues = (info.getCompleteTypeInfo().keySet() + info.getCompleteNullabilityInfo().keySet()).toSet() val actual = allValues.map { renderDataFlowValue(it) }.filterNotNull().sort().makeString("\n")