Add lazy debug diagnostic DEBUG_INFO_EXPRESSION_TYPE
This commit is contained in:
@@ -8,11 +8,14 @@ package org.jetbrains.kotlin.checkers.diagnostics
|
|||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
|
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory1
|
||||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
||||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil.INDIVIDUAL_PARAMETER_PATTERN
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil.INDIVIDUAL_PARAMETER_PATTERN
|
||||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil.SHOULD_BE_ESCAPED
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil.SHOULD_BE_ESCAPED
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.AbstractDiagnosticWithParametersRenderer
|
import org.jetbrains.kotlin.diagnostics.rendering.AbstractDiagnosticWithParametersRenderer
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticWithParameters1Renderer
|
||||||
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.TO_STRING
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class TextDiagnostic(
|
class TextDiagnostic(
|
||||||
@@ -141,9 +144,12 @@ class TextDiagnostic(
|
|||||||
|
|
||||||
private fun asTextDiagnostic(actualDiagnostic: ActualDiagnostic): TextDiagnostic {
|
private fun asTextDiagnostic(actualDiagnostic: ActualDiagnostic): TextDiagnostic {
|
||||||
val diagnostic = actualDiagnostic.diagnostic
|
val diagnostic = actualDiagnostic.diagnostic
|
||||||
|
val renderer = when (diagnostic.factory) {
|
||||||
val renderer = DefaultErrorMessages.getRendererForDiagnostic(diagnostic)
|
is DebugInfoDiagnosticFactory1 -> DiagnosticWithParameters1Renderer("{0}", TO_STRING)
|
||||||
|
else -> DefaultErrorMessages.getRendererForDiagnostic(diagnostic)
|
||||||
|
}
|
||||||
val diagnosticName = actualDiagnostic.name
|
val diagnosticName = actualDiagnostic.name
|
||||||
|
|
||||||
if (renderer is AbstractDiagnosticWithParametersRenderer) {
|
if (renderer is AbstractDiagnosticWithParametersRenderer) {
|
||||||
val renderParameters = renderer.renderParameters(diagnostic)
|
val renderParameters = renderer.renderParameters(diagnostic)
|
||||||
val parameters = ContainerUtil.map(renderParameters, { it.toString() })
|
val parameters = ContainerUtil.map(renderParameters, { it.toString() })
|
||||||
|
|||||||
+7
-1
@@ -5,15 +5,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.checkers.diagnostics.factories
|
package org.jetbrains.kotlin.checkers.diagnostics.factories
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
|
|
||||||
interface DebugInfoDiagnosticFactory {
|
interface DebugInfoDiagnosticFactory {
|
||||||
val withExplicitDefinitionOnly: Boolean
|
val withExplicitDefinitionOnly: Boolean
|
||||||
|
|
||||||
fun createDiagnostic(
|
fun createDiagnostic(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
languageVersionSettings: LanguageVersionSettings?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?
|
||||||
): Diagnostic
|
): Diagnostic
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -7,12 +7,15 @@ package org.jetbrains.kotlin.checkers.diagnostics.factories
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.checkers.diagnostics.DebugInfoDiagnostic
|
import org.jetbrains.kotlin.checkers.diagnostics.DebugInfoDiagnostic
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
|
||||||
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
|
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
|
|
||||||
class DebugInfoDiagnosticFactory0 : DiagnosticFactory0<PsiElement>,
|
class DebugInfoDiagnosticFactory0 : DiagnosticFactory0<PsiElement>,
|
||||||
DebugInfoDiagnosticFactory {
|
DebugInfoDiagnosticFactory {
|
||||||
@@ -21,7 +24,10 @@ class DebugInfoDiagnosticFactory0 : DiagnosticFactory0<PsiElement>,
|
|||||||
|
|
||||||
override fun createDiagnostic(
|
override fun createDiagnostic(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
languageVersionSettings: LanguageVersionSettings?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?
|
||||||
): Diagnostic {
|
): Diagnostic {
|
||||||
return DebugInfoDiagnostic(expression, this)
|
return DebugInfoDiagnostic(expression, this)
|
||||||
}
|
}
|
||||||
|
|||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.checkers.diagnostics.factories
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
||||||
|
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
|
|
||||||
|
class DebugInfoDiagnosticFactory1 : DiagnosticFactory1<PsiElement, String>,
|
||||||
|
DebugInfoDiagnosticFactory {
|
||||||
|
private val name: String
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "DEBUG_INFO_$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
override val withExplicitDefinitionOnly: Boolean
|
||||||
|
|
||||||
|
override fun createDiagnostic(
|
||||||
|
expression: KtExpression,
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
languageVersionSettings: LanguageVersionSettings?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?
|
||||||
|
) = when (name) {
|
||||||
|
"EXPRESSION_TYPE" -> {
|
||||||
|
val (type, dataFlowTypes) = CheckerTestUtil.getTypeInfo(
|
||||||
|
expression,
|
||||||
|
bindingContext,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
languageVersionSettings,
|
||||||
|
moduleDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
this.on(expression, Renderers.renderExpressionType(type, dataFlowTypes))
|
||||||
|
}
|
||||||
|
else -> throw NotImplementedError("Creation diagnostic '$name' isn't supported.")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected constructor(name: String, severity: Severity) : super(severity, PositioningStrategies.DEFAULT) {
|
||||||
|
this.name = name
|
||||||
|
this.withExplicitDefinitionOnly = false
|
||||||
|
}
|
||||||
|
|
||||||
|
protected constructor(name: String, severity: Severity, withExplicitDefinitionOnly: Boolean) : super(
|
||||||
|
severity,
|
||||||
|
PositioningStrategies.DEFAULT
|
||||||
|
) {
|
||||||
|
this.name = name
|
||||||
|
this.withExplicitDefinitionOnly = withExplicitDefinitionOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val EXPRESSION_TYPE = create(
|
||||||
|
"EXPRESSION_TYPE",
|
||||||
|
Severity.INFO,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
fun create(name: String, severity: Severity): DebugInfoDiagnosticFactory1 {
|
||||||
|
return DebugInfoDiagnosticFactory1(name, severity)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(name: String, severity: Severity, withExplicitDefinitionOnly: Boolean): DebugInfoDiagnosticFactory1 {
|
||||||
|
return DebugInfoDiagnosticFactory1(name, severity, withExplicitDefinitionOnly)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,10 +15,24 @@ import org.jetbrains.kotlin.checkers.*
|
|||||||
import org.jetbrains.kotlin.checkers.diagnostics.*
|
import org.jetbrains.kotlin.checkers.diagnostics.*
|
||||||
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory
|
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory
|
||||||
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory0
|
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory0
|
||||||
|
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory1
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
@@ -41,7 +55,11 @@ object CheckerTestUtil {
|
|||||||
root: PsiElement,
|
root: PsiElement,
|
||||||
markDynamicCalls: Boolean,
|
markDynamicCalls: Boolean,
|
||||||
dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
|
dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
|
||||||
withNewInference: Boolean
|
withNewInference: Boolean,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?,
|
||||||
|
diagnosedRanges: MutableMap<IntRange, MutableSet<String>>? = null
|
||||||
): List<ActualDiagnostic> {
|
): List<ActualDiagnostic> {
|
||||||
val result = getDiagnosticsIncludingSyntaxErrors(
|
val result = getDiagnosticsIncludingSyntaxErrors(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
@@ -49,7 +67,11 @@ object CheckerTestUtil {
|
|||||||
markDynamicCalls,
|
markDynamicCalls,
|
||||||
dynamicCallDescriptors,
|
dynamicCallDescriptors,
|
||||||
null,
|
null,
|
||||||
withNewInference
|
withNewInference,
|
||||||
|
languageVersionSettings,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
moduleDescriptor,
|
||||||
|
diagnosedRanges
|
||||||
)
|
)
|
||||||
val sortedBindings = implementingModulesBindings.sortedBy { it.first }
|
val sortedBindings = implementingModulesBindings.sortedBy { it.first }
|
||||||
|
|
||||||
@@ -63,7 +85,11 @@ object CheckerTestUtil {
|
|||||||
markDynamicCalls,
|
markDynamicCalls,
|
||||||
dynamicCallDescriptors,
|
dynamicCallDescriptors,
|
||||||
(platform as MultiTargetPlatform.Specific).platform,
|
(platform as MultiTargetPlatform.Specific).platform,
|
||||||
withNewInference
|
withNewInference,
|
||||||
|
languageVersionSettings,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
moduleDescriptor,
|
||||||
|
diagnosedRanges
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -77,7 +103,11 @@ object CheckerTestUtil {
|
|||||||
markDynamicCalls: Boolean,
|
markDynamicCalls: Boolean,
|
||||||
dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
|
dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
|
||||||
platform: String?,
|
platform: String?,
|
||||||
withNewInference: Boolean
|
withNewInference: Boolean,
|
||||||
|
languageVersionSettings: LanguageVersionSettings?,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?,
|
||||||
|
diagnosedRanges: MutableMap<IntRange, MutableSet<String>>? = null
|
||||||
): MutableList<ActualDiagnostic> {
|
): MutableList<ActualDiagnostic> {
|
||||||
val diagnostics: MutableList<ActualDiagnostic> = mutableListOf()
|
val diagnostics: MutableList<ActualDiagnostic> = mutableListOf()
|
||||||
|
|
||||||
@@ -98,7 +128,11 @@ object CheckerTestUtil {
|
|||||||
markDynamicCalls,
|
markDynamicCalls,
|
||||||
dynamicCallDescriptors,
|
dynamicCallDescriptors,
|
||||||
platform,
|
platform,
|
||||||
withNewInference
|
withNewInference,
|
||||||
|
languageVersionSettings,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
moduleDescriptor,
|
||||||
|
diagnosedRanges
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -111,7 +145,11 @@ object CheckerTestUtil {
|
|||||||
markDynamicCalls: Boolean,
|
markDynamicCalls: Boolean,
|
||||||
dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
|
dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
|
||||||
platform: String?,
|
platform: String?,
|
||||||
withNewInference: Boolean
|
withNewInference: Boolean,
|
||||||
|
languageVersionSettings: LanguageVersionSettings?,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?,
|
||||||
|
diagnosedRanges: MutableMap<IntRange, MutableSet<String>>?
|
||||||
): List<ActualDiagnostic> {
|
): List<ActualDiagnostic> {
|
||||||
val debugAnnotations = mutableListOf<ActualDiagnostic>()
|
val debugAnnotations = mutableListOf<ActualDiagnostic>()
|
||||||
|
|
||||||
@@ -131,6 +169,7 @@ object CheckerTestUtil {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
|
|
||||||
val factoryList = listOf(
|
val factoryList = listOf(
|
||||||
|
BindingContext.EXPRESSION_TYPE_INFO to DebugInfoDiagnosticFactory1.EXPRESSION_TYPE,
|
||||||
BindingContext.SMARTCAST to DebugInfoDiagnosticFactory0.SMARTCAST,
|
BindingContext.SMARTCAST to DebugInfoDiagnosticFactory0.SMARTCAST,
|
||||||
BindingContext.IMPLICIT_RECEIVER_SMARTCAST to DebugInfoDiagnosticFactory0.IMPLICIT_RECEIVER_SMARTCAST,
|
BindingContext.IMPLICIT_RECEIVER_SMARTCAST to DebugInfoDiagnosticFactory0.IMPLICIT_RECEIVER_SMARTCAST,
|
||||||
BindingContext.SMARTCAST_NULL to DebugInfoDiagnosticFactory0.CONSTANT,
|
BindingContext.SMARTCAST_NULL to DebugInfoDiagnosticFactory0.CONSTANT,
|
||||||
@@ -140,10 +179,16 @@ object CheckerTestUtil {
|
|||||||
|
|
||||||
for ((context, factory) in factoryList) {
|
for ((context, factory) in factoryList) {
|
||||||
for ((expression, _) in bindingContext.getSliceContents(context)) {
|
for ((expression, _) in bindingContext.getSliceContents(context)) {
|
||||||
if (PsiTreeUtil.isAncestor(root, expression, false)) {
|
val needRender = !factory.withExplicitDefinitionOnly
|
||||||
|
|| diagnosedRanges?.get(expression.startOffset..expression.endOffset)?.contains(factory.name) == true
|
||||||
|
|
||||||
|
if (PsiTreeUtil.isAncestor(root, expression, false) && needRender) {
|
||||||
val diagnostic = factory.createDiagnostic(
|
val diagnostic = factory.createDiagnostic(
|
||||||
expression,
|
expression,
|
||||||
bindingContext
|
bindingContext,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
languageVersionSettings,
|
||||||
|
moduleDescriptor
|
||||||
)
|
)
|
||||||
debugAnnotations.add(ActualDiagnostic(diagnostic, platform, withNewInference))
|
debugAnnotations.add(ActualDiagnostic(diagnostic, platform, withNewInference))
|
||||||
}
|
}
|
||||||
@@ -323,8 +368,11 @@ object CheckerTestUtil {
|
|||||||
return if (iterator.hasNext()) iterator.next() else null
|
return if (iterator.hasNext()) iterator.next() else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun parseDiagnosedRanges(
|
||||||
fun parseDiagnosedRanges(text: String, result: MutableList<DiagnosedRange>): String {
|
text: String,
|
||||||
|
ranges: MutableList<DiagnosedRange>,
|
||||||
|
rangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>? = null
|
||||||
|
): String {
|
||||||
val matcher = rangeStartOrEndPattern.matcher(text)
|
val matcher = rangeStartOrEndPattern.matcher(text)
|
||||||
val opened = Stack<DiagnosedRange>()
|
val opened = Stack<DiagnosedRange>()
|
||||||
var offsetCompensation = 0
|
var offsetCompensation = 0
|
||||||
@@ -340,7 +388,7 @@ object CheckerTestUtil {
|
|||||||
while (diagnosticTypeMatcher.find())
|
while (diagnosticTypeMatcher.find())
|
||||||
range.addDiagnostic(diagnosticTypeMatcher.group())
|
range.addDiagnostic(diagnosticTypeMatcher.group())
|
||||||
opened.push(range)
|
opened.push(range)
|
||||||
result.add(range)
|
ranges.add(range)
|
||||||
}
|
}
|
||||||
offsetCompensation += matchedText.length
|
offsetCompensation += matchedText.length
|
||||||
}
|
}
|
||||||
@@ -349,6 +397,14 @@ object CheckerTestUtil {
|
|||||||
|
|
||||||
matcher.reset()
|
matcher.reset()
|
||||||
|
|
||||||
|
if (rangesToDiagnosticNames != null) {
|
||||||
|
ranges.forEach {
|
||||||
|
val range = it.start..it.end
|
||||||
|
rangesToDiagnosticNames.putIfAbsent(range, mutableSetOf())
|
||||||
|
rangesToDiagnosticNames[range]!! += it.getDiagnostics().map { it.name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return matcher.replaceAll("")
|
return matcher.replaceAll("")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,4 +605,42 @@ object CheckerTestUtil {
|
|||||||
ActualDiagnosticDescriptor(range.startOffset, range.endOffset, abstractDiagnostics)
|
ActualDiagnosticDescriptor(range.startOffset, range.endOffset, abstractDiagnostics)
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTypeInfo(
|
||||||
|
expression: PsiElement,
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
dataFlowValueFactory: DataFlowValueFactory?,
|
||||||
|
languageVersionSettings: LanguageVersionSettings?,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl?
|
||||||
|
): Pair<KotlinType?, Set<KotlinType>?> {
|
||||||
|
if (expression is KtCallableDeclaration) {
|
||||||
|
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, expression] as? CallableDescriptor
|
||||||
|
if (descriptor != null) {
|
||||||
|
return Pair(descriptor.returnType, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val expressionTypeInfo =
|
||||||
|
bindingContext[BindingContext.EXPRESSION_TYPE_INFO, expression as KtExpression] ?: noTypeInfo(DataFlowInfo.EMPTY)
|
||||||
|
val expressionType = expression.getType(bindingContext)
|
||||||
|
val result = expressionType ?: return Pair(null, null)
|
||||||
|
|
||||||
|
if (dataFlowValueFactory == null || moduleDescriptor == null)
|
||||||
|
return Pair(expressionType, null)
|
||||||
|
|
||||||
|
val dataFlowValue = dataFlowValueFactory.createDataFlowValue(expression, expressionType, bindingContext, moduleDescriptor)
|
||||||
|
val types = expressionTypeInfo.dataFlowInfo.getStableTypes(dataFlowValue, languageVersionSettings!!)
|
||||||
|
|
||||||
|
if (!types.isNullOrEmpty())
|
||||||
|
return Pair(result, types)
|
||||||
|
|
||||||
|
val smartCast = bindingContext[BindingContext.SMARTCAST, expression]
|
||||||
|
if (smartCast != null && expression is KtReferenceExpression) {
|
||||||
|
val declaredType = (bindingContext[BindingContext.REFERENCE_TARGET, expression] as? CallableDescriptor)?.returnType
|
||||||
|
if (declaredType != null) {
|
||||||
|
return Pair(result, setOf(declaredType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Pair(result, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
-1
@@ -40,7 +40,6 @@ public final class DiagnosticFactoryToRendererMap {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "DiagnosticFactory#" + name;
|
return "DiagnosticFactory#" + name;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
|
||||||
private void checkMutability() {
|
private void checkMutability() {
|
||||||
if (immutable) {
|
if (immutable) {
|
||||||
|
|||||||
@@ -24,19 +24,19 @@ import org.jetbrains.kotlin.analyzer.ModuleInfo
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.cfg.WhenMissingCase
|
import org.jetbrains.kotlin.cfg.WhenMissingCase
|
||||||
import org.jetbrains.kotlin.cfg.hasUnknown
|
import org.jetbrains.kotlin.cfg.hasUnknown
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newTable
|
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newTable
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newText
|
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newText
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer.Companion.DEBUG_TEXT
|
||||||
import org.jetbrains.kotlin.renderer.PropertyAccessorRenderingPolicy
|
import org.jetbrains.kotlin.renderer.PropertyAccessorRenderingPolicy
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||||
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.*
|
import org.jetbrains.kotlin.resolve.calls.inference.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
|
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
|
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
|
||||||
@@ -45,9 +45,11 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.getValidityConstraintForConstituentType
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.getValidityConstraintForConstituentType
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
@@ -679,6 +681,18 @@ object Renderers {
|
|||||||
receiverAfterName = false
|
receiverAfterName = false
|
||||||
propertyAccessorRenderingPolicy = PropertyAccessorRenderingPolicy.PRETTY
|
propertyAccessorRenderingPolicy = PropertyAccessorRenderingPolicy.PRETTY
|
||||||
}.asRenderer()
|
}.asRenderer()
|
||||||
|
|
||||||
|
fun renderExpressionType(type: KotlinType?, dataFlowTypes: Set<KotlinType>?): String {
|
||||||
|
if (type == null)
|
||||||
|
return "Type is unknown"
|
||||||
|
|
||||||
|
if (dataFlowTypes == null)
|
||||||
|
return DEBUG_TEXT.renderType(type)
|
||||||
|
|
||||||
|
val typesAsString = dataFlowTypes.map { DEBUG_TEXT.renderType(it) }.toMutableSet().apply { add(DEBUG_TEXT.renderType(type)) }
|
||||||
|
|
||||||
|
return typesAsString.sorted().joinToString(separator = " & ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DescriptorRenderer.asRenderer() = SmartDescriptorRenderer(this)
|
fun DescriptorRenderer.asRenderer() = SmartDescriptorRenderer(this)
|
||||||
|
|||||||
+8
-2
@@ -175,9 +175,15 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
|||||||
if (platform is MultiTargetPlatform.Specific) platform to moduleBindings[testModule]!!
|
if (platform is MultiTargetPlatform.Specific) platform to moduleBindings[testModule]!!
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
|
val moduleDescriptor = modules[module]!!
|
||||||
|
|
||||||
ok = ok and testFile.getActualText(
|
ok = ok and testFile.getActualText(
|
||||||
moduleBindings[module]!!, implementingModulesBindings, actualText,
|
moduleBindings[module]!!,
|
||||||
shouldSkipJvmSignatureDiagnostics(groupedByModule) || isCommonModule
|
implementingModulesBindings,
|
||||||
|
actualText,
|
||||||
|
shouldSkipJvmSignatureDiagnostics(groupedByModule) || isCommonModule,
|
||||||
|
languageVersionSettingsByModule[module]!!,
|
||||||
|
moduleDescriptor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.*
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
|
import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@@ -132,8 +134,9 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
textWithMarkers: String,
|
textWithMarkers: String,
|
||||||
val directives: Map<String, String>
|
val directives: Map<String, String>
|
||||||
) {
|
) {
|
||||||
private val diagnosedRanges: MutableList<DiagnosedRange> = ArrayList()
|
private val diagnosedRanges: MutableList<DiagnosedRange> = mutableListOf()
|
||||||
val actualDiagnostics: MutableList<ActualDiagnostic> = ArrayList()
|
private val diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>> = mutableMapOf()
|
||||||
|
val actualDiagnostics: MutableList<ActualDiagnostic> = mutableListOf()
|
||||||
val expectedText: String
|
val expectedText: String
|
||||||
val clearText: String
|
val clearText: String
|
||||||
private val createKtFile: Lazy<KtFile?>
|
private val createKtFile: Lazy<KtFile?>
|
||||||
@@ -144,7 +147,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
val declareFlexibleType: Boolean
|
val declareFlexibleType: Boolean
|
||||||
val checkLazyLog: Boolean
|
val checkLazyLog: Boolean
|
||||||
private val markDynamicCalls: Boolean
|
private val markDynamicCalls: Boolean
|
||||||
val dynamicCallDescriptors: MutableList<DeclarationDescriptor> = ArrayList()
|
val dynamicCallDescriptors: MutableList<DeclarationDescriptor> = mutableListOf()
|
||||||
val withNewInferenceDirective: Boolean
|
val withNewInferenceDirective: Boolean
|
||||||
val newInferenceEnabled: Boolean
|
val newInferenceEnabled: Boolean
|
||||||
val renderDiagnosticMessages: Boolean
|
val renderDiagnosticMessages: Boolean
|
||||||
@@ -167,7 +170,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
this.expectedText = this.clearText
|
this.expectedText = this.clearText
|
||||||
} else {
|
} else {
|
||||||
this.expectedText = textWithMarkers
|
this.expectedText = textWithMarkers
|
||||||
this.clearText = CheckerTestUtil.parseDiagnosedRanges(addExtras(expectedText), diagnosedRanges)
|
this.clearText = CheckerTestUtil.parseDiagnosedRanges(addExtras(expectedText), diagnosedRanges, diagnosedRangesToDiagnosticNames)
|
||||||
this.createKtFile = lazy { TestCheckerUtil.createCheckAndReturnPsiFile(fileName, clearText, project) }
|
this.createKtFile = lazy { TestCheckerUtil.createCheckAndReturnPsiFile(fileName, clearText, project) }
|
||||||
}
|
}
|
||||||
this.renderDiagnosticMessages = RENDER_DIAGNOSTICS_MESSAGES in directives
|
this.renderDiagnosticMessages = RENDER_DIAGNOSTICS_MESSAGES in directives
|
||||||
@@ -223,7 +226,9 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
implementingModulesBindings: List<Pair<MultiTargetPlatform, BindingContext>>,
|
implementingModulesBindings: List<Pair<MultiTargetPlatform, BindingContext>>,
|
||||||
actualText: StringBuilder,
|
actualText: StringBuilder,
|
||||||
skipJvmSignatureDiagnostics: Boolean
|
skipJvmSignatureDiagnostics: Boolean,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
moduleDescriptor: ModuleDescriptorImpl
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val ktFile = this.ktFile
|
val ktFile = this.ktFile
|
||||||
if (ktFile == null) {
|
if (ktFile == null) {
|
||||||
@@ -242,21 +247,31 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
|
|
||||||
val ok = booleanArrayOf(true)
|
val ok = booleanArrayOf(true)
|
||||||
val withNewInference = newInferenceEnabled && withNewInferenceDirective && !USE_OLD_INFERENCE_DIAGNOSTICS_FOR_NI
|
val withNewInference = newInferenceEnabled && withNewInferenceDirective && !USE_OLD_INFERENCE_DIAGNOSTICS_FOR_NI
|
||||||
val diagnostics = ContainerUtil.filter(
|
val diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
||||||
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
bindingContext,
|
||||||
bindingContext, implementingModulesBindings, ktFile, markDynamicCalls, dynamicCallDescriptors, newInferenceEnabled
|
implementingModulesBindings,
|
||||||
) + jvmSignatureDiagnostics,
|
ktFile,
|
||||||
|
markDynamicCalls,
|
||||||
|
dynamicCallDescriptors,
|
||||||
|
newInferenceEnabled,
|
||||||
|
languageVersionSettings,
|
||||||
|
DataFlowValueFactoryImpl(languageVersionSettings),
|
||||||
|
moduleDescriptor,
|
||||||
|
this.diagnosedRangesToDiagnosticNames
|
||||||
|
)
|
||||||
|
val filteredDiagnostics = ContainerUtil.filter(
|
||||||
|
diagnostics + jvmSignatureDiagnostics,
|
||||||
{ whatDiagnosticsToConsider.value(it.diagnostic) }
|
{ whatDiagnosticsToConsider.value(it.diagnostic) }
|
||||||
)
|
)
|
||||||
|
|
||||||
actualDiagnostics.addAll(diagnostics)
|
actualDiagnostics.addAll(filteredDiagnostics)
|
||||||
|
|
||||||
val uncheckedDiagnostics = mutableListOf<PositionalTextDiagnostic>()
|
val uncheckedDiagnostics = mutableListOf<PositionalTextDiagnostic>()
|
||||||
val inferenceCompatibilityOfTest = asInferenceCompatibility(withNewInference)
|
val inferenceCompatibilityOfTest = asInferenceCompatibility(withNewInference)
|
||||||
val invertedInferenceCompatibilityOfTest = asInferenceCompatibility(!withNewInference)
|
val invertedInferenceCompatibilityOfTest = asInferenceCompatibility(!withNewInference)
|
||||||
|
|
||||||
val diagnosticToExpectedDiagnostic =
|
val diagnosticToExpectedDiagnostic =
|
||||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, object : DiagnosticDiffCallbacks {
|
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, filteredDiagnostics, object : DiagnosticDiffCallbacks {
|
||||||
override fun missingDiagnostic(diagnostic: TextDiagnostic, expectedStart: Int, expectedEnd: Int) {
|
override fun missingDiagnostic(diagnostic: TextDiagnostic, expectedStart: Int, expectedEnd: Int) {
|
||||||
if (withNewInferenceDirective && diagnostic.inferenceCompatibility != inferenceCompatibilityOfTest) {
|
if (withNewInferenceDirective && diagnostic.inferenceCompatibility != inferenceCompatibilityOfTest) {
|
||||||
updateUncheckedDiagnostics(diagnostic, expectedStart, expectedEnd)
|
updateUncheckedDiagnostics(diagnostic, expectedStart, expectedEnd)
|
||||||
@@ -307,7 +322,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
actualText.append(
|
actualText.append(
|
||||||
CheckerTestUtil.addDiagnosticMarkersToText(
|
CheckerTestUtil.addDiagnosticMarkersToText(
|
||||||
ktFile,
|
ktFile,
|
||||||
diagnostics,
|
filteredDiagnostics,
|
||||||
diagnosticToExpectedDiagnostic,
|
diagnosticToExpectedDiagnostic,
|
||||||
{ file -> file.text },
|
{ file -> file.text },
|
||||||
uncheckedDiagnostics,
|
uncheckedDiagnostics,
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ private data class DiagnosticData(
|
|||||||
private abstract class Test(private vararg val expectedMessages: String) {
|
private abstract class Test(private vararg val expectedMessages: String) {
|
||||||
fun test(psiFile: PsiFile, environment: KotlinCoreEnvironment) {
|
fun test(psiFile: PsiFile, environment: KotlinCoreEnvironment) {
|
||||||
val bindingContext = JvmResolveUtil.analyze(psiFile as KtFile, environment).bindingContext
|
val bindingContext = JvmResolveUtil.analyze(psiFile as KtFile, environment).bindingContext
|
||||||
|
val emptyModule = KotlinTestUtils.createEmptyModule()
|
||||||
|
val container = createContainerForTests(environment.project, emptyModule)
|
||||||
|
val dataFlowValueFactory = container.dataFlowValueFactory
|
||||||
|
val languageVersionSettings = container.expressionTypingServices.languageVersionSettings
|
||||||
val expectedText = CheckerTestUtil.addDiagnosticMarkersToText(
|
val expectedText = CheckerTestUtil.addDiagnosticMarkersToText(
|
||||||
psiFile,
|
psiFile,
|
||||||
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
||||||
@@ -40,12 +44,15 @@ private abstract class Test(private vararg val expectedMessages: String) {
|
|||||||
false,
|
false,
|
||||||
mutableListOf(),
|
mutableListOf(),
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
languageVersionSettings,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
emptyModule
|
||||||
)
|
)
|
||||||
).toString()
|
).toString()
|
||||||
val diagnosedRanges = Lists.newArrayList<DiagnosedRange>()
|
val diagnosedRanges = Lists.newArrayList<DiagnosedRange>()
|
||||||
|
|
||||||
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges)
|
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges, mutableMapOf())
|
||||||
|
|
||||||
val actualDiagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
val actualDiagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
@@ -53,7 +60,10 @@ private abstract class Test(private vararg val expectedMessages: String) {
|
|||||||
false,
|
false,
|
||||||
mutableListOf(),
|
mutableListOf(),
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
languageVersionSettings,
|
||||||
|
dataFlowValueFactory,
|
||||||
|
emptyModule
|
||||||
)
|
)
|
||||||
|
|
||||||
makeTestData(actualDiagnostics, diagnosedRanges)
|
makeTestData(actualDiagnostics, diagnosedRanges)
|
||||||
|
|||||||
@@ -367,7 +367,8 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
|||||||
List<KtFile> ktFiles = new ArrayList<>(files.size());
|
List<KtFile> ktFiles = new ArrayList<>(files.size());
|
||||||
for (TestFile file : files) {
|
for (TestFile file : files) {
|
||||||
if (file.name.endsWith(".kt")) {
|
if (file.name.endsWith(".kt")) {
|
||||||
String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(file.content, new ArrayList<>(0));
|
// `rangesToDiagnosticNames` parameter is not-null only for diagnostic tests, it's using for lazy diagnostics
|
||||||
|
String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(file.content, new ArrayList<>(0), null);
|
||||||
ktFiles.add(KotlinTestUtils.createFile(file.name, content, project));
|
ktFiles.add(KotlinTestUtils.createFile(file.name, content, project));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,8 @@ public class CodegenTestFiles {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static CodegenTestFiles create(@NotNull String fileName, @NotNull String contentWithDiagnosticMarkup, @NotNull Project project) {
|
public static CodegenTestFiles create(@NotNull String fileName, @NotNull String contentWithDiagnosticMarkup, @NotNull Project project) {
|
||||||
String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(contentWithDiagnosticMarkup, new ArrayList<>());
|
// `rangesToDiagnosticNames` parameter is not-null only for diagnostic tests, it's using for lazy diagnostics
|
||||||
|
String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(contentWithDiagnosticMarkup, new ArrayList<>(), null);
|
||||||
KtFile file = KotlinTestUtils.createFile(fileName, content, project);
|
KtFile file = KotlinTestUtils.createFile(fileName, content, project);
|
||||||
List<PsiErrorElement> ranges = AnalyzingUtils.getSyntaxErrorRanges(file);
|
List<PsiErrorElement> ranges = AnalyzingUtils.getSyntaxErrorRanges(file);
|
||||||
assert ranges.isEmpty() : "Syntax errors found in " + file + ": " + ranges;
|
assert ranges.isEmpty() : "Syntax errors found in " + file + ": " + ranges;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
|
|||||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.*
|
import org.jetbrains.kotlin.idea.caches.resolve.*
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
@@ -34,13 +35,17 @@ class CopyAsDiagnosticTestAction : AnAction() {
|
|||||||
|
|
||||||
val bindingContext = (psiFile as KtFile).analyzeWithContent()
|
val bindingContext = (psiFile as KtFile).analyzeWithContent()
|
||||||
|
|
||||||
|
// Parameters `languageVersionSettings`, `dataFlowValueFactory` and `moduleDescriptor` are not-null only for compiler diagnostic tests
|
||||||
val diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
val diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
psiFile,
|
psiFile,
|
||||||
false,
|
false,
|
||||||
mutableListOf(),
|
mutableListOf(),
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
val result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString()
|
val result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString()
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -102,7 +102,8 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
|||||||
val ktFiles = ArrayList<KtFile>(files.size)
|
val ktFiles = ArrayList<KtFile>(files.size)
|
||||||
for (file in files.sorted()) {
|
for (file in files.sorted()) {
|
||||||
if (file.name.endsWith(".kt")) {
|
if (file.name.endsWith(".kt")) {
|
||||||
val content = CheckerTestUtil.parseDiagnosedRanges(file.content, ArrayList(0))
|
// `rangesToDiagnosticNames` parameter is not-null only for diagnostic tests, it's using for lazy diagnostics
|
||||||
|
val content = CheckerTestUtil.parseDiagnosedRanges(file.content, ArrayList(0), null)
|
||||||
val tmpKtFile = File(tmpDir, file.name).apply { writeText(content) }
|
val tmpKtFile = File(tmpDir, file.name).apply { writeText(content) }
|
||||||
val virtualFile = StandardFileSystems.local().findFileByPath(tmpKtFile.path) ?: error("Can't find ${file.name}")
|
val virtualFile = StandardFileSystems.local().findFileByPath(tmpKtFile.path) ?: error("Can't find ${file.name}")
|
||||||
ktFiles.add(psiManager.findFile(virtualFile) as? KtFile ?: error("Can't load ${file.name}"))
|
ktFiles.add(psiManager.findFile(virtualFile) as? KtFile ?: error("Can't load ${file.name}"))
|
||||||
|
|||||||
Reference in New Issue
Block a user