[JS BE] Support val in when subject
#KT-25014 Fixed
This commit is contained in:
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var y: String = "OK"
|
var y: String = "OK"
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JS, JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
fun dense(x: Int): Int {
|
fun dense(x: Int): Int {
|
||||||
return when (val xx = x) {
|
return when (val xx = x) {
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
val x = 1
|
val x = 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
val dz = -0.0
|
val dz = -0.0
|
||||||
val fz = -0.0f
|
val fz = -0.0f
|
||||||
@@ -29,5 +28,14 @@ fun box(): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testDoubleAsUpperBound(-0.0)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T: Double> testDoubleAsUpperBound(v: T): Boolean {
|
||||||
|
return when (val a = v*v) {
|
||||||
|
0.0 -> true
|
||||||
|
else -> throw AssertionError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+15
-5
@@ -1,22 +1,32 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject +ProperIeee754Comparisons
|
// !LANGUAGE: +VariableDeclarationInWhenSubject +ProperIeee754Comparisons
|
||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS, JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
val az: Any = -0.0
|
val az: Any = -0.0
|
||||||
val afz: Any = -0.0f
|
val afz: Any = -0.0f
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
when (val y = az) {
|
val y = az
|
||||||
|
when (y) {
|
||||||
!is Double -> throw AssertionError()
|
!is Double -> throw AssertionError()
|
||||||
0.0 -> {}
|
0.0 -> {}
|
||||||
else -> throw AssertionError()
|
else -> throw AssertionError()
|
||||||
}
|
}
|
||||||
|
val yy = afz
|
||||||
when (val y = afz) {
|
when (yy) {
|
||||||
!is Float -> throw AssertionError()
|
!is Float -> throw AssertionError()
|
||||||
0.0 -> {}
|
0.0 -> {}
|
||||||
else -> throw AssertionError()
|
else -> throw AssertionError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testDoubleAsUpperBound(-0.0)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T: Double> testDoubleAsUpperBound(v: T): Boolean {
|
||||||
|
return when (val a = v*v) {
|
||||||
|
0.0 -> true
|
||||||
|
else -> throw AssertionError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
val x: Any = 1
|
val x: Any = 1
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JS, JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
fun sparse(x: Int): Int {
|
fun sparse(x: Int): Int {
|
||||||
return when (val xx = (x % 4) * 100) {
|
return when (val xx = (x % 4) * 100) {
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
var effectCount = 0
|
var effectCount = 0
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JS, JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JS, JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|||||||
+11
-24
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* 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.js.translate.expression;
|
package org.jetbrains.kotlin.js.translate.expression;
|
||||||
@@ -36,10 +25,7 @@ import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelF
|
|||||||
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
|
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.*;
|
import org.jetbrains.kotlin.js.translate.utils.*;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.psi.KtExpression;
|
|
||||||
import org.jetbrains.kotlin.psi.KtIsExpression;
|
|
||||||
import org.jetbrains.kotlin.psi.KtTypeReference;
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonInfo;
|
import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonInfo;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
@@ -270,31 +256,32 @@ public final class PatternTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression translateExpressionPattern(
|
public JsExpression translateExpressionPattern(
|
||||||
@NotNull KtExpression subjectExpression,
|
@NotNull KotlinType subjectType,
|
||||||
@NotNull JsExpression expressionToMatch,
|
@NotNull JsExpression expressionToMatch,
|
||||||
@NotNull KtExpression patternExpression
|
@NotNull KtExpression patternExpression
|
||||||
) {
|
) {
|
||||||
PrimitiveNumericComparisonInfo ieeeInfo = UtilsKt.getPrimitiveNumericComparisonInfo(context(), patternExpression);
|
PrimitiveNumericComparisonInfo ieeeInfo = UtilsKt.getPrimitiveNumericComparisonInfo(context(), patternExpression);
|
||||||
|
|
||||||
KotlinType subjectType, patternType;
|
KotlinType actualSubjectType;
|
||||||
|
KotlinType patternType;
|
||||||
if (ieeeInfo != null) {
|
if (ieeeInfo != null) {
|
||||||
subjectType = ieeeInfo.getLeftType();
|
actualSubjectType = ieeeInfo.getLeftType();
|
||||||
patternType = ieeeInfo.getRightType();
|
patternType = ieeeInfo.getRightType();
|
||||||
} else {
|
} else {
|
||||||
subjectType = UtilsKt.getPrecisePrimitiveTypeNotNull(context(), subjectExpression);
|
actualSubjectType = UtilsKt.refineType(subjectType);
|
||||||
patternType = UtilsKt.getPrecisePrimitiveTypeNotNull(context(), patternExpression);
|
patternType = UtilsKt.getPrecisePrimitiveTypeNotNull(context(), patternExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
EqualityType matchEquality = equalityType(subjectType);
|
EqualityType matchEquality = equalityType(actualSubjectType);
|
||||||
EqualityType patternEquality = equalityType(patternType);
|
EqualityType patternEquality = equalityType(patternType);
|
||||||
|
|
||||||
JsExpression expressionToMatchAgainst = TranslationUtils.coerce(context(), translateExpressionForExpressionPattern(patternExpression), subjectType);
|
JsExpression expressionToMatchAgainst = TranslationUtils.coerce(context(), translateExpressionForExpressionPattern(patternExpression), actualSubjectType);
|
||||||
|
|
||||||
if (matchEquality == EqualityType.PRIMITIVE && patternEquality == EqualityType.PRIMITIVE) {
|
if (matchEquality == EqualityType.PRIMITIVE && patternEquality == EqualityType.PRIMITIVE) {
|
||||||
return equality(expressionToMatch, expressionToMatchAgainst);
|
return equality(expressionToMatch, expressionToMatchAgainst);
|
||||||
}
|
}
|
||||||
else if (expressionToMatchAgainst instanceof JsNullLiteral) {
|
else if (expressionToMatchAgainst instanceof JsNullLiteral) {
|
||||||
return TranslationUtils.nullCheck(subjectExpression, expressionToMatch, context(), false);
|
return TranslationUtils.nullCheck(actualSubjectType, expressionToMatch, context(), false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return TopLevelFIF.KOTLIN_EQUALS.apply(expressionToMatch, Collections.singletonList(expressionToMatchAgainst), context());
|
return TopLevelFIF.KOTLIN_EQUALS.apply(expressionToMatch, Collections.singletonList(expressionToMatchAgainst), context());
|
||||||
|
|||||||
+28
-18
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* 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.js.translate.expression
|
package org.jetbrains.kotlin.js.translate.expression
|
||||||
@@ -19,6 +8,7 @@ package org.jetbrains.kotlin.js.translate.expression
|
|||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
@@ -27,6 +17,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
|||||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
|
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
|
||||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||||
import org.jetbrains.kotlin.js.translate.operation.InOperationTranslator
|
import org.jetbrains.kotlin.js.translate.operation.InOperationTranslator
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.not
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.not
|
||||||
import org.jetbrains.kotlin.js.translate.utils.mutator.CoercionMutator
|
import org.jetbrains.kotlin.js.translate.utils.mutator.CoercionMutator
|
||||||
@@ -49,6 +40,7 @@ private typealias EntryWithConstants = Pair<List<JsExpression>, KtWhenEntry>
|
|||||||
|
|
||||||
class WhenTranslator
|
class WhenTranslator
|
||||||
private constructor(private val whenExpression: KtWhenExpression, context: TranslationContext) : AbstractTranslator(context) {
|
private constructor(private val whenExpression: KtWhenExpression, context: TranslationContext) : AbstractTranslator(context) {
|
||||||
|
private val subjectType: KotlinType?
|
||||||
private val expressionToMatch: JsExpression?
|
private val expressionToMatch: JsExpression?
|
||||||
private val type: KotlinType?
|
private val type: KotlinType?
|
||||||
private val uniqueConstants = mutableSetOf<Any>()
|
private val uniqueConstants = mutableSetOf<Any>()
|
||||||
@@ -63,8 +55,27 @@ private constructor(private val whenExpression: KtWhenExpression, context: Trans
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val subject = whenExpression.subjectExpression
|
val subjectVariable = whenExpression.subjectVariable
|
||||||
expressionToMatch = if (subject != null) context.defineTemporary(Translation.translateAsExpression(subject, context)) else null
|
val subjectExpression = whenExpression.subjectExpression
|
||||||
|
|
||||||
|
when {
|
||||||
|
subjectVariable != null -> {
|
||||||
|
val variable = Translation.translateAsStatement(subjectVariable, context) as JsVars
|
||||||
|
context.addStatementToCurrentBlock(variable)
|
||||||
|
|
||||||
|
val descriptor = BindingUtils.getDescriptorForElement(context.bindingContext(), subjectVariable) as? CallableDescriptor
|
||||||
|
subjectType = descriptor?.returnType
|
||||||
|
expressionToMatch = variable.vars.first().name.makeRef()
|
||||||
|
}
|
||||||
|
subjectExpression != null -> {
|
||||||
|
subjectType = bindingContext().getType(subjectExpression)
|
||||||
|
expressionToMatch = context.defineTemporary(Translation.translateAsExpression(subjectExpression, context))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
subjectType = null
|
||||||
|
expressionToMatch = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type = bindingContext().getType(whenExpression)
|
type = bindingContext().getType(whenExpression)
|
||||||
}
|
}
|
||||||
@@ -123,8 +134,8 @@ private constructor(private val whenExpression: KtWhenExpression, context: Trans
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateAsSwitch(fromIndex: Int): Pair<JsSwitch, Int>? {
|
private fun translateAsSwitch(fromIndex: Int): Pair<JsSwitch, Int>? {
|
||||||
|
val subjectType = subjectType ?: return null
|
||||||
val ktSubject = whenExpression.subjectExpression ?: return null
|
val ktSubject = whenExpression.subjectExpression ?: return null
|
||||||
val subjectType = bindingContext().getType(ktSubject) ?: return null
|
|
||||||
|
|
||||||
val dataFlow = dataFlowValueFactory.createDataFlowValue(
|
val dataFlow = dataFlowValueFactory.createDataFlowValue(
|
||||||
ktSubject, subjectType, bindingContext(), context().declarationDescriptor ?: context().currentModule)
|
ktSubject, subjectType, bindingContext(), context().declarationDescriptor ?: context().currentModule)
|
||||||
@@ -322,12 +333,11 @@ private constructor(private val whenExpression: KtWhenExpression, context: Trans
|
|||||||
private fun translateExpressionCondition(condition: KtWhenConditionWithExpression, context: TranslationContext): JsExpression {
|
private fun translateExpressionCondition(condition: KtWhenConditionWithExpression, context: TranslationContext): JsExpression {
|
||||||
val patternExpression = condition.expression ?: error("Expression pattern should have an expression.")
|
val patternExpression = condition.expression ?: error("Expression pattern should have an expression.")
|
||||||
|
|
||||||
val expressionToMatch = expressionToMatch
|
|
||||||
val patternTranslator = Translation.patternTranslator(context)
|
val patternTranslator = Translation.patternTranslator(context)
|
||||||
return if (expressionToMatch == null) {
|
return if (expressionToMatch == null) {
|
||||||
patternTranslator.translateExpressionForExpressionPattern(patternExpression)
|
patternTranslator.translateExpressionForExpressionPattern(patternExpression)
|
||||||
} else {
|
} else {
|
||||||
patternTranslator.translateExpressionPattern(whenExpression.subjectExpression!!, expressionToMatch, patternExpression)
|
patternTranslator.translateExpressionPattern(subjectType!!, expressionToMatch, patternExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,16 @@ public final class TranslationUtils {
|
|||||||
return nullCheck(prepareForNullCheck(ktSubject, expressionToCheck, context), isNegated);
|
return nullCheck(prepareForNullCheck(ktSubject, expressionToCheck, context), isNegated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsBinaryOperation nullCheck(
|
||||||
|
@NotNull KotlinType expressionType,
|
||||||
|
@NotNull JsExpression expressionToCheck,
|
||||||
|
@NotNull TranslationContext context,
|
||||||
|
boolean isNegated
|
||||||
|
) {
|
||||||
|
return nullCheck(coerce(context, expressionToCheck, TypeUtils.makeNullable(expressionType)), isNegated);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsConditional notNullConditional(
|
public static JsConditional notNullConditional(
|
||||||
@NotNull JsExpression expression,
|
@NotNull JsExpression expression,
|
||||||
|
|||||||
@@ -242,6 +242,9 @@ fun TranslationContext.createCoroutineResult(resolvedCall: ResolvedCall<*>): JsE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KotlinType.refineType() =
|
||||||
|
TypeUtils.getAllSupertypes(this).find(KotlinBuiltIns::isPrimitiveTypeOrNullablePrimitiveType) ?: this
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to get precise statically known primitive type. Takes generic supertypes into account. Doesn't handle smart-casts.
|
* Tries to get precise statically known primitive type. Takes generic supertypes into account. Doesn't handle smart-casts.
|
||||||
* This is needed to be compatible with JVM NaN behaviour:
|
* This is needed to be compatible with JVM NaN behaviour:
|
||||||
@@ -256,7 +259,7 @@ fun TranslationContext.getPrecisePrimitiveType(expression: KtExpression): Kotlin
|
|||||||
val bindingContext = bindingContext()
|
val bindingContext = bindingContext()
|
||||||
val ktType = bindingContext.getType(expression) ?: return null
|
val ktType = bindingContext.getType(expression) ?: return null
|
||||||
|
|
||||||
return TypeUtils.getAllSupertypes(ktType).find(KotlinBuiltIns::isPrimitiveTypeOrNullablePrimitiveType) ?: ktType
|
return ktType.refineType()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TranslationContext.getPrecisePrimitiveTypeNotNull(expression: KtExpression): KotlinType {
|
fun TranslationContext.getPrecisePrimitiveTypeNotNull(expression: KtExpression): KotlinType {
|
||||||
|
|||||||
Reference in New Issue
Block a user