diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index 9a89a6151dc..a7a6402039a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -608,7 +608,7 @@ public class BodyResolver { KtExpression body = anonymousInitializer.getBody(); if (body != null) { PreliminaryDeclarationVisitor.Companion.createForDeclaration( - (KtDeclaration) anonymousInitializer.getParent().getParent(), trace); + (KtDeclaration) anonymousInitializer.getParent().getParent(), trace, languageVersionSettings); expressionTypingServices.getTypeInfo( scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace, /*isStatement = */true ); @@ -680,7 +680,7 @@ public class BodyResolver { ) { computeDeferredType(propertyDescriptor.getReturnType()); - PreliminaryDeclarationVisitor.Companion.createForDeclaration(property, trace); + PreliminaryDeclarationVisitor.Companion.createForDeclaration(property, trace, languageVersionSettings); KtExpression initializer = property.getInitializer(); LexicalScope propertyHeaderScope = ScopeUtils.makeScopeForPropertyHeader(getScopeForProperty(c, property), propertyDescriptor); @@ -851,7 +851,7 @@ public class BodyResolver { // Creates wrapper scope for header resolution if necessary (see resolveSecondaryConstructorBody) @Nullable Function1 headerScopeFactory ) { - PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace); + PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace, languageVersionSettings); LexicalScope innerScope = FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace, overloadChecker); List valueParameters = function.getValueParameters(); List valueParameterDescriptors = functionDescriptor.getValueParameters(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index d87f347ba72..a95edda3a84 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -1154,7 +1154,7 @@ public class DescriptorResolver { @NotNull FunctionDescriptor functionDescriptor ) { return wrappedTypeFactory.createRecursionIntolerantDeferredType(trace, () -> { - PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace); + PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace, languageVersionSettings); KotlinType type = expressionTypingServices.getBodyExpressionType( trace, scope, dataFlowInfo, function, functionDescriptor); KotlinType result = transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt index a170bcb0540..32bf5ff6334 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt @@ -84,7 +84,8 @@ class VariableTypeAndInitializerResolver( wrappedTypeFactory.createRecursionIntolerantDeferredType( trace ) { - PreliminaryDeclarationVisitor.createForDeclaration(variable, trace) + PreliminaryDeclarationVisitor.createForDeclaration(variable, trace, + expressionTypingServices.languageVersionSettings) val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local) transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt index 26cef648be0..ab62698ef55 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowValueFactory.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.smartcasts import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableNothing import org.jetbrains.kotlin.cfg.ControlFlowInformationProvider +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor @@ -378,7 +379,8 @@ object DataFlowValueFactory { val variableContainingDeclaration = variableDescriptor.containingDeclaration if (isAccessedInsideClosure(variableContainingDeclaration, bindingContext, accessElement)) { // stable iff we have no writers in closures AND this closure is AFTER all writers - return if (hasNoWritersInClosures(variableContainingDeclaration, writers, bindingContext) && + return if (preliminaryVisitor.languageVersionSettings.supportsFeature(LanguageFeature.CapturedInClosureSmartCasts) && + hasNoWritersInClosures(variableContainingDeclaration, writers, bindingContext) && isAccessedInsideClosureAfterAllWriters(writers, accessElement)) { STABLE_VARIABLE } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java index 970f03ab20d..b6a9cc5f973 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java @@ -17,10 +17,10 @@ package org.jetbrains.kotlin.types.expressions; import com.intellij.psi.tree.IElementType; -import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; +import org.jetbrains.kotlin.config.LanguageVersionSettings; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.ScriptDescriptor; @@ -68,6 +68,11 @@ public class ExpressionTypingServices { this.expressionTypingFacade = facade; } + @NotNull + public LanguageVersionSettings getLanguageVersionSettings() { + return expressionTypingComponents.languageVersionSettings; + } + @NotNull public StatementFilter getStatementFilter() { return statementFilter; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PreliminaryDeclarationVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PreliminaryDeclarationVisitor.kt index 3470670759c..337a5c073ae 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PreliminaryDeclarationVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PreliminaryDeclarationVisitor.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.types.expressions +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -26,7 +27,10 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -class PreliminaryDeclarationVisitor(val declaration: KtDeclaration): AssignedVariablesSearcher() { +class PreliminaryDeclarationVisitor( + val declaration: KtDeclaration, + val languageVersionSettings: LanguageVersionSettings +): AssignedVariablesSearcher() { override fun writers(variableDescriptor: VariableDescriptor): MutableSet { lazyTrigger @@ -39,17 +43,18 @@ class PreliminaryDeclarationVisitor(val declaration: KtDeclaration): AssignedVar companion object { - fun createForExpression(expression: KtExpression, trace: BindingTrace) { - expression.getStrictParentOfType()?.let { createForDeclaration(it, trace) } + fun createForExpression(expression: KtExpression, trace: BindingTrace, languageVersionSettings: LanguageVersionSettings) { + expression.getStrictParentOfType()?.let { createForDeclaration(it, trace, languageVersionSettings) } } private fun topMostNonClassDeclaration(declaration: KtDeclaration) = declaration.parentsWithSelf.filterIsInstance().findLast { it !is KtClassOrObject } ?: declaration - fun createForDeclaration(declaration: KtDeclaration, trace: BindingTrace) { + fun createForDeclaration(declaration: KtDeclaration, trace: BindingTrace, languageVersionSettings: LanguageVersionSettings) { val visitorOwner = topMostNonClassDeclaration(declaration) if (trace.get(BindingContext.PRELIMINARY_VISITOR, visitorOwner) != null) return - trace.record(BindingContext.PRELIMINARY_VISITOR, visitorOwner, PreliminaryDeclarationVisitor(visitorOwner)) + trace.record(BindingContext.PRELIMINARY_VISITOR, visitorOwner, + PreliminaryDeclarationVisitor(visitorOwner, languageVersionSettings)) } fun getVisitorByVariable(variableDescriptor: VariableDescriptor, bindingContext: BindingContext): PreliminaryDeclarationVisitor? { diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureOff.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureOff.kt index 45f39b95079..808ac0518b6 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureOff.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/capturedInClosureOff.kt @@ -9,7 +9,7 @@ fun foo(s: String?) { } if (x != null) { run { - x.hashCode() + x.hashCode() } } } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt index f20e6217b80..60601151c4d 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt @@ -46,7 +46,7 @@ import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor contextDependency: ContextDependency = ContextDependency.INDEPENDENT, expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService() ): KotlinTypeInfo { - PreliminaryDeclarationVisitor.createForExpression(this, trace) + PreliminaryDeclarationVisitor.createForExpression(this, trace, expressionTypingServices.languageVersionSettings) return expressionTypingServices.getTypeInfo(scope, this, expectedType, dataFlowInfo, trace, isStatement, contextExpression, contextDependency) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt index f1b27e3f1e5..9e101453a04 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt @@ -54,7 +54,8 @@ class CodeFragmentAnalyzer( when (codeFragmentElement) { is KtExpression -> { - PreliminaryDeclarationVisitor.createForExpression(codeFragmentElement, trace) + PreliminaryDeclarationVisitor.createForExpression(codeFragmentElement, trace, + expressionTypingServices.languageVersionSettings) expressionTypingServices.getTypeInfo( scopeForContextElement, codeFragmentElement,