diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index c6da240ed7f..a81f110c286 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -6,15 +6,17 @@
-
-
+
+
+
-
+
+
+
-
@@ -39,7 +41,7 @@
-
+
@@ -92,13 +94,13 @@
-
+
-
-
+
+
-
+
@@ -109,52 +111,56 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
@@ -163,26 +169,28 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
+
+
@@ -191,10 +199,10 @@
-
+
-
+
@@ -202,24 +210,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -250,7 +240,7 @@
-
+
@@ -272,7 +262,29 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -305,22 +317,22 @@
@@ -381,24 +393,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -548,7 +542,7 @@
-
+
@@ -788,7 +782,7 @@
-
+
@@ -804,7 +798,7 @@
-
+
@@ -842,7 +836,7 @@
-
+
@@ -863,6 +857,7 @@
+
@@ -872,90 +867,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -964,34 +988,13 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/js/src/com/google/dart/compiler/backend/js/ast/JsFunction.java b/js/src/com/google/dart/compiler/backend/js/ast/JsFunction.java
index 4563ca58bec..f2c7d258791 100644
--- a/js/src/com/google/dart/compiler/backend/js/ast/JsFunction.java
+++ b/js/src/com/google/dart/compiler/backend/js/ast/JsFunction.java
@@ -14,211 +14,225 @@ import java.util.List;
*/
public final class JsFunction extends JsLiteral implements HasName {
- private static void trace(String title, String code) {
- System.out.println("---------------------------");
- System.out.println(title + ":");
- System.out.println("---------------------------");
- System.out.println(code);
- }
+ private static void trace(String title, String code) {
+ System.out.println("---------------------------");
+ System.out.println(title + ":");
+ System.out.println("---------------------------");
+ System.out.println(code);
+ }
- protected JsBlock body;
- protected final List params = new ArrayList();
- protected final JsScope scope;
- private boolean artificiallyRescued;
- private boolean executeOnce;
- private boolean fromDart;
- private JsFunction impliedExecute;
- private JsName name;
- private boolean trace = false;
- private boolean traceFirst = true;
- private boolean hoisted = false;
- private boolean constructor = false;
+ protected JsBlock body;
+ protected final List params = new ArrayList();
+ protected final JsScope scope;
+ private boolean artificiallyRescued;
+ private boolean executeOnce;
+ private boolean fromDart;
+ private JsFunction impliedExecute;
+ private JsName name;
+ private boolean trace = false;
+ private boolean traceFirst = true;
+ private boolean hoisted = false;
+ private boolean constructor = false;
- /**
- * Creates an anonymous function.
- */
- public JsFunction(JsScope parent) {
- this(parent, null, false);
- }
+ /**
+ * Creates an anonymous function.
+ */
+ public JsFunction(JsScope parent) {
+ this(parent, null, false);
+ }
- /**
- * Creates a function that is not derived from Dart source.
- */
- public JsFunction(JsScope parent, JsName name) {
- this(parent, name, false);
- }
+ /**
+ * Creates a function that is not derived from Dart source.
+ */
+ public JsFunction(JsScope parent, JsName name) {
+ this(parent, name, false);
+ }
- /**
- * Creates a named function, possibly derived from Dart source.
- */
- public JsFunction(JsScope parent, JsName name, boolean fromDart) {
- assert (parent != null);
- this.fromDart = fromDart;
- setName(name);
- String scopeName = (name == null) ? "" : name.getIdent();
- scopeName = "function " + scopeName;
- this.scope = new JsScope(parent, scopeName);
- }
+ /**
+ * Creates a named function, possibly derived from Dart source.
+ */
+ public JsFunction(JsScope parent, JsName name, boolean fromDart) {
+ assert (parent != null);
+ this.fromDart = fromDart;
+ setName(name);
+ String scopeName = (name == null) ? "" : name.getIdent();
+ scopeName = "function " + scopeName;
+ this.scope = new JsScope(parent, scopeName);
+ }
- public JsBlock getBody() {
- return body;
- }
+ public JsBlock getBody() {
+ return body;
+ }
- /**
- * If true, this indicates that only the first invocation of the function will
- * have any effects. Subsequent invocations may be considered to be no-op
- * calls whose return value is ignored.
- */
- public boolean getExecuteOnce() {
- return executeOnce;
- }
+ /**
+ * If true, this indicates that only the first invocation of the function will
+ * have any effects. Subsequent invocations may be considered to be no-op
+ * calls whose return value is ignored.
+ */
+ public boolean getExecuteOnce() {
+ return executeOnce;
+ }
- public JsFunction getImpliedExecute() {
- return impliedExecute;
- }
+ public JsFunction getImpliedExecute() {
+ return impliedExecute;
+ }
- @Override
- public JsName getName() {
- return name;
- }
+ @Override
+ public JsName getName() {
+ return name;
+ }
public void setParameters(List params) {
this.params.clear();
this.params.addAll(params);
}
- public List getParameters() {
- return params;
- }
-
- public JsScope getScope() {
- return scope;
- }
-
- @Override
- public boolean hasSideEffects() {
- // If there's a name, the name is assigned to.
- return name != null;
- }
-
- public boolean isArtificiallyRescued() {
- return artificiallyRescued;
- }
-
- @Override
- public boolean isBooleanFalse() {
- return false;
- }
-
- @Override
- public boolean isBooleanTrue() {
- return true;
- }
-
- @Override
- public boolean isDefinitelyNotNull() {
- return true;
- }
-
- @Override
- public boolean isDefinitelyNull() {
- return false;
- }
-
- public boolean isFromDart() {
- return fromDart;
- }
-
- public void setArtificiallyRescued(boolean rescued) {
- this.artificiallyRescued = rescued;
- }
-
- public void setBody(JsBlock body) {
- this.body = body;
- }
-
- public void setExecuteOnce(boolean executeOnce) {
- this.executeOnce = executeOnce;
- }
-
- public void setFromDart(boolean fromDart) {
- this.fromDart = fromDart;
- }
-
- public void setImpliedExecute(JsFunction impliedExecute) {
- this.impliedExecute = impliedExecute;
- }
-
- public void setName(JsName name) {
- this.name = name;
- if (name != null) {
- if (isFromDart()) {
- name.setStaticRef(this);
- }
+ public List getParameters() {
+ return params;
}
- }
- public void setTrace() {
- this.trace = true;
- }
-
- @Override
- public void traverse(JsVisitor v, JsContext ctx) {
- String before = null;
- if (trace && v instanceof JsModVisitor) {
- before = this.toSource();
- if (traceFirst) {
- traceFirst = false;
- trace("SCRIPT INITIAL", before);
- }
+ public JsScope getScope() {
+ return scope;
}
- if (v.visit(this, ctx)) {
- v.acceptWithInsertRemove(params);
- body = v.accept(body);
+
+ @Override
+ public boolean hasSideEffects() {
+ // If there's a name, the name is assigned to.
+ return name != null;
}
- v.endVisit(this, ctx);
- if (trace && v instanceof JsModVisitor) {
- String after = this.toSource();
- if (!after.equals(before)) {
- String title = v.getClass().getSimpleName();
- trace(title, after);
- }
+
+ public boolean isArtificiallyRescued() {
+ return artificiallyRescued;
}
- }
- public void setHoisted() {
- hoisted = true;
- }
+ @Override
+ public boolean isBooleanFalse() {
+ return false;
+ }
- /** Whether the function has been hoisted */
- public boolean isHoisted() {
- return hoisted;
- }
+ @Override
+ public boolean isBooleanTrue() {
+ return true;
+ }
- /**
- * Rebase the function to a new scope.
- * @param newScopeParent The scope to add the function to.
- */
- public void rebaseScope(JsScope newScopeParent) {
- this.scope.rebase(newScopeParent);
- }
+ @Override
+ public boolean isDefinitelyNotNull() {
+ return true;
+ }
- @Override
- public JsFunction setSourceRef(SourceInfo info) {
- super.setSourceRef(info);
- return this;
- }
+ @Override
+ public boolean isDefinitelyNull() {
+ return false;
+ }
- public boolean isConstructor() {
- return this.constructor;
- }
+ public boolean isFromDart() {
+ return fromDart;
+ }
- public boolean setIsConstructor(boolean constructor) {
- return this.constructor = constructor;
- }
+ public void setArtificiallyRescued(boolean rescued) {
+ this.artificiallyRescued = rescued;
+ }
- @Override
- public NodeKind getKind() {
- return NodeKind.FUNCTION;
- }
+ public void setBody(JsBlock body) {
+ this.body = body;
+ }
+
+ public void setExecuteOnce(boolean executeOnce) {
+ this.executeOnce = executeOnce;
+ }
+
+ public void setFromDart(boolean fromDart) {
+ this.fromDart = fromDart;
+ }
+
+ public void setImpliedExecute(JsFunction impliedExecute) {
+ this.impliedExecute = impliedExecute;
+ }
+
+ public void setName(JsName name) {
+ this.name = name;
+ if (name != null) {
+ if (isFromDart()) {
+ name.setStaticRef(this);
+ }
+ }
+ }
+
+ public void setTrace() {
+ this.trace = true;
+ }
+
+ @Override
+ public void traverse(JsVisitor v, JsContext ctx) {
+ String before = null;
+ if (trace && v instanceof JsModVisitor) {
+ before = this.toSource();
+ if (traceFirst) {
+ traceFirst = false;
+ trace("SCRIPT INITIAL", before);
+ }
+ }
+ if (v.visit(this, ctx)) {
+ v.acceptWithInsertRemove(params);
+ body = v.accept(body);
+ }
+ v.endVisit(this, ctx);
+ if (trace && v instanceof JsModVisitor) {
+ String after = this.toSource();
+ if (!after.equals(before)) {
+ String title = v.getClass().getSimpleName();
+ trace(title, after);
+ }
+ }
+ }
+
+ public void setHoisted() {
+ hoisted = true;
+ }
+
+ /**
+ * Whether the function has been hoisted
+ */
+ public boolean isHoisted() {
+ return hoisted;
+ }
+
+ /**
+ * Rebase the function to a new scope.
+ *
+ * @param newScopeParent The scope to add the function to.
+ */
+ public void rebaseScope(JsScope newScopeParent) {
+ this.scope.rebase(newScopeParent);
+ }
+
+ @Override
+ public JsFunction setSourceRef(SourceInfo info) {
+ super.setSourceRef(info);
+ return this;
+ }
+
+ public boolean isConstructor() {
+ return this.constructor;
+ }
+
+ public boolean setIsConstructor(boolean constructor) {
+ return this.constructor = constructor;
+ }
+
+ @Override
+ public NodeKind getKind() {
+ return NodeKind.FUNCTION;
+ }
+
+ // Pavel Talanov
+ // dummy parameter to distinguish from other constructors
+ private JsFunction(Void dummy, JsScope functionScope) {
+ this.fromDart = false;
+ this.scope = functionScope;
+ }
+
+ public static JsFunction getAnonymousFunctionWithScope(JsScope scope) {
+ return new JsFunction(null, scope);
+ }
}
diff --git a/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java b/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java
new file mode 100644
index 00000000000..e49124a4590
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/declarations/DeclarationExtractor.java
@@ -0,0 +1,36 @@
+package org.jetbrains.k2js.declarations;
+
+import com.google.dart.compiler.backend.js.ast.JsScope;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Talanov Pavel
+ */
+public final class DeclarationExtractor {
+ private final Map descriptorToScopeMap
+ = new HashMap();
+
+ public DeclarationExtractor() {
+
+ }
+
+ public void extractDeclarations(@NotNull DeclarationDescriptor descriptor, JsScope rootScope) {
+ ExtractionVisitor visitor = new ExtractionVisitor(this);
+ descriptor.accept(visitor, rootScope);
+ }
+
+ @NotNull
+ public JsScope getScope(@NotNull DeclarationDescriptor descriptor) {
+ JsScope scope = descriptorToScopeMap.get(descriptor);
+ assert scope != null : "Unknown declaration";
+ return scope;
+ }
+
+ /*package*/ void put(@NotNull DeclarationDescriptor descriptor, @NotNull JsScope scope) {
+ descriptorToScopeMap.put(descriptor, scope);
+ }
+}
diff --git a/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java b/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java
new file mode 100644
index 00000000000..c69cc8f0f17
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/declarations/ExtractionVisitor.java
@@ -0,0 +1,65 @@
+package org.jetbrains.k2js.declarations;
+
+import com.google.dart.compiler.backend.js.ast.JsName;
+import com.google.dart.compiler.backend.js.ast.JsScope;
+import com.intellij.codeInspection.ex.Descriptor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.descriptors.*;
+import org.jetbrains.k2js.translate.Namer;
+
+/**
+ * @author Talanov Pavel
+ */
+public final class ExtractionVisitor extends DeclarationDescriptorVisitor {
+
+ @NotNull private final DeclarationExtractor extractor;
+
+ /*package*/ ExtractionVisitor(@NotNull DeclarationExtractor extractor) {
+ this.extractor = extractor;
+ }
+
+
+ @Override
+ public Void visitClassDescriptor(ClassDescriptor descriptor, JsScope enclosingScope) {
+ String className = descriptor.getName();
+ enclosingScope.declareName(className);
+ JsScope classScope = new JsScope(enclosingScope, "Scope for class " + className);
+ extractor.put(descriptor, classScope);
+ for (DeclarationDescriptor memberDescriptor :
+ descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
+ memberDescriptor.accept(this, classScope);
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitFunctionDescriptor(FunctionDescriptor descriptor, JsScope enclosingScope) {
+ String functionName = descriptor.getName();
+ enclosingScope.declareName(functionName);
+ JsScope functionScope = new JsScope(enclosingScope, "Scope for function " + functionName);
+ extractor.put(descriptor, functionScope);
+ return null;
+ }
+
+ @Override
+ public Void visitPropertyDescriptor(PropertyDescriptor descriptor, JsScope enclosingScope) {
+ String propertyName = descriptor.getName();
+ enclosingScope.declareName(Namer.getNameForSetter(propertyName));
+ enclosingScope.declareName(Namer.getNameForGetter(propertyName));
+ return null;
+ }
+
+ @Override
+ public Void visitNamespaceDescriptor(NamespaceDescriptor descriptor, JsScope enclosingScope) {
+ String namespaceName = descriptor.getName();
+ enclosingScope.declareName(namespaceName);
+ JsScope namespaceScope = new JsScope(enclosingScope, "Scope for namespace " + namespaceName);
+ extractor.put(descriptor, namespaceScope);
+ for (DeclarationDescriptor memberDescriptor :
+ descriptor.getMemberScope().getAllDescriptors()) {
+ memberDescriptor.accept(this, namespaceScope);
+ }
+ return null;
+ }
+
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java
new file mode 100644
index 00000000000..0b49e75e897
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java
@@ -0,0 +1,54 @@
+package org.jetbrains.k2js.translate;
+
+import com.intellij.codeInsight.hint.ClassDeclarationRangeHandler;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
+import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
+import org.jetbrains.jet.lang.psi.JetClass;
+import org.jetbrains.jet.lang.psi.JetNamedFunction;
+import org.jetbrains.jet.lang.psi.JetNamespace;
+import org.jetbrains.jet.lang.resolve.BindingContext;
+
+import javax.xml.ws.Binding;
+
+/**
+ * @author Talanov Pavel
+ *
+ * This class contains some code related to BindingContext use. Intention is not to pollute other classes.
+ */
+public final class BindingUtils {
+ private BindingUtils() {}
+
+ //TODO generalise methods?
+ @NotNull
+ static public ClassDescriptor getClassDescriptor(@NotNull BindingContext context, @NotNull JetClass declaration) {
+ DeclarationDescriptor descriptor
+ = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
+ assert descriptor instanceof ClassDescriptor : "Class should have a descriptor" +
+ " of type ClassDescriptor";
+ return (ClassDescriptor)descriptor;
+ }
+
+ @NotNull
+ static public NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
+ @NotNull JetNamespace declaration) {
+ DeclarationDescriptor descriptor
+ = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
+ assert descriptor instanceof NamespaceDescriptor : "Namespace should have a descriptor" +
+ " of type NamespaceDescriptor";
+ return (NamespaceDescriptor)descriptor;
+ }
+
+ @NotNull
+ static public FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
+ @NotNull JetNamedFunction declaration) {
+ DeclarationDescriptor descriptor =
+ context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
+ assert descriptor instanceof FunctionDescriptor : "JetNamedFunction should have" +
+ " descriptor of type FunctionDescriptor.";
+ return (FunctionDescriptor)descriptor;
+ }
+
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/ClassTranslator.java b/translator/src/org/jetbrains/k2js/translate/ClassTranslator.java
index 4bcf939bb6f..e92007db439 100644
--- a/translator/src/org/jetbrains/k2js/translate/ClassTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/ClassTranslator.java
@@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType;
import java.util.ArrayList;
@@ -46,7 +47,8 @@ public final class ClassTranslator extends AbstractTranslator {
private JsObjectLiteral translateClassDeclarations(JetClass classDeclaration) {
List propertyList = new ArrayList();
propertyList.add(generateInitializeMethod(classDeclaration));
- propertyList.addAll(classDeclaration.accept(classBodyVisitor, translationContext().newClass()));
+ propertyList.addAll(classDeclaration.accept(classBodyVisitor,
+ translationContext().newClass(classDeclaration)));
return new JsObjectLiteral(propertyList);
}
diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
index ba049aac277..1de62d25e08 100644
--- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
+++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
@@ -276,6 +276,7 @@ public final class ExpressionVisitor extends TranslatorVisitor {
return null;
}
+ //TODO method too long
@Override
@NotNull
public JsNode visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression,
diff --git a/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java b/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java
index 69247208b79..3e9571b48b8 100644
--- a/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java
@@ -3,10 +3,14 @@ package org.jetbrains.k2js.translate;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import com.sun.istack.internal.NotNull;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.psi.JetParameter;
+import org.jetbrains.jet.lang.resolve.BindingContext;
+import javax.xml.ws.Binding;
import java.util.ArrayList;
import java.util.List;
@@ -36,8 +40,9 @@ public final class FunctionTranslator extends AbstractTranslator {
@NotNull
private JsFunction generateFunctionObject(@NotNull JetNamedFunction jetFunction) {
JetExpression jetBodyExpression = jetFunction.getBodyExpression();
- JsFunction result = new JsFunction(scope());
- JsNode jsBody = (new ExpressionTranslator(functionBodyContext(result)))
+ JsFunction result = JsFunction.getAnonymousFunctionWithScope
+ (translationContext().getScopeForElement(jetFunction));
+ JsNode jsBody = (new ExpressionTranslator(functionContext(jetFunction)))
.translate(jetBodyExpression);
List jsParameters = translateParameters(jetFunction.getValueParameters(), result.getScope());
result.setParameters(jsParameters);
@@ -46,8 +51,10 @@ public final class FunctionTranslator extends AbstractTranslator {
}
@NotNull
- private TranslationContext functionBodyContext(@NotNull JsFunction function) {
- return translationContext().newFunction(function);
+ private TranslationContext functionContext(@NotNull JetNamedFunction jetFunction) {
+ FunctionDescriptor descriptor =
+ BindingUtils.getFunctionDescriptor(translationContext().bindingContext(), jetFunction);
+ return translationContext().newFunction(descriptor);
}
@NotNull
diff --git a/translator/src/org/jetbrains/k2js/translate/GenerationState.java b/translator/src/org/jetbrains/k2js/translate/GenerationState.java
index 4b44c0d0948..1e7d89bc9a3 100644
--- a/translator/src/org/jetbrains/k2js/translate/GenerationState.java
+++ b/translator/src/org/jetbrains/k2js/translate/GenerationState.java
@@ -6,12 +6,18 @@ package org.jetbrains.k2js.translate;
import com.google.dart.compiler.backend.js.ast.JsProgram;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
+import org.jetbrains.k2js.declarations.DeclarationExtractor;
+import javax.print.attribute.standard.MediaSize;
+import javax.xml.ws.Binding;
+import java.beans.beancontext.BeanContext;
import java.util.Collections;
import java.util.List;
@@ -21,19 +27,19 @@ public final class GenerationState {
public GenerationState() {
}
-// public void compile(JetFile psiFile) {
-// final JetNamespace namespace = psiFile.getRootNamespace();
-// final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
-// AnalyzingUtils.throwExceptionOnErrors(bindingContext);
-// compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace));
-// }
-
+ //TODO method too long
public JsProgram compileCorrectNamespaces(BindingContext bindingContext, List namespaces) {
//TODO hardcoded
JsProgram result = new JsProgram("main");
JetNamespace namespace = namespaces.get(0);
- (new NamespaceTranslator(TranslationContext.rootContext(result, bindingContext))).generateAst(namespace);
+ NamespaceDescriptor descriptor = BindingUtils.getNamespaceDescriptor(bindingContext, namespace);
+ DeclarationExtractor extractor = new DeclarationExtractor();
+ extractor.extractDeclarations(descriptor, result.getRootScope());
+ (new NamespaceTranslator(TranslationContext.rootContext(result, bindingContext, extractor)))
+ .generateAst(namespace);
return result;
}
+
+
}
diff --git a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java b/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java
index 14eb987582e..e8c79d15cf6 100644
--- a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java
@@ -23,14 +23,16 @@ public final class NamespaceTranslator extends AbstractTranslator {
return program();
}
+ //TODO logic unclear
@NotNull
public JsBlock translate(@NotNull JetNamespace namespace) {
// TODO support multiple namespaces
JsBlock block = program().getFragmentBlock(0);
JsName namespaceName = scope().declareName(Namer.getNameForNamespace(namespace.getName()));
block.addStatement(namespaceInitStatement(namespaceName));
- JsFunction dummyFunction = new JsFunction(scope());
- TranslationContext newContext = translationContext().newNamespace(namespaceName, dummyFunction);
+ TranslationContext newContext = translationContext().newNamespace(namespace);
+ JsFunction dummyFunction = JsFunction.getAnonymousFunctionWithScope
+ (translationContext().getScopeForElement(namespace));
JsBlock namespaceDeclarations = translateDeclarations(namespace, newContext);
block.addStatement(AstUtil.convertToStatement(newNamespace(namespaceName, namespaceDeclarations, dummyFunction)));
return block;
diff --git a/translator/src/org/jetbrains/k2js/translate/TranslationContext.java b/translator/src/org/jetbrains/k2js/translate/TranslationContext.java
index 9380ff5777d..056f3c7f847 100644
--- a/translator/src/org/jetbrains/k2js/translate/TranslationContext.java
+++ b/translator/src/org/jetbrains/k2js/translate/TranslationContext.java
@@ -4,7 +4,16 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
+import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
+import org.jetbrains.jet.lang.psi.JetClass;
+import org.jetbrains.jet.lang.psi.JetElement;
+import org.jetbrains.jet.lang.psi.JetNamedFunction;
+import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.k2js.declarations.DeclarationExtractor;
/**
* @author Talanov Pavel
@@ -25,64 +34,79 @@ public final class TranslationContext {
}
@NotNull
- public static TranslationContext rootContext(JsProgram program, BindingContext bindingContext) {
+ public static TranslationContext rootContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
+ @NotNull DeclarationExtractor extractor) {
JsScope rootScope = program.getRootScope();
Scopes scopes = new Scopes(rootScope, rootScope, rootScope);
- return new TranslationContext(null,
- program, bindingContext, scopes);
+ return new TranslationContext(null, program, bindingContext, scopes, extractor);
}
@NotNull private final JsProgram program;
@NotNull private final BindingContext bindingContext;
@NotNull private final Scopes scopes;
- @Nullable private final JsName currentNamespace;
+ @Nullable private final JsName namespaceName;
+ @NotNull private final DeclarationExtractor extractor;
- private TranslationContext(@Nullable JsName currentNamespace, @NotNull JsProgram program,
- @NotNull BindingContext bindingContext, @NotNull Scopes scopes) {
+ private TranslationContext(@Nullable JsName namespaceName, @NotNull JsProgram program,
+ @NotNull BindingContext bindingContext, @NotNull Scopes scopes,
+ @NotNull DeclarationExtractor extractor) {
this.program = program;
this.bindingContext = bindingContext;
- this.currentNamespace = currentNamespace;
+ this.namespaceName = namespaceName;
this.scopes = scopes;
+ this.extractor = extractor;
}
@NotNull
- public TranslationContext newNamespace(@NotNull JsName namespaceName, @NotNull JsFunction namespaceDummyFunction) {
- JsScope newScope = namespaceDummyFunction.getScope();
- Scopes newScopes = new Scopes(newScope, newScope, newScope);
- return new TranslationContext(namespaceName, program,
- bindingContext, newScopes);
+ public TranslationContext newNamespace(@NotNull JetNamespace declaration) {
+ return newNamespace(BindingUtils.getNamespaceDescriptor(bindingContext, declaration));
+ }
+
+ @NotNull
+ public TranslationContext newNamespace(@NotNull NamespaceDescriptor descriptor) {
+ JsScope namespaceScope = extractor.getScope(descriptor);
+ JsName namespaceName = scopes.enclosingScope.findExistingName(descriptor.getName());
+ Scopes newScopes = new Scopes(namespaceScope, namespaceScope, namespaceScope);
+ return new TranslationContext(namespaceName, program, bindingContext, newScopes, extractor);
}
@NotNull
public TranslationContext newBlock() {
Scopes newScopes = new Scopes(new JsScope
(scopes.enclosingScope, "Scope for a block"), scopes.classScope, scopes.namespaceScope);
- return new TranslationContext(currentNamespace, program,
- bindingContext, newScopes);
+ return new TranslationContext(namespaceName, program, bindingContext, newScopes, extractor);
}
@NotNull
- public TranslationContext newClass() {
- JsScope classDummyScope = new JsScope(namespaceScope(), "Scope for a class");
- Scopes newScopes = new Scopes(classDummyScope, classDummyScope, scopes.namespaceScope);
- return new TranslationContext(currentNamespace, program,
- bindingContext, newScopes);
+ TranslationContext newClass(@NotNull JetClass declaration) {
+ return newClass(BindingUtils.getClassDescriptor(bindingContext, declaration));
}
@NotNull
- public TranslationContext newFunction(@NotNull JsFunction function) {
- JsScope functionScope = function.getScope();
+ public TranslationContext newClass(@NotNull ClassDescriptor descriptor) {
+ JsScope classScope = extractor.getScope(descriptor);
+ Scopes newScopes = new Scopes(classScope, classScope, scopes.namespaceScope);
+ return new TranslationContext(namespaceName, program, bindingContext, newScopes, extractor);
+ }
+
+ @NotNull
+ TranslationContext newFunction(@NotNull JetNamedFunction declaration) {
+ return newFunction(BindingUtils.getFunctionDescriptor(bindingContext, declaration));
+ }
+
+ @NotNull
+ public TranslationContext newFunction(@NotNull FunctionDescriptor descriptor) {
+ JsScope functionScope = extractor.getScope(descriptor);
Scopes newScopes = new Scopes(functionScope, scopes.classScope, scopes.namespaceScope);
- return new TranslationContext(currentNamespace, program,
- bindingContext, newScopes);
+ return new TranslationContext(namespaceName, program, bindingContext, newScopes, extractor);
}
@NotNull
public JsNameRef getNamespaceQualifiedReference(JsName name) {
- if (currentNamespace != null) {
- return AstUtil.newNameRef(currentNamespace.makeRef(), name);
+ if (namespaceName != null) {
+ return AstUtil.newNameRef(namespaceName.makeRef(), name);
}
return new JsNameRef(name);
}
@@ -98,22 +122,34 @@ public final class TranslationContext {
}
@NotNull
- JsScope enclosingScope() {
+ public JsScope enclosingScope() {
return scopes.enclosingScope;
}
@NotNull
- JsScope namespaceScope() {
+ public JsScope namespaceScope() {
return scopes.namespaceScope;
}
@NotNull
- JsScope classScope() {
+ public JsScope classScope() {
return scopes.classScope;
}
@NotNull
- JsName declareLocalName(@NotNull String name) {
+ public JsName declareLocalName(@NotNull String name) {
return scopes.enclosingScope.declareFreshName(name);
}
+
+ @NotNull
+ public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
+ return extractor.getScope(descriptor);
+ }
+
+ @NotNull
+ public JsScope getScopeForElement(@NotNull JetElement element) {
+ DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
+ assert descriptor != null : "Element should have a descriptor";
+ return getScopeForDescriptor(descriptor);
+ }
}