KT-11030 Don't capture companion objects into closure

This commit is contained in:
Alexey Andreev
2016-03-10 20:17:03 +03:00
parent 1bded9d66f
commit 47dde9520d
2 changed files with 14 additions and 13 deletions
@@ -22,6 +22,7 @@ import com.google.dart.compiler.backend.js.ast.JsName
import org.jetbrains.kotlin.js.translate.utils.ManglingUtils.getSuggestedName
import com.google.dart.compiler.backend.js.ast.JsScope
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
private val CAPTURED_RECEIVER_NAME_PREFIX : String = "this$"
@@ -59,13 +60,23 @@ class UsageTracker(
}
private fun captureIfNeed(descriptor: DeclarationDescriptor?) {
if (descriptor == null || isCaptured(descriptor) || isAncestor(containingDescriptor, descriptor, /* strict = */ true)) return
if (descriptor == null || isCaptured(descriptor) || isAncestor(containingDescriptor, descriptor, /* strict = */ true) ||
isSingletonReceiver(descriptor)) return
parent?.captureIfNeed(descriptor)
captured[descriptor] = descriptor.getJsNameForCapturedDescriptor()
}
private fun isSingletonReceiver(descriptor: DeclarationDescriptor): Boolean {
if (descriptor !is ReceiverParameterDescriptor) return false
val value = descriptor.value
if (value !is ImplicitReceiver) return false
return DescriptorUtils.isObject(value.declarationDescriptor)
}
private fun DeclarationDescriptor.getJsNameForCapturedDescriptor(): JsName {
val suggestedName = when (this) {
is ReceiverParameterDescriptor -> this.getNameForCapturedReceiver()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,16 +67,6 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
}
fun JsFunction.withCapturedParameters(context: TranslationContext, invokingContext: TranslationContext, descriptor: MemberDescriptor): JsExpression {
fun getParameterNameRefForInvocation(descriptor: DeclarationDescriptor): JsExpression {
val alias = invokingContext.getAliasForDescriptor(descriptor)
if (alias != null) return alias
if (descriptor is ReceiverParameterDescriptor) return JsLiteral.THIS
return invokingContext.getNameForDescriptor(descriptor).makeRef()
}
val ref = invokingContext.define(descriptor, this)
val invocation = JsInvocation(ref)
@@ -88,7 +78,7 @@ fun JsFunction.withCapturedParameters(context: TranslationContext, invokingConte
for ((capturedDescriptor, name) in tracker.capturedDescriptorToJsName) {
if (capturedDescriptor == tracker.containingDescriptor) continue
val capturedRef = getParameterNameRefForInvocation(capturedDescriptor)
val capturedRef = invokingContext.getParameterNameRefForInvocation(capturedDescriptor)
var additionalArgs = listOf(capturedRef)
var additionalParams = listOf(JsParameter(name))