ControlFlowInformationProvider: fix warnings

This commit is contained in:
Mikhail Glukhikh
2019-07-09 17:24:25 +03:00
parent 5e94f537ef
commit b97f187cf6
@@ -218,7 +218,7 @@ class ControlFlowInformationProvider private constructor(
val element = localDeclarationInstruction.element
if (element is KtDeclarationWithBody) {
val functionDescriptor = trace.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element) as? CallableDescriptor
val functionDescriptor = trace.bindingContext.get(DECLARATION_TO_DESCRIPTOR, element) as? CallableDescriptor
val expectedType = functionDescriptor?.returnType
val providerForLocalDeclaration = ControlFlowInformationProvider(
@@ -440,7 +440,7 @@ class ControlFlowInformationProvider private constructor(
is KtDeclarationWithBody -> {
// If it is captured write in lambda that is called in-place, then skip it (treat as parent)
val maybeEnclosingLambdaExpr = parentDeclaration.parent
if (maybeEnclosingLambdaExpr is KtLambdaExpression && trace[BindingContext.LAMBDA_INVOCATIONS, maybeEnclosingLambdaExpr] != null) {
if (maybeEnclosingLambdaExpr is KtLambdaExpression && trace[LAMBDA_INVOCATIONS, maybeEnclosingLambdaExpr] != null) {
parentDeclaration = getElementParentDeclaration(parentDeclaration)
continue@loop
}
@@ -466,7 +466,7 @@ class ControlFlowInformationProvider private constructor(
val variableDescriptor = ctxt.variableDescriptor
val mayBeInitializedNotHere = ctxt.enterInitState?.mayBeInitialized() ?: false
val hasBackingField = (variableDescriptor as? PropertyDescriptor)?.let {
trace.get(BindingContext.BACKING_FIELD_REQUIRED, it)
trace.get(BACKING_FIELD_REQUIRED, it)
} ?: true
if (variableDescriptor is PropertyDescriptor && variableDescriptor.isVar) {
val descriptor = BindingContextUtils.getEnclosingDescriptor(trace.bindingContext, expression)
@@ -493,15 +493,14 @@ class ControlFlowInformationProvider private constructor(
variableDescriptor != null && !variableDescriptor.isVar
) {
var hasReassignMethodReturningUnit = false
val parent = expression.parent
val operationReference =
when (parent) {
when (val parent = expression.parent) {
is KtBinaryExpression -> parent.operationReference
is KtUnaryExpression -> parent.operationReference
else -> null
}
if (operationReference != null) {
val descriptor = trace.get(BindingContext.REFERENCE_TARGET, operationReference)
val descriptor = trace.get(REFERENCE_TARGET, operationReference)
if (descriptor is FunctionDescriptor) {
if (descriptor.returnType?.let { KotlinBuiltIns.isUnit(it) } == true) {
hasReassignMethodReturningUnit = true
@@ -545,9 +544,9 @@ class ControlFlowInformationProvider private constructor(
private fun reportValReassigned(expression: KtExpression, variableDescriptor: VariableDescriptor, ctxt: VariableInitContext) {
val diagnosticFactory = if (languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField))
Errors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
else
Errors.VAL_REASSIGNMENT_VIA_BACKING_FIELD
VAL_REASSIGNMENT_VIA_BACKING_FIELD
report(diagnosticFactory.on(expression, variableDescriptor), ctxt)
}
@@ -563,7 +562,7 @@ class ControlFlowInformationProvider private constructor(
}
private fun VariableInitContext.isInitializationBeforeDeclaration(): Boolean =
// is not declared
// is not declared
enterInitState?.isDeclared != true && exitInitState?.isDeclared != true &&
// wasn't initialized before current instruction
enterInitState?.mayBeInitialized() != true
@@ -574,7 +573,7 @@ class ControlFlowInformationProvider private constructor(
|| ctxt.enterInitState?.mayBeInitialized() == true
|| ctxt.exitInitState?.mayBeInitialized() != true
|| !variableDescriptor.isVar
|| trace.get(BindingContext.BACKING_FIELD_REQUIRED, variableDescriptor) != true
|| trace.get(BACKING_FIELD_REQUIRED, variableDescriptor) != true
) {
return false
}
@@ -609,7 +608,7 @@ class ControlFlowInformationProvider private constructor(
for (variable in declaredVariables) {
if (variable is PropertyDescriptor) {
if (initializers.incoming.getOrNull(variable)?.definitelyInitialized() == true) continue
trace.record(BindingContext.IS_UNINITIALIZED, variable)
trace.record(IS_UNINITIALIZED, variable)
}
}
}
@@ -643,7 +642,7 @@ class ControlFlowInformationProvider private constructor(
if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor) != null) return@traverse
val expressionInQuestion = instruction.element as? KtExpression ?: return@traverse
if (variableUseState != READ) {
unusedValueExpressions.put(expressionInQuestion, variableDescriptor to ctxt)
unusedValueExpressions[expressionInQuestion] = variableDescriptor to ctxt
} else {
usedValueExpressions.add(expressionInQuestion)
}
@@ -715,8 +714,7 @@ class ControlFlowInformationProvider private constructor(
!diagnosticSuppressor.shouldReportUnusedParameter(variableDescriptor)
) return
val owner = element.parent.parent
when (owner) {
when (val owner = element.parent.parent) {
is KtPrimaryConstructor -> if (!element.hasValOrVar()) {
val containingClass = (functionDescriptor as ConstructorDescriptor).containingDeclaration
if (!DescriptorUtils.isAnnotationClass(containingClass)) {
@@ -793,11 +791,11 @@ class ControlFlowInformationProvider private constructor(
val value = (instruction as? InstructionWithValue)?.outputValue
val pseudocode = instruction.owner
val usages = pseudocode.getUsages(value)
val isUsedAsExpression = !usages.isEmpty()
val isUsedAsExpression = usages.isNotEmpty()
val isUsedAsResultOfLambda = isUsedAsResultOfLambda(usages)
for (element in pseudocode.getValueElements(value)) {
trace.record(BindingContext.USED_AS_EXPRESSION, element, isUsedAsExpression)
trace.record(BindingContext.USED_AS_RESULT_OF_LAMBDA, element, isUsedAsResultOfLambda)
trace.record(USED_AS_EXPRESSION, element, isUsedAsExpression)
trace.record(USED_AS_RESULT_OF_LAMBDA, element, isUsedAsResultOfLambda)
}
}
@@ -898,14 +896,14 @@ class ControlFlowInformationProvider private constructor(
val enumClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfEnum(subjectType)
if (enumClassDescriptor != null) {
val enumMissingCases = WhenChecker.getEnumMissingCases(element, context, enumClassDescriptor)
if (!enumMissingCases.isEmpty()) {
if (enumMissingCases.isNotEmpty()) {
trace.report(NON_EXHAUSTIVE_WHEN.on(element, enumMissingCases))
}
}
val sealedClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfSealed(subjectType)
if (sealedClassDescriptor != null) {
val sealedMissingCases = WhenChecker.getSealedMissingCases(element, context, sealedClassDescriptor)
if (!sealedMissingCases.isEmpty()) {
if (sealedMissingCases.isNotEmpty()) {
trace.report(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS.on(element, sealedMissingCases))
}
}
@@ -926,7 +924,7 @@ class ControlFlowInformationProvider private constructor(
// Tail calls
private fun markAndCheckTailCalls() {
val subroutineDescriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, subroutine) as? FunctionDescriptor ?: return
val subroutineDescriptor = trace.get(DECLARATION_TO_DESCRIPTOR, subroutine) as? FunctionDescriptor ?: return
markAndCheckRecursiveTailCalls(subroutineDescriptor)
}
@@ -936,7 +934,7 @@ class ControlFlowInformationProvider private constructor(
if (subroutine is KtNamedFunction && !subroutine.hasBody()) return
// finally blocks are copied which leads to multiple diagnostics reported on one instruction
class KindAndCall(var kind: TailRecursionKind, internal val call: ResolvedCall<*>)
class KindAndCall(var kind: TailRecursionKind, val call: ResolvedCall<*>)
val calls = HashMap<KtElement, KindAndCall>()
traverseCalls traverse@{ instruction, resolvedCall ->
@@ -955,7 +953,7 @@ class ControlFlowInformationProvider private constructor(
if (isInsideTry(element)) {
// We do not support tail calls Collections.singletonMap() try-catch-finally, for simplicity of the mental model
// very few cases there would be real tail-calls, and it's often not so easy for the user to see why
calls.put(element, KindAndCall(IN_TRY, resolvedCall))
calls[element] = KindAndCall(IN_TRY, resolvedCall)
return@traverse
}
@@ -970,14 +968,14 @@ class ControlFlowInformationProvider private constructor(
val kind = if (sameDispatchReceiver && instruction.isTailCall()) TAIL_CALL else NON_TAIL
val kindAndCall = calls[element]
calls.put(element, KindAndCall(combineKinds(kind, kindAndCall?.kind), resolvedCall))
calls[element] = KindAndCall(combineKinds(kind, kindAndCall?.kind), resolvedCall)
}
var hasTailCalls = false
for ((element, kindAndCall) in calls) {
when (kindAndCall.kind) {
TAIL_CALL -> {
trace.record(TAIL_RECURSION_CALL, kindAndCall.call.call, TailRecursionKind.TAIL_CALL)
trace.record(TAIL_RECURSION_CALL, kindAndCall.call.call, TAIL_CALL)
hasTailCalls = true
}
IN_TRY -> trace.report(Errors.TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED.on(element))
@@ -1034,7 +1032,7 @@ class ControlFlowInformationProvider private constructor(
return
}
val previouslyReported = ctxt.reportedDiagnosticMap
previouslyReported.put(instruction, diagnostic.factory)
previouslyReported[instruction] = diagnostic.factory
var alreadyReported = false
var sameErrorForAllCopies = true