[FIR] Always expand a type before checking it in FirConstChecks
The issue appeared when we analyzed some typealias. 1. The typealias itself could be valid, but it could point to an invalid type. 2. The typealias could point, for example, to an unsigned type that must be handled in a special way #KT-59894
This commit is contained in:
+12
@@ -6901,6 +6901,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeAliasToUnsigned.kt")
|
||||||
|
public void testTypeAliasToUnsigned() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/typeAliasToUnsigned.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
||||||
public void testUnaryMinusIndepWoExpType() throws Exception {
|
public void testUnaryMinusIndepWoExpType() throws Exception {
|
||||||
@@ -6913,6 +6919,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unresolvedReference.kt")
|
||||||
|
public void testUnresolvedReference() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unresolvedReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unsignedOperations.kt")
|
@TestMetadata("unsignedOperations.kt")
|
||||||
public void testUnsignedOperations() throws Exception {
|
public void testUnsignedOperations() throws Exception {
|
||||||
|
|||||||
+12
@@ -6901,6 +6901,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeAliasToUnsigned.kt")
|
||||||
|
public void testTypeAliasToUnsigned() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/typeAliasToUnsigned.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
||||||
public void testUnaryMinusIndepWoExpType() throws Exception {
|
public void testUnaryMinusIndepWoExpType() throws Exception {
|
||||||
@@ -6913,6 +6919,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unresolvedReference.kt")
|
||||||
|
public void testUnresolvedReference() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unresolvedReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unsignedOperations.kt")
|
@TestMetadata("unsignedOperations.kt")
|
||||||
public void testUnsignedOperations() throws Exception {
|
public void testUnsignedOperations() throws Exception {
|
||||||
|
|||||||
+12
@@ -6895,6 +6895,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeAliasToUnsigned.kt")
|
||||||
|
public void testTypeAliasToUnsigned() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/typeAliasToUnsigned.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
||||||
public void testUnaryMinusIndepWoExpType() throws Exception {
|
public void testUnaryMinusIndepWoExpType() throws Exception {
|
||||||
@@ -6907,6 +6913,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unresolvedReference.kt")
|
||||||
|
public void testUnresolvedReference() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unresolvedReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unsignedOperations.kt")
|
@TestMetadata("unsignedOperations.kt")
|
||||||
public void testUnsignedOperations() throws Exception {
|
public void testUnsignedOperations() throws Exception {
|
||||||
|
|||||||
+12
@@ -6901,6 +6901,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeAliasToUnsigned.kt")
|
||||||
|
public void testTypeAliasToUnsigned() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/typeAliasToUnsigned.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
||||||
public void testUnaryMinusIndepWoExpType() throws Exception {
|
public void testUnaryMinusIndepWoExpType() throws Exception {
|
||||||
@@ -6913,6 +6919,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unresolvedReference.kt")
|
||||||
|
public void testUnresolvedReference() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unresolvedReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unsignedOperations.kt")
|
@TestMetadata("unsignedOperations.kt")
|
||||||
public void testUnsignedOperations() throws Exception {
|
public void testUnsignedOperations() throws Exception {
|
||||||
|
|||||||
+17
-14
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.languageVersionSettings
|
|||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
@@ -48,6 +49,8 @@ internal fun checkConstantArguments(
|
|||||||
return intrinsicConstEvaluation && this.hasAnnotation(StandardClassIds.Annotations.IntrinsicConstEvaluation, session)
|
return intrinsicConstEvaluation && this.hasAnnotation(StandardClassIds.Annotations.IntrinsicConstEvaluation, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirExpression.getExpandedType() = resolvedType.fullyExpandedType(session)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
expression is FirNamedArgumentExpression -> {
|
expression is FirNamedArgumentExpression -> {
|
||||||
checkConstantArguments(expression.expression, session)
|
checkConstantArguments(expression.expression, session)
|
||||||
@@ -93,19 +96,19 @@ internal fun checkConstantArguments(
|
|||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
}
|
}
|
||||||
for (exp in (expression as FirCall).arguments) {
|
for (exp in (expression as FirCall).arguments) {
|
||||||
if (exp is FirResolvedQualifier || expression.isForbiddenComplexConstant(session) || exp.resolvedType.isUnsignedType) {
|
if (exp is FirResolvedQualifier || expression.isForbiddenComplexConstant(session) || exp.getExpandedType().isUnsignedType) {
|
||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
}
|
}
|
||||||
checkConstantArguments(exp, session)?.let { return it }
|
checkConstantArguments(exp, session)?.let { return it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expression is FirGetClassCall -> {
|
expression is FirGetClassCall -> {
|
||||||
var coneType = (expression as? FirCall)?.argument?.resolvedType
|
var coneType = (expression as? FirCall)?.argument?.getExpandedType()
|
||||||
|
|
||||||
if (coneType is ConeErrorType)
|
if (coneType is ConeErrorType)
|
||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
|
|
||||||
while (coneType?.fullyExpandedClassId(session) == StandardClassIds.Array)
|
while (coneType?.classId == StandardClassIds.Array)
|
||||||
coneType = (coneType.lowerBoundIfFlexible().typeArguments.first() as? ConeKotlinTypeProjection)?.type ?: break
|
coneType = (coneType.lowerBoundIfFlexible().typeArguments.first() as? ConeKotlinTypeProjection)?.type ?: break
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
@@ -134,7 +137,7 @@ internal fun checkConstantArguments(
|
|||||||
}
|
}
|
||||||
expressionSymbol is FirConstructorSymbol -> {
|
expressionSymbol is FirConstructorSymbol -> {
|
||||||
if (expression is FirCallableReferenceAccess) return null
|
if (expression is FirCallableReferenceAccess) return null
|
||||||
if (expression.resolvedType.isUnsignedType) {
|
if (expression.getExpandedType().isUnsignedType) {
|
||||||
(expression as FirFunctionCall).arguments.forEach { argumentExpression ->
|
(expression as FirFunctionCall).arguments.forEach { argumentExpression ->
|
||||||
checkConstantArguments(argumentExpression, session)?.let { return it }
|
checkConstantArguments(argumentExpression, session)?.let { return it }
|
||||||
}
|
}
|
||||||
@@ -147,7 +150,7 @@ internal fun checkConstantArguments(
|
|||||||
if (calleeReference is FirErrorNamedReference) {
|
if (calleeReference is FirErrorNamedReference) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (expression.resolvedType.fullyExpandedClassId(session) == StandardClassIds.KClass) {
|
if (expression.getExpandedType().classId == StandardClassIds.KClass) {
|
||||||
return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +163,7 @@ internal fun checkConstantArguments(
|
|||||||
|
|
||||||
for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) {
|
for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) {
|
||||||
if (exp == null) continue
|
if (exp == null) continue
|
||||||
val expClassId = exp.resolvedType.lowerBoundIfFlexible().fullyExpandedClassId(session)
|
val expClassId = exp.getExpandedType().lowerBoundIfFlexible().fullyExpandedClassId(session)
|
||||||
// TODO, KT-59823: add annotation for allowed constant types
|
// TODO, KT-59823: add annotation for allowed constant types
|
||||||
if (expClassId !in StandardClassIds.constantAllowedTypes) {
|
if (expClassId !in StandardClassIds.constantAllowedTypes) {
|
||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
@@ -172,7 +175,7 @@ internal fun checkConstantArguments(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
expression is FirQualifiedAccessExpression -> {
|
expression is FirQualifiedAccessExpression -> {
|
||||||
val expressionType = expression.resolvedType
|
val expressionType = expression.getExpandedType()
|
||||||
if (expressionType.isReflectFunctionType(session) || expressionType.isKProperty(session) || expressionType.isKMutableProperty(
|
if (expressionType.isReflectFunctionType(session) || expressionType.isKProperty(session) || expressionType.isKMutableProperty(
|
||||||
session
|
session
|
||||||
)
|
)
|
||||||
@@ -190,7 +193,7 @@ internal fun checkConstantArguments(
|
|||||||
return checkConstantArguments(receiver, session)
|
return checkConstantArguments(receiver, session)
|
||||||
}
|
}
|
||||||
propertySymbol.isLocal -> return ConstantArgumentKind.NOT_CONST
|
propertySymbol.isLocal -> return ConstantArgumentKind.NOT_CONST
|
||||||
expressionType.fullyExpandedClassId(session) == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
expressionType.classId == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
||||||
}
|
}
|
||||||
return when (property.initializer) {
|
return when (property.initializer) {
|
||||||
is FirConstExpression<*> -> when {
|
is FirConstExpression<*> -> when {
|
||||||
@@ -213,16 +216,17 @@ private fun FirExpression.isForbiddenComplexConstant(session: FirSession): Boole
|
|||||||
val intrinsicConstEvaluation = session.languageVersionSettings.supportsFeature(
|
val intrinsicConstEvaluation = session.languageVersionSettings.supportsFeature(
|
||||||
LanguageFeature.IntrinsicConstEvaluation
|
LanguageFeature.IntrinsicConstEvaluation
|
||||||
)
|
)
|
||||||
return !intrinsicConstEvaluation && forbidComplexBooleanExpressions && isComplexBooleanConstant
|
return !intrinsicConstEvaluation && forbidComplexBooleanExpressions && isComplexBooleanConstant(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirExpression.isComplexBooleanConstant
|
private fun FirExpression.isComplexBooleanConstant(session: FirSession): Boolean {
|
||||||
get(): Boolean = when {
|
return when {
|
||||||
!resolvedType.isBoolean -> false
|
!resolvedType.fullyExpandedType(session).isBoolean -> false
|
||||||
this is FirConstExpression<*> -> false
|
this is FirConstExpression<*> -> false
|
||||||
usesVariableAsConstant -> false
|
usesVariableAsConstant -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See: org.jetbranis.kotlin.resolve.constants.CompileTimeConstant.Parameters.usesVariableAsConstant
|
* See: org.jetbranis.kotlin.resolve.constants.CompileTimeConstant.Parameters.usesVariableAsConstant
|
||||||
@@ -254,8 +258,7 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(session: FirSession): Boole
|
|||||||
val symbol = calleeReference.resolvedSymbol as? FirCallableSymbol
|
val symbol = calleeReference.resolvedSymbol as? FirCallableSymbol
|
||||||
if (!symbol.fromKotlin()) return false
|
if (!symbol.fromKotlin()) return false
|
||||||
|
|
||||||
val coneType = this.dispatchReceiver?.resolvedType
|
val receiverClassId = this.dispatchReceiver?.resolvedType?.fullyExpandedClassId(session)
|
||||||
val receiverClassId = coneType?.fullyExpandedClassId(session)
|
|
||||||
|
|
||||||
if (receiverClassId in StandardClassIds.unsignedTypes) return false
|
if (receiverClassId in StandardClassIds.unsignedTypes) return false
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -73,7 +73,7 @@ fun throwsSpreadArrayOfUnresolved() {}
|
|||||||
|
|
||||||
typealias UEAlias = <!UNRESOLVED_REFERENCE!>UE<!>
|
typealias UEAlias = <!UNRESOLVED_REFERENCE!>UE<!>
|
||||||
|
|
||||||
@Throws(UEAlias::class)
|
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>UEAlias::class<!>)
|
||||||
fun throwsTypealiasToUnresolved() {}
|
fun throwsTypealiasToUnresolved() {}
|
||||||
|
|
||||||
interface Base0 {
|
interface Base0 {
|
||||||
@@ -313,7 +313,7 @@ suspend fun suspendThrowsSpreadLiteralWithUnresolved() {}
|
|||||||
@Throws(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)<!>)
|
@Throws(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)<!>)
|
||||||
suspend fun suspendThrowsSpreadArrayOfUnresolved() {}
|
suspend fun suspendThrowsSpreadArrayOfUnresolved() {}
|
||||||
|
|
||||||
@Throws(UEAlias::class)
|
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>UEAlias::class<!>)
|
||||||
suspend fun suspendThrowsTypealiasToUnresolved() {}
|
suspend fun suspendThrowsTypealiasToUnresolved() {}
|
||||||
|
|
||||||
@Throws(<!ARGUMENT_TYPE_MISMATCH!>Orphan::class<!>)
|
@Throws(<!ARGUMENT_TYPE_MISMATCH!>Orphan::class<!>)
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
typealias UI = UInt
|
||||||
|
|
||||||
|
const val a: UI = 1u
|
||||||
|
const val b: UI = a
|
||||||
|
const val c = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>a == b<!>
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
public annotation class Throws(vararg val exceptionClasses: KClass<out Throwable>)
|
||||||
|
|
||||||
|
typealias UEAlias = <!UNRESOLVED_REFERENCE!>UE<!>
|
||||||
|
|
||||||
|
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>UEAlias::class<!>)
|
||||||
|
fun throwsTypealiasToUnresolved() {}
|
||||||
Generated
+12
@@ -6901,6 +6901,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/topLevelVar.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeAliasToUnsigned.kt")
|
||||||
|
public void testTypeAliasToUnsigned() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/typeAliasToUnsigned.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
||||||
public void testUnaryMinusIndepWoExpType() throws Exception {
|
public void testUnaryMinusIndepWoExpType() throws Exception {
|
||||||
@@ -6913,6 +6919,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unresolvedReference.kt")
|
||||||
|
public void testUnresolvedReference() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/constantEvaluator/constant/unresolvedReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("unsignedOperations.kt")
|
@TestMetadata("unsignedOperations.kt")
|
||||||
public void testUnsignedOperations() throws Exception {
|
public void testUnsignedOperations() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user