[Analysis API] do not create multiple attachments inside exceptions
This commit is contained in:
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.utils.errors
|
||||
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
public class ExceptionAttachmentBuilder {
|
||||
private val printer = PrettyPrinter()
|
||||
|
||||
public fun <T> withEntry(name: String, value: T, render: (T & Any) -> String) {
|
||||
withEntry(name) {
|
||||
appendLine("Class: ${value?.let { it::class.java.name }}")
|
||||
appendLine("Value:")
|
||||
withIndent {
|
||||
appendLine(value?.let(render) ?: "null")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun withEntry(name: String, value: String?) {
|
||||
with(printer) {
|
||||
appendLine("- $name:")
|
||||
withIndent {
|
||||
appendLine(value)
|
||||
}
|
||||
appendLine(separator)
|
||||
}
|
||||
}
|
||||
|
||||
public fun withEntry(name: String, buildValue: PrettyPrinter.() -> Unit) {
|
||||
withEntry(name, prettyPrint { buildValue() })
|
||||
}
|
||||
|
||||
public fun withEntryGroup(groupName: String, build: ExceptionAttachmentBuilder.() -> Unit) {
|
||||
val builder = ExceptionAttachmentBuilder().apply(build)
|
||||
withEntry(groupName, builder) { it.buildString() }
|
||||
}
|
||||
|
||||
public fun buildString(): String = printer.toString()
|
||||
|
||||
private companion object {
|
||||
private const val separator = "========"
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun KotlinExceptionWithAttachments.buildAttachment(
|
||||
name: String = "info.txt",
|
||||
buildContent: ExceptionAttachmentBuilder.() -> Unit
|
||||
): KotlinExceptionWithAttachments {
|
||||
return withAttachment(name, ExceptionAttachmentBuilder().apply(buildContent).buildString())
|
||||
}
|
||||
|
||||
public inline fun buildErrorWithAttachment(
|
||||
message: String,
|
||||
cause: Throwable? = null,
|
||||
attachmentName: String = "info.txt",
|
||||
buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {}
|
||||
): Nothing {
|
||||
val exception = KotlinExceptionWithAttachments(message, cause)
|
||||
exception.buildAttachment(attachmentName) { buildAttachment() }
|
||||
throw exception
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
public inline fun checkWithAttachmentBuilder(
|
||||
value: Boolean,
|
||||
lazyMessage: () -> String,
|
||||
buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {}
|
||||
) {
|
||||
contract { returns() implies (value) }
|
||||
|
||||
if (!value) {
|
||||
buildErrorWithAttachment(lazyMessage(), buildAttachment = buildAttachment)
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.utils.errors
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||
|
||||
public fun unexpectedElementError(elementName: String, element: Any?): Nothing {
|
||||
errorWithAttachment("Unexpected $elementName ${element?.let { it::class.simpleName }}") {
|
||||
withAttachment("element", element)
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified ELEMENT> unexpectedElementError(element: Any?): Nothing {
|
||||
unexpectedElementError(ELEMENT::class.simpleName ?: ELEMENT::class.java.name, element)
|
||||
}
|
||||
|
||||
public fun KotlinExceptionWithAttachments.withPsiAttachment(name: String, psi: PsiElement?): KotlinExceptionWithAttachments {
|
||||
withAttachmentDetailed(name, psi) { psiElement ->
|
||||
when (psiElement) {
|
||||
is KtElement -> psiElement.getElementTextInContext()
|
||||
else -> psiElement.text
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.utils.errors
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
public fun ExceptionAttachmentBuilder.withPsiEntry(name: String, psi: PsiElement?) {
|
||||
withEntry(name, psi) { psiElement ->
|
||||
when (psiElement) {
|
||||
is KtElement -> psiElement.getElementTextInContext()
|
||||
else -> psiElement.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public fun ExceptionAttachmentBuilder.withClassEntry(name: String, element: Any?) {
|
||||
withEntry(name, element) { it::class.java.name }
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.utils.errors
|
||||
|
||||
public fun unexpectedElementError(elementName: String, element: Any?): Nothing {
|
||||
buildErrorWithAttachment("Unexpected $elementName ${element?.let { it::class.simpleName }}") {
|
||||
withEntry(elementName, element) { element.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified ELEMENT> unexpectedElementError(element: Any?): Nothing {
|
||||
unexpectedElementError(ELEMENT::class.simpleName ?: ELEMENT::class.java.name, element)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user