JS: fix translation of try statements with multiple catches

This commit is contained in:
Alexey Andreev
2016-11-24 14:43:49 +03:00
parent d9e0e9f0b3
commit 8ef72935a8
2 changed files with 21 additions and 13 deletions
@@ -17,6 +17,8 @@
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.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
@@ -76,42 +78,48 @@ class CatchTranslator(
val parameterRef = jsCatch.parameter.name.makeRef() val parameterRef = jsCatch.parameter.name.makeRef()
val catchContext = context().innerContextWithAliased(parameterDescriptor, parameterRef) val catchContext = context().innerContextWithAliased(parameterDescriptor, parameterRef)
jsCatch.body = JsBlock(translateCatches(catchContext, parameterDescriptor, parameterRef, catches.iterator())) jsCatch.body = JsBlock(translateCatches(catchContext, parameterRef, catches.iterator()))
return jsCatch return jsCatch
} }
private fun translateCatches( private fun translateCatches(
context: TranslationContext, context: TranslationContext,
parameterDescriptor: DeclarationDescriptor, initialCatchParameterRef: JsNameRef,
parameterRef: JsNameRef,
catches: Iterator<KtCatchClause> catches: Iterator<KtCatchClause>
): JsStatement { ): JsStatement {
if (!catches.hasNext()) return JsThrow(parameterRef) if (!catches.hasNext()) return JsThrow(initialCatchParameterRef)
var nextContext = context var nextContext = context
val catch = catches.next() val catch = catches.next()
val param = catch.catchParameter!! val param = catch.catchParameter!!
val paramName = context.getNameForElement(param) val parameterDescriptor = BindingUtils.getDescriptorForElement(bindingContext(), catch.catchParameter!!)
val parameterName = context().getNameForDescriptor(parameterDescriptor)
val paramType = param.typeReference!! val paramType = param.typeReference!!
val additionalStatements = mutableListOf<JsStatement>() val additionalStatements = mutableListOf<JsStatement>()
if (paramName.ident != parameterRef.ident) { val parameterRef = if (parameterName.ident != initialCatchParameterRef.ident) {
additionalStatements += JsAstUtils.newVar(paramName, parameterRef) val parameterAlias = context.scope().declareTemporaryName(parameterName.ident)
nextContext = nextContext.innerContextWithAliased(parameterDescriptor, paramName.makeRef()) additionalStatements += JsAstUtils.newVar(parameterAlias, initialCatchParameterRef)
val ref = JsAstUtils.pureFqn(parameterAlias, null)
ref
} }
val thenBlock = translateCatchBody(context, catch) else {
initialCatchParameterRef
}
nextContext = nextContext.innerContextWithAliased(parameterDescriptor, parameterRef)
val thenBlock = translateCatchBody(nextContext, catch)
thenBlock.statements.addAll(0, additionalStatements) thenBlock.statements.addAll(0, additionalStatements)
if (paramType.isDynamic) return thenBlock if (paramType.isDynamic) return thenBlock
// translateIsCheck won't ever return `null` if its second argument is `null` // translateIsCheck won't ever return `null` if its second argument is `null`
val typeCheck = with (patternTranslator(nextContext)) { val typeCheck = with (patternTranslator(nextContext)) {
translateIsCheck(parameterRef, paramType) translateIsCheck(initialCatchParameterRef, paramType)
}!! }!!
val elseBlock = translateCatches(nextContext, parameterDescriptor, parameterRef, catches) val elseBlock = translateCatches(context, initialCatchParameterRef, catches)
return JsIf(typeCheck, thenBlock, elseBlock) return JsIf(typeCheck, thenBlock, elseBlock)
} }
@@ -17,9 +17,9 @@ fun bar(e: Exception): String {
s = "IllegalArgumentException" s = "IllegalArgumentException"
exceptionObject = e exceptionObject = e
} }
catch (e: IllegalStateException) { catch (f: IllegalStateException) {
s = "IllegalStateException" s = "IllegalStateException"
exceptionObject = e exceptionObject = f
} }
catch (e: Exception) { catch (e: Exception) {
s = "Exception" s = "Exception"