org.jetbrains.kotlin.resolve.calls.DiagnosticReporterImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.calls
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.ValueArgument
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.model.DiagnosticReporter
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
// this file is example for future use
object CallDiagnosticToDiagnostic {
private val diagnosticMap: MutableMap, KotlinCallDiagnostic.(PsiElement) -> ParametrizedDiagnostic<*>> =
HashMap()
private fun checkPut(
klass: Class,
factory: C.(PsiElement) -> ParametrizedDiagnostic?
) {
@Suppress("UNCHECKED_CAST")
diagnosticMap.put(klass, factory as KotlinCallDiagnostic.(PsiElement) -> ParametrizedDiagnostic<*>)
}
private inline fun put(factory0: DiagnosticFactory0, klass: Class) {
checkPut(klass) {
(it as? E)?.let { factory0.on(it) }
}
}
private inline fun put(
factory1: DiagnosticFactory1,
klass: Class,
crossinline getA: C.() -> A
) {
checkPut(klass) {
(it as? E)?.let { factory1.on(it, getA()) }
}
}
private inline fun put(
factory2: DiagnosticFactory2, klass: Class, crossinline getA: C.() -> A, crossinline getB: C.() -> B
) {
checkPut(klass) {
(it as? E)?.let { factory2.on(it, getA(), getB()) }
}
}
init {
// put(Errors.UNSAFE_CALL, UnsafeCallDiagnostic::class.java, UnsafeCallDiagnostic::receiverType)
put(
Errors.TYPE_MISMATCH,
TypeMismatchDiagnostic::class.java,
TypeMismatchDiagnostic::expectedType,
TypeMismatchDiagnostic::actualType
)
}
// null means, that E is not subtype of required type for diagnostic factory
fun toDiagnostic(element: E, diagnostic: KotlinCallDiagnostic): ParametrizedDiagnostic? {
val diagnosticClass = diagnostic.javaClass
val factory = diagnosticMap[diagnosticClass] ?: error("Illegal call diagnostic class: ${diagnosticClass.canonicalName}")
@Suppress("UNCHECKED_CAST")
return factory(diagnostic, element) as ParametrizedDiagnostic?
}
}
abstract class DiagnosticReporterImpl(private val bindingTrace: BindingTrace, private val call: Call) : DiagnosticReporter {
override fun onCallArgument(callArgument: KotlinCallArgument, diagnostic: KotlinCallDiagnostic) {
val d = CallDiagnosticToDiagnostic.toDiagnostic((callArgument as ValueArgument).asElement(), diagnostic)
if (d != null) {
bindingTrace.report(d)
}
}
}
class TypeMismatchDiagnostic(
val callArgument: KotlinCallArgument,
val expectedType: KotlinType,
val actualType: KotlinType
) : KotlinCallDiagnostic(CandidateApplicability.INAPPLICABLE) {
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(callArgument, this)
}