[FIR] Fix missing ErrorTypeRef for QA and clean DiagnosticCollector

This commit is contained in:
Nick
2020-07-30 13:05:05 +03:00
committed by Mikhail Glukhikh
parent 7086b0cbf3
commit c55cdf1935
5 changed files with 37 additions and 55 deletions
@@ -68,46 +68,6 @@ abstract class AbstractDiagnosticCollector(
element.acceptChildren(this)
}
override fun visitFunctionCall(functionCall: FirFunctionCall) {
functionCall.runComponents()
// no need to visit typeRef because if there's
// an error it should've been reported at the
// corresponding declaration
functionCall.annotations.forEach { it.accept(visitor) }
functionCall.typeArguments.forEach { it.accept(visitor) }
functionCall.explicitReceiver?.accept(visitor)
if (functionCall.dispatchReceiver !== functionCall.explicitReceiver) {
functionCall.dispatchReceiver.accept(visitor)
}
if (
functionCall.extensionReceiver !== functionCall.explicitReceiver &&
functionCall.extensionReceiver !== functionCall.dispatchReceiver
) {
functionCall.extensionReceiver.accept(visitor)
}
functionCall.argumentList.accept(visitor)
functionCall.calleeReference.accept(visitor)
}
override fun visitComponentCall(componentCall: FirComponentCall) {
componentCall.runComponents()
// same as FirFunctionCall.typeRef that
// you can see above
componentCall.annotations.forEach { it.accept(visitor) }
componentCall.typeArguments.forEach { it.accept(visitor) }
componentCall.argumentList.accept(visitor)
componentCall.calleeReference.accept(visitor)
componentCall.explicitReceiver.accept(visitor)
if (componentCall.dispatchReceiver !== componentCall.explicitReceiver) {
componentCall.dispatchReceiver.accept(visitor)
}
if (componentCall.extensionReceiver !== componentCall.explicitReceiver &&
componentCall.extensionReceiver !== componentCall.dispatchReceiver
) {
componentCall.extensionReceiver.accept(visitor)
}
}
private fun visitJump(loopJump: FirLoopJump) {
loopJump.runComponents()
loopJump.acceptChildren(this)
@@ -36,7 +36,10 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
// It always uses the same type ref as the corresponding property
return
}
else -> if (lastContainingDeclaration?.source?.kind is FirFakeSourceElementKind) {
else -> if (
errorTypeRef.source?.kind is FirFakeSourceElementKind ||
lastContainingDeclaration?.source?.kind is FirFakeSourceElementKind
) {
return
}
}
@@ -5,16 +5,13 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
@@ -27,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.propagateTypeFromQualifiedAccessAfterNul
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.types.*
@@ -41,7 +37,6 @@ import org.jetbrains.kotlin.types.AbstractTypeApproximator
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import kotlin.math.min
class FirCallCompletionResultsWriterTransformer(
override val session: FirSession,
@@ -66,10 +61,22 @@ class FirCallCompletionResultsWriterTransformer(
val declaration: FirDeclaration = subCandidate.symbol.phasedFir
val typeArguments = computeTypeArguments(qualifiedAccessExpression, subCandidate)
val typeRef = if (declaration is FirTypedDeclaration) {
typeCalculator.tryCalculateReturnType(declaration)
val calculated = typeCalculator.tryCalculateReturnType(declaration)
if (calculated !is FirErrorTypeRef) {
buildResolvedTypeRef {
source = calculated.source?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
annotations += calculated.annotations
type = calculated.type
}
} else {
buildErrorTypeRef {
source = calculated.source?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
diagnostic = calculated.diagnostic
}
}
} else {
buildErrorTypeRef {
source = calleeReference.source
source = calleeReference.source //?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
diagnostic = ConeSimpleDiagnostic("Callee reference to candidate without return type: ${declaration.render()}")
}
}
@@ -413,19 +420,31 @@ class FirCallCompletionResultsWriterTransformer(
// Transformations for synthetic calls generated by FirSyntheticCallGenerator
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
override fun transformWhenExpression(
whenExpression: FirWhenExpression,
data: ExpectedArgumentType?
): CompositeTransformResult<FirStatement> {
return transformSyntheticCall(whenExpression, data)
}
override fun transformTryExpression(tryExpression: FirTryExpression, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
override fun transformTryExpression(
tryExpression: FirTryExpression,
data: ExpectedArgumentType?
): CompositeTransformResult<FirStatement> {
return transformSyntheticCall(tryExpression, data)
}
override fun transformCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
override fun transformCheckNotNullCall(
checkNotNullCall: FirCheckNotNullCall,
data: ExpectedArgumentType?
): CompositeTransformResult<FirStatement> {
return transformSyntheticCall(checkNotNullCall, data)
}
override fun transformElvisExpression(elvisExpression: FirElvisExpression, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
override fun transformElvisExpression(
elvisExpression: FirElvisExpression,
data: ExpectedArgumentType?
): CompositeTransformResult<FirStatement> {
return transformSyntheticCall(elvisExpression, data)
}
@@ -23,7 +23,7 @@ object DefaultHttpClientWithFun : HttpClient by fClient() {
private fun fClient() = HttpClientImpl()
private fun <T> lazy(init: () -> T): <!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>kotlin.Lazy<T><!> {
private fun <T> lazy(init: () -> T): <!UNRESOLVED_REFERENCE!>kotlin.Lazy<T><!> {
init()
null!!
}
@@ -8,7 +8,7 @@ fun <T> foo() {
val a: <!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>LT<!> = emptyList()
fun localFun(): <!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>LT<!> {
fun localFun(): <!UNRESOLVED_REFERENCE!>LT<!> {
typealias LLT = List<T>
val b: <!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>LLT<!> = a