Support a simple case with nested namespaces.

This commit is contained in:
Pavel V. Talanov
2012-03-15 22:26:59 +04:00
parent 452bbdce4d
commit ff3c0a20a0
7 changed files with 95 additions and 61 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.k2js.translate.declaration;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
@@ -150,10 +151,10 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
}
@NotNull
public JsObjectLiteral classDeclarationsForNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
JsObjectLiteral result = new JsObjectLiteral();
public List<JsPropertyInitializer> classDeclarationsForNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
List<JsPropertyInitializer> result = Lists.newArrayList();
for (ClassDescriptor classDescriptor : getAllClassesDefinedInNamespace(namespaceDescriptor)) {
result.getPropertyInitializers().add(getClassNameToClassObject(classDescriptor));
result.add(getClassNameToClassObject(classDescriptor));
}
return result;
}
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import java.util.List;
import java.util.Set;
@@ -90,10 +91,8 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
private List<NamespaceTranslator> getTranslatorsForNonEmptyNamespaces() {
List<NamespaceTranslator> namespaceTranslators = Lists.newArrayList();
for (NamespaceDescriptor descriptor : namespaceDescriptors) {
NamespaceTranslator namespaceTranslator =
new NamespaceTranslator(descriptor, classDeclarationTranslator, context());
if (!namespaceTranslator.isNamespaceEmpty()) {
namespaceTranslators.add(namespaceTranslator);
if (!DescriptorUtils.isNamespaceEmpty(descriptor)) {
namespaceTranslators.add(new NamespaceTranslator(descriptor, classDeclarationTranslator, context()));
}
}
return namespaceTranslators;
@@ -16,6 +16,7 @@
package org.jetbrains.k2js.translate.declaration;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
@@ -24,7 +25,7 @@ import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import java.util.ArrayList;
import java.util.List;
@@ -54,12 +55,6 @@ public final class NamespaceTranslator extends AbstractTranslator {
this.classDeclarationTranslator = classDeclarationTranslator;
}
//TODO: at the moment this check is very ineffective, possible solution is to cash the result of getDFN
// other solution is to determine it's not affecting performance :D
public boolean isNamespaceEmpty() {
return BindingUtils.getDeclarationsForNamespace(bindingContext(), descriptor).isEmpty();
}
@NotNull
public JsStatement getInitializeStatement() {
@@ -76,18 +71,35 @@ public final class NamespaceTranslator extends AbstractTranslator {
@NotNull
public JsStatement getDeclarationStatement() {
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
addMemberDeclarations(namespaceDeclaration);
addClassesDeclarations(namespaceDeclaration);
namespaceDeclaration.getArguments().add(translateNamespaceMemberDeclarations());
namespaceDeclaration.getArguments().add(getClassesAndNestedNamespaces());
return newVar(namespaceName, namespaceDeclaration);
}
private void addClassesDeclarations(@NotNull JsInvocation namespaceDeclaration) {
namespaceDeclaration.getArguments().add(classDeclarationTranslator.classDeclarationsForNamespace(descriptor));
@NotNull
private JsObjectLiteral getClassesAndNestedNamespaces() {
JsObjectLiteral classesAndNestedNamespaces = new JsObjectLiteral();
classesAndNestedNamespaces.getPropertyInitializers()
.addAll(getClassesDefined());
classesAndNestedNamespaces.getPropertyInitializers()
.addAll(getNestedNamespaceDeclarations());
return classesAndNestedNamespaces;
}
private void addMemberDeclarations(@NotNull JsInvocation jsNamespace) {
JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations();
jsNamespace.getArguments().add(jsClassDescription);
@NotNull
private List<JsPropertyInitializer> getClassesDefined() {
return classDeclarationTranslator.classDeclarationsForNamespace(descriptor);
}
@NotNull
private List<JsPropertyInitializer> getNestedNamespaceDeclarations() {
List<JsPropertyInitializer> result = Lists.newArrayList();
List<NamespaceDescriptor> nestedNamespaces = DescriptorUtils.getNestedNamespaces(descriptor);
for (NamespaceDescriptor nestedNamespace : nestedNamespaces) {
JsName nameForDescriptor = context().getNameForDescriptor(nestedNamespace);
result.add(new JsPropertyInitializer(nameForDescriptor.makeRef(), nameForDescriptor.makeRef()));
}
return result;
}
@NotNull
@@ -97,11 +97,7 @@ public final class BindingUtils {
public static List<JetDeclaration> getDeclarationsForNamespace(@NotNull BindingContext bindingContext,
@NotNull NamespaceDescriptor namespace) {
List<JetDeclaration> declarations = new ArrayList<JetDeclaration>();
for (DeclarationDescriptor descriptor : namespace.getMemberScope().getAllDescriptors()) {
if (AnnotationsUtils.isPredefinedObject(descriptor)) {
continue;
}
//TODO:
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespace)) {
if (descriptor instanceof NamespaceDescriptor) {
continue;
}
@@ -199,27 +195,6 @@ public final class BindingUtils {
return !superClassDescriptor.equals(JetStandardClasses.getAny());
}
//TODO: refactor duplication
//TODO: check where we use these, suspicious
public static boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) {
DeclarationDescriptor classDescriptor = descriptor.getContainingDeclaration();
assert classDescriptor != null;
return isOwnedByNamespace(classDescriptor);
}
return (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor);
}
public static boolean isOwnedByClass(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) {
DeclarationDescriptor classDescriptor = descriptor.getContainingDeclaration();
assert classDescriptor != null;
return isOwnedByClass(classDescriptor);
}
return (descriptor.getContainingDeclaration() instanceof ClassDescriptor);
}
@NotNull
public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
@NotNull JetExpression expression) {
@@ -321,7 +296,7 @@ public final class BindingUtils {
for (JetFile file : files) {
NamespaceDescriptor namespaceDescriptor = getNamespaceDescriptor(context, file);
if (!AnnotationsUtils.isPredefinedObject(namespaceDescriptor)) {
descriptorSet.add(namespaceDescriptor);
descriptorSet.addAll(getNamespaceDescriptorHierarchy(namespaceDescriptor));
}
}
return descriptorSet;
@@ -338,8 +313,7 @@ public final class BindingUtils {
@NotNull
public static ResolvedCall<FunctionDescriptor> getResolvedCallForArrayAccess(@NotNull BindingContext context,
@NotNull JetArrayAccessExpression arrayAccessExpression,
boolean isGet
) {
boolean isGet) {
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(isGet
? INDEXED_LVALUE_GET
: INDEXED_LVALUE_SET, arrayAccessExpression);
@@ -81,13 +81,9 @@ public final class DescriptorUtils {
@NotNull
public static PropertyDescriptor getPropertyByName(@NotNull JetScope scope,
@NotNull String name) {
VariableDescriptor variable = scope.getLocalVariable(name);
if (variable == null) {
variable = scope.getPropertyByFieldReference("$" + name);
}
Set<VariableDescriptor> variables = scope.getProperties(name);
assert variables.size() == 1 : "Actual size: " + variables.size();
variable = variables.iterator().next();
VariableDescriptor variable = variables.iterator().next();
PropertyDescriptor descriptor = (PropertyDescriptor) variable;
assert descriptor != null : "Must have a descriptor.";
return descriptor;
@@ -208,10 +204,7 @@ public final class DescriptorUtils {
@NotNull
public static List<ClassDescriptor> getAllClassesDefinedInNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
List<ClassDescriptor> classDescriptors = Lists.newArrayList();
for (DeclarationDescriptor descriptor : namespaceDescriptor.getMemberScope().getAllDescriptors()) {
if (AnnotationsUtils.isPredefinedObject(descriptor)) {
continue;
}
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor)) {
if (descriptor instanceof ClassDescriptor) {
classDescriptors.add((ClassDescriptor) descriptor);
}
@@ -219,6 +212,17 @@ public final class DescriptorUtils {
return classDescriptors;
}
@NotNull
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor) {
List<NamespaceDescriptor> result = Lists.newArrayList();
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor)) {
if (descriptor instanceof NamespaceDescriptor) {
result.add((NamespaceDescriptor) descriptor);
}
}
return result;
}
@Nullable
public static FunctionDescriptor getOverriddenDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
Set<? extends FunctionDescriptor> overriddenDescriptors = functionDescriptor.getOverriddenDescriptors();
@@ -242,4 +246,49 @@ public final class DescriptorUtils {
// return functionDescriptor;
// }
// }
@NotNull
public static List<DeclarationDescriptor> getContainedDescriptorsWhichAreNotPredefined
(@NotNull NamespaceDescriptor namespace) {
List<DeclarationDescriptor> result = Lists.newArrayList();
for (DeclarationDescriptor descriptor : namespace.getMemberScope().getAllDescriptors()) {
if (!AnnotationsUtils.isPredefinedObject(descriptor)) {
result.add(descriptor);
}
}
return result;
}
//TODO: at the moment this check is very ineffective
public static boolean isNamespaceEmpty(@NotNull NamespaceDescriptor namespace) {
List<DeclarationDescriptor> containedDescriptors = getContainedDescriptorsWhichAreNotPredefined(namespace);
for (DeclarationDescriptor descriptor : containedDescriptors) {
if (descriptor instanceof NamespaceDescriptor) {
if (!isNamespaceEmpty((NamespaceDescriptor) descriptor)) {
return false;
}
}
else {
return false;
}
}
return true;
}
@NotNull
public static List<NamespaceDescriptor> getNamespaceDescriptorHierarchy(@NotNull NamespaceDescriptor namespaceDescriptor) {
List<NamespaceDescriptor> result = Lists.newArrayList(namespaceDescriptor);
NamespaceDescriptor current = namespaceDescriptor;
while (!current.getName().equals("<root>")) {
result.add(current);
if (current.getContainingDeclaration() instanceof NamespaceDescriptor) {
current = (NamespaceDescriptor) current.getContainingDeclaration();
assert current != null;
}
else {
break;
}
}
return result;
}
}
@@ -45,7 +45,7 @@ public final class PartiallyOrderedSet<Element> {
}
public interface Order<Element> {
boolean firstDependsOnSecond(@NotNull Element first, @NotNull Element Second);
boolean firstDependsOnSecond(@NotNull Element first, @NotNull Element second);
}
@NotNull
-1
View File
@@ -233,7 +233,6 @@ var Kotlin;
}
function create() {
var result = {};
for (var i = 0, length = arguments.length; i < length; i++) {
add(result, arguments[i]);