KT-16264 Forbid usage of _ without backticks

Forbid underscore-only (_, __, ___, ...) names as callees and as types.

If CHECK_TYPE directive is on, filter out UNDERSCORE_USAGE_WITHOUT_BACKTICKS messages.
This commit is contained in:
Dmitry Petrov
2017-03-28 17:15:23 +03:00
parent 0a3c031528
commit caae6ff2ec
22 changed files with 317 additions and 19 deletions
@@ -706,6 +706,7 @@ public interface Errors {
DiagnosticFactory1<KtSimpleNameExpression, KotlinType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> YIELD_IS_RESERVED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_RESERVED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> UNDERSCORE_USAGE_WITHOUT_BACKTICKS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> INVALID_CHARACTERS = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory1.create(ERROR);
@@ -465,6 +465,7 @@ public class DefaultErrorMessages {
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return Int, but returns {0}", RENDER_TYPE);
MAP.put(UNDERSCORE_IS_RESERVED, "Names _, __, ___, ..., are reserved in Kotlin");
MAP.put(UNDERSCORE_USAGE_WITHOUT_BACKTICKS, "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)");
MAP.put(YIELD_IS_RESERVED, "{0}", STRING);
MAP.put(INVALID_CHARACTERS, "Name {0}", STRING);
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
import org.jetbrains.kotlin.resolve.calls.CallExpressionElement
import org.jetbrains.kotlin.resolve.calls.checkers.UnderscoreUsageChecker
import org.jetbrains.kotlin.resolve.calls.unrollToLeftMostQualifiedExpression
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
@@ -143,7 +144,6 @@ class QualifiedExpressionResolver {
val (name, simpleName) = qualifierPartList.single()
val descriptor = scope.findClassifier(name, KotlinLookupLocation(simpleName))
storeResult(trace, simpleName, descriptor, ownerDescriptor, position = QualifierPosition.TYPE, isQualifier = true)
return TypeQualifierResolutionResult(qualifierPartList, descriptor)
}
@@ -597,6 +597,8 @@ class QualifiedExpressionResolver {
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptor)
UnderscoreUsageChecker.checkSimpleNameUsage(descriptor, referenceExpression, trace)
if (descriptor is DeclarationDescriptorWithVisibility) {
val fromToCheck =
if (shouldBeVisibleFrom is PackageFragmentDescriptor && shouldBeVisibleFrom.source == SourceElement.NO_SOURCE && referenceExpression.containingFile !is DummyHolder) {
@@ -95,7 +95,8 @@ private val DEFAULT_CALL_CHECKERS = listOf(
DeprecatedCallChecker, CallReturnsArrayOfNothingChecker(), InfixCallChecker(), OperatorCallChecker(),
ConstructorHeaderCallChecker, ProtectedConstructorCallChecker, ApiVersionCallChecker,
CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker, MissingDependencyClassChecker,
CallableReferenceCompatibilityChecker()
CallableReferenceCompatibilityChecker(),
UnderscoreUsageChecker
)
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
object UnderscoreUsageChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
if (resolvedCall is VariableAsFunctionResolvedCall) return
val descriptor = resolvedCall.resultingDescriptor
val namedDescriptor = if (descriptor is ConstructorDescriptor) descriptor.containingDeclaration else descriptor
if (!namedDescriptor.name.asString().isUnderscoreOnlyName()) return
checkCallElement(resolvedCall.call.callElement, context)
}
private fun checkCallElement(ktElement: KtElement, context: CallCheckerContext) {
when (ktElement) {
is KtSimpleNameExpression ->
checkSimpleNameUsage(ktElement, context.trace)
is KtCallExpression ->
ktElement.calleeExpression?.let { checkCallElement(it, context) }
}
}
private fun checkSimpleNameUsage(ktName: KtSimpleNameExpression, trace: BindingTrace) {
if (ktName.text.isUnderscoreOnlyName()) {
trace.report(Errors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.on(ktName))
}
}
fun checkSimpleNameUsage(descriptor: DeclarationDescriptor, ktName: KtSimpleNameExpression, trace: BindingTrace) {
if (descriptor.name.asString().isUnderscoreOnlyName()) {
checkSimpleNameUsage(ktName, trace)
}
}
fun String.isUnderscoreOnlyName() =
isNotEmpty() && all { it == '_' }
}
+1 -1
View File
@@ -10,5 +10,5 @@ fun box() : String {
val (`_`, c) = A()
return if (a == 1 && b == 2 && _ == 1 && c == 2) "OK" else "fail"
return if (a == 1 && b == 2 && `_` == 1 && c == 2) "OK" else "fail"
}
@@ -31,7 +31,7 @@ fun doTest(): String {
}
for ((_, `_`) in C(2)..C(4)) {
s += "$_;"
s += "$`_`;"
}
return s
+2
View File
@@ -58,6 +58,8 @@ With that, an exact type of an expression can be checked in the following way:
expr checkType { _<A>() }
}
`CHECK_TYPE` directive also disables `UNDERSCORE_USAGE_WITHOUT_BACKTICKS` diagnostics output.
#### Usage:
// !CHECK_TYPE
+7 -7
View File
@@ -5,14 +5,14 @@
@___("") data class Pair(val x: Int, val y: Int)
class <!UNDERSCORE_IS_RESERVED!>_<!><<!UNDERSCORE_IS_RESERVED!>________<!>>
val <!UNDERSCORE_IS_RESERVED!>______<!> = _<Int>()
val <!UNDERSCORE_IS_RESERVED!>______<!> = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!><Int>()
fun <!UNDERSCORE_IS_RESERVED!>__<!>(<!UNDERSCORE_IS_RESERVED!>___<!>: Int, y: _<Int>?): Int {
val (_, <!UNUSED_VARIABLE!>z<!>) = Pair(___ - 1, 42)
val (x, <!UNDERSCORE_IS_RESERVED!>__________<!>) = Pair(___ - 1, 42)
fun <!UNDERSCORE_IS_RESERVED!>__<!>(<!UNDERSCORE_IS_RESERVED!>___<!>: Int, y: <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!><Int>?): Int {
val (_, <!UNUSED_VARIABLE!>z<!>) = Pair(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!> - 1, 42)
val (x, <!UNDERSCORE_IS_RESERVED!>__________<!>) = Pair(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!> - 1, 42)
val <!UNDERSCORE_IS_RESERVED!>____<!> = x
// in backquotes: allowed
val `_` = __________
val `_` = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__________<!>
val q = fun(_: Int, <!UNDERSCORE_IS_RESERVED, UNUSED_PARAMETER!>__<!>: Int) {}
q(1, 2)
@@ -21,7 +21,7 @@ fun <!UNDERSCORE_IS_RESERVED!>__<!>(<!UNDERSCORE_IS_RESERVED!>___<!>: Int, y: _<
fun localFun(<!UNDERSCORE_IS_RESERVED!>_<!>: String) = 1
<!UNDERSCORE_IS_RESERVED!>__<!>@ return if (y != null) __(____, y) else __(`_`, ______)
<!UNDERSCORE_IS_RESERVED!>__<!>@ return if (y != null) <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>, y) else <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>(`_`, <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>______<!>)
}
@@ -42,5 +42,5 @@ fun oneUnderscore(<!UNDERSCORE_IS_RESERVED!>_<!>: Int) {}
fun doIt(f: (Any?) -> Any?) = f(null)
val something = doIt { <!UNDERSCORE_IS_RESERVED!>__<!> -> __ }
val something = doIt { <!UNDERSCORE_IS_RESERVED!>__<!> -> <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!> }
val something2 = doIt { _ -> 1 }
@@ -0,0 +1,6 @@
package test
annotation class `__`(val value: String)
@<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>("") class TestAnn
@`__`("") class TestAnn2
@@ -0,0 +1,26 @@
package
package test {
@test.__(value = "") public final class TestAnn {
public constructor TestAnn()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@test.__(value = "") public final class TestAnn2 {
public constructor TestAnn2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class __ : kotlin.Annotation {
public constructor __(/*0*/ value: kotlin.String)
public final val value: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,42 @@
// !DIAGNOSTICS: -DEPRECATION -TOPLEVEL_TYPEALIASES_ONLY
fun test(`_`: Int) {
<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!> + 1
`_` + 1
}
fun `__`() {}
fun testCall() {
<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>()
`__`()
}
val testCallableRef = ::<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>
val testCallableRef2 = ::`__`
object Host {
val `_` = 42
object `__` {
val bar = 4
}
}
val testQualified = Host.<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!>
val testQualified2 = Host.`_`
object `___` {
val test = 42
}
val testQualifier = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!>.test
val testQualifier2 = `___`.test
val testQualifier3 = Host.<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>.bar
val testQualifier4 = Host.`__`.bar
fun testCallableRefLHSValue(`_`: Any) = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!>::toString
fun testCallableRefLHSValue2(`_`: Any) = `_`::toString
val testCallableRefLHSObject = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!>::toString
val testCallableRefLHSObject2 = `___`::toString
@@ -0,0 +1,41 @@
package
public val testCallableRef: kotlin.reflect.KFunction0<kotlin.Unit>
public val testCallableRef2: kotlin.reflect.KFunction0<kotlin.Unit>
public val testCallableRefLHSObject: kotlin.reflect.KFunction0<kotlin.String>
public val testCallableRefLHSObject2: kotlin.reflect.KFunction0<kotlin.String>
public val testQualified: kotlin.Int = 42
public val testQualified2: kotlin.Int = 42
public val testQualifier: kotlin.Int = 42
public val testQualifier2: kotlin.Int = 42
public val testQualifier3: kotlin.Int = 4
public val testQualifier4: kotlin.Int = 4
public fun __(): kotlin.Unit
public fun test(/*0*/ _: kotlin.Int): kotlin.Unit
public fun testCall(): kotlin.Unit
public fun testCallableRefLHSValue(/*0*/ _: kotlin.Any): kotlin.reflect.KFunction0<kotlin.String>
public fun testCallableRefLHSValue2(/*0*/ _: kotlin.Any): kotlin.reflect.KFunction0<kotlin.String>
public object Host {
private constructor Host()
public final val _: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object __ {
private constructor __()
public final val bar: kotlin.Int = 4
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public object ___ {
private constructor ___()
public final val test: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,11 @@
class `___` {
class `____`
}
val testCallableRefLHSType = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!>::toString
val testCallableRefLHSType2 = `___`::toString
val testClassLiteralLHSType = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>___<!>::class
val testClassLiteralLHSType2 = `___`::class
val tesLHSTypeFQN = `___`.<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>::class
@@ -0,0 +1,21 @@
package
public val tesLHSTypeFQN: kotlin.reflect.KClass<___.____>
public val testCallableRefLHSType: kotlin.reflect.KFunction1<___, kotlin.String>
public val testCallableRefLHSType2: kotlin.reflect.KFunction1<___, kotlin.String>
public val testClassLiteralLHSType: kotlin.reflect.KClass<___>
public val testClassLiteralLHSType2: kotlin.reflect.KClass<___>
public final class ___ {
public constructor ___()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class ____ {
public constructor ____()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -DEPRECATION -TOPLEVEL_TYPEALIASES_ONLY
class `_`<`__`> {
fun testTypeArgument(x: List<<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>>) = x
fun testTypeArgument2(x: List<`__`>) = x
}
fun <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!><Any>.testTypeConstructor() {}
fun `_`<Any>.testTypeConstructor2() {}
val testConstructor = <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!><Any>()
val testConstructor2 = `_`<Any>()
@@ -0,0 +1,15 @@
package
public val testConstructor: _<kotlin.Any>
public val testConstructor2: _<kotlin.Any>
public fun _<kotlin.Any>.testTypeConstructor(): kotlin.Unit
public fun _<kotlin.Any>.testTypeConstructor2(): kotlin.Unit
public final class _</*0*/ __> {
public constructor _</*0*/ __>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun testTypeArgument(/*0*/ x: kotlin.collections.List<__>): kotlin.collections.List<__>
public final fun testTypeArgument2(/*0*/ x: kotlin.collections.List<__>): kotlin.collections.List<__>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,6 @@
object Host {
val `____` = { -> }
fun testFunTypeVal() {
<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>()
}
}
@@ -0,0 +1,10 @@
package
public object Host {
private constructor Host()
public final val ____: () -> kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun testFunTypeVal(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -38,11 +38,11 @@ fun test() {
val (<!REDECLARATION!>`_`<!>, z) = A()
foo(_, z)
foo(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>_<!>, z)
val (_, <!NAME_SHADOWING, REDECLARATION!>`_`<!>) = A()
foo(<!TYPE_MISMATCH!>_<!>, y)
foo(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, TYPE_MISMATCH!>_<!>, y)
val (<!UNUSED_VARIABLE!>unused<!>, _) = A()
}
@@ -130,10 +130,10 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
val dynamicCallDescriptors: List<DeclarationDescriptor> = ArrayList()
init {
this.whatDiagnosticsToConsider = parseDiagnosticFilterDirective(directives)
this.declareCheckType = CHECK_TYPE_DIRECTIVE in directives
this.whatDiagnosticsToConsider = parseDiagnosticFilterDirective(directives, declareCheckType)
this.customLanguageVersionSettings = parseLanguageVersionSettings(directives)
this.checkLazyLog = CHECK_LAZY_LOG_DIRECTIVE in directives || CHECK_LAZY_LOG_DEFAULT
this.declareCheckType = CHECK_TYPE_DIRECTIVE in directives
this.declareFlexibleType = EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE in directives
this.markDynamicCalls = MARK_DYNAMIC_CALLS_DIRECTIVE in directives
if (fileName.endsWith(".java")) {
@@ -358,18 +358,26 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
return values
}
private fun parseDiagnosticFilterDirective(directiveMap: Map<String, String>): Condition<Diagnostic> {
private fun parseDiagnosticFilterDirective(directiveMap: Map<String, String>, allowUnderscoreUsage: Boolean): Condition<Diagnostic> {
val directives = directiveMap[DIAGNOSTICS_DIRECTIVE]
val initialCondition =
if (allowUnderscoreUsage)
Condition<Diagnostic> { it.factory.name != "UNDERSCORE_USAGE_WITHOUT_BACKTICKS" }
else
Conditions.alwaysTrue()
if (directives == null) {
// If "!API_VERSION" is present, disable the NEWER_VERSION_IN_SINCE_KOTLIN diagnostic.
// Otherwise it would be reported in any non-trivial test on the @SinceKotlin value.
if (API_VERSION_DIRECTIVE in directiveMap) {
return Condition { diagnostic -> diagnostic.factory !== Errors.NEWER_VERSION_IN_SINCE_KOTLIN }
return Conditions.and(initialCondition, Condition {
diagnostic -> diagnostic.factory !== Errors.NEWER_VERSION_IN_SINCE_KOTLIN
})
}
return Conditions.alwaysTrue()
return initialCondition
}
var condition = Conditions.alwaysTrue<Diagnostic>()
var condition = initialCondition
val matcher = DIAGNOSTICS_PATTERN.matcher(directives)
if (!matcher.find()) {
Assert.fail("Wrong syntax in the '// !$DIAGNOSTICS_DIRECTIVE: ...' directive:\n" +
@@ -764,6 +764,36 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("UnderscoreUsageInAnnotation.kt")
public void testUnderscoreUsageInAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnderscoreUsageInAnnotation.kt");
doTest(fileName);
}
@TestMetadata("UnderscoreUsageInCall.kt")
public void testUnderscoreUsageInCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnderscoreUsageInCall.kt");
doTest(fileName);
}
@TestMetadata("UnderscoreUsageInCallableRefTypeLHS.kt")
public void testUnderscoreUsageInCallableRefTypeLHS() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnderscoreUsageInCallableRefTypeLHS.kt");
doTest(fileName);
}
@TestMetadata("UnderscoreUsageInType.kt")
public void testUnderscoreUsageInType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnderscoreUsageInType.kt");
doTest(fileName);
}
@TestMetadata("UnderscoreUsageInVariableAsFunctionCall.kt")
public void testUnderscoreUsageInVariableAsFunctionCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnderscoreUsageInVariableAsFunctionCall.kt");
doTest(fileName);
}
@TestMetadata("UnitByDefaultForFunctionTypes.kt")
public void testUnitByDefaultForFunctionTypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnitByDefaultForFunctionTypes.kt");