-
+
-
+
-
+
-
-
-
-
-
-
-
-
+
@@ -943,41 +932,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -985,46 +939,88 @@
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/js.jar b/lib/js.jar
new file mode 100644
index 00000000000..878b0d9422b
Binary files /dev/null and b/lib/js.jar differ
diff --git a/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsCatchScope.class b/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsCatchScope.class
index 79d916026f2..8b43745bbbe 100644
Binary files a/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsCatchScope.class and b/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsCatchScope.class differ
diff --git a/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsRootScope.class b/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsRootScope.class
index 9d7aa936a36..8e7c8221ab3 100644
Binary files a/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsRootScope.class and b/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsRootScope.class differ
diff --git a/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsScope.class b/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsScope.class
index eac974f40c4..57c3e51710f 100644
Binary files a/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsScope.class and b/out/production/k2js/com/google/dart/compiler/backend/js/ast/JsScope.class differ
diff --git a/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$FunctionVariableDeclaration.class b/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$FunctionVariableDeclaration.class
index 7b64b371e27..a981cf1ce32 100644
Binary files a/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$FunctionVariableDeclaration.class and b/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$FunctionVariableDeclaration.class differ
diff --git a/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$NamespacePropertyDeclaration.class b/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$NamespacePropertyDeclaration.class
index b31289d3086..c01e6d1e8b3 100644
Binary files a/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$NamespacePropertyDeclaration.class and b/out/production/k2js/org/jetbrains/k2js/translate/DeclarationTranslator$NamespacePropertyDeclaration.class differ
diff --git a/out/production/k2js/org/jetbrains/k2js/translate/FunctionTranslator.class b/out/production/k2js/org/jetbrains/k2js/translate/FunctionTranslator.class
index d6aea207751..c22493230f7 100644
Binary files a/out/production/k2js/org/jetbrains/k2js/translate/FunctionTranslator.class and b/out/production/k2js/org/jetbrains/k2js/translate/FunctionTranslator.class differ
diff --git a/out/production/k2js/org/jetbrains/k2js/translate/TranslationContext.class b/out/production/k2js/org/jetbrains/k2js/translate/TranslationContext.class
index cab077100a6..b00a0789714 100644
Binary files a/out/production/k2js/org/jetbrains/k2js/translate/TranslationContext.class and b/out/production/k2js/org/jetbrains/k2js/translate/TranslationContext.class differ
diff --git a/src/com/google/dart/compiler/backend/js/ast/JsCatchScope.java b/src/com/google/dart/compiler/backend/js/ast/JsCatchScope.java
index 6c9ce22a0e8..5e5a2f2f577 100644
--- a/src/com/google/dart/compiler/backend/js/ast/JsCatchScope.java
+++ b/src/com/google/dart/compiler/backend/js/ast/JsCatchScope.java
@@ -65,7 +65,7 @@ public class JsCatchScope extends JsScope {
}
@Override
- protected JsName findExistingNameNoRecurse(String ident) {
+ public JsName findExistingNameNoRecurse(String ident) {
if (name.getIdent().equals(ident)) {
return name;
} else {
diff --git a/src/com/google/dart/compiler/backend/js/ast/JsRootScope.java b/src/com/google/dart/compiler/backend/js/ast/JsRootScope.java
index 25c50b2c9ad..33b71f26222 100644
--- a/src/com/google/dart/compiler/backend/js/ast/JsRootScope.java
+++ b/src/com/google/dart/compiler/backend/js/ast/JsRootScope.java
@@ -33,7 +33,7 @@ public final class JsRootScope extends JsScope {
}
@Override
- protected JsName findExistingNameNoRecurse(String ident) {
+ public JsName findExistingNameNoRecurse(String ident) {
JsName name = super.findExistingNameNoRecurse(ident);
if (name == null) {
if (JsReservedIdentifiers.getReservedGlobalSymbols().contains(ident)) {
diff --git a/src/com/google/dart/compiler/backend/js/ast/JsScope.java b/src/com/google/dart/compiler/backend/js/ast/JsScope.java
index 178f85e51f6..e5f0578fb49 100644
--- a/src/com/google/dart/compiler/backend/js/ast/JsScope.java
+++ b/src/com/google/dart/compiler/backend/js/ast/JsScope.java
@@ -18,18 +18,18 @@ import java.util.Map;
* {@link com.google.dart.compiler.backend.js.ast.JsName}s. A JavaScript AST is
* built in terms of abstract name objects without worrying about obfuscation,
* keyword/identifier blacklisting, and so on.
- *
- *
- *
+ *
+ *
+ *
* Scopes are associated with
* {@link com.google.dart.compiler.backend.js.ast.JsFunction}s, but the two are
* not equivalent. Functions have scopes, but a scope does not
* necessarily have an associated Function. Examples of this include the
* {@link com.google.dart.compiler.backend.js.ast.JsRootScope} and synthetic
* scopes that might be created by a client.
- *
- *
- *
+ *
+ *
+ *
* Scopes can have parents to provide constraints when allocating actual
* identifiers for names. Specifically, names in child scopes are chosen such
* that they do not conflict with names in their parent scopes. The ultimate
@@ -41,258 +41,260 @@ import java.util.Map;
*/
public class JsScope implements Serializable {
- private List children = Collections.emptyList();
- private final String description;
- private Map names = Collections.emptyMap();
- private JsScope parent;
- protected int tempIndex = 0;
- private final String scopeId;
+ private List children = Collections.emptyList();
+ private final String description;
+ private Map names = Collections.emptyMap();
+ private JsScope parent;
+ protected int tempIndex = 0;
+ private final String scopeId;
- /*
- * Create a scope with parent.
- */
- public JsScope(JsScope parent, String description) {
- this(parent, description, null);
- }
-
- /**
- * Create a scope with parent.
- */
- public JsScope(JsScope parent, String description, String scopeId) {
- assert (parent != null);
- this.scopeId = scopeId;
- this.description = description;
- this.parent = parent;
- parent.children = Lists.add(parent.children, this);
- }
-
- /**
- * Rebase the function to a new scope.
- * @param newParent The scope to add the function to.
- */
- public void rebase(JsScope newParent) {
- detachFromParent();
- parent = newParent;
- parent.children = Lists.add(parent.children, this);
- }
-
- /**
- * Rebase the function's children to a new scope.
- * @param newParent
- */
- public void rebaseChildScopes(JsScope newParent) {
- if (newParent == this) {
- return;
+ /*
+ * Create a scope with parent.
+ */
+ public JsScope(JsScope parent, String description) {
+ this(parent, description, null);
}
- parent.children = Lists.addAll(parent.children, children);
- for (JsScope child : children) {
- child.parent = newParent;
+
+ /**
+ * Create a scope with parent.
+ */
+ public JsScope(JsScope parent, String description, String scopeId) {
+ assert (parent != null);
+ this.scopeId = scopeId;
+ this.description = description;
+ this.parent = parent;
+ parent.children = Lists.add(parent.children, this);
}
- children = Collections.emptyList();
- }
- /**
- * Subclasses can detach and become parentless.
- */
- protected void detachFromParent() {
- JsScope oldParent = parent;
-
- oldParent.children = Lists.remove(
- parent.children, oldParent.children.indexOf(this));
-
- parent = null;
- }
-
- /**
- * Subclasses can be parentless.
- */
- protected JsScope(String description) {
- this.description = description;
- this.parent = null;
- this.scopeId = null;
- }
-
- /**
- * Gets a name object associated with the specified ident in this scope,
- * creating it if necessary.
- * If the JsName does not exist yet, a new JsName is created. The ident,
- * short name, and original name of the newly created JsName are equal to
- * the given ident.
- *
- * @param ident An identifier that is unique within this scope.
- */
- public JsName declareName(String ident) {
- JsName name = findExistingNameNoRecurse(ident);
- if (name != null) {
- return name;
+ /**
+ * Rebase the function to a new scope.
+ *
+ * @param newParent The scope to add the function to.
+ */
+ public void rebase(JsScope newParent) {
+ detachFromParent();
+ parent = newParent;
+ parent.children = Lists.add(parent.children, this);
}
- return doCreateName(ident, ident, ident);
- }
- /**
- * Creates a new variable with an unique ident in this scope.
- * The generated JsName is guaranteed to have an identifier (but not short
- * name) that does not clash with any existing variables in the scope.
- * Future declarations of variables might however clash with the temporary
- * (unless they use this function).
- */
- public JsName declareFreshName(String shortName) {
- String ident = shortName;
- int counter = 0;
- while (findExistingNameNoRecurse(ident) != null) {
- ident = shortName + "_" + counter++;
+ /**
+ * Rebase the function's children to a new scope.
+ *
+ * @param newParent
+ */
+ public void rebaseChildScopes(JsScope newParent) {
+ if (newParent == this) {
+ return;
+ }
+ parent.children = Lists.addAll(parent.children, children);
+ for (JsScope child : children) {
+ child.parent = newParent;
+ }
+ children = Collections.emptyList();
}
- return doCreateName(ident, shortName, shortName);
- }
- String getNextTempName() {
- // TODO(ngeoffray): Decide on a convention for temporary variables
- // introduced by the compiler.
- return "tmp$" + (scopeId != null ? scopeId + "$" : "") + tempIndex++;
- }
+ /**
+ * Subclasses can detach and become parentless.
+ */
+ protected void detachFromParent() {
+ JsScope oldParent = parent;
- /**
- * Creates a temporary variable with an unique name in this scope.
- * The generated temporary is guaranteed to have an identifier (but not short
- * name) that does not clash with any existing variables in the scope.
- * Future declarations of variables might however clash with the temporary.
- */
- public JsName declareTemporary() {
- return declareFreshName(getNextTempName());
- }
+ oldParent.children = Lists.remove(
+ parent.children, oldParent.children.indexOf(this));
- /**
- * Gets a name object associated with the specified ident in this scope,
- * creating it if necessary.
- * If the JsName does not exist yet, a new JsName is created with the given
- * ident, short name and original name.
- *
- * @param ident An identifier that is unique within this scope.
- * @param shortIdent A "pretty" name that does not have to be unique.
- * @throws IllegalArgumentException if ident already exists in this scope but
- * the requested short name does not match the existing short name.
- */
- public JsName declareName(String ident, String shortIdent) {
- return declareName(ident, shortIdent, ident);
- }
-
- /**
- * Gets a name object associated with the specified ident in this scope,
- * creating it if necessary.
- * If the JsName does not exist yet, a new JsName is created. The original
- * name stored in the JsName is equal to the (unmangled) specified originalName.
- *
- * @param ident An identifier that is unique within this scope.
- * @param shortIdent A "pretty" name that does not have to be unique.
- * @param originalName The original name in the source.
- * @throws IllegalArgumentException if ident already exists in this scope but
- * the requested short name does not match the existing short name,
- * or the original name does not match the existing original name.
- */
- public JsName declareName(String ident, String shortIdent, String originalName) {
- JsName name = findExistingNameNoRecurse(ident);
- if (name != null) {
- if (!name.getShortIdent().equals(shortIdent)
- || !nullableEquals(name.getOriginalName(), originalName)) {
- throw new IllegalArgumentException("Requested short name " + shortIdent
- + " conflicts with preexisting short name " + name.getShortIdent() + " for identifier "
- + ident);
- }
- return name;
+ parent = null;
}
- return doCreateName(ident, shortIdent, originalName);
- }
- boolean nullableEquals(String s1, String s2) {
- return (s1 == null) ? (s2 == null) : s1.equals(s2);
- }
-
- /**
- * Attempts to find the name object for the specified ident, searching in this
- * scope, and if not found, in the parent scopes.
- *
- * @return null if the identifier has no associated name
- */
- public final JsName findExistingName(String ident) {
- JsName name = findExistingNameNoRecurse(ident);
- if (name == null && parent != null) {
- return parent.findExistingName(ident);
+ /**
+ * Subclasses can be parentless.
+ */
+ protected JsScope(String description) {
+ this.description = description;
+ this.parent = null;
+ this.scopeId = null;
}
- return name;
- }
- /**
- * Attempts to find an unobfuscatable name object for the specified ident,
- * searching in this scope, and if not found, in the parent scopes.
- *
- * @return null if the identifier has no associated name
- */
- public final JsName findExistingUnobfuscatableName(String ident) {
- JsName name = findExistingNameNoRecurse(ident);
- if (name != null && name.isObfuscatable()) {
- name = null;
+ /**
+ * Gets a name object associated with the specified ident in this scope,
+ * creating it if necessary.
+ * If the JsName does not exist yet, a new JsName is created. The ident,
+ * short name, and original name of the newly created JsName are equal to
+ * the given ident.
+ *
+ * @param ident An identifier that is unique within this scope.
+ */
+ public JsName declareName(String ident) {
+ JsName name = findExistingNameNoRecurse(ident);
+ if (name != null) {
+ return name;
+ }
+ return doCreateName(ident, ident, ident);
}
- if (name == null && parent != null) {
- return parent.findExistingUnobfuscatableName(ident);
+
+ /**
+ * Creates a new variable with an unique ident in this scope.
+ * The generated JsName is guaranteed to have an identifier (but not short
+ * name) that does not clash with any existing variables in the scope.
+ * Future declarations of variables might however clash with the temporary
+ * (unless they use this function).
+ */
+ public JsName declareFreshName(String shortName) {
+ String ident = shortName;
+ int counter = 0;
+ while (findExistingNameNoRecurse(ident) != null) {
+ ident = shortName + "_" + counter++;
+ }
+ return doCreateName(ident, shortName, shortName);
}
- return name;
- }
- /**
- * Returns an iterator for all the names defined by this scope.
- */
- public Iterator getAllNames() {
- return names.values().iterator();
- }
-
- /**
- * Returns a list of this scope's child scopes.
- */
- public final List getChildren() {
- return children;
- }
-
- /**
- * Returns the parent scope of this scope, or null if this is the
- * root scope.
- */
- public final JsScope getParent() {
- return parent;
- }
-
- /**
- * Returns the associated program.
- */
- public JsProgram getProgram() {
- assert (parent != null) : "Subclasses must override getProgram() if they do not set a parent";
- return parent.getProgram();
- }
-
- @Override
- public final String toString() {
- if (parent != null) {
- return description + "->" + parent;
- } else {
- return description;
+ String getNextTempName() {
+ // TODO(ngeoffray): Decide on a convention for temporary variables
+ // introduced by the compiler.
+ return "tmp$" + (scopeId != null ? scopeId + "$" : "") + tempIndex++;
}
- }
- /**
- * Creates a new name in this scope.
- */
- protected JsName doCreateName(String ident, String shortIdent, String originalName) {
- JsName name = new JsName(this, ident, shortIdent, originalName);
- names = Maps.putOrdered(names, ident, name);
- return name;
- }
+ /**
+ * Creates a temporary variable with an unique name in this scope.
+ * The generated temporary is guaranteed to have an identifier (but not short
+ * name) that does not clash with any existing variables in the scope.
+ * Future declarations of variables might however clash with the temporary.
+ */
+ public JsName declareTemporary() {
+ return declareFreshName(getNextTempName());
+ }
- /**
- * Attempts to find the name object for the specified ident, searching in this
- * scope only.
- *
- * @return null if the identifier has no associated name
- */
- protected JsName findExistingNameNoRecurse(String ident) {
- return names.get(ident);
- }
+ /**
+ * Gets a name object associated with the specified ident in this scope,
+ * creating it if necessary.
+ * If the JsName does not exist yet, a new JsName is created with the given
+ * ident, short name and original name.
+ *
+ * @param ident An identifier that is unique within this scope.
+ * @param shortIdent A "pretty" name that does not have to be unique.
+ * @throws IllegalArgumentException if ident already exists in this scope but
+ * the requested short name does not match the existing short name.
+ */
+ public JsName declareName(String ident, String shortIdent) {
+ return declareName(ident, shortIdent, ident);
+ }
+
+ /**
+ * Gets a name object associated with the specified ident in this scope,
+ * creating it if necessary.
+ * If the JsName does not exist yet, a new JsName is created. The original
+ * name stored in the JsName is equal to the (unmangled) specified originalName.
+ *
+ * @param ident An identifier that is unique within this scope.
+ * @param shortIdent A "pretty" name that does not have to be unique.
+ * @param originalName The original name in the source.
+ * @throws IllegalArgumentException if ident already exists in this scope but
+ * the requested short name does not match the existing short name,
+ * or the original name does not match the existing original name.
+ */
+ public JsName declareName(String ident, String shortIdent, String originalName) {
+ JsName name = findExistingNameNoRecurse(ident);
+ if (name != null) {
+ if (!name.getShortIdent().equals(shortIdent)
+ || !nullableEquals(name.getOriginalName(), originalName)) {
+ throw new IllegalArgumentException("Requested short name " + shortIdent
+ + " conflicts with preexisting short name " + name.getShortIdent() + " for identifier "
+ + ident);
+ }
+ return name;
+ }
+ return doCreateName(ident, shortIdent, originalName);
+ }
+
+ boolean nullableEquals(String s1, String s2) {
+ return (s1 == null) ? (s2 == null) : s1.equals(s2);
+ }
+
+ /**
+ * Attempts to find the name object for the specified ident, searching in this
+ * scope, and if not found, in the parent scopes.
+ *
+ * @return null if the identifier has no associated name
+ */
+ public final JsName findExistingName(String ident) {
+ JsName name = findExistingNameNoRecurse(ident);
+ if (name == null && parent != null) {
+ return parent.findExistingName(ident);
+ }
+ return name;
+ }
+
+ /**
+ * Attempts to find an unobfuscatable name object for the specified ident,
+ * searching in this scope, and if not found, in the parent scopes.
+ *
+ * @return null if the identifier has no associated name
+ */
+ public final JsName findExistingUnobfuscatableName(String ident) {
+ JsName name = findExistingNameNoRecurse(ident);
+ if (name != null && name.isObfuscatable()) {
+ name = null;
+ }
+ if (name == null && parent != null) {
+ return parent.findExistingUnobfuscatableName(ident);
+ }
+ return name;
+ }
+
+ /**
+ * Returns an iterator for all the names defined by this scope.
+ */
+ public Iterator getAllNames() {
+ return names.values().iterator();
+ }
+
+ /**
+ * Returns a list of this scope's child scopes.
+ */
+ public final List getChildren() {
+ return children;
+ }
+
+ /**
+ * Returns the parent scope of this scope, or null if this is the
+ * root scope.
+ */
+ public final JsScope getParent() {
+ return parent;
+ }
+
+ /**
+ * Returns the associated program.
+ */
+ public JsProgram getProgram() {
+ assert (parent != null) : "Subclasses must override getProgram() if they do not set a parent";
+ return parent.getProgram();
+ }
+
+ @Override
+ public final String toString() {
+ if (parent != null) {
+ return description + "->" + parent;
+ } else {
+ return description;
+ }
+ }
+
+ /**
+ * Creates a new name in this scope.
+ */
+ protected JsName doCreateName(String ident, String shortIdent, String originalName) {
+ JsName name = new JsName(this, ident, shortIdent, originalName);
+ names = Maps.putOrdered(names, ident, name);
+ return name;
+ }
+
+ /**
+ * Attempts to find the name object for the specified ident, searching in this
+ * scope only.
+ *
+ * @return null if the identifier has no associated name
+ */
+ public JsName findExistingNameNoRecurse(String ident) {
+ return names.get(ident);
+ }
}
diff --git a/src/org/jetbrains/k2js/translate/DeclarationTranslator.java b/src/org/jetbrains/k2js/translate/DeclarationTranslator.java
index a33885ffce4..3bb19ebdeeb 100644
--- a/src/org/jetbrains/k2js/translate/DeclarationTranslator.java
+++ b/src/org/jetbrains/k2js/translate/DeclarationTranslator.java
@@ -65,8 +65,7 @@ public class DeclarationTranslator extends AbstractTranslator {
public final class FunctionVariableDeclaration extends State {
@NotNull
public JsStatement translateProperty(JetProperty declaration) {
- String propertyName = declaration.getName();
- JsName jsPropertyName = getJSName(propertyName);
+ JsName jsPropertyName = translationContext().declareLocalName(declaration.getName());
JsExpression jsInitExpression = translateInitializer(declaration);
return AstUtil.newVar(jsPropertyName, jsInitExpression);
}
@@ -76,8 +75,9 @@ public class DeclarationTranslator extends AbstractTranslator {
public final class NamespacePropertyDeclaration extends State {
@NotNull
public JsStatement translateProperty(JetProperty declaration) {
- String propertyName = declaration.getName();
- JsNameRef jsPropertyNameReference = translationContext().getNamespaceQualifiedReference(getJSName(propertyName));
+ JsName propertyName = translationContext().declareLocalName(declaration.getName());
+ JsNameRef jsPropertyNameReference =
+ translationContext().getNamespaceQualifiedReference(propertyName);
JsExpression jsInitExpression = translateInitializer(declaration);
JsExpression result;
if (jsInitExpression != null) {
diff --git a/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
index 854798ba96e..a1a89bd3fbd 100644
--- a/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
+++ b/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
@@ -5,6 +5,7 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.resolve.calls.ExpressionValueArgument;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lexer.JetToken;
@@ -39,10 +40,11 @@ public class ExpressionVisitor extends K2JsVisitor {
public JsNode visitBlockExpression(JetBlockExpression jetBlock, TranslationContext context) {
List jetElements = jetBlock.getStatements();
JsBlock jsBlock = new JsBlock();
+ TranslationContext newContext = context.newBlock();
for (JetElement jetElement : jetElements) {
//TODO hack alert
JetExpression jetExpression = (JetExpression) jetElement;
- JsNode jsNode = jetExpression.accept(this, context.newBlock());
+ JsNode jsNode = jetExpression.accept(this, newContext);
jsBlock.addStatement(AstUtil.convertToStatement(jsNode));
}
assert jsBlock != null;
@@ -79,15 +81,24 @@ public class ExpressionVisitor extends K2JsVisitor {
return jsBinaryOperation;
}
+ //TODO think about recursive/non-recursive name look-up
@Override
@NotNull
public JsNode visitSimpleNameExpression(JetSimpleNameExpression expression, TranslationContext context) {
String referencedName = expression.getReferencedName();
- if (context.enclosingScope().findExistingName(referencedName) == null) {
- JsName name = context.enclosingScope().declareName(referencedName);
- return name.makeRef();
+ JsName jsName = context.enclosingScope().findExistingNameNoRecurse(referencedName);
+ if (jsName != null) {
+ return jsName.makeRef();
}
- return context.getNamespaceQualifiedReference(context.getJSName(referencedName));
+ jsName = context.functionScope().findExistingNameNoRecurse(referencedName);
+ if (jsName != null) {
+ return context.getNamespaceQualifiedReference(jsName);
+ }
+ jsName = context.namespaceScope().findExistingNameNoRecurse(referencedName);
+ if (jsName != null) {
+ return context.getNamespaceQualifiedReference(jsName);
+ }
+ throw new AssertionError("Unindentified name " + expression.getReferencedName());
}
@Override
@@ -101,7 +112,7 @@ public class ExpressionVisitor extends K2JsVisitor {
@NotNull
public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) {
JsExpression callee = getCallee(expression, context);
- List arguments = generateArgumentList(expression.getFunctionLiteralArguments(), context);
+ List arguments = generateArgumentList(expression.getValueArguments(), context);
return AstUtil.newInvocation(callee, arguments);
}
@@ -112,9 +123,10 @@ public class ExpressionVisitor extends K2JsVisitor {
}
@NotNull
- private List generateArgumentList(List jetArguments, TranslationContext context) {
+ private List generateArgumentList(List extends ValueArgument> jetArguments, TranslationContext context) {
List jsArguments = new ArrayList();
- for (JetExpression jetExpression : jetArguments) {
+ for (ValueArgument argument : jetArguments) {
+ JetExpression jetExpression = argument.getArgumentExpression();
jsArguments.add(AstUtil.convertToExpression(jetExpression.accept(this, context)));
}
return jsArguments;
diff --git a/src/org/jetbrains/k2js/translate/FunctionTranslator.java b/src/org/jetbrains/k2js/translate/FunctionTranslator.java
index 9eba740dcc6..e1096e981b4 100644
--- a/src/org/jetbrains/k2js/translate/FunctionTranslator.java
+++ b/src/org/jetbrains/k2js/translate/FunctionTranslator.java
@@ -21,9 +21,10 @@ public class FunctionTranslator extends AbstractTranslator {
@NotNull
public JsStatement translateFunction(JetNamedFunction jetFunction) {
- JsNameRef functionName = translationContext().getNamespaceQualifiedReference(getJSName(jetFunction.getName()));
+ JsName functionName = translationContext().namespaceScope().declareFreshName(jetFunction.getName());
JsFunction function = generateFunctionObject(jetFunction);
- return AstUtil.convertToStatement(AstUtil.newAssignment(functionName, function));
+ return AstUtil.convertToStatement(AstUtil.newAssignment
+ (translationContext().getNamespaceQualifiedReference(functionName), function));
}
private JsFunction generateFunctionObject(JetNamedFunction jetFunction) {
diff --git a/src/org/jetbrains/k2js/translate/TranslationContext.java b/src/org/jetbrains/k2js/translate/TranslationContext.java
index f75c262bb9e..661cfc3f571 100644
--- a/src/org/jetbrains/k2js/translate/TranslationContext.java
+++ b/src/org/jetbrains/k2js/translate/TranslationContext.java
@@ -25,11 +25,7 @@ public class TranslationContext {
public Scopes(JsScope enclosing, JsScope function, JsScope namespace) {
this.enclosingScope = enclosing;
this.functionScope = function;
- this.namespaceScope = function;
- }
-
- public Scopes(Scopes other) {
- this(other.enclosingScope, other.functionScope, other.namespaceScope);
+ this.namespaceScope = namespace;
}
public final JsScope enclosingScope;
@@ -42,7 +38,6 @@ public class TranslationContext {
assert program != null;
assert bindingContext != null;
assert scopes != null;
- assert currentNamespace != null;
assert type != null;
this.program = program;
this.bindingContext = bindingContext;
@@ -59,7 +54,6 @@ public class TranslationContext {
program, bindingContext, scopes, ContextType.NAMESPACE_BODY);
}
- //TODO implement correct factories
@NotNull
public TranslationContext newNamespace(JsName namespaceName, JsFunction namespaceDummyFunction) {
JsScope newScope = namespaceDummyFunction.getScope();
@@ -112,6 +106,21 @@ public class TranslationContext {
return scopes.enclosingScope;
}
+ @NotNull
+ JsScope namespaceScope() {
+ return scopes.namespaceScope;
+ }
+
+ @NotNull
+ JsScope functionScope() {
+ return scopes.functionScope;
+ }
+
+ @NotNull
+ JsName declareLocalName(String name) {
+ return scopes.enclosingScope.declareFreshName(name);
+ }
+
@NotNull
ContextType type() {
return type;
diff --git a/test/org/jetbrains/k2js/test/TranslatorTests.java b/test/org/jetbrains/k2js/test/TranslatorTests.java
index eea79046209..fa2e794097f 100644
--- a/test/org/jetbrains/k2js/test/TranslatorTests.java
+++ b/test/org/jetbrains/k2js/test/TranslatorTests.java
@@ -45,6 +45,8 @@ public class TranslatorTests {
Object functionArgs[] = {};
Function function = (Function) box;
Object result = function.call(cx, scope, scope, functionArgs);
+ assertTrue(result instanceof Boolean);
+ assertTrue((Boolean)result == true);
String report = "foo.box() = " + Context.toString(result);
System.out.println(report);
diff --git a/test_files/test_cases/test.kt b/test_files/test_cases/test.kt
index be2f39a55cc..98ee81ba1ea 100644
--- a/test_files/test_cases/test.kt
+++ b/test_files/test_cases/test.kt
@@ -5,4 +5,5 @@ fun box() : Boolean {
val b = 3;
var c = 4;
return (a < c)
-}
\ No newline at end of file
+}
+