diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 775f518124a..0e69cc0ab93 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -506,6 +506,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } else { context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); + ExpressionTypingUtils.checkWrappingInRef(baseExpression, context); } // TODO : Maybe returnType? result = receiverType; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index 75aefa19eb0..1b181c887b0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -6,6 +6,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -24,6 +26,7 @@ import java.util.List; import static org.jetbrains.jet.lang.diagnostics.Errors.RESULT_TYPE_MISMATCH; import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH; +import static org.jetbrains.jet.lang.resolve.BindingContext.MUST_BE_WRAPPED_IN_A_REF; /** * @author abreslav @@ -249,4 +252,16 @@ public class ExpressionTypingUtils { } return context.expectedType; } + + public static void checkWrappingInRef(JetExpression expression, ExpressionTypingContext context) { + if (!(expression instanceof JetSimpleNameExpression)) return; + JetSimpleNameExpression simpleName = (JetSimpleNameExpression) expression; + VariableDescriptor variable = AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), simpleName); + if (variable != null) { + DeclarationDescriptor containingDeclaration = variable.getContainingDeclaration(); + if (context.scope.getContainingDeclaration() != containingDeclaration && containingDeclaration instanceof CallableDescriptor) { + context.trace.record(MUST_BE_WRAPPED_IN_A_REF, variable); + } + } + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java index bd5a325ffdf..acbd1271b57 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java @@ -8,7 +8,6 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TopDownAnalyzer; -import org.jetbrains.jet.lang.resolve.calls.AutoCastUtils; import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; @@ -16,7 +15,6 @@ import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lexer.JetTokens; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.MUST_BE_WRAPPED_IN_A_REF; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getExpressionReceiver; @@ -107,6 +105,7 @@ public class ExpressionTypingVisitorWithWritableScope extends BasicExpressionTyp JetType typeForBinaryCall = getTypeForBinaryCall(scope, counterpartName, context, expression); if (typeForBinaryCall != null) { context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); + ExpressionTypingUtils.checkWrappingInRef(expression.getLeft(), context); } } else { @@ -149,13 +148,7 @@ public class ExpressionTypingVisitorWithWritableScope extends BasicExpressionTyp context.trace.record(BindingContext.VARIABLE_ASSIGNMENT, simpleName, property); } } - VariableDescriptor variable = AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), simpleName); - if (variable != null) { - DeclarationDescriptor containingDeclaration = variable.getContainingDeclaration(); - if (context.scope.getContainingDeclaration() != containingDeclaration && containingDeclaration instanceof CallableDescriptor) { - context.trace.record(MUST_BE_WRAPPED_IN_A_REF, variable); - } - } + ExpressionTypingUtils.checkWrappingInRef(simpleName, context); } return checkExpectedType(expression, context); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java deleted file mode 100644 index 4b4200764d2..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.jet.lang.types.expressions; - -/** - * @author abreslav - */ -public class FunctionBodyTyper { -} diff --git a/idea/testData/checker/infos/WrapIntoRef.jet b/idea/testData/checker/infos/WrapIntoRef.jet index 47613236fa0..fb938acda53 100644 --- a/idea/testData/checker/infos/WrapIntoRef.jet +++ b/idea/testData/checker/infos/WrapIntoRef.jet @@ -1,4 +1,4 @@ -fun notContainsBreak() { +fun refs() { var a = 1 val v = { a = 2 @@ -16,3 +16,22 @@ fun notContainsBreak() { y = 1 } } + +fun refsPlusAssign() { + var a = 1 + val v = { + a += 2 + } + + var x = 1 + val b = object { + fun foo() { + x += 2 + } + } + + var y = 1 + fun foo() { + y += 1 + } +}