KT-1191 Wrong detection of unused parameters

KT-1219 Incorrect 'unused value' error in closures
This commit is contained in:
Svetlana Isakova
2012-02-22 17:07:49 +04:00
parent 7f2a8100c4
commit cc244fad94
12 changed files with 94 additions and 22 deletions
@@ -167,7 +167,7 @@ public class JetControlFlowGraphTraverser<D> {
}
public D getResultInfo() {
return dataMap.get(pseudocode.getSinkInstruction()).getFirst();
return dataMap.get(pseudocode.getExitInstruction()).getFirst();
}
interface InstructionDataMergeStrategy<D> {
@@ -711,6 +711,14 @@ public class JetControlFlowProcessor {
value(initializer, false);
builder.write(property, property);
}
for (JetPropertyAccessor accessor : property.getAccessors()) {
value(accessor, false);
}
}
@Override
public void visitPropertyAccessor(JetPropertyAccessor accessor) {
processLocalDeclaration(accessor);
}
@Override
@@ -41,6 +41,7 @@ import org.jetbrains.jet.plugin.JetMainDetector;
import java.util.*;
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.types.TypeUtils.NO_EXPECTED_TYPE;
/**
@@ -254,7 +255,7 @@ public class JetFlowInformationProvider {
if (!error && !processLocalDeclaration) { // error has been generated before, while processing outer function of this local declaration
error = checkValReassignment(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), varWithValReassignErrorGenerated);
}
if (!error) {
if (!error && processClassOrObject) {
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), exitData.get(variableDescriptor));
}
if (!error && processClassOrObject) {
@@ -265,7 +266,7 @@ public class JetFlowInformationProvider {
});
recordInitializedVariables(declaredVariables, traverser.getResultInfo());
analyzeLocalDeclarations(processLocalDeclaration, pseudocode);
analyzeLocalDeclarations(pseudocode, processLocalDeclaration);
}
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
@@ -442,7 +443,7 @@ public class JetFlowInformationProvider {
}
}
private void analyzeLocalDeclarations(boolean processLocalDeclaration, Pseudocode pseudocode) {
private void analyzeLocalDeclarations(Pseudocode pseudocode, boolean processLocalDeclaration) {
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof LocalDeclarationInstruction) {
JetElement element = ((LocalDeclarationInstruction) instruction).getElement();
@@ -595,6 +596,7 @@ public class JetFlowInformationProvider {
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
VariableStatus variableStatus = enterData.get(variableDescriptor);
if (instruction instanceof WriteValueInstruction) {
if (trace.get(MUST_BE_WRAPPED_IN_A_REF, variableDescriptor)) return;
JetElement element = ((WriteValueInstruction) instruction).getElement();
if (variableStatus != VariableStatus.READ) {
if (element instanceof JetBinaryExpression && ((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
@@ -66,12 +66,14 @@ public class ControlFlowAnalyzer {
}
for (Map.Entry<JetProperty, PropertyDescriptor> entry : context.getProperties().entrySet()) {
JetProperty property = entry.getKey();
if (!context.completeAnalysisNeeded(property)) continue;
PropertyDescriptor propertyDescriptor = entry.getValue();
checkProperty(property, propertyDescriptor);
}
}
private void checkClassOrObject(JetClassOrObject klass) {
// A pseudocode of class initialization corresponds to a class
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, (JetExpression) klass, flowDataTraceFactory, context.getTrace());
flowInformationProvider.markUninitializedVariables((JetElement) klass, context.isDeclaredLocally());
}
@@ -95,7 +97,9 @@ public class ControlFlowAnalyzer {
flowInformationProvider.checkDefiniteReturn(function, expectedReturnType);
flowInformationProvider.markUninitializedVariables(function.asElement(), context.isDeclaredLocally());
// Property accessor is checked through initialization of a class check (at 'checkClassOrObject')
boolean isPropertyAccessor = function instanceof JetPropertyAccessor;
flowInformationProvider.markUninitializedVariables(function.asElement(), context.isDeclaredLocally() || isPropertyAccessor);
flowInformationProvider.markUnusedVariables(function.asElement());