Backing field: four more errors dropped
This commit is contained in:
@@ -325,9 +325,7 @@ public class JetFlowInformationProvider {
|
|||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
ReadValueInstruction readValueInstruction = (ReadValueInstruction) instruction;
|
ReadValueInstruction readValueInstruction = (ReadValueInstruction) instruction;
|
||||||
KtElement element = readValueInstruction.getElement();
|
KtElement element = readValueInstruction.getElement();
|
||||||
boolean error = checkBackingField(ctxt, element);
|
if (PseudocodeUtil.isThisOrNoDispatchReceiver(readValueInstruction, trace.getBindingContext()) &&
|
||||||
if (!error &&
|
|
||||||
PseudocodeUtil.isThisOrNoDispatchReceiver(readValueInstruction, trace.getBindingContext()) &&
|
|
||||||
declaredVariables.contains(ctxt.variableDescriptor)) {
|
declaredVariables.contains(ctxt.variableDescriptor)) {
|
||||||
checkIsInitialized(ctxt, element, varWithUninitializedErrorGenerated);
|
checkIsInitialized(ctxt, element, varWithUninitializedErrorGenerated);
|
||||||
}
|
}
|
||||||
@@ -336,12 +334,9 @@ public class JetFlowInformationProvider {
|
|||||||
if (!(instruction instanceof WriteValueInstruction)) return;
|
if (!(instruction instanceof WriteValueInstruction)) return;
|
||||||
WriteValueInstruction writeValueInstruction = (WriteValueInstruction) instruction;
|
WriteValueInstruction writeValueInstruction = (WriteValueInstruction) instruction;
|
||||||
KtElement element = writeValueInstruction.getLValue();
|
KtElement element = writeValueInstruction.getLValue();
|
||||||
boolean error = checkBackingField(ctxt, element);
|
|
||||||
if (!(element instanceof KtExpression)) return;
|
if (!(element instanceof KtExpression)) return;
|
||||||
if (!error) {
|
boolean error = checkValReassignment(ctxt, (KtExpression) element, writeValueInstruction,
|
||||||
error = checkValReassignment(ctxt, (KtExpression) element, writeValueInstruction,
|
varWithValReassignErrorGenerated);
|
||||||
varWithValReassignErrorGenerated);
|
|
||||||
}
|
|
||||||
if (!error && processClassOrObject) {
|
if (!error && processClassOrObject) {
|
||||||
error = checkAssignmentBeforeDeclaration(ctxt, (KtExpression) element);
|
error = checkAssignmentBeforeDeclaration(ctxt, (KtExpression) element);
|
||||||
}
|
}
|
||||||
@@ -522,62 +517,6 @@ public class JetFlowInformationProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkBackingField(@NotNull VariableContext cxtx, @NotNull KtElement element) {
|
|
||||||
VariableDescriptor variableDescriptor = cxtx.variableDescriptor;
|
|
||||||
boolean[] error = new boolean[1];
|
|
||||||
if (!isCorrectBackingFieldReference(element, cxtx, error, true)) return false;
|
|
||||||
if (error[0]) return true;
|
|
||||||
if (!(variableDescriptor instanceof PropertyDescriptor)) {
|
|
||||||
report(Errors.NOT_PROPERTY_BACKING_FIELD.on(element), cxtx);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
PsiElement property = DescriptorToSourceUtils.descriptorToDeclaration(variableDescriptor);
|
|
||||||
boolean insideSelfAccessors = PsiTreeUtil.isAncestor(property, element, false);
|
|
||||||
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor) &&
|
|
||||||
// not to generate error in accessors of abstract properties, there is one: declared accessor of abstract property
|
|
||||||
!insideSelfAccessors) {
|
|
||||||
|
|
||||||
if (((PropertyDescriptor) variableDescriptor).getModality() == Modality.ABSTRACT) {
|
|
||||||
report(NO_BACKING_FIELD_ABSTRACT_PROPERTY.on(element), cxtx);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
report(NO_BACKING_FIELD_CUSTOM_ACCESSORS.on(element), cxtx);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (insideSelfAccessors) return false;
|
|
||||||
|
|
||||||
DeclarationDescriptor declarationDescriptor = BindingContextUtils.getEnclosingDescriptor(trace.getBindingContext(), element);
|
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = variableDescriptor.getContainingDeclaration();
|
|
||||||
if ((containingDeclaration instanceof ClassDescriptor)
|
|
||||||
&& DescriptorUtils.isAncestor(containingDeclaration, declarationDescriptor, false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
report(Errors.INACCESSIBLE_BACKING_FIELD.on(element), cxtx);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCorrectBackingFieldReference(
|
|
||||||
@Nullable KtElement element,
|
|
||||||
VariableContext ctxt,
|
|
||||||
boolean[] error,
|
|
||||||
boolean reportError
|
|
||||||
) {
|
|
||||||
error[0] = false;
|
|
||||||
if (element instanceof KtDotQualifiedExpression && isCorrectBackingFieldReference(
|
|
||||||
((KtDotQualifiedExpression) element).getSelectorExpression(), ctxt, error, false)) {
|
|
||||||
if (((KtDotQualifiedExpression) element).getReceiverExpression() instanceof KtThisExpression) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
error[0] = true;
|
|
||||||
if (reportError) {
|
|
||||||
report(Errors.INACCESSIBLE_BACKING_FIELD.on(element), ctxt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recordInitializedVariables(
|
private void recordInitializedVariables(
|
||||||
@NotNull Pseudocode pseudocode,
|
@NotNull Pseudocode pseudocode,
|
||||||
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> initializersMap
|
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> initializersMap
|
||||||
|
|||||||
@@ -669,13 +669,6 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_CATCH_PARAMETER = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_CATCH_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
// Backing fields
|
|
||||||
|
|
||||||
DiagnosticFactory0<KtElement> NO_BACKING_FIELD_ABSTRACT_PROPERTY = DiagnosticFactory0.create(ERROR);
|
|
||||||
DiagnosticFactory0<KtElement> NO_BACKING_FIELD_CUSTOM_ACCESSORS = DiagnosticFactory0.create(ERROR);
|
|
||||||
DiagnosticFactory0<KtElement> INACCESSIBLE_BACKING_FIELD = DiagnosticFactory0.create(ERROR);
|
|
||||||
DiagnosticFactory0<KtElement> NOT_PROPERTY_BACKING_FIELD = DiagnosticFactory0.create(ERROR);
|
|
||||||
|
|
||||||
// When expressions
|
// When expressions
|
||||||
|
|
||||||
DiagnosticFactory0<KtWhenCondition> EXPECTED_CONDITION = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<KtWhenCondition> EXPECTED_CONDITION = DiagnosticFactory0.create(ERROR);
|
||||||
|
|||||||
-6
@@ -164,12 +164,6 @@ public class DefaultErrorMessages {
|
|||||||
|
|
||||||
MAP.put(CANNOT_INFER_PARAMETER_TYPE, "Cannot infer a type for this parameter. Please specify it explicitly.");
|
MAP.put(CANNOT_INFER_PARAMETER_TYPE, "Cannot infer a type for this parameter. Please specify it explicitly.");
|
||||||
|
|
||||||
MAP.put(NO_BACKING_FIELD_ABSTRACT_PROPERTY, "This property doesn't have a backing field, because it's abstract");
|
|
||||||
MAP.put(NO_BACKING_FIELD_CUSTOM_ACCESSORS,
|
|
||||||
"This property doesn't have a backing field, because it has custom accessors without reference to the backing field");
|
|
||||||
MAP.put(INACCESSIBLE_BACKING_FIELD, "The backing field is not accessible here");
|
|
||||||
MAP.put(NOT_PROPERTY_BACKING_FIELD, "The referenced variable is not a property and doesn't have backing field");
|
|
||||||
|
|
||||||
MAP.put(MIXING_NAMED_AND_POSITIONED_ARGUMENTS, "Mixing named and positioned arguments is not allowed");
|
MAP.put(MIXING_NAMED_AND_POSITIONED_ARGUMENTS, "Mixing named and positioned arguments is not allowed");
|
||||||
MAP.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter");
|
MAP.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter");
|
||||||
MAP.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", ELEMENT_TEXT);
|
MAP.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", ELEMENT_TEXT);
|
||||||
|
|||||||
@@ -123,11 +123,6 @@ public class QuickFixRegistrar : QuickFixContributor {
|
|||||||
WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(removeModifierFactory)
|
WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(removeModifierFactory)
|
||||||
REPEATED_MODIFIER.registerFactory(removeModifierFactory)
|
REPEATED_MODIFIER.registerFactory(removeModifierFactory)
|
||||||
|
|
||||||
val changeToPropertyNameFactory = ChangeToPropertyNameFix.createFactory()
|
|
||||||
NO_BACKING_FIELD_ABSTRACT_PROPERTY.registerFactory(changeToPropertyNameFactory)
|
|
||||||
NO_BACKING_FIELD_CUSTOM_ACCESSORS.registerFactory(changeToPropertyNameFactory)
|
|
||||||
INACCESSIBLE_BACKING_FIELD.registerFactory(changeToPropertyNameFactory)
|
|
||||||
|
|
||||||
UNRESOLVED_REFERENCE.registerFactory(AutoImportFix)
|
UNRESOLVED_REFERENCE.registerFactory(AutoImportFix)
|
||||||
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AutoImportFix)
|
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AutoImportFix)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user