JS: fix translation of try statements with multiple catches
This commit is contained in:
+19
-11
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user