From 213b39f2132f575f626a5b5913d0ebb2cfb19448 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 26 Jun 2023 11:13:55 +0300 Subject: [PATCH] [FIR] Get rid of obsolete TODOs in :fir:resolve module --- .../kotlin/fir/resolve/ResolveUtils.kt | 2 -- .../kotlin/fir/resolve/SamResolution.kt | 4 +-- .../calls/AbstractConeCallConflictResolver.kt | 8 ++--- .../kotlin/fir/resolve/calls/Arguments.kt | 10 +----- .../resolve/calls/ConstructorProcessing.kt | 8 ++--- ...CreateFreshTypeVariableSubstitutorStage.kt | 2 +- .../fir/resolve/calls/ResolutionStages.kt | 6 ---- .../fir/resolve/dfa/FirDataFlowAnalyzer.kt | 12 +++---- .../dfa/FirLocalVariableAssignmentAnalyzer.kt | 1 - .../dfa/cfg/ControlFlowGraphBuilder.kt | 34 ++++++------------- .../dfa/cfg/ControlFlowGraphRenderer.kt | 2 -- .../inference/ConstraintSystemCompleter.kt | 5 ++- .../FirInferenceSessionForChainedResolve.kt | 2 +- .../inference/PostponedArgumentsAnalyzer.kt | 2 -- .../providers/impl/FirTypeResolverImpl.kt | 1 - .../transformers/FirSupertypesResolution.kt | 4 --- .../body/resolve/BodyResolveUtils.kt | 2 +- .../FirDeclarationsResolveTransformer.kt | 4 +-- .../FirExpressionsResolveTransformer.kt | 1 - ...actContractResolveTransformerDispatcher.kt | 1 - ...FirSpecificAnnotationResolveTransformer.kt | 1 - .../kotlin/fir/scopes/ImportingScopes.kt | 1 - 22 files changed, 31 insertions(+), 82 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 6f8d26ae94c..5bc9860d15e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -228,7 +228,6 @@ fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifi typeForQualifierByDeclaration(declaration, resultType, session)?.let { return it } } } - // TODO: Handle no value type here return session.builtinTypes.unitType } @@ -349,7 +348,6 @@ private fun BodyResolveComponents.typeFromSymbol(symbol: FirBasedSymbol<*>): Fir returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef) } is FirClassifierSymbol<*> -> { - // TODO: unhack buildResolvedTypeRef { source = null type = symbol.constructType(emptyArray(), isNullable = false) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index 7861b9ec7cd..fb8f6ef3bc1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -116,7 +116,7 @@ class FirSamResolver( val syntheticFunctionSymbol = classSymbol.createSyntheticConstructorSymbol() val newTypeParameters = firRegularClass.typeParameters.map { typeParameter -> - val declaredTypeParameter = typeParameter.symbol.fir // TODO: or really declared? + val declaredTypeParameter = typeParameter.symbol.fir FirTypeParameterBuilder().apply { source = declaredTypeParameter.source moduleData = session.moduleData @@ -143,7 +143,7 @@ class FirSamResolver( ) for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(firRegularClass.typeParameters)) { - val declared = oldTypeParameter.symbol.fir // TODO: or really declared? + val declared = oldTypeParameter.symbol.fir newTypeParameter.bounds += declared.symbol.resolvedBounds.map { typeRef -> buildResolvedTypeRef { source = typeRef.source diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt index 9d827d99574..c755f0b4ba8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt @@ -134,7 +134,7 @@ abstract class AbstractConeCallConflictResolver( hasVarargs = false, numDefaults = 0, isExpect = (variable as? FirProperty)?.isExpect == true, - isSyntheticMember = false // TODO + isSyntheticMember = false ) } @@ -149,7 +149,7 @@ abstract class AbstractConeCallConflictResolver( hasVarargs = constructor.valueParameters.any { it.isVararg }, numDefaults = call.numDefaults, isExpect = constructor.isExpect, - isSyntheticMember = false // TODO + isSyntheticMember = false ) } @@ -163,7 +163,7 @@ abstract class AbstractConeCallConflictResolver( hasVarargs = function.valueParameters.any { it.isVararg }, numDefaults = call.numDefaults, isExpect = function.isExpect, - isSyntheticMember = false // TODO + isSyntheticMember = false ) } @@ -226,7 +226,7 @@ abstract class AbstractConeCallConflictResolver( (klass as? FirTypeParameterRefsOwner)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(), emptyList(), hasExtensionReceiver = false, - 0, // TODO + 0, hasVarargs = false, numDefaults = 0, isExpect = (klass as? FirRegularClass)?.isExpect == true, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 4ab67fc985a..742f22bc2cc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -110,10 +110,7 @@ fun Candidate.resolveArgumentExpression( ) else preprocessCallableReference(argument, expectedType, context) - // TODO:! is FirAnonymousFunctionExpression -> preprocessLambdaArgument(csBuilder, argument, expectedType, context, sink) - // TODO:! - //TODO: Collection literal is FirWrappedArgumentExpression -> resolveArgumentExpression( csBuilder, argument.expression, @@ -344,7 +341,6 @@ private fun checkApplicabilityForArgumentType( ) { if (expectedType == null) return - // todo run this approximation only once for call val argumentType = captureFromTypeParameterUpperBoundIfNeeded(argumentTypeBeforeCapturing, expectedType, context.session) fun subtypeError(actualExpectedType: ConeKotlinType): ResolutionDiagnostic { @@ -422,7 +418,7 @@ private fun checkApplicabilityForArgumentType( val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, context.session.typeContext) if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, nullableExpectedType, position)) { - sink.reportDiagnostic(UnsafeCall(argumentType)) // TODO + sink.reportDiagnostic(UnsafeCall(argumentType)) } else { csBuilder.addSubtypeConstraint(argumentType, expectedType, position) sink.reportDiagnostic(InapplicableWrongReceiver(expectedType, argumentType)) @@ -496,8 +492,6 @@ private fun Candidate.getExpectedTypeWithSAMConversion( ): ConeKotlinType? { if (candidateExpectedType.isSomeFunctionType(session)) return null - // TODO: resolvedCall.registerArgumentWithSamConversion(argument, SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!)) - val expectedFunctionType = context.bodyResolveComponents.samResolver.getFunctionTypeForPossibleSamType(candidateExpectedType) ?: return null return runIf(argument.isFunctional(session, scopeSession, expectedFunctionType, context.returnTypeCalculator)) { @@ -527,8 +521,6 @@ private fun getExpectedTypeWithImplicintIntegerCoercion( }?.resolvedReturnType } - // TODO: consider adding a check that argument could be converted to the parameter type (maybe difficult for platform types) - return argumentType?.withNullability(candidateExpectedType.nullability, session.typeContext) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt index da9ef52a998..20393eeb485 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt @@ -210,10 +210,10 @@ private fun processConstructors( } } - //TODO: why don't we use declared member scope at this point? - scope?.processDeclaredConstructors { - if (includeInnerConstructors || !it.fir.isInner) { - processor(it) + scope?.processDeclaredConstructors { + if (includeInnerConstructors || !it.fir.isInner) { + processor(it) + } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt index 6e63c3df17c..bda80f98d82 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt @@ -38,7 +38,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() { // bad function -- error on declaration side if (csBuilder.hasContradiction) { - sink.yieldDiagnostic(InapplicableCandidate) //TODO: auto report it + sink.yieldDiagnostic(InapplicableCandidate) return } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index e21b5ab171d..371e672dbec 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -55,7 +55,6 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { val receiverKind = candidate.explicitReceiverKind val explicitReceiver = callInfo.explicitReceiver - // TODO: add invoke cases when (receiverKind) { NO_EXPLICIT_RECEIVER -> { if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier && !explicitReceiver.isSuperReferenceExpression()) { @@ -71,7 +70,6 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() { if (explicitReceiver == null) { return sink.yieldDiagnostic(InapplicableWrongReceiver()) } - // Here we should also check additional invoke receiver } } } @@ -268,7 +266,6 @@ object CheckDslScopeViolation : ResolutionStage() { context, { getDslMarkersOfImplicitReceiver(thisReference.boundSymbol, receiver.typeRef.coneType, context) } ) { - // TODO: is there better alternative? // Here we rely on the fact that receiver expression of implicit receiver value can not be changed // during resolution of one single call it.receiverExpression == receiver @@ -550,7 +547,6 @@ internal object CheckVisibility : CheckerStage() { } if (declaration is FirConstructor) { - // TODO: Should be some other form val classSymbol = declaration.returnTypeRef.coneTypeUnsafe().lookupTag.toSymbol(context.session) if (classSymbol is FirRegularClassSymbol) { @@ -621,10 +617,8 @@ internal object CheckIncompatibleTypeVariableUpperBounds : ResolutionStage() { } internal object PostponedVariablesInitializerResolutionStage : ResolutionStage() { - override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { val argumentMapping = candidate.argumentMapping ?: return - // TODO: convert type argument mapping to map [FirTypeParameterSymbol, FirTypedProjection?] if (candidate.typeArgumentMapping is TypeArgumentMapping.Mapped) return for (parameter in argumentMapping.values) { if (!parameter.hasBuilderInferenceAnnotation(context.session)) continue diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 27cc5344b1b..3c687b7d351 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -449,8 +449,9 @@ abstract class FirDataFlowAnalyzer( return } - // TODO: should be `getOrCreateIfRealAndUnchanged(flow from LHS, flow, leftOperand)`, otherwise the statement will - // be added even if the value has changed in the RHS. Currently the only previous node is the RHS. + // Ideally it should be `getOrCreateIfRealAndUnchanged(flow from LHS, flow, leftOperand)`, otherwise the statement will + // be added even if the value has changed in the RHS. Currently, the only previous node is the RHS. + // But seems like everything works and with current implementation val leftOperandVariable = variableStorage.getOrCreateIfReal(flow, leftOperand) val rightOperandVariable = variableStorage.getOrCreateIfReal(flow, rightOperand) if (leftOperandVariable == null && rightOperandVariable == null) return @@ -751,8 +752,6 @@ abstract class FirDataFlowAnalyzer( // Otherwise if the result is non-null, then `b` executed, which implies `a` is not null // and every statement from `b` holds. val expressionVariable = variableStorage.getOrCreate(flow, safeCall) - // TODO? if the callee has non-null return type, then safe-call == null => receiver == null - // if (x?.toString() == null) { /* x == null */ } // TODO? all new implications in previous node's flow are valid here if receiver != null // (that requires a second level of implications: receiver != null => condition => effect). flow.addAllConditionally(expressionVariable notEq null, node.lastPreviousNode.flow) @@ -842,8 +841,6 @@ abstract class FirDataFlowAnalyzer( if (conditionalEffects.isEmpty()) return val arguments = qualifiedAccess.orderedArguments(callee) ?: return - // TODO: should be `getOrCreateIfRealAndUnchanged(last flow of argument i, flow, it)` - // ^-- good luck finding that val argumentVariables = Array(arguments.size) { i -> arguments[i]?.let { variableStorage.getOrCreateIfReal(flow, it) } } if (argumentVariables.all { it == null }) return @@ -899,7 +896,6 @@ abstract class FirDataFlowAnalyzer( if (property.isLocal || property.isVal) { exitVariableInitialization(flow, assignment.rValue, property, assignment.lValue, hasExplicitType = false) } else { - // TODO: add unstable smartcast for non-local var val variable = variableStorage.getRealVariableWithoutUnwrappingAlias(flow, assignment) if (variable != null) { logicSystem.recordNewAssignment(flow, variable, context.newAssignmentIndex()) @@ -946,7 +942,7 @@ abstract class FirDataFlowAnalyzer( if (isAssignment) { // `propertyVariable` can be an alias to `initializerVariable`, in which case this will add - // a redundant type statement which is fine...probably. TODO: store initial type within the variable? + // a redundant type statement which is fine...probably flow.addTypeStatement(flow.unwrapVariable(propertyVariable) typeEq initializer.typeRef.coneType) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirLocalVariableAssignmentAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirLocalVariableAssignmentAnalyzer.kt index ce9f87d9c57..c9cdf3f26b0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirLocalVariableAssignmentAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirLocalVariableAssignmentAnalyzer.kt @@ -137,7 +137,6 @@ internal class FirLocalVariableAssignmentAnalyzer { val (info, prohibitSmartCasts) = enterScope(klass.symbol, klass is FirAnonymousObject) if (klass is FirAnonymousObject && info != null) { // Assignments in initializers and methods invalidate smart casts in other members. - // TODO: initializers shouldn't invalidate smart casts in themselves. prohibitSmartCasts.addAll(info.assignedInside) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index f72c99139e9..11fa07e1182 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -269,7 +269,7 @@ class ControlFlowGraphBuilder { // Postponed exit node was needed so we could create lambda->call edges without having the subgraph ready. If it // doesn't exist, then we probably can't do that anymore, and the lambda won't be called-in-place in the CFG. // TODO: verify & enable this assertion? - //assert(invocationKind?.canBeVisited() != true) { "no exit node for calledInPlace($invocationKind) lambda" } + // assert(invocationKind?.canBeVisited() != true) { "no exit node for calledInPlace($invocationKind) lambda" } return Triple(exitNode, null, graph) } @@ -310,7 +310,6 @@ class ControlFlowGraphBuilder { } else { for ((exit, kind) in currentLevelExits) { // Do not add data flow edges from non-terminating lambdas; there is no "dead data flow only" - // `EdgeKind`. TODO? if (kind.usedInCfa || !exit.isDead) { // Since `node` is a union node, it is dead iff any input is dead. For once, `propagateDeadness` // semantics are correct without an `updateDeadStatus`. @@ -397,7 +396,6 @@ class ControlFlowGraphBuilder { } val localClassEnterNode = when { - // TODO: enum classes cannot be local so this is mostly fine, but it looks hacky. Maybe handle FirEnumEntry? klass is FirAnonymousObject && klass.classKind != ClassKind.ENUM_ENTRY -> createAnonymousObjectEnterNode(klass) // Local classes are only initialized on first use, so they look pretty much like named functions: // control flow enters here and never leaves, and assignments invalidate smart casts. @@ -511,14 +509,8 @@ class ControlFlowGraphBuilder { addEdge(enterNode, exitNode, preferredKind = EdgeKind.DeadForward, propagateDeadness = false) } - // TODO: Here we're assuming that the methods are called after the object is constructed, which is really not true - // (init blocks can call them). But FE1.0 did so too, hence the following code compiles and prints 0: - // val x: Int - // object { - // fun bar() = x - // init { x = bar() } - // } - // println(x) + // Here we're assuming that the methods are called after the object is constructed, which is really not true + // But it's fine, since Kotlin intentionally does not support analysis of "leaked this" bugs for (graph in calledLater) { addEdgeToSubGraph(exitNode, graph.enterNode) } @@ -534,7 +526,6 @@ class ControlFlowGraphBuilder { return createAnonymousObjectExpressionExitNode(anonymousObjectExpression).also { val exitNode = klass.controlFlowGraphReference?.controlFlowGraph?.exitNode - // TODO: `lastNode` should be `AnonymousObjectEnterNode`, but delegate properties are somewhat broken. if (exitNode != null && lastNode is AnonymousObjectEnterNode) { addEdge(exitNode, it) // Fake edge to enforce ordering. @@ -879,7 +870,6 @@ class ControlFlowGraphBuilder { // These edges should really be from `enterTryMainBlockNode`, but there is no practical difference // so w/e. In fact, `enterTryExpressionNode` is just 100% redundant. - // TODO: this is more or less `addExceptionEdgesFrom(enterTryExpressionNode)`. Hmm. for (catchEnterNode in catchNodes.top()) { addEdge(enterTryExpressionNode, catchEnterNode) } @@ -904,8 +894,6 @@ class ControlFlowGraphBuilder { addEdge(node, nextNode, propagateDeadness = false) for (catchEnterNode in catchNodes.pop().asReversed()) { catchBlocksInProgress.push(catchEnterNode) - // TODO: figure out if this edge is correct. - // try { x = /* something non-throwing like variable read */ } catch (...) { /* can assume assignment didn't happen? */ } addEdge(node, catchEnterNode, propagateDeadness = false) } return node @@ -915,7 +903,6 @@ class ControlFlowGraphBuilder { val catchEnterNode = catchBlocksInProgress.pop() assert(catchEnterNode.fir == catch) if (tryExitNodes.top().fir.finallyBlock != null) { - // TODO: not sure this does anything? addEdge(catchEnterNode, finallyEnterNodes.top(), propagateDeadness = false, label = UncaughtExceptionPath) } lastNodes.push(catchEnterNode) @@ -946,10 +933,6 @@ class ControlFlowGraphBuilder { val exitNode = createFinallyBlockExitNode(enterNode.fir) popAndAddEdge(exitNode) addEdge(exitNode, tryExitNode, isDead = enterNode.allNormalInputsAreDead) - // TODO: there should also be edges to outer catch blocks? Control flow can go like this: - // try { try { throw E2() } catch (e: E1) { } finally { } } catch (e: E2) { } - // \-----------------------------^ \-----------------^ - // Wait, that's just `addExceptionEdgesFrom(exitNode)` again! val nextExitLevel = levelOfNextExceptionCatchingGraph() val nextFinally = finallyEnterNodes.topOrNull()?.takeIf { it.level > nextExitLevel } if (nextFinally != null) { @@ -984,7 +967,12 @@ class ControlFlowGraphBuilder { for (node in nodes) { when { // TODO: this check is imprecise and can add redundant edges: - // x@{ try { return@x } finally {}; try {} finally { /* return@x target is in nonDirectJumps */ } + // x@{ + // try { + // return@x + // } finally {} + // } + // try {} finally { /* return@x target is in nonDirectJumps */ } node.level < minLevel || node !in nonDirectJumps -> continue // TODO: if the input to finally with that label is dead, then so should be the exit probably node.returnPathIsBackwards -> addBackEdge(this, node, label = node) @@ -1038,7 +1026,7 @@ class ControlFlowGraphBuilder { // this is a workaround to make function call dead when call is completed _after_ building its node in the graph // this happens when completing the last call in try/catch blocks - // todo this doesn't make fully 'right' Nothing node (doesn't support going to catch and pass through finally) + // TODO: this doesn't make fully 'right' Nothing node (doesn't support going to catch and pass through finally) // because doing those afterwards is quite challenging // it would be much easier if we could build calls after full completion only, at least for Nothing calls // @returns `true` if node actually returned Nothing @@ -1164,7 +1152,6 @@ class ControlFlowGraphBuilder { fun enterFakeExpression(): FakeExpressionEnterNode { // Things like annotations and `contract { ... }` use normal call resolution, but aren't real expressions // and are never evaluated. We'll push all nodes created in the process into a stub graph, then throw it away. - // TODO: don't waste time creating the nodes in the first place return enterGraph(null, "", ControlFlowGraph.Kind.FakeCall) { createFakeExpressionEnterNode() to createFakeExpressionEnterNode() } @@ -1188,7 +1175,6 @@ class ControlFlowGraphBuilder { // ----------------------------------- Block ----------------------------------- fun enterInitBlock(initBlock: FirAnonymousInitializer): InitBlockEnterNode { - // TODO: questionable moment that we should pass data flow from init to init return enterGraph(initBlock, "init block", ControlFlowGraph.Kind.ClassInitializer) { createInitBlockEnterNode(it) to createInitBlockExitNode(it) }.also { addEdgeIfLocalClassMember(it) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt index f77fb483a01..ae60d06b18a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt @@ -125,8 +125,6 @@ class FirControlFlowGraphRenderVisitor( val controlFlowGraph = (controlFlowGraphReference as? FirControlFlowGraphReferenceImpl)?.controlFlowGraph ?: return if (controlFlowGraph.isSubGraph) return - // TODO: nodes are already in a topological order, but grouping nodes into clusters requires something more. - // But what exactly? And is there a way to do `renderNodes` differently so that any topological order is ok? val nodes = DFS.topologicalOrder(listOf(controlFlowGraph.enterNode)) { it.followingNodes } .associateWithTo(linkedMapOf()) { nodeCounter++ } printer.renderNodes(nodes) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 16e448ec202..d9d30009d54 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -233,7 +233,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c is ResolvedCallableReferenceAtom -> argument.reviseExpectedType(revisedExpectedType) is LambdaWithTypeVariableAsExpectedTypeAtom -> - argument.transformToResolvedLambda(c.getBuilder(), resolutionContext, revisedExpectedType, null /*TODO()*/) + argument.transformToResolvedLambda(c.getBuilder(), resolutionContext, revisedExpectedType) else -> throw IllegalStateException("Unsupported postponed argument type of $argument") } @@ -338,7 +338,6 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c fun ConeTypeVariable?.toTypeConstructor(): TypeConstructorMarker? = this?.typeConstructor?.takeIf { it in notFixedTypeVariables.keys } - // TODO: non-top-level variables? fun PostponedAtomWithRevisableExpectedType.collectNotFixedVariables() { revisedExpectedType?.lowerBoundIfFlexible()?.asArgumentList()?.let { typeArgumentList -> for (typeArgument in typeArgumentList) { @@ -402,7 +401,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN ) val variable = variableWithConstraints.typeVariable - c.fixVariable(variable, resultType, ConeFixVariableConstraintPosition(variable)) // TODO: obtain atom for diagnostics + c.fixVariable(variable, resultType, ConeFixVariableConstraintPosition(variable)) } companion object { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSessionForChainedResolve.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSessionForChainedResolve.kt index 92a12fc26cc..a5dfb432a8d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSessionForChainedResolve.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSessionForChainedResolve.kt @@ -92,7 +92,7 @@ abstract class FirInferenceSessionForChainedResolve( lowerSubstituted, upperSubstituted, this.constraintKind, - ConeBuilderInferenceSubstitutionConstraintPosition(this) // TODO + ConeBuilderInferenceSubstitutionConstraintPosition(this) ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt index 24abdcf8edc..f4b23607f19 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt @@ -63,8 +63,6 @@ class PostponedArgumentsAnalyzer( analyzeLambda(c, argument.transformToResolvedLambda(c.getBuilder(), resolutionContext), candidate, completionMode) is ResolvedCallableReferenceAtom -> processCallableReference(argument, candidate) - -// is ResolvedCollectionLiteralAtom -> TODO("Not supported") } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index 9ecd26af141..b5d37188b28 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -412,7 +412,6 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { userTypeRef: FirUserTypeRef, qualifierPartArgumentsCount: Int? ): ConeErrorType? { - // TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null val actualTypeParametersCount = getActualTypeParametersCount(parameterClass ?: symbol.fir) if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt index 4baddb4611a..ff81c51b683 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt @@ -163,8 +163,6 @@ private class FirApplySupertypesTransformer( private fun applyResolvedSupertypesToClass(firClass: FirClass) { if (firClass.superTypeRefs.any { it !is FirResolvedTypeRef || it is FirImplicitBuiltinTypeRef }) { val supertypeRefs = getResolvedSupertypeRefs(firClass) - - // TODO: Replace with an immutable version or transformer firClass.replaceSuperTypeRefs(supertypeRefs) } @@ -196,7 +194,6 @@ private class FirApplySupertypesTransformer( "Expected single supertypeRefs, but found ${supertypeRefs.size} in ${typeAlias.symbol.classId}" } - // TODO: Replace with an immutable version or transformer typeAlias.replaceExpandedTypeRef(supertypeRefs[0]) return typeAlias } @@ -521,7 +518,6 @@ open class FirSupertypeResolverVisitor( expandedTypeRef: FirTypeRef, resolveRecursively: Boolean, ): List { - // TODO: this if is a temporary hack for built-in types (because we can't load file for them) if (expandedTypeRef is FirResolvedTypeRef) { return listOf(expandedTypeRef) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt index 9e991ef6f42..6156e926c6a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt @@ -41,7 +41,7 @@ internal fun remapArgumentsWithVararg( var indexAfterVarargs = argumentList.size val newArgumentMapping = linkedMapOf() val varargArgument = buildVarargArgumentsExpression { - //todo ideally we should use here a source from the use-site and not from the declaration-site + // TODO: ideally we should use here a source from the use-site and not from the declaration-site this.varargElementType = varargParameterTypeRef.withReplacedConeType(varargElementType, KtFakeSourceElementKind.VarargArgument) this.typeRef = varargParameterTypeRef.withReplacedConeType(varargArrayType, KtFakeSourceElementKind.VarargArgument) var startOffset = Int.MAX_VALUE diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 6934f761578..3f7e2bdec35 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -434,8 +434,7 @@ open class FirDeclarationsResolveTransformer( return variable } - // TODO: This enum might actually be a boolean (resolve setter/don't resolve setter) - // But for some reason, in IDE there's a need to resolve setter's parameter types on the implicit-resolution stage + // In IDE there's a need to resolve setter's parameter types on the implicit-resolution stage // See ad183434137939a0c9eeea2f7df9ef522672a18e commit. // But for delegate inference case, we don't need both body of the setter and its parameter resolved (SKIP mode) private enum class SetterResolutionMode { @@ -630,7 +629,6 @@ open class FirDeclarationsResolveTransformer( return context.withSimpleFunction(simpleFunction, session) { doTransformTypeParameters(simpleFunction) - // TODO: I think it worth creating something like runAllPhasesForLocalFunction if (containingDeclaration != null && containingDeclaration !is FirClass) { // For class members everything should be already prepared prepareSignatureForBodyResolve(simpleFunction) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 3763702fd1c..bcb06d1b607 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -104,7 +104,6 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT qualifiedAccessExpression.transformTypeArguments(transformer, ResolutionMode.ContextIndependent) var result = when (val callee = qualifiedAccessExpression.calleeReference) { - // TODO: there was FirExplicitThisReference is FirThisReference -> { val labelName = callee.labelName val implicitReceiver = implicitReceiverStack[labelName] diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt index d7526e8412e..10d05bd00d9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt @@ -301,7 +301,6 @@ abstract class FirAbstractContractResolveTransformerDispatcher( } private fun transformOwnerOfErrorContract(owner: T): T { - // TODO dataFlowAnalyzer.exitContractDescription() return owner } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt index a9770a173fc..ad6b09d6138 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt @@ -244,7 +244,6 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer( annotationCall.replaceAnnotationTypeRef(transformedAnnotationType) annotationCall.replaceAnnotationResolvePhase(FirAnnotationResolvePhase.CompilerRequiredAnnotations) - // TODO: what if we have type alias here? if (transformedAnnotationType.coneTypeSafe()?.lookupTag?.classId in REQUIRED_ANNOTATIONS_WITH_ARGUMENTS) { argumentsTransformer.transformAnnotation(annotationCall, ResolutionMode.ContextDependent) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt index 1e23910453e..24476125c4a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt @@ -77,7 +77,6 @@ private fun doCreateImportingScopes( else -> FirPackageMemberScope(file.packageFqName, session, excludedNames = excludedNamesInPackage) }, - // TODO: explicit simple importing scope should have highest priority (higher than inner scopes added in process) FirExplicitSimpleImportingScope(file.imports, session, scopeSession) ) }