From 9bfa90dc0e73101546ac8cc79964f09b8c7afa3c Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 12 Jan 2016 14:12:30 +0300 Subject: [PATCH] Analyze local variable declarations in expression position Fixes exception on invalid code "val c = 1 < val Int.f: Int = 3" --- .../jetbrains/kotlin/resolve/LocalVariableResolver.kt | 8 +++----- .../expressions/BasicExpressionTypingVisitor.java | 10 ++++++++-- .../expressions/ExpressionTypingVisitorDispatcher.java | 5 +++++ .../ExpressionTypingVisitorForStatements.java | 5 ++++- .../tests/deparenthesize/ParenthesizedVariable.kt | 2 +- .../regression/PropertyDeclarationAsExpression.kt | 2 ++ .../kotlin/checkers/PsiCheckerTestGenerated.java | 6 ++++++ 7 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 idea/testData/checker/regression/PropertyDeclarationAsExpression.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt index 8aaeff453a7..e0e814434ee 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil import org.jetbrains.kotlin.resolve.scopes.LexicalScope -import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope import org.jetbrains.kotlin.resolve.source.toSourceElement import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.expressions.* @@ -47,9 +46,9 @@ class LocalVariableResolver( fun process( property: KtProperty, typingContext: ExpressionTypingContext, - scope: LexicalWritableScope, + scope: LexicalScope, facade: ExpressionTypingFacade - ): KotlinTypeInfo { + ): Pair { val context = typingContext.replaceContextDependency(ContextDependency.INDEPENDENT).replaceScope(scope) val receiverTypeRef = property.receiverTypeReference if (receiverTypeRef != null) { @@ -99,11 +98,10 @@ class LocalVariableResolver( ExpressionTypingUtils.checkVariableShadowing(context.scope, context.trace, propertyDescriptor) - scope.addVariableDescriptor(propertyDescriptor) property.checkTypeReferences(context.trace) modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(property, propertyDescriptor) identifierChecker.checkDeclaration(property, context.trace) - return typeInfo.replaceType(dataFlowAnalyzer.checkStatementType(property, context)) + return Pair(typeInfo.replaceType(dataFlowAnalyzer.checkStatementType(property, context)), propertyDescriptor) } private fun resolveLocalVariableDescriptor( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 95333339dd9..4f5cd1e03f7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -1461,13 +1461,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @NotNull private static KotlinTypeInfo declarationInIllegalContext( - @NotNull KtDeclaration declaration, - @NotNull ExpressionTypingContext context + @NotNull KtDeclaration declaration, + @NotNull ExpressionTypingContext context ) { context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(declaration)); return TypeInfoFactoryKt.noTypeInfo(context); } + @Override + public KotlinTypeInfo visitProperty(@NotNull KtProperty property, ExpressionTypingContext context) { + components.localVariableResolver.process(property, context, context.scope, facade); + return declarationInIllegalContext(property, context); + } + @NotNull public KotlinTypeInfo getTypeInfoForBinaryCall( @NotNull Name name, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java index c2ea86740d0..e382d37e015 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -389,6 +389,11 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor typeInfoAndVariableDescriptor = components.localVariableResolver.process(property, typingContext, scope, facade); + scope.addVariableDescriptor(typeInfoAndVariableDescriptor.getSecond()); + return typeInfoAndVariableDescriptor.getFirst(); } @Override diff --git a/compiler/testData/diagnostics/tests/deparenthesize/ParenthesizedVariable.kt b/compiler/testData/diagnostics/tests/deparenthesize/ParenthesizedVariable.kt index 444b3845c71..fd48e57fb02 100644 --- a/compiler/testData/diagnostics/tests/deparenthesize/ParenthesizedVariable.kt +++ b/compiler/testData/diagnostics/tests/deparenthesize/ParenthesizedVariable.kt @@ -1,3 +1,3 @@ fun test() { - (d@ val bar = 2) + (d@ val bar = 2) } \ No newline at end of file diff --git a/idea/testData/checker/regression/PropertyDeclarationAsExpression.kt b/idea/testData/checker/regression/PropertyDeclarationAsExpression.kt new file mode 100644 index 00000000000..7c7bef2609b --- /dev/null +++ b/idea/testData/checker/regression/PropertyDeclarationAsExpression.kt @@ -0,0 +1,2 @@ +val f = 1 > + val g: Int = 3 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java b/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java index 8efed23ab0f..81bd8444568 100644 --- a/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java @@ -562,6 +562,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest { doTest(fileName); } + @TestMetadata("PropertyDeclarationAsExpression.kt") + public void testPropertyDeclarationAsExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/PropertyDeclarationAsExpression.kt"); + doTest(fileName); + } + @TestMetadata("ScopeForSecondaryConstructors.kt") public void testScopeForSecondaryConstructors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ScopeForSecondaryConstructors.kt");