From 6b50d74056f712da84f4b2ff7be19404314cede5 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Wed, 10 Dec 2014 22:46:42 +0300 Subject: [PATCH] JS backend: use special JsScope(JsDynamicScope) for names from dynamic calls instead of use containing scope to avoid the impact on local names. --- .../dart/compiler/backend/js/ast/jsScopes.kt | 4 +++ .../test/semantics/DynamicTestGenerated.java | 6 +++++ .../k2js/translate/context/StaticContext.java | 4 +-- .../testData/dynamic/cases/nameClashing.kt | 26 +++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 js/js.translator/testData/dynamic/cases/nameClashing.kt diff --git a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt index 51d5b299a6b..ccaaf943b7c 100644 --- a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt +++ b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt @@ -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() diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/DynamicTestGenerated.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/DynamicTestGenerated.java index 2cc936e50f2..3c26b07a216 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/DynamicTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/DynamicTestGenerated.java @@ -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"); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index 3f78cffe5c8..fcc876796a3 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -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; diff --git a/js/js.translator/testData/dynamic/cases/nameClashing.kt b/js/js.translator/testData/dynamic/cases/nameClashing.kt new file mode 100644 index 00000000000..b108bcca9b2 --- /dev/null +++ b/js/js.translator/testData/dynamic/cases/nameClashing.kt @@ -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" +} \ No newline at end of file