Decompose and rewrite CheckerTestUtil to Kotlin

This commit is contained in:
victor.petukhov
2019-02-07 17:29:54 +03:00
parent 9e06e1eec0
commit f92232f015
21 changed files with 1225 additions and 1206 deletions
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2019 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
import org.jetbrains.kotlin.checkers.diagnostics.ActualDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.DebugInfoDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory0
import org.jetbrains.kotlin.checkers.utils.DebugInfoUtil
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtReferenceExpression
class CheckerDebugInfoReporter(
private val dynamicCallDescriptors: MutableList<DeclarationDescriptor>,
private val markDynamicCalls: Boolean,
private val debugAnnotations: MutableList<ActualDiagnostic>,
private val withNewInference: Boolean,
private val platform: String?
) : DebugInfoUtil.DebugInfoReporter() {
override fun reportElementWithErrorType(expression: KtReferenceExpression) {
newDiagnostic(
expression,
DebugInfoDiagnosticFactory0.ELEMENT_WITH_ERROR_TYPE
)
}
override fun reportMissingUnresolved(expression: KtReferenceExpression) {
newDiagnostic(
expression,
DebugInfoDiagnosticFactory0.MISSING_UNRESOLVED
)
}
override fun reportUnresolvedWithTarget(
expression: KtReferenceExpression,
target: String
) {
newDiagnostic(expression, DebugInfoDiagnosticFactory0.UNRESOLVED_WITH_TARGET)
}
override fun reportDynamicCall(
element: KtElement,
declarationDescriptor: DeclarationDescriptor
) {
dynamicCallDescriptors.add(declarationDescriptor)
if (markDynamicCalls) {
newDiagnostic(element, DebugInfoDiagnosticFactory0.DYNAMIC)
}
}
private fun newDiagnostic(
element: KtElement,
factory: DebugInfoDiagnosticFactory0
) {
debugAnnotations.add(
ActualDiagnostic(
DebugInfoDiagnostic(element, factory), platform, withNewInference
)
)
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2019 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
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic
class DiagnosedRange constructor(val start: Int) {
var end: Int = 0
private val diagnostics = ContainerUtil.newSmartList<TextDiagnostic>()
fun getDiagnostics(): List<TextDiagnostic> {
return diagnostics
}
fun addDiagnostic(diagnostic: String) {
diagnostics.add(TextDiagnostic.parseDiagnostic(diagnostic))
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2019 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
import com.google.common.collect.Maps
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.checkers.diagnostics.AbstractTestDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.PositionalTextDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic
abstract class AbstractDiagnosticDescriptor internal constructor(val start: Int, val end: Int) {
val textRange: TextRange
get() = TextRange(start, end)
}
class ActualDiagnosticDescriptor internal constructor(start: Int, end: Int, val diagnostics: List<AbstractTestDiagnostic>) :
AbstractDiagnosticDescriptor(start, end) {
val textDiagnosticsMap: MutableMap<AbstractTestDiagnostic, TextDiagnostic>
get() {
val diagnosticMap = Maps.newLinkedHashMap<AbstractTestDiagnostic, TextDiagnostic>()
for (diagnostic in diagnostics) {
diagnosticMap[diagnostic] = TextDiagnostic.asTextDiagnostic(diagnostic)
}
return diagnosticMap
}
}
class TextDiagnosticDescriptor internal constructor(private val positionalTextDiagnostic: PositionalTextDiagnostic) :
AbstractDiagnosticDescriptor(positionalTextDiagnostic.start, positionalTextDiagnostic.end) {
val textDiagnostic: TextDiagnostic
get() = positionalTextDiagnostic.diagnostic
}
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2019 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
import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic
interface DiagnosticDiffCallbacks {
fun missingDiagnostic(diagnostic: TextDiagnostic, expectedStart: Int, expectedEnd: Int)
fun wrongParametersDiagnostic(expectedDiagnostic: TextDiagnostic, actualDiagnostic: TextDiagnostic, start: Int, end: Int)
fun unexpectedDiagnostic(diagnostic: TextDiagnostic, actualStart: Int, actualEnd: Int)
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 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
interface AbstractTestDiagnostic : Comparable<AbstractTestDiagnostic> {
val name: String
val platform: String?
val inferenceCompatibility: TextDiagnostic.InferenceCompatibility
fun enhanceInferenceCompatibility(inferenceCompatibility: TextDiagnostic.InferenceCompatibility)
override fun compareTo(other: AbstractTestDiagnostic): Int
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2019 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
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters1
class ActualDiagnostic constructor(val diagnostic: Diagnostic, override val platform: String?, withNewInference: Boolean) :
AbstractTestDiagnostic {
override var inferenceCompatibility = if (withNewInference)
TextDiagnostic.InferenceCompatibility.NEW
else
TextDiagnostic.InferenceCompatibility.OLD
override val name: String
get() = diagnostic.factory.name
val file: PsiFile
get() = diagnostic.psiFile
override fun compareTo(other: AbstractTestDiagnostic): Int {
return if (this.diagnostic is DiagnosticWithParameters1<*, *> && other is ActualDiagnostic && other.diagnostic is DiagnosticWithParameters1<*, *>) {
(name + this.diagnostic.a).compareTo(other.name + other.diagnostic.a)
} else if (this.diagnostic is DiagnosticWithParameters1<*, *>) {
(name + this.diagnostic.a).compareTo(other.name)
} else if (other is ActualDiagnostic && other.diagnostic is DiagnosticWithParameters1<*, *>) {
name.compareTo(other.name + other.diagnostic.a)
} else {
name.compareTo(other.name)
}
}
override fun enhanceInferenceCompatibility(inferenceCompatibility: TextDiagnostic.InferenceCompatibility) {
this.inferenceCompatibility = inferenceCompatibility
}
override fun equals(other: Any?): Boolean {
if (other !is ActualDiagnostic) return false
// '==' on diagnostics is intentional here
return other.diagnostic === diagnostic &&
(if (other.platform == null) platform == null else other.platform == platform) &&
other.inferenceCompatibility == inferenceCompatibility
}
override fun hashCode(): Int {
var result = System.identityHashCode(diagnostic)
result = 31 * result + (platform?.hashCode() ?: 0)
result = 31 * result + inferenceCompatibility.hashCode()
return result
}
override fun toString(): String {
val inferenceAbbreviation = inferenceCompatibility.abbreviation
return (if (inferenceAbbreviation != null) inferenceAbbreviation + ";" else "") +
(if (platform != null) "$platform:" else "") +
diagnostic.toString()
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2019 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
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.checkers.diagnostics.factories.SyntaxErrorDiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.psi.KtElement
class DebugInfoDiagnostic(element: KtElement, factory: DiagnosticFactory<*>) : AbstractDiagnosticForTests(element, factory)
class SyntaxErrorDiagnostic(errorElement: PsiErrorElement) : AbstractDiagnosticForTests(errorElement,
SyntaxErrorDiagnosticFactory.INSTANCE
)
open class AbstractDiagnosticForTests(private val element: PsiElement, private val factory: DiagnosticFactory<*>) : Diagnostic {
override fun getFactory(): DiagnosticFactory<*> {
return factory
}
override fun getSeverity(): Severity {
return Severity.ERROR
}
override fun getPsiElement(): PsiElement {
return element
}
override fun getTextRanges(): List<TextRange> {
return listOf(element.textRange)
}
override fun getPsiFile(): PsiFile {
return element.containingFile
}
override fun isValid(): Boolean {
return true
}
}
@@ -1,19 +1,8 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 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.
* 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.checkers.diagnostics package org.jetbrains.kotlin.checkers.diagnostics
data class PositionalTextDiagnostic(val diagnostic: CheckerTestUtil.TextDiagnostic, val start: Int, val end: Int) data class PositionalTextDiagnostic(val diagnostic: TextDiagnostic, val start: Int, val end: Int)
@@ -0,0 +1,165 @@
/*
* Copyright 2010-2019 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
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.SmartList
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil.INDIVIDUAL_PARAMETER_PATTERN
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil.SHOULD_BE_ESCAPED
import org.jetbrains.kotlin.diagnostics.rendering.AbstractDiagnosticWithParametersRenderer
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import java.util.regex.Pattern
class TextDiagnostic(
override val name: String,
override val platform: String?,
val parameters: List<String>?,
inference: InferenceCompatibility?
) : AbstractTestDiagnostic {
override var inferenceCompatibility = inference ?: InferenceCompatibility.ALL
val description: String
get() = (if (platform != null) "$platform:" else "") + name
enum class InferenceCompatibility constructor(internal var abbreviation: String?) {
NEW(CheckerTestUtil.NEW_INFERENCE_PREFIX), OLD(CheckerTestUtil.OLD_INFERENCE_PREFIX), ALL(null);
fun isCompatible(other: InferenceCompatibility): Boolean {
return this == other || this == ALL || other == ALL
}
}
override fun compareTo(other: AbstractTestDiagnostic): Int {
return name.compareTo(other.name)
}
override fun enhanceInferenceCompatibility(inferenceCompatibility: InferenceCompatibility) {
this.inferenceCompatibility = inferenceCompatibility
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val that = other as TextDiagnostic?
if (name != that!!.name) return false
if (if (platform != null) platform != that.platform else that.platform != null) return false
if (if (parameters != null) parameters != that.parameters else that.parameters != null) return false
return inferenceCompatibility == that.inferenceCompatibility
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + (platform?.hashCode() ?: 0)
result = 31 * result + (parameters?.hashCode() ?: 0)
result = 31 * result + inferenceCompatibility.hashCode()
return result
}
fun asString(): String {
val result = StringBuilder()
if (inferenceCompatibility.abbreviation != null) {
result.append(inferenceCompatibility.abbreviation)
result.append(";")
}
if (platform != null) {
result.append(platform)
result.append(":")
}
result.append(name)
if (parameters != null) {
result.append("(")
result.append(StringUtil.join(parameters, { escape(it) }, "; "))
result.append(")")
}
return result.toString()
}
override fun toString(): String {
return asString()
}
companion object {
private fun escape(s: String): String {
return s.replace("([$SHOULD_BE_ESCAPED])".toRegex(), "\\\\$1")
}
private fun unescape(s: String): String {
return s.replace("\\\\([$SHOULD_BE_ESCAPED])".toRegex(), "$1")
}
fun parseDiagnostic(text: String): TextDiagnostic {
val matcher = CheckerTestUtil.individualDiagnosticPattern.matcher(text)
if (!matcher.find())
throw IllegalArgumentException("Could not parse diagnostic: $text")
val inference = computeInferenceCompatibility(
extractDataBefore(
matcher.group(1),
";"
)
)
val platform =
extractDataBefore(matcher.group(2), ":")
val name = matcher.group(3)
val parameters = matcher.group(4) ?: return TextDiagnostic(
name,
platform,
null,
inference
)
val parsedParameters = SmartList<String>()
val parametersMatcher = INDIVIDUAL_PARAMETER_PATTERN.matcher(parameters)
while (parametersMatcher.find())
parsedParameters.add(unescape(parametersMatcher.group().trim({ it <= ' ' })))
return TextDiagnostic(name, platform, parsedParameters, inference)
}
private fun computeInferenceCompatibility(abbreviation: String?): InferenceCompatibility {
return if (abbreviation == null) InferenceCompatibility.ALL else InferenceCompatibility.values().single { inference -> abbreviation == inference.abbreviation }
}
private fun extractDataBefore(prefix: String?, anchor: String): String? {
assert(prefix == null || prefix.endsWith(anchor)) { prefix ?: "" }
return prefix?.substringBeforeLast(anchor, prefix)
}
fun asTextDiagnostic(abstractTestDiagnostic: AbstractTestDiagnostic): TextDiagnostic {
return if (abstractTestDiagnostic is ActualDiagnostic) {
asTextDiagnostic(abstractTestDiagnostic)
} else abstractTestDiagnostic as TextDiagnostic
}
private fun asTextDiagnostic(actualDiagnostic: ActualDiagnostic): TextDiagnostic {
val diagnostic = actualDiagnostic.diagnostic
val renderer = DefaultErrorMessages.getRendererForDiagnostic(diagnostic)
val diagnosticName = actualDiagnostic.name
if (renderer is AbstractDiagnosticWithParametersRenderer) {
val renderParameters = renderer.renderParameters(diagnostic)
val parameters = ContainerUtil.map(renderParameters, { it.toString() })
return TextDiagnostic(
diagnosticName,
actualDiagnostic.platform,
parameters,
actualDiagnostic.inferenceCompatibility
)
}
return TextDiagnostic(
diagnosticName,
actualDiagnostic.platform,
null,
actualDiagnostic.inferenceCompatibility
)
}
}
}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2019 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 org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext
interface DebugInfoDiagnosticFactory {
val withExplicitDefinitionOnly: Boolean
fun createDiagnostic(
expression: KtExpression,
bindingContext: BindingContext
): Diagnostic
}
@@ -0,0 +1,59 @@
/*
* Copyright 2010-2019 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.diagnostics.DebugInfoDiagnostic
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext
class DebugInfoDiagnosticFactory0 : DiagnosticFactory0<PsiElement>,
DebugInfoDiagnosticFactory {
private val name: String
override val withExplicitDefinitionOnly: Boolean
override fun createDiagnostic(
expression: KtExpression,
bindingContext: BindingContext
): Diagnostic {
return DebugInfoDiagnostic(expression, this)
}
private constructor(name: String, severity: Severity = Severity.ERROR) : super(severity, PositioningStrategies.DEFAULT) {
this.name = name
this.withExplicitDefinitionOnly = false
}
private constructor(name: String, severity: Severity, withExplicitDefinitionOnly: Boolean) : super(
severity,
PositioningStrategies.DEFAULT
) {
this.name = name
this.withExplicitDefinitionOnly = withExplicitDefinitionOnly
}
override fun getName(): String {
return "DEBUG_INFO_$name"
}
companion object {
val SMARTCAST = DebugInfoDiagnosticFactory0("SMARTCAST", Severity.INFO)
val IMPLICIT_RECEIVER_SMARTCAST =
DebugInfoDiagnosticFactory0("IMPLICIT_RECEIVER_SMARTCAST", Severity.INFO)
val CONSTANT = DebugInfoDiagnosticFactory0("CONSTANT", Severity.INFO)
val LEAKING_THIS = DebugInfoDiagnosticFactory0("LEAKING_THIS")
val IMPLICIT_EXHAUSTIVE =
DebugInfoDiagnosticFactory0("IMPLICIT_EXHAUSTIVE", Severity.INFO)
val ELEMENT_WITH_ERROR_TYPE = DebugInfoDiagnosticFactory0("ELEMENT_WITH_ERROR_TYPE")
val UNRESOLVED_WITH_TARGET = DebugInfoDiagnosticFactory0("UNRESOLVED_WITH_TARGET")
val MISSING_UNRESOLVED = DebugInfoDiagnosticFactory0("MISSING_UNRESOLVED")
val DYNAMIC = DebugInfoDiagnosticFactory0("DYNAMIC", Severity.INFO)
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2019 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 org.jetbrains.kotlin.checkers.diagnostics.SyntaxErrorDiagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Severity
class SyntaxErrorDiagnosticFactory private constructor() : DiagnosticFactory<SyntaxErrorDiagnostic>(Severity.ERROR) {
override fun getName(): String {
return "SYNTAX"
}
companion object {
val INSTANCE = SyntaxErrorDiagnosticFactory()
}
}
File diff suppressed because it is too large Load Diff
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * 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.
* 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.checkers; package org.jetbrains.kotlin.checkers.utils;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
@@ -26,7 +26,12 @@ import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.asJava.getJvmSignatureDiagnostics import org.jetbrains.kotlin.asJava.getJvmSignatureDiagnostics
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestFile import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestFile
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestModule import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestModule
import org.jetbrains.kotlin.checkers.CheckerTestUtil.ActualDiagnostic import org.jetbrains.kotlin.checkers.diagnostics.ActualDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.PositionalTextDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory0
import org.jetbrains.kotlin.checkers.diagnostics.factories.SyntaxErrorDiagnosticFactory
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
@@ -127,7 +132,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
textWithMarkers: String, textWithMarkers: String,
val directives: Map<String, String> val directives: Map<String, String>
) { ) {
private val diagnosedRanges: List<CheckerTestUtil.DiagnosedRange> = ArrayList() private val diagnosedRanges: MutableList<DiagnosedRange> = ArrayList()
val actualDiagnostics: MutableList<ActualDiagnostic> = ArrayList() val actualDiagnostics: MutableList<ActualDiagnostic> = ArrayList()
val expectedText: String val expectedText: String
val clearText: String val clearText: String
@@ -139,7 +144,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: List<DeclarationDescriptor> = ArrayList() val dynamicCallDescriptors: MutableList<DeclarationDescriptor> = ArrayList()
val withNewInferenceDirective: Boolean val withNewInferenceDirective: Boolean
val newInferenceEnabled: Boolean val newInferenceEnabled: Boolean
val renderDiagnosticMessages: Boolean val renderDiagnosticMessages: Boolean
@@ -251,8 +256,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
val invertedInferenceCompatibilityOfTest = asInferenceCompatibility(!withNewInference) val invertedInferenceCompatibilityOfTest = asInferenceCompatibility(!withNewInference)
val diagnosticToExpectedDiagnostic = val diagnosticToExpectedDiagnostic =
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, object : CheckerTestUtil.DiagnosticDiffCallbacks { CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, object : DiagnosticDiffCallbacks {
override fun missingDiagnostic(diagnostic: CheckerTestUtil.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)
return return
@@ -267,8 +272,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
} }
override fun wrongParametersDiagnostic( override fun wrongParametersDiagnostic(
expectedDiagnostic: CheckerTestUtil.TextDiagnostic, expectedDiagnostic: TextDiagnostic,
actualDiagnostic: CheckerTestUtil.TextDiagnostic, actualDiagnostic: TextDiagnostic,
start: Int, start: Int,
end: Int end: Int
) { ) {
@@ -279,7 +284,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
ok[0] = false ok[0] = false
} }
override fun unexpectedDiagnostic(diagnostic: CheckerTestUtil.TextDiagnostic, actualStart: Int, actualEnd: Int) { override fun unexpectedDiagnostic(diagnostic: TextDiagnostic, actualStart: Int, actualEnd: Int) {
if (withNewInferenceDirective && diagnostic.inferenceCompatibility != inferenceCompatibilityOfTest) { if (withNewInferenceDirective && diagnostic.inferenceCompatibility != inferenceCompatibilityOfTest) {
updateUncheckedDiagnostics(diagnostic, actualStart, actualEnd) updateUncheckedDiagnostics(diagnostic, actualStart, actualEnd)
return return
@@ -293,7 +298,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
ok[0] = false ok[0] = false
} }
fun updateUncheckedDiagnostics(diagnostic: CheckerTestUtil.TextDiagnostic, start: Int, end: Int) { fun updateUncheckedDiagnostics(diagnostic: TextDiagnostic, start: Int, end: Int) {
diagnostic.enhanceInferenceCompatibility(invertedInferenceCompatibilityOfTest) diagnostic.enhanceInferenceCompatibility(invertedInferenceCompatibilityOfTest)
uncheckedDiagnostics.add(PositionalTextDiagnostic(diagnostic, start, end)) uncheckedDiagnostics.add(PositionalTextDiagnostic(diagnostic, start, end))
} }
@@ -316,11 +321,11 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
return ok[0] return ok[0]
} }
private fun asInferenceCompatibility(isNewInference: Boolean): CheckerTestUtil.TextDiagnostic.InferenceCompatibility { private fun asInferenceCompatibility(isNewInference: Boolean): TextDiagnostic.InferenceCompatibility {
return if (isNewInference) return if (isNewInference)
CheckerTestUtil.TextDiagnostic.InferenceCompatibility.NEW TextDiagnostic.InferenceCompatibility.NEW
else else
CheckerTestUtil.TextDiagnostic.InferenceCompatibility.OLD TextDiagnostic.InferenceCompatibility.OLD
} }
private fun computeJvmSignatureDiagnostics(bindingContext: BindingContext): Set<ActualDiagnostic> { private fun computeJvmSignatureDiagnostics(bindingContext: BindingContext): Set<ActualDiagnostic> {
@@ -346,10 +351,10 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
val DIAGNOSTICS_TO_INCLUDE_ANYWAY: Set<DiagnosticFactory<*>> = setOf( val DIAGNOSTICS_TO_INCLUDE_ANYWAY: Set<DiagnosticFactory<*>> = setOf(
Errors.UNRESOLVED_REFERENCE, Errors.UNRESOLVED_REFERENCE,
Errors.UNRESOLVED_REFERENCE_WRONG_RECEIVER, Errors.UNRESOLVED_REFERENCE_WRONG_RECEIVER,
CheckerTestUtil.SyntaxErrorDiagnosticFactory.INSTANCE, SyntaxErrorDiagnosticFactory.INSTANCE,
CheckerTestUtil.DebugInfoDiagnosticFactory.ELEMENT_WITH_ERROR_TYPE, DebugInfoDiagnosticFactory0.ELEMENT_WITH_ERROR_TYPE,
CheckerTestUtil.DebugInfoDiagnosticFactory.MISSING_UNRESOLVED, DebugInfoDiagnosticFactory0.MISSING_UNRESOLVED,
CheckerTestUtil.DebugInfoDiagnosticFactory.UNRESOLVED_WITH_TARGET DebugInfoDiagnosticFactory0.UNRESOLVED_WITH_TARGET
) )
val DEFAULT_DIAGNOSTIC_TESTS_FEATURES = mapOf( val DEFAULT_DIAGNOSTIC_TESTS_FEATURES = mapOf(
@@ -1,258 +1,238 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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.checkers; package org.jetbrains.kotlin.checkers
import com.google.common.collect.Lists; import com.google.common.collect.Lists
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.checkers.diagnostics.ActualDiagnostic
import org.jetbrains.kotlin.checkers.CheckerTestUtil.ActualDiagnostic; import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic
import org.jetbrains.kotlin.checkers.CheckerTestUtil.DiagnosedRange; import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil; import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.test.ConfigurationKind; import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils; import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment; import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
import org.jetbrains.kotlin.tests.di.createContainerForTests
import java.io.File
import kotlin.test.assertEquals
import java.io.File; private data class DiagnosticData(
import java.util.List; val index: Int,
val rangeIndex: Int,
val name: String,
val startOffset: Int,
val endOffset: Int
)
public class CheckerTestUtilTest extends KotlinTestWithEnvironment { private abstract class Test(private vararg val expectedMessages: String) {
@NotNull fun test(psiFile: PsiFile, environment: KotlinCoreEnvironment) {
private static String getTestDataPath() { val bindingContext = JvmResolveUtil.analyze(psiFile as KtFile, environment).bindingContext
return KotlinTestUtils.getTestDataPathBase() + "/diagnostics/checkerTestUtil"; val expectedText = CheckerTestUtil.addDiagnosticMarkersToText(
} psiFile,
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
bindingContext, psiFile,
false,
mutableListOf(),
null,
false
)
).toString()
val diagnosedRanges = Lists.newArrayList<DiagnosedRange>()
@Override CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges)
protected KotlinCoreEnvironment createEnvironment() {
return createEnvironmentWithMockJdk(ConfigurationKind.ALL);
}
protected void doTest(TheTest theTest) throws Exception { val actualDiagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
String text = KotlinTestUtils.doLoadFile(getTestDataPath(), "test.kt"); bindingContext,
theTest.test(TestCheckerUtil.createCheckAndReturnPsiFile("test.kt", text, getProject()), getEnvironment()); psiFile,
} false,
mutableListOf(),
null,
false
)
public void testEquals() throws Exception { makeTestData(actualDiagnostics, diagnosedRanges)
doTest(new TheTest() {
@Override val expectedMessages = listOf(*expectedMessages)
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) { val actualMessages = mutableListOf<String>()
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, actualDiagnostics, object : DiagnosticDiffCallbacks {
override fun missingDiagnostic(diagnostic: TextDiagnostic, expectedStart: Int, expectedEnd: Int) {
actualMessages.add(CheckerTestUtilTest.missing(diagnostic.description, expectedStart, expectedEnd))
} }
});
}
public void testMissing() throws Exception { override fun wrongParametersDiagnostic(
DiagnosticData typeMismatch1 = diagnostics.get(1); expectedDiagnostic: TextDiagnostic,
doTest(new TheTest(missing(typeMismatch1)) { actualDiagnostic: TextDiagnostic,
@Override start: Int,
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) { end: Int
diagnostics.remove(typeMismatch1.index); ) {
actualMessages.add(
CheckerTestUtilTest.wrongParameters(expectedDiagnostic.asString(), actualDiagnostic.asString(), start, end)
)
} }
});
}
public void testUnexpected() throws Exception { override fun unexpectedDiagnostic(diagnostic: TextDiagnostic, actualStart: Int, actualEnd: Int) {
DiagnosticData typeMismatch1 = diagnostics.get(1); actualMessages.add(CheckerTestUtilTest.unexpected(diagnostic.description, actualStart, actualEnd))
doTest(new TheTest(unexpected(typeMismatch1)) {
@Override
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) {
diagnosedRanges.remove(typeMismatch1.index);
} }
}); })
assertEquals(expectedMessages.joinToString("\n"), actualMessages.joinToString("\n"))
} }
public void testBoth() throws Exception { abstract fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>)
DiagnosticData typeMismatch1 = diagnostics.get(1); }
DiagnosticData unresolvedReference = diagnostics.get(6);
doTest(new TheTest(unexpected(typeMismatch1), missing(unresolvedReference)) { class CheckerTestUtilTest : KotlinTestWithEnvironment() {
@Override private val diagnostics = listOf(
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) { DiagnosticData(0, 0, "UNUSED_PARAMETER", 8, 9),
diagnosedRanges.remove(typeMismatch1.rangeIndex); DiagnosticData(1, 1, "CONSTANT_EXPECTED_TYPE_MISMATCH", 56, 57),
diagnostics.remove(unresolvedReference.index); DiagnosticData(2, 2, "UNUSED_VARIABLE", 67, 68),
} DiagnosticData(3, 3, "TYPE_MISMATCH", 98, 99),
}); DiagnosticData(4, 4, "NONE_APPLICABLE", 120, 121),
} DiagnosticData(5, 5, "TYPE_MISMATCH", 159, 167),
DiagnosticData(6, 6, "UNRESOLVED_REFERENCE", 164, 166),
public void testMissingInTheMiddle() throws Exception { DiagnosticData(7, 6, "TOO_MANY_ARGUMENTS", 164, 166)
DiagnosticData noneApplicable = diagnostics.get(4); )
DiagnosticData typeMismatch3 = diagnostics.get(5);
doTest(new TheTest(unexpected(noneApplicable), missing(typeMismatch3)) { private fun getTestDataPath() = KotlinTestUtils.getTestDataPathBase() + "/diagnostics/checkerTestUtil"
@Override
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) { override fun createEnvironment(): KotlinCoreEnvironment {
diagnosedRanges.remove(noneApplicable.rangeIndex); println(System.getProperty("user.home"))
diagnostics.remove(typeMismatch3.index); System.setProperty("user.dir", "/Users/victor.petukhov/IdeaProjects/kotlin")
} println(System.getProperty("user.dir"))
}); return createEnvironmentWithMockJdk(ConfigurationKind.ALL)
} }
public void testWrongParameters() throws Exception { private fun doTest(test: Test) = test.test(
DiagnosticData unused = diagnostics.get(2); TestCheckerUtil.createCheckAndReturnPsiFile(
String unusedDiagnostic = asTextDiagnostic(unused, "i"); "test.kt",
DiagnosedRange range = asDiagnosticRange(unused, unusedDiagnostic); KotlinTestUtils.doLoadFile(getTestDataPath(), "test.kt"),
doTest(new TheTest(wrongParameters(unusedDiagnostic, "OI;UNUSED_VARIABLE(a)", unused.startOffset, unused.endOffset)) { project
@Override ),
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) { environment
diagnosedRanges.set(unused.rangeIndex, range); )
}
}); fun testEquals() {
} doTest(object : Test() {
override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {}
public void testWrongParameterInMultiRange() throws Exception { })
DiagnosticData unresolvedReference = diagnostics.get(6); }
String unusedDiagnostic = asTextDiagnostic(unresolvedReference, "i");
String toManyArguments = asTextDiagnostic(diagnostics.get(7)); fun testMissing() {
DiagnosedRange range = asDiagnosticRange(unresolvedReference, unusedDiagnostic, toManyArguments); val typeMismatch1 = diagnostics[1]
doTest(new TheTest(wrongParameters(unusedDiagnostic, "OI;UNRESOLVED_REFERENCE(xx)", unresolvedReference.startOffset, unresolvedReference.endOffset)) {
@Override doTest(object : Test(missing(typeMismatch1)) {
protected void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges) { override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {
diagnosedRanges.set(unresolvedReference.rangeIndex, range); diagnostics.removeAt(typeMismatch1.index)
} }
}); })
} }
public void testAbstractJetDiagnosticsTest() throws Exception { fun testUnexpected() {
AbstractDiagnosticsTest test = new AbstractDiagnosticsTest() { val typeMismatch1 = diagnostics[1]
{setUp();}
}; doTest(object : Test(unexpected(typeMismatch1)) {
test.doTest(getTestDataPath() + File.separatorChar + "test_with_diagnostic.kt"); override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {
} diagnosedRanges.removeAt(typeMismatch1.index)
}
private static abstract class TheTest { })
private final String[] expected; }
protected TheTest(String... expectedMessages) { fun testBoth() {
this.expected = expectedMessages; val typeMismatch1 = diagnostics[1]
} val unresolvedReference = diagnostics[6]
public void test(@NotNull PsiFile psiFile, @NotNull KotlinCoreEnvironment environment) { doTest(object : Test(unexpected(typeMismatch1), missing(unresolvedReference)) {
BindingContext bindingContext = override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {
JvmResolveUtil.analyze((KtFile) psiFile, environment).getBindingContext(); diagnosedRanges.removeAt(typeMismatch1.rangeIndex)
diagnostics.removeAt(unresolvedReference.index)
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText( }
psiFile, })
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null, false) }
).toString();
fun testMissingInTheMiddle() {
List<DiagnosedRange> diagnosedRanges = Lists.newArrayList(); val noneApplicable = diagnostics[4]
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges); val typeMismatch3 = diagnostics[5]
List<ActualDiagnostic> actualDiagnostics = doTest(object : Test(unexpected(noneApplicable), missing(typeMismatch3)) {
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null, false); override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {
actualDiagnostics.sort(CheckerTestUtil.DIAGNOSTIC_COMPARATOR); diagnosedRanges.removeAt(noneApplicable.rangeIndex)
diagnostics.removeAt(typeMismatch3.index)
makeTestData(actualDiagnostics, diagnosedRanges); }
})
List<String> expectedMessages = Lists.newArrayList(expected); }
List<String> actualMessages = Lists.newArrayList();
fun testWrongParameters() {
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, actualDiagnostics, new CheckerTestUtil.DiagnosticDiffCallbacks() { val unused = diagnostics[2]
@Override val unusedDiagnostic = asTextDiagnostic(unused, "i")
public void missingDiagnostic(CheckerTestUtil.TextDiagnostic diagnostic, int expectedStart, int expectedEnd) { val range = asDiagnosticRange(unused, unusedDiagnostic)
actualMessages.add(missing(diagnostic.getDescription(), expectedStart, expectedEnd)); val wrongParameter = wrongParameters(unusedDiagnostic, "OI;UNUSED_VARIABLE(a)", unused.startOffset, unused.endOffset)
}
doTest(object : Test(wrongParameter) {
@Override override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {
public void wrongParametersDiagnostic( diagnosedRanges[unused.rangeIndex] = range
CheckerTestUtil.TextDiagnostic expectedDiagnostic, }
CheckerTestUtil.TextDiagnostic actualDiagnostic, })
int start, }
int end
) { fun testWrongParameterInMultiRange() {
actualMessages.add(wrongParameters(expectedDiagnostic.asString(), actualDiagnostic.asString(), start, end)); val unresolvedReference = diagnostics[6]
} val unusedDiagnostic = asTextDiagnostic(unresolvedReference, "i")
val toManyArguments = asTextDiagnostic(diagnostics[7])
@Override val range = asDiagnosticRange(unresolvedReference, unusedDiagnostic, toManyArguments)
public void unexpectedDiagnostic(CheckerTestUtil.TextDiagnostic diagnostic, int actualStart, int actualEnd) { val wrongParameter = wrongParameters(
actualMessages.add(unexpected(diagnostic.getDescription(), actualStart, actualEnd)); unusedDiagnostic,
} "OI;UNRESOLVED_REFERENCE(xx)",
}); unresolvedReference.startOffset,
unresolvedReference.endOffset
assertEquals(listToString(expectedMessages), listToString(actualMessages)); )
}
doTest(object : Test(wrongParameter) {
private static String listToString(List<String> expectedMessages) { override fun makeTestData(diagnostics: MutableList<ActualDiagnostic>, diagnosedRanges: MutableList<DiagnosedRange>) {
StringBuilder stringBuilder = new StringBuilder(); diagnosedRanges[unresolvedReference.rangeIndex] = range
for (String expectedMessage : expectedMessages) { }
stringBuilder.append(expectedMessage).append("\n"); })
} }
return stringBuilder.toString();
} fun testAbstractJetDiagnosticsTest() {
val test = object : AbstractDiagnosticsTest() {
protected abstract void makeTestData(List<ActualDiagnostic> diagnostics, List<DiagnosedRange> diagnosedRanges); init {
} setUp()
}
private static String wrongParameters(String expected, String actual, int start, int end) { }
return "Wrong parameters " + expected + " != " + actual +" at " + start + " to " + end;
} test.doTest(getTestDataPath() + File.separatorChar + "test_with_diagnostic.kt")
}
private static String unexpected(String type, int actualStart, int actualEnd) {
return "Unexpected " + type + " at " + actualStart + " to " + actualEnd; companion object {
} fun wrongParameters(expected: String, actual: String, start: Int, end: Int) =
"Wrong parameters $expected != $actual at $start to $end"
private static String missing(String type, int expectedStart, int expectedEnd) {
return "Missing " + type + " at " + expectedStart + " to " + expectedEnd; fun unexpected(type: String, actualStart: Int, actualEnd: Int) =
} "Unexpected $type at $actualStart to $actualEnd"
private static String unexpected(DiagnosticData data) { fun missing(type: String, expectedStart: Int, expectedEnd: Int) =
return unexpected(data.name, data.startOffset, data.endOffset); "Missing $type at $expectedStart to $expectedEnd"
}
private fun unexpected(data: DiagnosticData) = unexpected(data.name, data.startOffset, data.endOffset)
private static String missing(DiagnosticData data) {
return missing(data.name, data.startOffset, data.endOffset); private fun missing(data: DiagnosticData) = missing(data.name, data.startOffset, data.endOffset)
}
private fun asTextDiagnostic(diagnosticData: DiagnosticData, vararg params: String) =
private static String asTextDiagnostic(DiagnosticData diagnosticData, String... params) { diagnosticData.name + "(" + StringUtil.join(params, "; ") + ")"
return diagnosticData.name + "(" + StringUtil.join(params, "; ") + ")";
} private fun asDiagnosticRange(diagnosticData: DiagnosticData, vararg textDiagnostics: String): DiagnosedRange {
val range = DiagnosedRange(diagnosticData.startOffset)
private static DiagnosedRange asDiagnosticRange(DiagnosticData diagnosticData, String... textDiagnostics) { range.end = diagnosticData.endOffset
DiagnosedRange range = new DiagnosedRange(diagnosticData.startOffset); for (textDiagnostic in textDiagnostics)
range.setEnd(diagnosticData.endOffset); range.addDiagnostic(textDiagnostic)
for (String textDiagnostic : textDiagnostics) return range
range.addDiagnostic(textDiagnostic); }
return range; }
}
private static class DiagnosticData {
public int index;
public int rangeIndex;
public String name;
public int startOffset;
public int endOffset;
private DiagnosticData(int index, int rangeIndex, String name, int startOffset, int endOffset) {
this.index = index;
this.rangeIndex = rangeIndex;
this.name = name;
this.startOffset = startOffset;
this.endOffset = endOffset;
}
}
private final List<DiagnosticData> diagnostics = Lists.newArrayList(
new DiagnosticData(0, 0, "UNUSED_PARAMETER", 8, 9),
new DiagnosticData(1, 1, "CONSTANT_EXPECTED_TYPE_MISMATCH", 56, 57),
new DiagnosticData(2, 2, "UNUSED_VARIABLE", 67, 68),
new DiagnosticData(3, 3, "TYPE_MISMATCH", 98, 99),
new DiagnosticData(4, 4, "NONE_APPLICABLE", 120, 121),
new DiagnosticData(5, 5, "TYPE_MISMATCH", 159, 167),
new DiagnosticData(6, 6, "UNRESOLVED_REFERENCE", 164, 166),
new DiagnosticData(7, 6, "TOO_MANY_ARGUMENTS", 164, 166)
);
} }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.TestsCompilerError;
import org.jetbrains.kotlin.TestsCompiletimeError; import org.jetbrains.kotlin.TestsCompiletimeError;
import org.jetbrains.kotlin.backend.common.output.OutputFile; import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection; import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection;
import org.jetbrains.kotlin.checkers.CheckerTestUtil; import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil;
import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettings; import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettings;
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys; import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
import org.jetbrains.kotlin.cli.common.output.OutputUtilsKt; import org.jetbrains.kotlin.cli.common.output.OutputUtilsKt;
@@ -367,7 +367,7 @@ 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.parseDiagnosedRanges(file.content, new ArrayList<>(0)); String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(file.content, new ArrayList<>(0));
ktFiles.add(KotlinTestUtils.createFile(file.name, content, project)); ktFiles.add(KotlinTestUtils.createFile(file.name, content, project));
} }
} }
@@ -22,7 +22,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiErrorElement;
import com.intellij.util.ArrayUtil; import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.checkers.CheckerTestUtil; import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil;
import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.AnalyzingUtils; import org.jetbrains.kotlin.resolve.AnalyzingUtils;
import org.jetbrains.kotlin.test.KotlinTestUtils; import org.jetbrains.kotlin.test.KotlinTestUtils;
@@ -101,7 +101,7 @@ 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.parseDiagnosedRanges(contentWithDiagnosticMarkup, new ArrayList<>()); String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(contentWithDiagnosticMarkup, new ArrayList<>());
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,7 +21,7 @@ import com.intellij.lang.annotation.Annotator
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.checkers.DebugInfoUtil import org.jetbrains.kotlin.checkers.utils.DebugInfoUtil
import org.jetbrains.kotlin.idea.KotlinPluginUtil import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
@@ -20,7 +20,7 @@ import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent 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.CheckerTestUtil import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
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.*
@@ -35,7 +35,12 @@ class CopyAsDiagnosticTestAction : AnAction() {
val bindingContext = (psiFile as KtFile).analyzeWithContent() val bindingContext = (psiFile as KtFile).analyzeWithContent()
val diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors( val diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
bindingContext, psiFile, false, null, null, false bindingContext,
psiFile,
false,
mutableListOf(),
null,
false
) )
val result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString() val result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString()
@@ -27,7 +27,7 @@ import junit.framework.ComparisonFailure
import org.jetbrains.kotlin.base.kapt3.DetectMemoryLeaksMode import org.jetbrains.kotlin.base.kapt3.DetectMemoryLeaksMode
import org.jetbrains.kotlin.base.kapt3.KaptFlag import org.jetbrains.kotlin.base.kapt3.KaptFlag
import org.jetbrains.kotlin.base.kapt3.KaptOptions import org.jetbrains.kotlin.base.kapt3.KaptOptions
import org.jetbrains.kotlin.checkers.CheckerTestUtil import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
@@ -102,7 +102,7 @@ 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<CheckerTestUtil.DiagnosedRange>(0)) val content = CheckerTestUtil.parseDiagnosedRanges(file.content, ArrayList(0))
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}"))