JS: fix exception during translation of for expression with iterator having generic type constrained by Iterable. Fix #KT-8385
This commit is contained in:
@@ -2094,6 +2094,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forIteratesOverTypeParameter.kt")
|
||||||
|
public void testForIteratesOverTypeParameter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/for/forIteratesOverTypeParameter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("forOnEmptyArray.kt")
|
@TestMetadata("forOnEmptyArray.kt")
|
||||||
public void testForOnEmptyArray() throws Exception {
|
public void testForOnEmptyArray() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/for/forOnEmptyArray.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/for/forOnEmptyArray.kt");
|
||||||
|
|||||||
+7
-12
@@ -19,25 +19,23 @@
|
|||||||
package org.jetbrains.kotlin.js.translate.expression
|
package org.jetbrains.kotlin.js.translate.expression
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.CompositeFIF
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.CompositeFIF
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getHasNextCallable
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.*
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getIteratorFunction
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getNextFunction
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getTypeForExpression
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
||||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.psi.KtWhileExpressionBase
|
import org.jetbrains.kotlin.psi.KtWhileExpressionBase
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.getClassDescriptorForType
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
|
||||||
fun createWhile(doWhile: Boolean, expression: KtWhileExpressionBase, context: TranslationContext): JsNode {
|
fun createWhile(doWhile: Boolean, expression: KtWhileExpressionBase, context: TranslationContext): JsNode {
|
||||||
val conditionExpression = expression.condition ?:
|
val conditionExpression = expression.condition ?:
|
||||||
@@ -83,19 +81,16 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
|
|||||||
val rangeType = getTypeForExpression(context.bindingContext(), loopRange)
|
val rangeType = getTypeForExpression(context.bindingContext(), loopRange)
|
||||||
|
|
||||||
fun isForOverRange(): Boolean {
|
fun isForOverRange(): Boolean {
|
||||||
//TODO: better check
|
|
||||||
//TODO: long range?
|
//TODO: long range?
|
||||||
return getClassDescriptorForType(rangeType).name.asString() == "IntRange"
|
val fqn = rangeType.constructor.declarationDescriptor?.fqNameSafe ?: return false
|
||||||
|
return fqn.asString() == "kotlin.ranges.IntRange"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isForOverRangeLiteral(): Boolean =
|
fun isForOverRangeLiteral(): Boolean =
|
||||||
loopRange is KtBinaryExpression && loopRange.operationToken == KtTokens.RANGE && isForOverRange()
|
loopRange is KtBinaryExpression && loopRange.operationToken == KtTokens.RANGE && isForOverRange()
|
||||||
|
|
||||||
fun isForOverArray(): Boolean {
|
fun isForOverArray(): Boolean {
|
||||||
//TODO: better check
|
return KotlinBuiltIns.isArray(rangeType) || KotlinBuiltIns.isPrimitiveArray(rangeType)
|
||||||
//TODO: IMPORTANT!
|
|
||||||
return getClassDescriptorForType(rangeType).name.asString() == "Array" ||
|
|
||||||
getClassDescriptorForType(rangeType).name.asString() == "IntArray"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
public fun <T, C : Collection<T>> bar(collection: C, f: (T) -> Unit) { for (item in collection) f(item) }
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val collection = listOf("O", "K")
|
||||||
|
var result = ""
|
||||||
|
bar(collection) { result += it }
|
||||||
|
return result
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user