JS: fix exception during translation of for expression with iterator having generic type constrained by Iterable. Fix #KT-8385

This commit is contained in:
Alexey Andreev
2016-09-30 16:30:43 +03:00
parent 977fd8f591
commit 61b429f2f0
3 changed files with 21 additions and 12 deletions
@@ -2094,6 +2094,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
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")
public void testForOnEmptyArray() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/for/forOnEmptyArray.kt");
@@ -19,25 +19,23 @@
package org.jetbrains.kotlin.js.translate.expression
import com.google.dart.compiler.backend.js.ast.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.Translation
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.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.BindingUtils.*
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtForExpression
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.descriptorUtil.fqNameSafe
fun createWhile(doWhile: Boolean, expression: KtWhileExpressionBase, context: TranslationContext): JsNode {
val conditionExpression = expression.condition ?:
@@ -83,19 +81,16 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
val rangeType = getTypeForExpression(context.bindingContext(), loopRange)
fun isForOverRange(): Boolean {
//TODO: better check
//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 =
loopRange is KtBinaryExpression && loopRange.operationToken == KtTokens.RANGE && isForOverRange()
fun isForOverArray(): Boolean {
//TODO: better check
//TODO: IMPORTANT!
return getClassDescriptorForType(rangeType).name.asString() == "Array" ||
getClassDescriptorForType(rangeType).name.asString() == "IntArray"
return KotlinBuiltIns.isArray(rangeType) || KotlinBuiltIns.isPrimitiveArray(rangeType)
}
@@ -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
}