Support for namespace variables in nested namespaces.

This commit is contained in:
Pavel V. Talanov
2012-03-19 16:27:58 +04:00
parent 02da9b42c1
commit eeb3bc9a8e
5 changed files with 48 additions and 29 deletions
@@ -38,8 +38,11 @@ public final class NamespaceTest extends SingleFileTranslationTest {
runFunctionOutputTest("deeplyNestedNamespaceFunctionCalled.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true); runFunctionOutputTest("deeplyNestedNamespaceFunctionCalled.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true);
} }
public void testClassCreatedInDeeplyNestedNamespace() throws Exception { public void testClassCreatedInDeeplyNestedNamespace() throws Exception {
runFunctionOutputTest("classCreatedInDeeplyNestedNamespace.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true); runFunctionOutputTest("classCreatedInDeeplyNestedNamespace.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true);
} }
public void testInitializersOfNestedNamespacesExecute() throws Exception {
runFunctionOutputTest("initializersOfNestedNamespacesExecute.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true);
}
} }
@@ -17,20 +17,25 @@
package org.jetbrains.k2js.translate.declaration; package org.jetbrains.k2js.translate.declaration;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.backend.js.ast.JsStatement; import com.google.dart.compiler.backend.js.ast.JsStatement;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.DescriptorUtils; import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors; import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/** /**
* @author Pavel Talanov * @author Pavel Talanov
@@ -90,10 +95,8 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
@NotNull @NotNull
private List<NamespaceTranslator> getTranslatorsForNonEmptyNamespaces() { private List<NamespaceTranslator> getTranslatorsForNonEmptyNamespaces() {
List<NamespaceTranslator> namespaceTranslators = Lists.newArrayList(); List<NamespaceTranslator> namespaceTranslators = Lists.newArrayList();
for (NamespaceDescriptor descriptor : filterTopLevelNamespaces(namespaceDescriptors)) { for (NamespaceDescriptor descriptor : filterNonEmptyNamespaces(filterTopLevelNamespaces(namespaceDescriptors))) {
if (!DescriptorUtils.isNamespaceEmpty(descriptor)) { namespaceTranslators.add(new NamespaceTranslator(descriptor, classDeclarationTranslator, context()));
namespaceTranslators.add(new NamespaceTranslator(descriptor, classDeclarationTranslator, context()));
}
} }
return namespaceTranslators; return namespaceTranslators;
} }
@@ -108,10 +111,13 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
} }
@NotNull @NotNull
private static List<JsStatement> initializeStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) { private List<JsStatement> initializeStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) {
List<JsStatement> result = Lists.newArrayList(); List<JsStatement> result = Lists.newArrayList();
for (NamespaceTranslator translator : namespaceTranslators) { for (NamespaceDescriptor descriptor : filterNonEmptyNamespaces(namespaceDescriptors)) {
result.add(translator.getInitializeStatement()); JsNameRef initializeMethodReference = Namer.initializeMethodReference();
JsNameRef fqNamespaceNameRef = TranslationUtils.getQualifiedReference(context(), descriptor);
setQualifier(initializeMethodReference, fqNamespaceNameRef);
result.add(AstUtil.newInvocation(initializeMethodReference).makeStmt());
} }
return result; return result;
} }
@@ -126,4 +132,15 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
} }
return result; return result;
} }
@NotNull
private static List<NamespaceDescriptor> filterNonEmptyNamespaces(@NotNull List<NamespaceDescriptor> namespaceDescriptors) {
List<NamespaceDescriptor> result = Lists.newArrayList();
for (NamespaceDescriptor descriptor : namespaceDescriptors) {
if (!DescriptorUtils.isNamespaceEmpty(descriptor)) {
result.add(descriptor);
}
}
return result;
}
} }
@@ -21,7 +21,6 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil; import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.general.Translation;
@@ -30,7 +29,8 @@ import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.JsAstUtils.newObjectLiteral;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
/** /**
* @author Pavel.Talanov * @author Pavel.Talanov
@@ -56,13 +56,6 @@ public final class NamespaceTranslator extends AbstractTranslator {
} }
@NotNull
public JsStatement getInitializeStatement() {
JsNameRef initializeMethodReference = Namer.initializeMethodReference();
setQualifier(initializeMethodReference, namespaceName.makeRef());
return AstUtil.newInvocation(initializeMethodReference).makeStmt();
}
@NotNull @NotNull
public JsStatement getDeclarationAsVar() { public JsStatement getDeclarationAsVar() {
return newVar(namespaceName, getNamespaceDeclaration()); return newVar(namespaceName, getNamespaceDeclaration());
@@ -53,9 +53,9 @@ public final class BindingUtils {
DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
assert descriptor != null; assert descriptor != null;
assert descriptorClass.isInstance(descriptor) assert descriptorClass.isInstance(descriptor)
: expression.toString() + " expected to have of type" + descriptorClass.toString(); : expression.toString() + " expected to have of type" + descriptorClass.toString();
//noinspection unchecked //noinspection unchecked
return (D) descriptor; return (D)descriptor;
} }
@NotNull @NotNull
@@ -68,7 +68,7 @@ public final class BindingUtils {
public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context, public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
@NotNull JetFile declaration) { @NotNull JetFile declaration) {
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor namespaceDescriptor =
context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration)); context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration));
assert namespaceDescriptor != null : "File should have a namespace descriptor."; assert namespaceDescriptor != null : "File should have a namespace descriptor.";
return namespaceDescriptor; return namespaceDescriptor;
} }
@@ -90,7 +90,7 @@ public final class BindingUtils {
@NotNull ClassDescriptor descriptor) { @NotNull ClassDescriptor descriptor) {
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
assert result instanceof JetClass : "ClassDescriptor should have declaration of type JetClass"; assert result instanceof JetClass : "ClassDescriptor should have declaration of type JetClass";
return (JetClass) result; return (JetClass)result;
} }
@NotNull @NotNull
@@ -118,7 +118,7 @@ public final class BindingUtils {
return null; return null;
} }
assert result instanceof JetDeclaration : "Descriptor should correspond to an element."; assert result instanceof JetDeclaration : "Descriptor should correspond to an element.";
return (JetDeclaration) result; return (JetDeclaration)result;
} }
@NotNull @NotNull
@@ -126,7 +126,7 @@ public final class BindingUtils {
@NotNull ValueParameterDescriptor descriptor) { @NotNull ValueParameterDescriptor descriptor) {
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter."; assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter.";
return (JetParameter) result; return (JetParameter)result;
} }
public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) { public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) {
@@ -169,7 +169,7 @@ public final class BindingUtils {
if (!(result instanceof JetProperty)) { if (!(result instanceof JetProperty)) {
return null; return null;
} }
return (JetProperty) result; return (JetProperty)result;
} }
@NotNull @NotNull
@@ -186,7 +186,7 @@ public final class BindingUtils {
DeclarationDescriptor referencedDescriptor = context.get(BindingContext.REFERENCE_TARGET, reference); DeclarationDescriptor referencedDescriptor = context.get(BindingContext.REFERENCE_TARGET, reference);
if (isVariableAsFunction(referencedDescriptor)) { if (isVariableAsFunction(referencedDescriptor)) {
assert referencedDescriptor != null; assert referencedDescriptor != null;
return getVariableDescriptorForVariableAsFunction((VariableAsFunctionDescriptor) referencedDescriptor); return getVariableDescriptorForVariableAsFunction((VariableAsFunctionDescriptor)referencedDescriptor);
} }
return referencedDescriptor; return referencedDescriptor;
} }
@@ -221,13 +221,13 @@ public final class BindingUtils {
public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context, public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context,
@NotNull JetOperationExpression expression) { @NotNull JetOperationExpression expression) {
DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression
(context, expression.getOperationReference()); (context, expression.getOperationReference());
if (descriptorForReferenceExpression == null) return null; if (descriptorForReferenceExpression == null) return null;
assert descriptorForReferenceExpression instanceof FunctionDescriptor assert descriptorForReferenceExpression instanceof FunctionDescriptor
: "Operation should resolve to function descriptor."; : "Operation should resolve to function descriptor.";
return (FunctionDescriptor) descriptorForReferenceExpression; return (FunctionDescriptor)descriptorForReferenceExpression;
} }
@NotNull @NotNull
@@ -294,6 +294,7 @@ public final class BindingUtils {
@NotNull List<JetFile> files) { @NotNull List<JetFile> files) {
Set<NamespaceDescriptor> descriptorSet = Sets.newHashSet(); Set<NamespaceDescriptor> descriptorSet = Sets.newHashSet();
for (JetFile file : files) { for (JetFile file : files) {
//TODO: can't be
NamespaceDescriptor namespaceDescriptor = getNamespaceDescriptor(context, file); NamespaceDescriptor namespaceDescriptor = getNamespaceDescriptor(context, file);
if (!AnnotationsUtils.isPredefinedObject(namespaceDescriptor)) { if (!AnnotationsUtils.isPredefinedObject(namespaceDescriptor)) {
descriptorSet.addAll(getNamespaceDescriptorHierarchy(namespaceDescriptor)); descriptorSet.addAll(getNamespaceDescriptorHierarchy(namespaceDescriptor));
@@ -324,7 +325,7 @@ public final class BindingUtils {
public static ConstructorDescriptor getConstructor(@NotNull BindingContext bindingContext, public static ConstructorDescriptor getConstructor(@NotNull BindingContext bindingContext,
@NotNull JetClassOrObject declaration) { @NotNull JetClassOrObject declaration) {
ConstructorDescriptor primaryConstructor = ConstructorDescriptor primaryConstructor =
getClassDescriptor(bindingContext, declaration).getUnsubstitutedPrimaryConstructor(); getClassDescriptor(bindingContext, declaration).getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null : "Traits do not have initialize methods."; assert primaryConstructor != null : "Traits do not have initialize methods.";
return primaryConstructor; return primaryConstructor;
} }
@@ -0,0 +1,5 @@
package foo1.foo2.foo3.foo5.foo6.foo7.foo8
val f = true
fun box() = f