Analyze local variable declarations in expression position

Fixes exception on invalid code "val c = 1 < val Int.f: Int = 3"
This commit is contained in:
Pavel V. Talanov
2016-01-12 14:12:30 +03:00
parent 060864f7af
commit 9bfa90dc0e
7 changed files with 29 additions and 9 deletions
@@ -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<KotlinTypeInfo, VariableDescriptor> {
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(
@@ -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,
@@ -389,6 +389,11 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
return basic.visitClass(klass, data);
}
@Override
public KotlinTypeInfo visitProperty(@NotNull KtProperty property, ExpressionTypingContext data) {
return basic.visitProperty(property, data);
}
@Override
public KotlinTypeInfo visitStringTemplateExpression(@NotNull KtStringTemplateExpression expression, ExpressionTypingContext data) {
return basic.visitStringTemplateExpression(expression, data);
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.types.expressions;
import com.google.common.collect.Sets;
import com.intellij.psi.tree.IElementType;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
@@ -103,7 +104,9 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override
public KotlinTypeInfo visitProperty(@NotNull KtProperty property, ExpressionTypingContext typingContext) {
return components.localVariableResolver.process(property, typingContext, scope, facade);
Pair<KotlinTypeInfo, VariableDescriptor> typeInfoAndVariableDescriptor = components.localVariableResolver.process(property, typingContext, scope, facade);
scope.addVariableDescriptor(typeInfoAndVariableDescriptor.getSecond());
return typeInfoAndVariableDescriptor.getFirst();
}
@Override
@@ -1,3 +1,3 @@
fun test() {
(d@ <!DECLARATION_IN_ILLEGAL_CONTEXT!>val bar = 2<!>)
(d@ <!DECLARATION_IN_ILLEGAL_CONTEXT!>val <!UNUSED_VARIABLE!>bar<!> = 2<!>)
}
@@ -0,0 +1,2 @@
val f = 1 >
<error descr="[DECLARATION_IN_ILLEGAL_CONTEXT] Declarations are not allowed in this position">val g: Int = 3</error>
@@ -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");