[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:
committed by
teamcity
parent
9f870b0549
commit
50f6825775
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user