[FE 1.0] Cleanup code of ControlFlowProcessor

- Always pass not nullable language version settings
- Fix warnings and style
- Remove redundant pseudocode utils
This commit is contained in:
Dmitriy Novozhilov
2022-01-12 16:49:36 +03:00
committed by teamcity
parent 9f870b0549
commit 50f6825775
4 changed files with 51 additions and 47 deletions
@@ -33,16 +33,13 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.InstructionWithValu
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.contracts.description.canBeRevisited
import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
@@ -71,7 +68,7 @@ typealias DeferredGenerator = (ControlFlowBuilder) -> Unit
class ControlFlowProcessor(
private val trace: BindingTrace,
private val languageVersionSettings: LanguageVersionSettings?
private val languageVersionSettings: LanguageVersionSettings
) {
private val builder: ControlFlowBuilder = ControlFlowInstructionsGenerator()
@@ -169,7 +166,7 @@ class ControlFlowProcessor(
}
override fun visitKtElement(element: KtElement) {
throw UnsupportedOperationException("[ControlFlowProcessor] " + element.toString())
throw UnsupportedOperationException("[ControlFlowProcessor] $element")
}
}
@@ -310,7 +307,7 @@ class ControlFlowProcessor(
deparenthesizedBaseExpression !is KtLoopExpression &&
deparenthesizedBaseExpression !is KtNamedFunction
) {
trace.report(Errors.REDUNDANT_LABEL_WARNING.on(labelNameExpression))
trace.report(REDUNDANT_LABEL_WARNING.on(labelNameExpression))
}
}
}
@@ -348,7 +345,7 @@ class ControlFlowProcessor(
generateInstructions(right)
builder.bindLabel(afterElvis)
mergeValues(listOfNotNull(left, right), expression)
if (right != null && languageVersionSettings?.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis) == true) {
if (right != null && languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis)) {
trace.record(USED_AS_EXPRESSION, right, true)
}
} else {
@@ -373,12 +370,12 @@ class ControlFlowProcessor(
generateInstructions(right)
builder.bindLabel(resultLabel)
val operation = if (operationType === ANDAND) ControlFlowBuilder.PredefinedOperation.AND else OR
builder.predefinedOperation(expression, operation, elementsToValues(listOf(left, right).filterNotNull()))
builder.predefinedOperation(expression, operation, elementsToValues(listOfNotNull(left, right)))
}
private fun getValueAsFunction(value: PseudoValue?) = { value }
private fun getValueAsFunction(value: PseudoValue?): () -> PseudoValue? = { value }
private fun getDeferredValue(expression: KtExpression?) = {
private fun getDeferredValue(expression: KtExpression?): () -> PseudoValue? = {
generateInstructions(expression)
getBoundOrUnreachableValue(expression)
}
@@ -413,7 +410,7 @@ class ControlFlowProcessor(
return
}
var receiverValues: Map<PseudoValue, ReceiverValue> = SmartFMap.emptyMap<PseudoValue, ReceiverValue>()
var receiverValues: Map<PseudoValue, ReceiverValue> = SmartFMap.emptyMap()
var accessTarget: AccessTarget = AccessTarget.BlackBox
if (left is KtSimpleNameExpression || left is KtQualifiedExpression) {
accessTarget = getResolvedCallAccessTarget(left.getQualifiedElementSelector())
@@ -444,7 +441,7 @@ class ControlFlowProcessor(
if (setResolvedCall == null) {
generateArrayAccess(lhs, null)
val arguments = listOf(getBoundOrUnreachableValue(lhs), rhsDeferredValue.invoke()).filterNotNull()
val arguments = listOfNotNull(getBoundOrUnreachableValue(lhs), rhsDeferredValue.invoke())
builder.magic(parentExpression, parentExpression, arguments, MagicKind.UNRESOLVED_CALL)
return
@@ -474,7 +471,7 @@ class ControlFlowProcessor(
setResolvedCall: ResolvedCall<FunctionDescriptor>
): SmartFMap<PseudoValue, ValueParameterDescriptor> {
val valueArguments = setResolvedCall.resultingDescriptor.valueParameters.flatMapTo(
ArrayList<ValueArgument>()
ArrayList()
) { descriptor -> setResolvedCall.valueArguments[descriptor]?.arguments ?: emptyList() }
val rhsArgument = valueArguments.lastOrNull()
@@ -527,7 +524,7 @@ class ControlFlowProcessor(
val operationSign = expression.operationReference
val operationType = operationSign.getReferencedNameElementType()
val baseExpression = expression.baseExpression ?: return
if (KtTokens.EXCLEXCL === operationType) {
if (EXCLEXCL === operationType) {
generateInstructions(baseExpression)
builder.predefinedOperation(expression, NOT_NULL_ASSERTION, elementsToValues(listOf(baseExpression)))
return
@@ -552,7 +549,7 @@ class ControlFlowProcessor(
}
private fun isIncrementOrDecrement(operationType: IElementType): Boolean =
operationType === KtTokens.PLUSPLUS || operationType === KtTokens.MINUSMINUS
operationType === PLUSPLUS || operationType === MINUSMINUS
override fun visitIfExpression(expression: KtIfExpression) {
mark(expression)
@@ -656,7 +653,7 @@ class ControlFlowProcessor(
// Returns label for 'finally' block
private fun generateTryAndCatches(expression: KtTryExpression): Label? {
val catchClauses = expression.catchClauses
val hasCatches = !catchClauses.isEmpty()
val hasCatches = catchClauses.isNotEmpty()
var onException: Label? = null
if (hasCatches) {
@@ -684,7 +681,7 @@ class ControlFlowProcessor(
val catchLabels = LinkedList<Label>()
val catchClausesSize = catchClauses.size
for (i in 0 until catchClausesSize - 1) {
catchLabels.add(builder.createUnboundLabel("catch " + i))
catchLabels.add(builder.createUnboundLabel("catch $i"))
}
if (!catchLabels.isEmpty()) {
builder.nondeterministicJump(catchLabels, expression)
@@ -884,7 +881,7 @@ class ControlFlowProcessor(
if (loop == null) {
trace.report(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP.on(expression))
} else {
if (true != languageVersionSettings?.supportsFeature(LanguageFeature.AllowBreakAndContinueInsideWhen)) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.AllowBreakAndContinueInsideWhen)) {
val whenExpression = PsiTreeUtil.getParentOfType(
expression, KtWhenExpression::class.java, true,
KtLoopExpression::class.java
@@ -977,12 +974,11 @@ class ControlFlowProcessor(
}
private fun checkReturnLabelTarget(returnExpression: KtReturnExpression, labeledElement: KtElement) {
if (languageVersionSettings == null) return
if (labeledElement !is KtFunctionLiteral && labeledElement !is KtNamedFunction) {
if (languageVersionSettings.supportsFeature(LanguageFeature.RestrictReturnStatementTarget)) {
trace.report(Errors.NOT_A_FUNCTION_LABEL.on(returnExpression))
trace.report(NOT_A_FUNCTION_LABEL.on(returnExpression))
} else {
trace.report(Errors.NOT_A_FUNCTION_LABEL_WARNING.on(returnExpression))
trace.report(NOT_A_FUNCTION_LABEL_WARNING.on(returnExpression))
}
}
}
@@ -1056,24 +1052,24 @@ class ControlFlowProcessor(
private fun visitInlinedFunction(lambdaFunctionLiteral: KtFunction, eventOccurrencesRange: EventOccurrencesRange) {
// Defer emitting of inlined declaration
deferredGeneratorsStack.peek().add({ builder ->
val beforeDeclaration = builder.createUnboundLabel("before inlined declaration")
val afterDeclaration = builder.createUnboundLabel("after inlined declaration")
deferredGeneratorsStack.peek().add { builder ->
val beforeDeclaration = builder.createUnboundLabel("before inlined declaration")
val afterDeclaration = builder.createUnboundLabel("after inlined declaration")
builder.bindLabel(beforeDeclaration)
builder.bindLabel(beforeDeclaration)
if (!eventOccurrencesRange.isDefinitelyVisited()) {
builder.nondeterministicJump(afterDeclaration, lambdaFunctionLiteral, null)
}
if (!eventOccurrencesRange.isDefinitelyVisited()) {
builder.nondeterministicJump(afterDeclaration, lambdaFunctionLiteral, null)
}
generate(lambdaFunctionLiteral, eventOccurrencesRange)
generate(lambdaFunctionLiteral, eventOccurrencesRange)
if (eventOccurrencesRange.canBeRevisited()) {
builder.nondeterministicJump(beforeDeclaration, lambdaFunctionLiteral, null)
}
if (eventOccurrencesRange.canBeRevisited()) {
builder.nondeterministicJump(beforeDeclaration, lambdaFunctionLiteral, null)
}
builder.bindLabel(afterDeclaration)
})
builder.bindLabel(afterDeclaration)
}
}
override fun visitNamedFunction(function: KtNamedFunction) {
@@ -1185,8 +1181,7 @@ class ControlFlowProcessor(
val resolvedCall = trace.get(BindingContext.COMPONENT_RESOLVED_CALL, entry)
val writtenValue: PseudoValue?
writtenValue = if (resolvedCall != null) {
val writtenValue = if (resolvedCall != null) {
builder.call(
entry,
resolvedCall,
@@ -1212,7 +1207,7 @@ class ControlFlowProcessor(
val operationType = expression.operationReference.getReferencedNameElementType()
val left = expression.left
if (operationType === KtTokens.AS_KEYWORD || operationType === KtTokens.`AS_SAFE`) {
if (operationType === AS_KEYWORD || operationType === `AS_SAFE`) {
generateInstructions(left)
if (getBoundOrUnreachableValue(left) != null) {
createNonSyntheticValue(expression, MagicKind.CAST, left)
@@ -1325,7 +1320,7 @@ class ControlFlowProcessor(
WhenChecker.checkDuplicatedLabels(
expression,
trace,
languageVersionSettings ?: LanguageVersionSettingsImpl.DEFAULT
languageVersionSettings
)
}
@@ -1604,9 +1599,8 @@ class ControlFlowProcessor(
if (resolvedCall is VariableAsFunctionResolvedCall) {
varCallResult = generateCall(resolvedCall.variableCall).outputValue
val kind = resolvedCall.explicitReceiverKind
//noinspection EnumSwitchStatementWhichMissesCases
when (kind) {
when (resolvedCall.explicitReceiverKind) {
ExplicitReceiverKind.DISPATCH_RECEIVER -> explicitReceiver = resolvedCall.dispatchReceiver
ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> explicitReceiver =
resolvedCall.extensionReceiver
@@ -1662,7 +1656,7 @@ class ControlFlowProcessor(
// Do nothing
}
else -> {
throw IllegalArgumentException("Unknown receiver kind: " + receiver)
throw IllegalArgumentException("Unknown receiver kind: $receiver")
}
}
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction;
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessTarget;
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessValueInstruction;
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.VariableDeclarationInstruction;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.psi.KtDeclaration;
@@ -44,6 +46,11 @@ import static org.jetbrains.kotlin.resolve.BindingContextUtils.variableDescripto
public class PseudocodeUtil {
@NotNull
public static Pseudocode generatePseudocode(@NotNull KtDeclaration declaration, @NotNull BindingContext bindingContext) {
return generatePseudocode(declaration, bindingContext, LanguageVersionSettingsImpl.DEFAULT);
}
@NotNull
public static Pseudocode generatePseudocode(@NotNull KtDeclaration declaration, @NotNull BindingContext bindingContext, @NotNull LanguageVersionSettings languageVersionSettings) {
BindingTrace mockTrace = new BindingTrace() {
@NotNull
@Override
@@ -89,7 +96,7 @@ public class PseudocodeUtil {
return false;
}
};
return new ControlFlowProcessor(mockTrace, null).generatePseudocode(declaration);
return new ControlFlowProcessor(mockTrace, languageVersionSettings).generatePseudocode(declaration);
}
@Nullable
@@ -287,7 +287,7 @@ fun KtDeclaration.getContainingPseudocode(context: BindingContext): Pseudocode?
it.parents.firstOrNull { it is KtDeclaration && it !is KtFunctionLiteral } as? KtDeclaration
} ?: this
val enclosingPseudocode = PseudocodeUtil.generatePseudocode(enclosingPseudocodeDeclaration, context)
val enclosingPseudocode = PseudocodeUtil.generatePseudocode(enclosingPseudocodeDeclaration, context, LanguageVersionSettingsImpl.DEFAULT)
return enclosingPseudocode.getPseudocodeByElement(this)
}
@@ -34,6 +34,8 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl;
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction;
import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.test.ConfigurationKind;
@@ -66,14 +68,15 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironmentMa
AnalysisResult analysisResult = KotlinTestUtils.analyzeFile(ktFile, environment);
List<KtDeclaration> declarations = ktFile.getDeclarations();
BindingContext bindingContext = analysisResult.getBindingContext();
final LanguageVersionSettings languageVersionSettings = environment.getConfiguration().get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS);
for (KtDeclaration declaration : declarations) {
addDeclaration(data, bindingContext, declaration);
addDeclaration(data, bindingContext, declaration, languageVersionSettings);
if (declaration instanceof KtDeclarationContainer) {
for (KtDeclaration member : ((KtDeclarationContainer) declaration).getDeclarations()) {
// Properties and initializers are processed elsewhere
if (member instanceof KtNamedFunction || member instanceof KtSecondaryConstructor) {
addDeclaration(data, bindingContext, member);
addDeclaration(data, bindingContext, member, languageVersionSettings);
}
}
}
@@ -92,8 +95,8 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironmentMa
}
}
private static void addDeclaration(SetMultimap<KtElement, Pseudocode> data, BindingContext bindingContext, KtDeclaration declaration) {
Pseudocode pseudocode = PseudocodeUtil.generatePseudocode(declaration, bindingContext);
private static void addDeclaration(SetMultimap<KtElement, Pseudocode> data, BindingContext bindingContext, KtDeclaration declaration, LanguageVersionSettings languageVersionSettings) {
Pseudocode pseudocode = PseudocodeUtil.generatePseudocode(declaration, bindingContext, languageVersionSettings);
data.put(declaration, pseudocode);
for (LocalFunctionDeclarationInstruction instruction : pseudocode.getLocalDeclarations()) {
Pseudocode localPseudocode = instruction.getBody();