Report IR errors via new diagnostic infrastructure

This commit is contained in:
Ilya Chernikov
2021-09-28 19:15:23 +02:00
parent 21ea92cd4a
commit 1e056a7aa8
13 changed files with 216 additions and 102 deletions
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings
@@ -69,6 +71,7 @@ class GenerationState private constructor(
val jvmBackendClassResolver: JvmBackendClassResolver, val jvmBackendClassResolver: JvmBackendClassResolver,
val isIrBackend: Boolean, val isIrBackend: Boolean,
val ignoreErrors: Boolean, val ignoreErrors: Boolean,
val diagnosticReporter: DiagnosticReporter,
) { ) {
class Builder( class Builder(
private val project: Project, private val project: Project,
@@ -122,12 +125,17 @@ class GenerationState private constructor(
fun ignoreErrors(v: Boolean): Builder = fun ignoreErrors(v: Boolean): Builder =
apply { ignoreErrors = v } apply { ignoreErrors = v }
var diagnosticReporter: DiagnosticReporter? = null
fun diagnosticReporter(v: DiagnosticReporter) =
apply { diagnosticReporter = v }
fun build() = fun build() =
GenerationState( GenerationState(
project, builderFactory, module, bindingContext, files, configuration, project, builderFactory, module, bindingContext, files, configuration,
generateDeclaredClassFilter, codegenFactory, targetId, generateDeclaredClassFilter, codegenFactory, targetId,
moduleName, outDirectory, onIndependentPartCompilationEnd, wantsDiagnostics, moduleName, outDirectory, onIndependentPartCompilationEnd, wantsDiagnostics,
jvmBackendClassResolver, isIrBackend, ignoreErrors jvmBackendClassResolver, isIrBackend, ignoreErrors,
diagnosticReporter ?: DiagnosticReporterFactory.createReporter()
) )
} }
@@ -190,7 +190,7 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
object ParameterNameAnnotationCall : KtFakeSourceElementKind() object ParameterNameAnnotationCall : KtFakeSourceElementKind()
} }
abstract class AbstractKtSourceElement { sealed class AbstractKtSourceElement {
abstract val startOffset: Int abstract val startOffset: Int
abstract val endOffset: Int abstract val endOffset: Int
} }
@@ -0,0 +1,53 @@
/*
* Copyright 2010-2021 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.resolve.jvm.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.error1
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.utils.join
object KtErrorsJvm {
// TODO: slightly different errors of this type exist also in fir checkers, consider unifying
val CONFLICTING_JVM_DECLARATIONS by error1<PsiElement, ConflictingJvmDeclarationsData>()
val CONFLICTING_INHERITED_JVM_DECLARATIONS by error1<PsiElement, ConflictingJvmDeclarationsData>()
val ACCIDENTAL_OVERRIDE by error1<PsiElement, ConflictingJvmDeclarationsData>()
}
class KtDefaultJvmErrorMessages {
companion object {
@JvmField
val CONFLICTING_JVM_DECLARATIONS_DATA = Renderer<ConflictingJvmDeclarationsData> {
val renderedDescriptors: List<DeclarationDescriptor?> =
it.signatureOrigins.mapNotNull(
JvmDeclarationOrigin::descriptor
).sortedWith(MemberComparator.INSTANCE)
val renderingContext: RenderingContext =
RenderingContext.Impl(renderedDescriptors)
"""
The following declarations have the same JVM signature (${it.signature.name}${it.signature.desc}):
""".trimIndent() +
join(renderedDescriptors.map { descriptor: DeclarationDescriptor? ->
" " + Renderers.WITHOUT_MODIFIERS.render(
descriptor!!, renderingContext
)
}, "\n")
}
val MAP = KtDiagnosticFactoryToRendererMap("KT").also { map ->
map.put(KtErrorsJvm.CONFLICTING_JVM_DECLARATIONS, "Platform declaration clash: {0}", CONFLICTING_JVM_DECLARATIONS_DATA)
map.put(KtErrorsJvm.ACCIDENTAL_OVERRIDE, "Accidental override: {0}", CONFLICTING_JVM_DECLARATIONS_DATA)
map.put(KtErrorsJvm.CONFLICTING_INHERITED_JVM_DECLARATIONS, "Inherited platform declarations clash: {0}", CONFLICTING_JVM_DECLARATIONS_DATA)
}
}
}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2021 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.diagnostics
import com.intellij.psi.PsiElement
object KtErrors {
val NON_LOCAL_RETURN_IN_DISABLED_INLINE by error0<PsiElement>()
val TYPEOF_SUSPEND_TYPE by error0<PsiElement>()
val TYPEOF_EXTENSION_FUNCTION_TYPE by error0<PsiElement>()
val TYPEOF_ANNOTATED_TYPE by error0<PsiElement>()
val TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND by error1<PsiElement, String>()
val SUSPENSION_POINT_INSIDE_MONITOR by error1<PsiElement, String>()
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2021 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.diagnostics.rendering
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.KtErrors.NON_LOCAL_RETURN_IN_DISABLED_INLINE
import org.jetbrains.kotlin.diagnostics.KtErrors.SUSPENSION_POINT_INSIDE_MONITOR
import org.jetbrains.kotlin.diagnostics.KtErrors.TYPEOF_ANNOTATED_TYPE
import org.jetbrains.kotlin.diagnostics.KtErrors.TYPEOF_EXTENSION_FUNCTION_TYPE
import org.jetbrains.kotlin.diagnostics.KtErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND
import org.jetbrains.kotlin.diagnostics.KtErrors.TYPEOF_SUSPEND_TYPE
class KtDefaultErrorMessages {
companion object {
val MAP = KtDiagnosticFactoryToRendererMap("KT").also { map ->
map.put(NON_LOCAL_RETURN_IN_DISABLED_INLINE, "Non-local returns are not allowed with inlining disabled")
map.put(TYPEOF_SUSPEND_TYPE, "Suspend functional types are not supported in typeOf")
map.put(TYPEOF_EXTENSION_FUNCTION_TYPE, "Extension function types are not supported in typeOf")
map.put(TYPEOF_ANNOTATED_TYPE, "Annotated types are not supported in typeOf")
map.put(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, "Non-reified type parameters with recursive bounds are not supported yet: {0}", STRING)
map.put(SUSPENSION_POINT_INSIDE_MONITOR, "A suspension point at {0} is inside a critical section", STRING)
}
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2021 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
import org.jetbrains.kotlin.backend.common.sourceElement
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.util.file
class KtDiagnosticReporterWithImplicitIrBasedContext(
val diagnosticReporter: DiagnosticReporter,
val languageVersionSettings: LanguageVersionSettings
) : DiagnosticReporter() {
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) = diagnosticReporter.report(diagnostic, context)
fun at(irElement: IrElement, containingIrFile: IrFile): DiagnosticContextOverIr =
DiagnosticContextOverIr(irElement, containingIrFile)
fun at(irElement: IrElement, containingIrDeclaration: IrDeclaration): DiagnosticContextOverIr =
DiagnosticContextOverIr(irElement, containingIrDeclaration)
fun at(irDeclaration: IrDeclaration): DiagnosticContextOverIr =
DiagnosticContextOverIr(irDeclaration, irDeclaration)
@Suppress("UNUSED_PARAMETER")
inner class DiagnosticContextOverIr(irElement: IrElement, containingIrFile: IrFile) : DiagnosticContext {
constructor(irElement: IrElement, containingIrDeclaration: IrDeclaration): this(irElement, containingIrDeclaration.file)
val sourceElement = irElement.sourceElement()
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
TODO("Not yet implemented")
}
override val languageVersionSettings: LanguageVersionSettings
get() = this@KtDiagnosticReporterWithImplicitIrBasedContext.languageVersionSettings
@OptIn(InternalDiagnosticFactoryMethod::class)
fun report(
factory: KtDiagnosticFactory0,
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
) {
sourceElement?.let { report(factory.on(it, positioningStrategy), this) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any> report(
factory: KtDiagnosticFactory1<A>,
a: A,
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
) {
sourceElement?.let { report(factory.on(it, a, positioningStrategy), this) }
}
}
}
@@ -16,8 +16,16 @@
package org.jetbrains.kotlin.backend.common package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtOffsetsOnlySourceElement
import org.jetbrains.kotlin.KtRealPsiSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.util.render
fun CommonBackendContext.reportWarning(message: String, irFile: IrFile?, irElement: IrElement) { fun CommonBackendContext.reportWarning(message: String, irFile: IrFile?, irElement: IrElement) {
report(irElement, irFile, message, false) report(irElement, irFile, message, false)
@@ -28,3 +36,13 @@ fun <E> MutableList<E>.push(element: E) = this.add(element)
fun <E> MutableList<E>.pop() = this.removeAt(size - 1) fun <E> MutableList<E>.pop() = this.removeAt(size - 1)
fun <E> MutableList<E>.peek(): E? = if (size == 0) null else this[size - 1] fun <E> MutableList<E>.peek(): E? = if (size == 0) null else this[size - 1]
fun findKtSourceElement(irElement: IrElement, irDeclaration: IrDeclaration): KtSourceElement {
val psiElement = PsiSourceManager.findPsiElement(irElement, irDeclaration)
?: throw AssertionError("No PsiElement found for '${irElement.render()}'")
return KtRealPsiSourceElement(psiElement)
}
fun IrElement.sourceElement(): AbstractKtSourceElement? =
if (startOffset != UNDEFINED_OFFSET) KtOffsetsOnlySourceElement(this.startOffset, this.endOffset)
else null
@@ -1,72 +0,0 @@
/*
* Copyright 2010-2021 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.backend.common.psi
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.util.render
import kotlin.reflect.KClass
class PsiErrorBuilder(private val diagnosticSink: DiagnosticSink) {
fun <E : PsiElement> at(irDeclaration: IrDeclaration, psiElementClass: KClass<E>): Location<E> =
Location(
PsiSourceManager.findPsiElement(irDeclaration, psiElementClass)
?: throw AssertionError("No ${psiElementClass.simpleName} found for '${irDeclaration.render()}'")
)
fun at(irDeclaration: IrDeclaration): Location<PsiElement> =
Location(
PsiSourceManager.findPsiElement(irDeclaration)
?: throw AssertionError("No PsiElement found for '${irDeclaration.render()}'")
)
fun <E : PsiElement> at(psiElement: E) = Location(psiElement)
fun <E : PsiElement> at(irElement: IrElement, irDeclaration: IrDeclaration, psiElementClass: KClass<E>): Location<E> =
Location(
PsiSourceManager.findPsiElement(irElement, irDeclaration, psiElementClass)
?: throw AssertionError("No ${psiElementClass.simpleName} found for '${irElement.render()}'")
)
fun at(irElement: IrElement, irDeclaration: IrDeclaration): Location<PsiElement> =
Location(
PsiSourceManager.findPsiElement(irElement, irDeclaration)
?: throw AssertionError("No PsiElement found for '${irElement.render()}'")
)
fun <E : PsiElement> at(irElement: IrElement, irFile: IrFile, psiElementClass: KClass<E>): Location<E> =
Location(
PsiSourceManager.findPsiElement(irElement, irFile, psiElementClass)
?: throw AssertionError("No ${psiElementClass.simpleName} found for '${irElement.render()}'")
)
fun at(irElement: IrElement, irFile: IrFile): Location<PsiElement> =
Location(
PsiSourceManager.findPsiElement(irElement, irFile)
?: throw AssertionError("No PsiElement found for '${irElement.render()}'")
)
inner class Location<E : PsiElement>(private val psiElement: E) {
fun report(diagnosticFactory: DiagnosticFactory0<E>) {
diagnosticSink.report(diagnosticFactory.on(psiElement))
}
fun <A : Any> report(diagnosticFactory: DiagnosticFactory1<E, A>, a: A) {
diagnosticSink.report(diagnosticFactory.on(psiElement, a))
}
fun <A : Any, B : Any> report(diagnosticFactory: DiagnosticFactory2<E, A, B>, a: A, b: B) {
diagnosticSink.report(diagnosticFactory.on(psiElement, a, b))
}
fun <A : Any, B : Any, C : Any> report(diagnosticFactory: DiagnosticFactory3<E, A, B, C>, a: A, b: B, c: C) {
diagnosticSink.report(diagnosticFactory.on(psiElement, a, b, c))
}
}
}
@@ -5,12 +5,12 @@
package org.jetbrains.kotlin.backend.jvm package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.DefaultMapping import org.jetbrains.kotlin.backend.common.DefaultMapping
import org.jetbrains.kotlin.backend.common.Mapping import org.jetbrains.kotlin.backend.common.Mapping
import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.common.psi.PsiErrorBuilder
import org.jetbrains.kotlin.backend.jvm.caches.BridgeLoweringCache import org.jetbrains.kotlin.backend.jvm.caches.BridgeLoweringCache
import org.jetbrains.kotlin.backend.jvm.caches.CollectionStubComputer import org.jetbrains.kotlin.backend.jvm.caches.CollectionStubComputer
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
@@ -71,7 +71,7 @@ class JvmBackendContext(
override val mapping: Mapping = DefaultMapping() override val mapping: Mapping = DefaultMapping()
val psiErrorBuilder = PsiErrorBuilder(state.diagnostics) val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(state.diagnosticReporter, state.languageVersionSettings)
override val ir = JvmIr(irModuleFragment, this.symbolTable) override val ir = JvmIr(irModuleFragment, this.symbolTable)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.jvm.codegen package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.common.findKtSourceElement
import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER
import org.jetbrains.kotlin.backend.common.lower.LoweredStatementOrigins import org.jetbrains.kotlin.backend.common.lower.LoweredStatementOrigins
import org.jetbrains.kotlin.backend.jvm.* import org.jetbrains.kotlin.backend.jvm.*
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.KtErrors
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
@@ -913,7 +915,7 @@ class ExpressionCodegen(
private fun generateGlobalReturnFlagIfPossible(expression: IrExpression, label: String) { private fun generateGlobalReturnFlagIfPossible(expression: IrExpression, label: String) {
if (state.isInlineDisabled) { if (state.isInlineDisabled) {
context.psiErrorBuilder.at(expression, irFunction).report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE) context.ktDiagnosticReporter.at(expression, irFunction).report(KtErrors.NON_LOCAL_RETURN_IN_DISABLED_INLINE)
genThrow(mv, "java/lang/UnsupportedOperationException", "Non-local returns are not allowed with inlining disabled") genThrow(mv, "java/lang/UnsupportedOperationException", "Non-local returns are not allowed with inlining disabled")
} else { } else {
generateGlobalReturnFlag(mv, label) generateGlobalReturnFlag(mv, label)
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.diagnostics.KtErrors
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -26,7 +27,6 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.* import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.*
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
@@ -117,9 +117,9 @@ class IrInlineIntrinsicsSupport(
override fun checkAnnotatedType(type: IrType) { override fun checkAnnotatedType(type: IrType) {
if (type.hasAnnotation(StandardNames.FqNames.extensionFunctionType)) { if (type.hasAnnotation(StandardNames.FqNames.extensionFunctionType)) {
context.psiErrorBuilder.at(reportErrorsOn, containingFile).report(TYPEOF_EXTENSION_FUNCTION_TYPE) context.ktDiagnosticReporter.at(reportErrorsOn, containingFile).report(KtErrors.TYPEOF_EXTENSION_FUNCTION_TYPE)
} else if (type.annotations.any { !it.symbol.owner.constructedClass.isSpecialAnnotation() }) { } else if (type.annotations.any { !it.symbol.owner.constructedClass.isSpecialAnnotation() }) {
context.psiErrorBuilder.at(reportErrorsOn, containingFile).report(TYPEOF_ANNOTATED_TYPE) context.ktDiagnosticReporter.at(reportErrorsOn, containingFile).report(KtErrors.TYPEOF_ANNOTATED_TYPE)
} }
} }
@@ -131,11 +131,11 @@ class IrInlineIntrinsicsSupport(
hasEqualFqName(JvmSymbols.RAW_TYPE_ANNOTATION_FQ_NAME) hasEqualFqName(JvmSymbols.RAW_TYPE_ANNOTATION_FQ_NAME)
override fun reportSuspendTypeUnsupported() { override fun reportSuspendTypeUnsupported() {
context.psiErrorBuilder.at(reportErrorsOn, containingFile).report(TYPEOF_SUSPEND_TYPE) context.ktDiagnosticReporter.at(reportErrorsOn, containingFile).report(KtErrors.TYPEOF_SUSPEND_TYPE)
} }
override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) { override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) {
context.psiErrorBuilder.at(reportErrorsOn, containingFile) context.ktDiagnosticReporter.at(reportErrorsOn, containingFile)
.report(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, typeParameterName.asString()) .report(KtErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, typeParameterName.asString())
} }
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.inlineScopeVisibility
import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.KtErrors
import org.jetbrains.kotlin.incremental.components.LocationInfo import org.jetbrains.kotlin.incremental.components.LocationInfo
import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.incremental.components.Position
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
@@ -127,9 +128,9 @@ class IrSourceCompilerForInline(
// TODO: Find a way to avoid using PSI here // TODO: Find a way to avoid using PSI here
override fun reportSuspensionPointInsideMonitor(stackTraceElement: String) { override fun reportSuspensionPointInsideMonitor(stackTraceElement: String) {
codegen.context.psiErrorBuilder codegen.context.ktDiagnosticReporter
.at(callElement.symbol.owner as IrDeclaration) .at(callElement.symbol.owner as IrDeclaration)
.report(SUSPENSION_POINT_INSIDE_MONITOR, stackTraceElement) .report(KtErrors.SUSPENSION_POINT_INSIDE_MONITOR, stackTraceElement)
} }
} }
@@ -5,12 +5,11 @@
package org.jetbrains.kotlin.backend.jvm.codegen package org.jetbrains.kotlin.backend.jvm.codegen
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.util.isFakeOverride
@@ -89,7 +88,7 @@ class JvmSignatureClashDetector(
realMethodsCount == 0 && (fakeOverridesCount > 1 || specialOverridesCount > 1) -> realMethodsCount == 0 && (fakeOverridesCount > 1 || specialOverridesCount > 1) ->
if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
reportJvmSignatureClash( reportJvmSignatureClash(
ErrorsJvm.CONFLICTING_INHERITED_JVM_DECLARATIONS, KtErrorsJvm.CONFLICTING_INHERITED_JVM_DECLARATIONS,
listOf(irClass), listOf(irClass),
conflictingJvmDeclarationsData conflictingJvmDeclarationsData
) )
@@ -102,7 +101,7 @@ class JvmSignatureClashDetector(
methods.any { DescriptorVisibilities.isPrivate(it.visibility) } methods.any { DescriptorVisibilities.isPrivate(it.visibility) }
) { ) {
reportJvmSignatureClash( reportJvmSignatureClash(
ErrorsJvm.CONFLICTING_JVM_DECLARATIONS, KtErrorsJvm.CONFLICTING_JVM_DECLARATIONS,
methods, methods,
conflictingJvmDeclarationsData conflictingJvmDeclarationsData
) )
@@ -112,7 +111,7 @@ class JvmSignatureClashDetector(
else -> else ->
if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
reportJvmSignatureClash( reportJvmSignatureClash(
ErrorsJvm.ACCIDENTAL_OVERRIDE, KtErrorsJvm.ACCIDENTAL_OVERRIDE,
methods.filter { !it.isFakeOverride && !it.isSpecialOverride() }, methods.filter { !it.isFakeOverride && !it.isSpecialOverride() },
conflictingJvmDeclarationsData conflictingJvmDeclarationsData
) )
@@ -130,7 +129,7 @@ class JvmSignatureClashDetector(
type.internalName, classOrigin, predefinedSignature, type.internalName, classOrigin, predefinedSignature,
methods.map { it.getJvmDeclarationOrigin() } + JvmDeclarationOrigin(JvmDeclarationOriginKind.OTHER, null, null) methods.map { it.getJvmDeclarationOrigin() } + JvmDeclarationOrigin(JvmDeclarationOriginKind.OTHER, null, null)
) )
reportJvmSignatureClash(ErrorsJvm.ACCIDENTAL_OVERRIDE, methods, conflictingJvmDeclarationsData) reportJvmSignatureClash(KtErrorsJvm.ACCIDENTAL_OVERRIDE, methods, conflictingJvmDeclarationsData)
} }
} }
@@ -138,28 +137,21 @@ class JvmSignatureClashDetector(
for ((rawSignature, fields) in fieldsBySignature) { for ((rawSignature, fields) in fieldsBySignature) {
if (fields.size <= 1) continue if (fields.size <= 1) continue
val conflictingJvmDeclarationsData = getConflictingJvmDeclarationsData(classOrigin, rawSignature, fields) val conflictingJvmDeclarationsData = getConflictingJvmDeclarationsData(classOrigin, rawSignature, fields)
reportJvmSignatureClash(ErrorsJvm.CONFLICTING_JVM_DECLARATIONS, fields, conflictingJvmDeclarationsData) reportJvmSignatureClash(KtErrorsJvm.CONFLICTING_JVM_DECLARATIONS, fields, conflictingJvmDeclarationsData)
} }
} }
private fun reportJvmSignatureClash( private fun reportJvmSignatureClash(
diagnosticFactory1: DiagnosticFactory1<PsiElement, ConflictingJvmDeclarationsData>, diagnosticFactory1: KtDiagnosticFactory1<ConflictingJvmDeclarationsData>,
irDeclarations: Collection<IrDeclaration>, irDeclarations: Collection<IrDeclaration>,
conflictingJvmDeclarationsData: ConflictingJvmDeclarationsData conflictingJvmDeclarationsData: ConflictingJvmDeclarationsData
) { ) {
val psiElements = irDeclarations.mapNotNullTo(LinkedHashSet()) { it.getElementForDiagnostics() } for (irDeclaration in irDeclarations) {
for (psiElement in psiElements) { context.ktDiagnosticReporter.at(irDeclaration)
context.psiErrorBuilder.at(psiElement)
.report(diagnosticFactory1, conflictingJvmDeclarationsData) .report(diagnosticFactory1, conflictingJvmDeclarationsData)
} }
} }
private fun IrDeclaration.findPsiElement(): PsiElement? = PsiSourceManager.findPsiElement(this)
private fun IrDeclaration.getElementForDiagnostics(): PsiElement? =
findPsiElement()
?: irClass.findPsiElement()
private fun getConflictingJvmDeclarationsData( private fun getConflictingJvmDeclarationsData(
classOrigin: JvmDeclarationOrigin, classOrigin: JvmDeclarationOrigin,
rawSignature: RawSignature, rawSignature: RawSignature,