Simplify resolve for control labels by using PSI
Diagnostic `NOT_A_RETURN_LABEL` wasn't quite useful and its eliminating allows to simplify label resolver a lot. It could be also added using PSI
This commit is contained in:
@@ -731,7 +731,6 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtExpressionWithLabel> BREAK_OR_CONTINUE_IN_WHEN = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtExpressionWithLabel> BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<KtExpressionWithLabel, String> NOT_A_LOOP_LABEL = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<KtReturnExpression, String> NOT_A_RETURN_LABEL = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
// Control flow / Data flow
|
||||
|
||||
|
||||
-1
@@ -555,7 +555,6 @@ public class DefaultErrorMessages {
|
||||
MAP.put(BREAK_OR_CONTINUE_IN_WHEN, "'break' and 'continue' are not allowed in 'when' statements. Consider using labels to continue/break from the outer loop");
|
||||
MAP.put(BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY, "'break' or 'continue' jumps across a function or a class boundary");
|
||||
MAP.put(NOT_A_LOOP_LABEL, "The label ''{0}'' does not denote a loop", STRING);
|
||||
MAP.put(NOT_A_RETURN_LABEL, "The label ''{0}'' does not reference to a context from which we can return", STRING);
|
||||
|
||||
MAP.put(ANONYMOUS_INITIALIZER_IN_INTERFACE, "Anonymous initializers are not allowed in interfaces");
|
||||
MAP.put(NULLABLE_SUPERTYPE, "A supertype cannot be nullable");
|
||||
|
||||
+1
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -623,9 +623,6 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
context.trace.report(NOT_A_RETURN_LABEL.on(expression, expression.getLabelName()));
|
||||
}
|
||||
}
|
||||
|
||||
if (returnedExpression != null) {
|
||||
|
||||
@@ -106,32 +106,10 @@ object LabelResolver {
|
||||
val labelName = expression.getLabelNameAsName()
|
||||
if (labelElement == null || labelName == null) return null
|
||||
|
||||
val element = resolveNamedLabel(labelName, labelElement, context.trace)
|
||||
if (element != null) return element
|
||||
|
||||
val declarationsByLabel = context.scope.getDeclarationsByLabel(labelName)
|
||||
when (declarationsByLabel.size) {
|
||||
0 -> {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(labelElement, labelElement))
|
||||
return null
|
||||
}
|
||||
1 -> {
|
||||
val declarationDescriptor = declarationsByLabel.single()
|
||||
if (declarationDescriptor is FunctionDescriptor || declarationDescriptor is ClassDescriptor) {
|
||||
val declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor)
|
||||
if (declarationElement is KtElement) {
|
||||
context.trace.record(LABEL_TARGET, labelElement, declarationElement)
|
||||
return declarationElement
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
BindingContextUtils.reportAmbiguousLabel(context.trace, labelElement, declarationsByLabel)
|
||||
return null
|
||||
}
|
||||
return resolveNamedLabel(labelName, labelElement, context.trace) ?: run {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(labelElement, labelElement))
|
||||
null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun resolveNamedLabel(
|
||||
|
||||
+2
-2
@@ -6,10 +6,10 @@ class A {
|
||||
if (1 < 2)
|
||||
return@inner
|
||||
else
|
||||
<!RETURN_NOT_ALLOWED!>return@outer<!>
|
||||
<!RETURN_NOT_ALLOWED!>return@outer<!>
|
||||
}
|
||||
if (1 < 2)
|
||||
<!NOT_A_RETURN_LABEL!>return@A<!>
|
||||
return<!UNRESOLVED_REFERENCE!>@A<!>
|
||||
else if (2 < 3)
|
||||
return<!UNRESOLVED_REFERENCE!>@inner<!>
|
||||
return@outer
|
||||
|
||||
Reference in New Issue
Block a user