diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtPsiFactory.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtPsiFactory.kt index 973e521e823..f0e3f93c017 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtPsiFactory.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtPsiFactory.kt @@ -19,6 +19,8 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.ImportPath +import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments +import org.jetbrains.kotlin.utils.checkWithAttachment @JvmOverloads fun KtPsiFactory(project: Project?, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(project!!, markGenerated) @@ -299,7 +301,12 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m fun createDeclaration(text: String): TDeclaration { val file = createFile(text) val declarations = file.declarations - assert(declarations.size == 1) { "${declarations.size} declarations in $text" } + checkWithAttachment(declarations.size == 1, { "unexpected ${declarations.size} declarations" }) { + it.withAttachment("text.kt", text) + for (d in declarations.withIndex()) { + it.withAttachment("declaration${d.index}.kt", d.value.text) + } + } @Suppress("UNCHECKED_CAST") return declarations.first() as TDeclaration } diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinExceptionWithAttachments.kt b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinExceptionWithAttachments.kt index d9697ccc25d..ef70c0a200e 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinExceptionWithAttachments.kt +++ b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinExceptionWithAttachments.kt @@ -26,3 +26,11 @@ open class KotlinExceptionWithAttachments : RuntimeException, ExceptionWithAttac return this } } + +inline fun checkWithAttachment(value: Boolean, lazyMessage: () -> String, attachments: (KotlinExceptionWithAttachments) -> Unit = {}) { + if (!value) { + val e = KotlinExceptionWithAttachments(lazyMessage()) + attachments(e) + throw e + } +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt index f927f789ca0..a3f14910fff 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt @@ -251,6 +251,7 @@ interface DescriptorRendererOptions { var parameterNamesInFunctionalTypes: Boolean var renderFunctionContracts: Boolean var presentableUnresolvedTypes: Boolean + var informativeErrorType: Boolean } object ExcludedTypeAnnotations { diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index 8f2b2c7dbc3..1412e6590c1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -244,7 +244,11 @@ internal class DescriptorRendererImpl( if (type is UnresolvedType && presentableUnresolvedTypes) { append(type.presentableName) } else { - append(type.constructor.toString()) // Debug name of an error type is more informative + if (type is ErrorType && !informativeErrorType) { + append(type.presentableName) + } else { + append(type.constructor.toString()) // Debug name of an error type is more informative + } } append(renderTypeArguments(type.arguments)) } else { diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt index a225767bf80..9938968baee 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt @@ -127,4 +127,6 @@ internal class DescriptorRendererOptionsImpl : DescriptorRendererOptions { override var presentableUnresolvedTypes: Boolean by property(false) override var boldOnlyForNamesInHtml: Boolean by property(false) + + override var informativeErrorType: Boolean by property(true) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt index f07d2ede12b..da4301118e9 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt @@ -22,10 +22,11 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.refinement.TypeRefinement open class ErrorType @JvmOverloads internal constructor( - override val constructor: TypeConstructor, - override val memberScope: MemberScope, - override val arguments: List = emptyList(), - override val isMarkedNullable: Boolean = false + override val constructor: TypeConstructor, + override val memberScope: MemberScope, + override val arguments: List = emptyList(), + override val isMarkedNullable: Boolean = false, + open val presentableName: String = "???" ) : SimpleType() { override val annotations: Annotations get() = Annotations.EMPTY @@ -43,14 +44,14 @@ open class ErrorType @JvmOverloads internal constructor( } class UnresolvedType( - val presentableName: String, - constructor: TypeConstructor, - memberScope: MemberScope, - arguments: List, - isMarkedNullable: Boolean + override val presentableName: String, + constructor: TypeConstructor, + memberScope: MemberScope, + arguments: List, + isMarkedNullable: Boolean ) : ErrorType(constructor, memberScope, arguments, isMarkedNullable) { override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = - UnresolvedType(presentableName, constructor, memberScope, arguments, newNullability) + UnresolvedType(presentableName, constructor, memberScope, arguments, newNullability) @TypeRefinement override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = this diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ToFromOriginalFileMapper.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ToFromOriginalFileMapper.kt index 6dcf81e2361..b7297c0b0b4 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ToFromOriginalFileMapper.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ToFromOriginalFileMapper.kt @@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments +import org.jetbrains.kotlin.utils.checkWithAttachment import kotlin.math.min class ToFromOriginalFileMapper private constructor( @@ -49,12 +49,11 @@ class ToFromOriginalFileMapper private constructor( val syntheticText = syntheticFile.text val originalSubSequence = originalText.subSequence(0, completionOffset) val syntheticSubSequence = syntheticText.subSequence(0, completionOffset) - if (originalSubSequence != syntheticSubSequence) { - throw KotlinExceptionWithAttachments( - "original subText [len: ${originalSubSequence.length}]" + - " does not match synthetic subText [len: ${syntheticSubSequence.length}]" - ) - .withAttachment("original subText", originalSubSequence.toString()) + checkWithAttachment(originalSubSequence == syntheticSubSequence, { + "original subText [len: ${originalSubSequence.length}]" + + " does not match synthetic subText [len: ${syntheticSubSequence.length}]" + }) { + it.withAttachment("original subText", originalSubSequence.toString()) .withAttachment("synthetic subText", syntheticSubSequence.toString()) } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt index 67fb8b957b2..4fe18499d29 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt @@ -223,8 +223,10 @@ private val OVERRIDE_RENDERER = withOptions { it.type.constructor.declarationDescriptor?.annotations?.hasAnnotation(ExperimentalUsageChecker.EXPERIMENTAL_FQ_NAME) ?: false } presentableUnresolvedTypes = true + informativeErrorType = false } + private val EXPECT_RENDERER = OVERRIDE_RENDERER.withOptions { modifiers = setOf(VISIBILITY, MODALITY, OVERRIDE, INNER, MEMBER_KIND) renderConstructorKeyword = false