JS backend: use special JsScope(JsDynamicScope) for names from dynamic calls instead of use containing scope to avoid the impact on local names.

This commit is contained in:
Zalim Bashorov
2014-12-10 22:46:42 +03:00
parent af82e69214
commit 6b50d74056
4 changed files with 37 additions and 3 deletions
@@ -22,6 +22,10 @@ public fun JsObjectScope(parent: JsScope, description: String): JsObjectScope =
public class JsObjectScope(parent: JsScope, description: String, scopeId: String?) : JsScope(parent, description, scopeId)
public object JsDynamicScope : JsScope(null, "Scope for dynamic declarations", null) {
override fun doCreateName(name: String) = JsName(this, name)
}
public class JsFunctionScope(parent: JsScope, description: String) : JsScope(parent, description, null) {
private val labelScopes = Stack<LabelScope>()
@@ -120,6 +120,12 @@ public class DynamicTestGenerated extends AbstractDynamicTest {
doTest(fileName);
}
@TestMetadata("nameClashing.kt")
public void testNameClashing() throws Exception {
String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/dynamic/cases/nameClashing.kt");
doTest(fileName);
}
@TestMetadata("operationsWithAssignment.kt")
public void testOperationsWithAssignment() throws Exception {
String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/dynamic/cases/operationsWithAssignment.kt");
@@ -236,9 +236,7 @@ public final class StaticContext {
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
if (TasksPackage.isDynamic(descriptor)) {
String name = descriptor.getName().asString();
JsScope scope = getEnclosingScope(descriptor);
assert scope instanceof JsFunctionScope;
return ((JsFunctionScope) scope).declareNameUnsafe(name);
return JsDynamicScope.INSTANCE$.declareName(name);
}
return null;
@@ -0,0 +1,26 @@
package foo
fun assertContains(expectedName: String, f: () -> Unit) {
val s = f.toString()
assertTrue(s.contains(expectedName), "\"$s\" dosn't contain \"$expectedName\"")
}
fun box(): String {
val d: dynamic = bar
val a = {
val somethingBefore = 1
d.somethingBefore
}
assertContains("var somethingBefore = 1;", a)
val b = {
d.somethingAfter
val somethingAfter = 1
}
assertContains("var somethingAfter = 1;", b)
return "OK"
}