Vars modified in closures are marked with a MUST_BE_WRAPPED_IN_A_REF key
This commit is contained in:
@@ -45,8 +45,11 @@ public interface BindingContext {
|
|||||||
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice("STATEMENT");
|
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice("STATEMENT");
|
||||||
WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice("DELEGATED");
|
WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice("DELEGATED");
|
||||||
|
|
||||||
|
WritableSlice<VariableDescriptor, Boolean> MUST_BE_WRAPPED_IN_A_REF = Slices.createSimpleSetSlice("MUST_BE_WRAPPED_IN_A_REF");
|
||||||
|
|
||||||
enum DeferredTypeKey {DEFERRED_TYPE_KEY}
|
enum DeferredTypeKey {DEFERRED_TYPE_KEY}
|
||||||
WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice("DEFERRED_TYPES");
|
WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice("DEFERRED_TYPES");
|
||||||
|
|
||||||
WritableSlice<DeferredTypeKey, DeferredType> DEFERRED_TYPE = new CollectionSliceWrapper<DeferredTypeKey, DeferredType>(DEFERRED_TYPES, CommonSuppliers.<DeferredType>getArrayListSupplier());
|
WritableSlice<DeferredTypeKey, DeferredType> DEFERRED_TYPE = new CollectionSliceWrapper<DeferredTypeKey, DeferredType>(DEFERRED_TYPES, CommonSuppliers.<DeferredType>getArrayListSupplier());
|
||||||
|
|
||||||
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>("BACKING_FIELD_REQUIRED", RewritePolicy.DO_NOTHING) {
|
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>("BACKING_FIELD_REQUIRED", RewritePolicy.DO_NOTHING) {
|
||||||
|
|||||||
@@ -2815,13 +2815,20 @@ public class JetTypeInferrer {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
if (left instanceof JetSimpleNameExpression) {
|
if (left instanceof JetSimpleNameExpression) {
|
||||||
JetSimpleNameExpression variable = (JetSimpleNameExpression) left;
|
JetSimpleNameExpression simpleName = (JetSimpleNameExpression) left;
|
||||||
String referencedName = variable.getReferencedName();
|
String referencedName = simpleName.getReferencedName();
|
||||||
if (variable.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER
|
if (simpleName.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER
|
||||||
&& referencedName != null) {
|
&& referencedName != null) {
|
||||||
PropertyDescriptor property = context.scope.getPropertyByFieldReference(referencedName);
|
PropertyDescriptor property = context.scope.getPropertyByFieldReference(referencedName);
|
||||||
if (property != null) {
|
if (property != null) {
|
||||||
context.trace.record(BindingContext.VARIABLE_ASSIGNMENT, variable, property);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,6 +97,15 @@ public class JetHighlighter extends SyntaxHighlighterBase {
|
|||||||
JET_AUTO_CAST_EXPRESSION = TextAttributesKey.createTextAttributesKey("JET.AUTO.CAST.EXPRESSION", clone);
|
JET_AUTO_CAST_EXPRESSION = TextAttributesKey.createTextAttributesKey("JET.AUTO.CAST.EXPRESSION", clone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final TextAttributesKey JET_WRAPPED_INTO_REF;
|
||||||
|
|
||||||
|
static {
|
||||||
|
TextAttributes attributes = new TextAttributes();
|
||||||
|
attributes.setEffectType(EffectType.LINE_UNDERSCORE);
|
||||||
|
attributes.setEffectColor(Color.BLACK);
|
||||||
|
JET_WRAPPED_INTO_REF = TextAttributesKey.createTextAttributesKey("JET.WRAPPED.INTO.REF", attributes);
|
||||||
|
}
|
||||||
|
|
||||||
public static final TextAttributesKey JET_AUTOCREATED_IT;
|
public static final TextAttributesKey JET_AUTOCREATED_IT;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.plugin.annotations;
|
|||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.codeInsight.intention.IntentionAction;
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
import com.intellij.codeInspection.ProblemHighlightType;
|
import com.intellij.codeInspection.ProblemHighlightType;
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.lang.annotation.Annotation;
|
import com.intellij.lang.annotation.Annotation;
|
||||||
import com.intellij.lang.annotation.AnnotationHolder;
|
import com.intellij.lang.annotation.AnnotationHolder;
|
||||||
import com.intellij.lang.annotation.Annotator;
|
import com.intellij.lang.annotation.Annotator;
|
||||||
@@ -117,9 +118,28 @@ public class JetPsiChecker implements Annotator {
|
|||||||
holder.createInfoAnnotation(expression, "Automatically declared based on the expected type").setTextAttributes(JetHighlighter.JET_AUTOCREATED_IT);
|
holder.createInfoAnnotation(expression, "Automatically declared based on the expected type").setTextAttributes(JetHighlighter.JET_AUTOCREATED_IT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markVariableAsWrappedIfNeeded(expression.getNode(), target);
|
||||||
super.visitSimpleNameExpression(expression);
|
super.visitSimpleNameExpression(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void markVariableAsWrappedIfNeeded(ASTNode node, DeclarationDescriptor target) {
|
||||||
|
if (target instanceof VariableDescriptor) {
|
||||||
|
VariableDescriptor variableDescriptor = (VariableDescriptor) target;
|
||||||
|
if (bindingContext.get(MUST_BE_WRAPPED_IN_A_REF, variableDescriptor)) {
|
||||||
|
holder.createInfoAnnotation(node, "Wrapped into a ref-object to be modifier when captured in a closure").setTextAttributes(JetHighlighter.JET_WRAPPED_INTO_REF);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitProperty(JetProperty property) {
|
||||||
|
DeclarationDescriptor declarationDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, property);
|
||||||
|
markVariableAsWrappedIfNeeded(property.getNameIdentifier().getNode(), declarationDescriptor);
|
||||||
|
super.visitProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitExpression(JetExpression expression) {
|
public void visitExpression(JetExpression expression) {
|
||||||
JetType autoCast = bindingContext.get(AUTOCAST, expression);
|
JetType autoCast = bindingContext.get(AUTOCAST, expression);
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
fun notContainsBreak() {
|
||||||
|
var <info>a</info> = 1
|
||||||
|
val v = {
|
||||||
|
<info>a</info> = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
var <info>x</info> = 1
|
||||||
|
val b = object {
|
||||||
|
fun foo() {
|
||||||
|
<info>x</info> = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var <info>y</info> = 1
|
||||||
|
fun foo() {
|
||||||
|
<info>y</info> = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user