AA/FIR: differentiate dynamic type rendering
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt
index 591ff29..0c67d5e 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt
@@ -54,6 +54,7 @@
             }
         }
         when (val unwrappedType = type.unwrap()) {
+            is DynamicType -> append("dynamic")
             is FlexibleType -> renderFlexibleType(unwrappedType)
             is DefinitelyNotNullType -> renderDefinitelyNotNullType(unwrappedType)
             is ErrorType -> renderErrorType()
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt
index 2d05af8..e647a97 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt
@@ -48,7 +48,6 @@
             is ConeErrorType -> {
                 renderErrorType(type)
             }
-            //is Dynamic??? -> append("dynamic")
             is ConeClassLikeType -> {
                 if (options.renderFunctionType && shouldRenderAsPrettyFunctionType(type)) {
                     renderAnnotationList(type)
@@ -70,9 +69,11 @@
                 }
                 renderNullability(type.type)
             }
+            is ConeDynamicType -> {
+                append("dynamic")
+            }
             is ConeFlexibleType -> {
-                renderAnnotationList(type)
-                append(renderFlexibleType(renderType(type.lowerBound), renderType(type.upperBound)))
+                renderFlexibleType(type)
             }
             is ConeCapturedType -> {
                 renderAnnotationList(type)
@@ -88,6 +89,11 @@
         }
     }
 
+    private fun StringBuilder.renderFlexibleType(type: ConeFlexibleType) {
+        renderAnnotationList(type)
+        append(renderFlexibleType(renderType(type.lowerBound), renderType(type.upperBound)))
+    }
+
     private fun StringBuilder.renderErrorType(type: ConeErrorType) {
         val diagnostic = type.diagnostic
         if (options.renderUnresolvedTypeAsResolved && diagnostic is ConeUnresolvedError) {
diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.descriptors.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.descriptors.txt
deleted file mode 100644
index 00a213c..0000000
--- a/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.descriptors.txt
+++ /dev/null
@@ -1,113 +0,0 @@
-KtKotlinPropertySymbol:
-  annotationsList: []
-  callableIdIfNonLocal: /Foo.p
-  getter: KtPropertyGetterSymbol(<getter>)
-  hasBackingField: true
-  hasGetter: true
-  hasSetter: false
-  initializer: KtConstantInitializerValue(null)
-  isConst: false
-  isDelegatedProperty: false
-  isExtension: false
-  isFromPrimaryConstructor: false
-  isLateInit: false
-  isOverride: false
-  isStatic: false
-  isVal: true
-  modality: FINAL
-  name: p
-  origin: SOURCE
-  receiverType: null
-  returnType: ft<kotlin/Nothing, kotlin/Any?>
-  setter: null
-  symbolKind: CLASS_MEMBER
-  typeParameters: []
-  visibility: Public
-  getDispatchReceiver(): Foo
-  getContainingModule: KtSourceModule "Sources of main"
-  deprecationStatus: null
-  getterDeprecationStatus: null
-  javaGetterName: getP
-  javaSetterName: null
-  setterDeprecationStatus: null
-
-KtValueParameterSymbol:
-  annotationsList: []
-  callableIdIfNonLocal: null
-  generatedPrimaryConstructorProperty: null
-  hasDefaultValue: false
-  isExtension: false
-  isImplicitLambdaParameter: false
-  isVararg: false
-  name: p
-  origin: SOURCE
-  receiverType: null
-  returnType: ft<kotlin/Nothing, kotlin/Any?>
-  symbolKind: LOCAL
-  typeParameters: []
-  getContainingModule: KtSourceModule "Sources of main"
-  deprecationStatus: null
-
-KtAnonymousFunctionSymbol:
-  annotationsList: []
-  callableIdIfNonLocal: null
-  hasStableParameterNames: true
-  isExtension: false
-  origin: SOURCE
-  receiverType: null
-  returnType: ft<kotlin/Nothing, kotlin/Any?>
-  symbolKind: LOCAL
-  typeParameters: []
-  valueParameters: []
-  getContainingModule: KtSourceModule "Sources of main"
-  deprecationStatus: null
-
-KtFunctionSymbol:
-  annotationsList: []
-  callableIdIfNonLocal: /Foo.f
-  hasStableParameterNames: true
-  isBuiltinFunctionInvoke: false
-  isExtension: false
-  isExternal: false
-  isInfix: false
-  isInline: false
-  isOperator: false
-  isOverride: false
-  isStatic: false
-  isSuspend: false
-  modality: FINAL
-  name: f
-  origin: SOURCE
-  receiverType: null
-  returnType: ft<kotlin/Nothing, kotlin/Any?>
-  symbolKind: CLASS_MEMBER
-  typeParameters: []
-  valueParameters: [
-    KtValueParameterSymbol(p)
-  ]
-  visibility: Public
-  getDispatchReceiver(): Foo
-  getContainingModule: KtSourceModule "Sources of main"
-  deprecationStatus: null
-
-KtNamedClassOrObjectSymbol:
-  annotationsList: []
-  classIdIfNonLocal: Foo
-  classKind: CLASS
-  companionObject: null
-  isData: false
-  isExternal: false
-  isFun: false
-  isInline: false
-  isInner: false
-  modality: FINAL
-  name: Foo
-  origin: SOURCE
-  superTypes: [
-    kotlin/Any
-  ]
-  symbolKind: TOP_LEVEL
-  typeParameters: []
-  visibility: Public
-  getContainingModule: KtSourceModule "Sources of main"
-  deprecationStatus: null
diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.pretty.txt
index 25d2b70..5e6f513 100644
--- a/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.pretty.txt
+++ b/analysis/analysis-api/testData/symbols/symbolByPsi/dynamic.pretty.txt
@@ -1,5 +1,5 @@
 class Foo {
-  val p: (kotlin.Nothing..kotlin.Any?)
+  val p: dynamic
 
-  fun f(p: (kotlin.Nothing..kotlin.Any?)): (kotlin.Nothing..kotlin.Any?)
+  fun f(p: dynamic): dynamic
 }
diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt
index 7bf93a7..6e53abd 100644
--- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt
+++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt
@@ -30,20 +30,8 @@
         is ConeLookupTagBasedType -> {
             "${renderAttributes()}${lookupTag.name.asString()}"
         }
-        is ConeDynamicType -> {
-            buildString {
-                append("dynamic")
-            }
-        }
-        is ConeFlexibleType -> {
-            buildString {
-                append("ft<")
-                append(lowerBound.render())
-                append(", ")
-                append(upperBound.render())
-                append(">")
-            }
-        }
+        is ConeDynamicType -> "dynamic"
+        is ConeFlexibleType -> this.render()
         is ConeIntersectionType -> {
             intersectedTypes.joinToString(
                 separator = " & ",
@@ -59,6 +47,15 @@
     } + nullabilitySuffix
 }
 
+private fun ConeFlexibleType.render(): String =
+    buildString {
+        append("ft<")
+        append(lowerBound.render())
+        append(", ")
+        append(upperBound.render())
+        append(">")
+    }
+
 private fun ConeKotlinType.renderAttributes(): String {
     if (!attributes.any()) return ""
     return attributes.joinToString(" ", postfix = " ") { it.toString() }