From 639497d7c3c7c1e08920c975338da74e55bbdb23 Mon Sep 17 00:00:00 2001 From: svtk Date: Fri, 4 Nov 2011 15:58:46 +0400 Subject: [PATCH] Added 'variable expected' error on assignments --- .../jet/lang/diagnostics/Errors.java | 7 ++-- .../ExpressionTypingVisitorForStatements.java | 5 +++ .../quick/LValueAssignment.jet | 38 +++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index b53ce8d9122..8a9ccc2a60e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -143,17 +143,18 @@ public interface Errors { PsiElementOnlyDiagnosticFactory3 VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT); PsiElementOnlyDiagnosticFactory1 UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be initialized", NAME); - PsiElementOnlyDiagnosticFactory2 VAL_REASSIGNMENT = new PsiElementOnlyDiagnosticFactory2(ERROR, "Val can not be reassigned", NAME) { + PsiElementOnlyDiagnosticFactory2 VAL_REASSIGNMENT = new PsiElementOnlyDiagnosticFactory2(ERROR, "Val can not be reassigned", NAME) { @NotNull @Override - public DiagnosticWithPsiElement on(@NotNull JetSimpleNameExpression elementToBlame, @NotNull ASTNode nodeToMark, @NotNull DeclarationDescriptor declarationDescriptor, @NotNull JetProperty[] property) { - DiagnosticWithPsiElement diagnostic = super.on(elementToBlame, nodeToMark, declarationDescriptor, property); + public DiagnosticWithPsiElement on(@NotNull JetExpression elementToBlame, @NotNull ASTNode nodeToMark, @NotNull DeclarationDescriptor declarationDescriptor, @NotNull JetProperty[] property) { + DiagnosticWithPsiElement diagnostic = super.on(elementToBlame, nodeToMark, declarationDescriptor, property); if (property.length == 1) { return diagnostic.add(DiagnosticParameters.PROPERTY, property[0]); } return diagnostic; } }; + SimplePsiElementOnlyDiagnosticFactory VARIABLE_EXPECTED = new SimplePsiElementOnlyDiagnosticFactory(ERROR, "Variable expected"); PsiElementOnlyDiagnosticFactory1 INITIALIZATION_USING_BACKING_FIELD = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Initialization using backing field required", NAME); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java index b3de2c0511f..9686d71c786 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TopDownAnalyzer; import org.jetbrains.jet.lang.resolve.calls.CallMaker; @@ -150,6 +151,10 @@ public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingV if (right != null) { JetType rightType = facade.getType(right, context.replaceExpectedType(leftType).replaceScope(scope)); } + VariableDescriptor variable = BindingContextUtils.extractVariableDescriptorIfAny(context.trace.getBindingContext(), left, true); + if (variable == null && leftType != null) { //if leftType == null, some another error has been generated + context.trace.report(VARIABLE_EXPECTED.on(left != null ? left : expression.getLeft())); + } if (left instanceof JetSimpleNameExpression) { JetSimpleNameExpression simpleName = (JetSimpleNameExpression) left; String referencedName = simpleName.getReferencedName(); diff --git a/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet b/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet new file mode 100644 index 00000000000..6702808b0d8 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet @@ -0,0 +1,38 @@ +namespace lvalue_assignment + +open class B() { + var b: Int = 2 + val c: Int = 34 +} + +class C() : B() { + var x = 4 + fun foo(c: C) { + this.x = 34 + this.b = 123 + super.b = 23 + this.c = 34 + super.c = 3535 + + getInt() = 12 + } + + fun foo(c: C) { + this = c //should be an error + } +} + +fun getInt() = 0 + +class D() { + class B() { + fun foo() { + this@D = D() + } + } +} + +fun cannotBe() { + z = 30; + () = (); +}