classes declaration:
fix: class of the same unqualified name in package inside module (see MultiFileTest.testClassOfTheSameNameInAnotherPackage) We don't ever try to use meaningful var name for temp class declaration — we remember about incremental compilation inline final class declaration don't generate scope function if we don't need it failed and fixed test: fast fix Kt817 (we must investigate, actually, it seems dart ast bug — we must have ability to declare name in our scope without check the same name in the parent scope) perfomance: delete ClassSortingUtils, we don't need it
This commit is contained in:
@@ -20,6 +20,8 @@ import org.jetbrains.k2js.config.EcmaVersion;
|
|||||||
import org.jetbrains.k2js.translate.context.Namer;
|
import org.jetbrains.k2js.translate.context.Namer;
|
||||||
import org.mozilla.javascript.JavaScriptException;
|
import org.mozilla.javascript.JavaScriptException;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|||||||
@@ -34,4 +34,8 @@ public final class MultiFileTest extends MultipleFilesTranslationTest {
|
|||||||
public void testClassesInheritedFromOtherFile() throws Exception {
|
public void testClassesInheritedFromOtherFile() throws Exception {
|
||||||
checkFooBoxIsTrue("classesInheritedFromOtherFile");
|
checkFooBoxIsTrue("classesInheritedFromOtherFile");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testClassOfTheSameNameInAnotherPackage() throws Exception {
|
||||||
|
checkFooBoxIsTrue("classOfTheSameNameInAnotherPackage");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,9 @@ public final class StaticContext {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
NamingScope namingScope = getEnclosingScope(descriptor);
|
NamingScope namingScope = getEnclosingScope(descriptor);
|
||||||
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
|
return namingScope.declareUnobfuscatableName(descriptor.getName().getName());
|
||||||
|
}
|
||||||
return namingScope.declareObfuscatableName(descriptor.getName().getName());
|
return namingScope.declareObfuscatableName(descriptor.getName().getName());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jetbrains.k2js.translate.declaration;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
|
|
||||||
|
public interface ClassAliasingMap {
|
||||||
|
@Nullable
|
||||||
|
JsNameRef get(JetClass declaration, JetClass referencedDeclaration);
|
||||||
|
}
|
||||||
+152
-93
@@ -16,26 +16,29 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.declaration;
|
package org.jetbrains.k2js.translate.declaration;
|
||||||
|
|
||||||
import com.google.common.collect.BiMap;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
|
import gnu.trove.THashMap;
|
||||||
|
import gnu.trove.TLinkable;
|
||||||
|
import gnu.trove.TLinkableAdaptor;
|
||||||
|
import gnu.trove.TLinkedList;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.k2js.translate.context.Namer;
|
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.utils.BindingUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.ClassSortingUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
|
|
||||||
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 com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
||||||
|
import static org.jetbrains.k2js.translate.general.Translation.translateClassDeclaration;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
@@ -43,114 +46,170 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
|||||||
* Generates a big block where are all the classes(objects representing them) are created.
|
* Generates a big block where are all the classes(objects representing them) are created.
|
||||||
*/
|
*/
|
||||||
public final class ClassDeclarationTranslator extends AbstractTranslator {
|
public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||||
|
private int localNameCounter;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final List<ClassDescriptor> descriptors;
|
private final THashMap<JetClass, ListItem> openClassToItem = new THashMap<JetClass, ListItem>();
|
||||||
@NotNull
|
|
||||||
private final BiMap<JsName, JsName> localToGlobalClassName;
|
private final TLinkedList<ListItem> openList = new TLinkedList<ListItem>();
|
||||||
|
private final List<ListItem> finalList = new ArrayList<ListItem>();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsFunction dummyFunction;
|
private final JsFunction dummyFunction;
|
||||||
@Nullable
|
|
||||||
private JsName declarationsObject = null;
|
|
||||||
@Nullable
|
|
||||||
private JsStatement declarationsStatement = null;
|
|
||||||
|
|
||||||
public ClassDeclarationTranslator(@NotNull List<ClassDescriptor> descriptors,
|
private final JsName declarationsObject;
|
||||||
@NotNull TranslationContext context) {
|
private final JsVar classesVar;
|
||||||
|
|
||||||
|
public ClassDeclarationTranslator(@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.descriptors = descriptors;
|
|
||||||
this.localToGlobalClassName = HashBiMap.create();
|
dummyFunction = new JsFunction(context.jsScope());
|
||||||
this.dummyFunction = new JsFunction(context.jsScope());
|
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
||||||
|
classesVar = new JsVars.JsVar(declarationsObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class OpenClassRefProvider implements ClassAliasingMap {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JsNameRef get(JetClass declaration, JetClass referencedDeclaration) {
|
||||||
|
ListItem item = openClassToItem.get(declaration);
|
||||||
|
// class declared in library
|
||||||
|
if (item == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
addAfter(item, openClassToItem.get(referencedDeclaration));
|
||||||
|
return item.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAfter(@NotNull ListItem item, @NotNull ListItem referencedItem) {
|
||||||
|
for (TLinkable link = item.getNext(); link != null; link = link.getNext()) {
|
||||||
|
if (link == referencedItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openList.remove(referencedItem);
|
||||||
|
openList.addBefore((ListItem) item.getNext(), referencedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class FinalClassRefProvider implements ClassAliasingMap {
|
||||||
|
@Override
|
||||||
|
public JsNameRef get(JetClass declaration, JetClass referencedDeclaration) {
|
||||||
|
ListItem item = openClassToItem.get(declaration);
|
||||||
|
return item == null ? null : item.label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ListItem extends TLinkableAdaptor {
|
||||||
|
private final JetClass declaration;
|
||||||
|
private final JsNameRef label;
|
||||||
|
|
||||||
|
private JsExpression translatedDeclaration;
|
||||||
|
|
||||||
|
private ListItem(JetClass declaration, JsNameRef label) {
|
||||||
|
this.declaration = declaration;
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsVars getDeclarationsStatement() {
|
||||||
|
JsVars vars = new JsVars();
|
||||||
|
vars.add(classesVar);
|
||||||
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateDeclarations() {
|
public void generateDeclarations() {
|
||||||
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
JsObjectLiteral valueLiteral = new JsObjectLiteral();
|
||||||
assert declarationsObject != null;
|
JsVars vars = new JsVars();
|
||||||
declarationsStatement =
|
List<JsPropertyInitializer> propertyInitializers = valueLiteral.getPropertyInitializers();
|
||||||
newVar(declarationsObject, generateDummyFunctionInvocation());
|
|
||||||
|
generateOpenClassDeclarations(vars, propertyInitializers);
|
||||||
|
generateFinalClassDeclarations(vars, propertyInitializers);
|
||||||
|
|
||||||
|
if (vars.isEmpty()) {
|
||||||
|
classesVar.setInitExpr(valueLiteral);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||||
public JsName getDeclarationsObjectName() {
|
result.add(vars);
|
||||||
assert declarationsObject != null : "Should run generateDeclarations first";
|
result.add(new JsReturn(valueLiteral));
|
||||||
return declarationsObject;
|
dummyFunction.setBody(newBlock(result));
|
||||||
|
classesVar.setInitExpr(AstUtil.newInvocation(dummyFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private void generateOpenClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||||
public JsStatement getDeclarationsStatement() {
|
ClassAliasingMap classAliasingMap = new OpenClassRefProvider();
|
||||||
assert declarationsStatement != null : "Should run generateDeclarations first";
|
// first pass: set up list order
|
||||||
return declarationsStatement;
|
for (ListItem item : openList) {
|
||||||
|
item.translatedDeclaration = translateClassDeclaration(item.declaration, classAliasingMap, context());
|
||||||
|
}
|
||||||
|
// second pass: generate
|
||||||
|
for (ListItem item : openList) {
|
||||||
|
generate(item, propertyInitializers, item.translatedDeclaration, vars);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private void generateFinalClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||||
private JsInvocation generateDummyFunctionInvocation() {
|
ClassAliasingMap classAliasingMap = new FinalClassRefProvider();
|
||||||
List<JsStatement> classDeclarations = generateClassDeclarationStatements();
|
for (ListItem item : finalList) {
|
||||||
classDeclarations.add(new JsReturn(generateReturnedObjectLiteral()));
|
generate(item, propertyInitializers, translateClassDeclaration(item.declaration, classAliasingMap, context()), vars);
|
||||||
dummyFunction.setBody(newBlock(classDeclarations));
|
}
|
||||||
return AstUtil.newInvocation(dummyFunction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private static void generate(@NotNull ListItem item,
|
||||||
private JsObjectLiteral generateReturnedObjectLiteral() {
|
@NotNull List<JsPropertyInitializer> propertyInitializers,
|
||||||
JsObjectLiteral returnedValueLiteral = new JsObjectLiteral();
|
@NotNull JsExpression definition,
|
||||||
for (JsName localName : localToGlobalClassName.keySet()) {
|
@NotNull JsVars vars) {
|
||||||
returnedValueLiteral.getPropertyInitializers().add(classEntry(localName));
|
|
||||||
}
|
|
||||||
return returnedValueLiteral;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsPropertyInitializer classEntry(@NotNull JsName localName) {
|
|
||||||
return new JsPropertyInitializer(localToGlobalClassName.get(localName).makeRef(), localName.makeRef());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<JsStatement> generateClassDeclarationStatements() {
|
|
||||||
List<JsStatement> classDeclarations = new ArrayList<JsStatement>();
|
|
||||||
for (JetClass jetClass : getClassDeclarations()) {
|
|
||||||
classDeclarations.add(generateDeclaration(jetClass));
|
|
||||||
}
|
|
||||||
return classDeclarations;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<JetClass> getClassDeclarations() {
|
|
||||||
List<JetClass> classes = new ArrayList<JetClass>();
|
|
||||||
for (ClassDescriptor classDescriptor : descriptors) {
|
|
||||||
classes.add(BindingUtils.getClassForDescriptor(bindingContext(), classDescriptor));
|
|
||||||
}
|
|
||||||
return ClassSortingUtils.sortUsingInheritanceOrder(classes, bindingContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsStatement generateDeclaration(@NotNull JetClass declaration) {
|
|
||||||
JsName localClassName = generateLocalAlias(declaration);
|
|
||||||
JsExpression classDeclarationExpression =
|
|
||||||
Translation.translateClassDeclaration(declaration, localToGlobalClassName.inverse(), context());
|
|
||||||
return newVar(localClassName, classDeclarationExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsName generateLocalAlias(@NotNull JetClass declaration) {
|
|
||||||
JsName globalClassName = context().getNameForElement(declaration);
|
|
||||||
JsName localAlias = dummyFunction.getScope().declareTemporary();
|
|
||||||
localToGlobalClassName.put(localAlias, globalClassName);
|
|
||||||
return localAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JsPropertyInitializer getClassNameToClassObject(@NotNull ClassDescriptor classDescriptor) {
|
|
||||||
JsName className = context().getNameForDescriptor(classDescriptor);
|
|
||||||
JsNameRef alreadyDefinedClassReference = qualified(className, getDeclarationsObjectName().makeRef());
|
|
||||||
JsExpression value;
|
JsExpression value;
|
||||||
if (context().isEcma5()) {
|
if (item.label.getName() == null) {
|
||||||
value = JsAstUtils.createDataDescriptor(alreadyDefinedClassReference, false, context());
|
value = definition;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
value = alreadyDefinedClassReference;
|
assert item.label.getName() != null;
|
||||||
|
vars.add(new JsVar(item.label.getName(), definition));
|
||||||
|
value = item.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JsPropertyInitializer(className.makeRef(), value);
|
propertyInitializers.add(new JsPropertyInitializer(item.label, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsPropertyInitializer translateAndGetClassNameToClassObject(@NotNull JetClass declaration) {
|
||||||
|
ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
|
||||||
|
|
||||||
|
JsNameRef labelRef;
|
||||||
|
String label = 'c' + Integer.toString(localNameCounter++, 36);
|
||||||
|
boolean isFinal = descriptor.getModality() == Modality.FINAL;
|
||||||
|
if (isFinal) {
|
||||||
|
labelRef = new JsNameRef(label);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
labelRef = dummyFunction.getScope().declareName(label).makeRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
ListItem item = new ListItem(declaration, labelRef);
|
||||||
|
if (isFinal) {
|
||||||
|
finalList.add(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
openList.add(item);
|
||||||
|
openClassToItem.put(declaration, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsNameRef qualifiedLabelRef = new JsNameRef(labelRef.getIdent());
|
||||||
|
qualifiedLabelRef.setQualifier(declarationsObject.makeRef());
|
||||||
|
JsExpression value;
|
||||||
|
if (context().isEcma5()) {
|
||||||
|
value = JsAstUtils.createDataDescriptor(qualifiedLabelRef, false, context());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = qualifiedLabelRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JsPropertyInitializer(context().program().getStringLiteral(descriptor.getName().getName()), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-15
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
|
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||||
@@ -31,12 +32,11 @@ 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;
|
||||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||||
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||||
@@ -64,7 +64,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||||
@NotNull Map<JsName, JsName> aliasingMap,
|
@NotNull ClassAliasingMap aliasingMap,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
|
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
|
||||||
}
|
}
|
||||||
@@ -73,13 +73,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||||
|
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new ClassTranslator(classDeclaration, Collections.<JsName, JsName>emptyMap(), context)).translateClassOrObjectCreation();
|
return (new ClassTranslator(classDeclaration, null, context)).translateClassOrObjectCreation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), Collections.<JsName, JsName>emptyMap(), context))
|
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), null, context))
|
||||||
.translateObjectLiteralExpression();
|
.translateObjectLiteralExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,11 +95,11 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final ClassDescriptor descriptor;
|
private final ClassDescriptor descriptor;
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
private final Map<JsName, JsName> aliasingMap;
|
private final ClassAliasingMap aliasingMap;
|
||||||
|
|
||||||
private ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
private ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||||
@NotNull Map<JsName, JsName> aliasingMap,
|
@Nullable ClassAliasingMap aliasingMap,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context.newDeclaration(classDeclaration));
|
super(context.newDeclaration(classDeclaration));
|
||||||
this.aliasingMap = aliasingMap;
|
this.aliasingMap = aliasingMap;
|
||||||
@@ -209,8 +209,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
||||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
for (ClassDescriptor superClassDescriptor :
|
for (ClassDescriptor superClassDescriptor : superclassDescriptors) {
|
||||||
superclassDescriptors) {
|
|
||||||
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
||||||
superclassReferences.add(getClassReference(superClassDescriptor));
|
superclassReferences.add(getClassReference(superClassDescriptor));
|
||||||
}
|
}
|
||||||
@@ -227,12 +226,16 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
||||||
//NOTE: aliasing here is needed for the declaration generation step
|
// aliasing here is needed for the declaration generation step
|
||||||
JsName name = context().getNameForDescriptor(superClassDescriptor);
|
if (aliasingMap != null) {
|
||||||
JsName alias = aliasingMap.get(name);
|
JsNameRef name = aliasingMap.get(BindingUtils.getClassForDescriptor(bindingContext(), superClassDescriptor),
|
||||||
if (alias != null) {
|
(JetClass) classDeclaration);
|
||||||
return alias.makeRef();
|
if (name != null) {
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// from library
|
||||||
return getQualifiedReference(context(), superClassDescriptor);
|
return getQualifiedReference(context(), superClassDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -79,8 +79,7 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassDescriptor classDescriptor = getClassDescriptor(context.bindingContext(), expression);
|
return Collections.singletonList(classDeclarationTranslator.translateAndGetClassNameToClassObject(expression));
|
||||||
return Collections.singletonList(classDeclarationTranslator.getClassNameToClassObject(classDescriptor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+7
-19
@@ -17,10 +17,12 @@
|
|||||||
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.*;
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||||
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.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.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
@@ -34,7 +36,6 @@ 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.JsDescriptorUtils.getAllClassesDefinedInNamespace;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
@@ -55,29 +56,16 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
|||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.namespaceDescriptors = namespaceDescriptors;
|
this.namespaceDescriptors = namespaceDescriptors;
|
||||||
this.classDeclarationTranslator = new ClassDeclarationTranslator(getAllClasses(), context);
|
classDeclarationTranslator = new ClassDeclarationTranslator(context);
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<ClassDescriptor> getAllClasses() {
|
|
||||||
List<ClassDescriptor> result = Lists.newArrayList();
|
|
||||||
for (NamespaceDescriptor namespaceDescriptor : namespaceDescriptors) {
|
|
||||||
result.addAll(getAllClassesDefinedInNamespace(namespaceDescriptor, context().bindingContext()));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JsStatement> translate() {
|
private List<JsStatement> translate() {
|
||||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||||
classesDeclarations(result);
|
result.add(classDeclarationTranslator.getDeclarationsStatement());
|
||||||
namespacesDeclarations(result);
|
namespacesDeclarations(result);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void classesDeclarations(List<JsStatement> statements) {
|
|
||||||
classDeclarationTranslator.generateDeclarations();
|
classDeclarationTranslator.generateDeclarations();
|
||||||
statements.add(classDeclarationTranslator.getDeclarationsStatement());
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void namespacesDeclarations(List<JsStatement> statements) {
|
private void namespacesDeclarations(List<JsStatement> statements) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.jetbrains.k2js.facade.exceptions.TranslationInternalException;
|
|||||||
import org.jetbrains.k2js.facade.exceptions.UnsupportedFeatureException;
|
import org.jetbrains.k2js.facade.exceptions.UnsupportedFeatureException;
|
||||||
import org.jetbrains.k2js.translate.context.StaticContext;
|
import org.jetbrains.k2js.translate.context.StaticContext;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.declaration.ClassAliasingMap;
|
||||||
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
|
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
|
||||||
import org.jetbrains.k2js.translate.declaration.NamespaceDeclarationTranslator;
|
import org.jetbrains.k2js.translate.declaration.NamespaceDeclarationTranslator;
|
||||||
import org.jetbrains.k2js.translate.expression.ExpressionVisitor;
|
import org.jetbrains.k2js.translate.expression.ExpressionVisitor;
|
||||||
@@ -54,7 +55,6 @@ import org.jetbrains.k2js.translate.utils.dangerous.DangerousTranslator;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.plugin.JetMainDetector.getMainFunction;
|
import static org.jetbrains.jet.plugin.JetMainDetector.getMainFunction;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||||
@@ -85,9 +85,9 @@ public final class Translation {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression translateClassDeclaration(@NotNull JetClass classDeclaration,
|
public static JsExpression translateClassDeclaration(@NotNull JetClass classDeclaration,
|
||||||
@NotNull Map<JsName, JsName> aliasingMap,
|
@NotNull ClassAliasingMap classAliasingMap,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, aliasingMap, context);
|
return ClassTranslator.generateClassCreationExpression(classDeclaration, classAliasingMap, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2012 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.k2js.translate.utils;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getSuperclassDescriptors;
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: can optimise using less dumb implementation
|
|
||||||
//TODO: pass list of descriptors here, not the list of jet classes
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Pavel Talanov
|
|
||||||
*/
|
|
||||||
public final class ClassSortingUtils {
|
|
||||||
|
|
||||||
private ClassSortingUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static List<JetClass> sortUsingInheritanceOrder(@NotNull List<JetClass> elements,
|
|
||||||
@NotNull BindingContext bindingContext) {
|
|
||||||
List<ClassDescriptor> descriptors = descriptorsFromClasses(elements, bindingContext);
|
|
||||||
PartiallyOrderedSet<ClassDescriptor> partiallyOrderedSet
|
|
||||||
= new PartiallyOrderedSet<ClassDescriptor>(descriptors, inheritanceOrder());
|
|
||||||
List<JetClass> sortedClasses = descriptorsToClasses(partiallyOrderedSet.partiallySortedElements(), bindingContext);
|
|
||||||
assert elements.size() == sortedClasses.size();
|
|
||||||
return sortedClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static PartiallyOrderedSet.Order<ClassDescriptor> inheritanceOrder() {
|
|
||||||
return new PartiallyOrderedSet.Order<ClassDescriptor>() {
|
|
||||||
@Override
|
|
||||||
public boolean firstDependsOnSecond(@NotNull ClassDescriptor first, @NotNull ClassDescriptor second) {
|
|
||||||
return isDerivedClass(first, second);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isDerivedClass(@NotNull ClassDescriptor ancestor, @NotNull ClassDescriptor derived) {
|
|
||||||
return (getSuperclassDescriptors(derived).contains(ancestor));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<JetClass> descriptorsToClasses(@NotNull List<ClassDescriptor> descriptors,
|
|
||||||
@NotNull BindingContext bindingContext) {
|
|
||||||
List<JetClass> sortedClasses = Lists.newArrayList();
|
|
||||||
for (ClassDescriptor descriptor : descriptors) {
|
|
||||||
sortedClasses.add(BindingUtils.getClassForDescriptor(bindingContext, descriptor));
|
|
||||||
}
|
|
||||||
return sortedClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<ClassDescriptor> descriptorsFromClasses(@NotNull List<JetClass> classesToSort,
|
|
||||||
@NotNull BindingContext bindingContext) {
|
|
||||||
List<ClassDescriptor> descriptorList = new ArrayList<ClassDescriptor>();
|
|
||||||
for (JetClass jetClass : classesToSort) {
|
|
||||||
descriptorList.add(BindingUtils.getClassDescriptor(bindingContext, jetClass));
|
|
||||||
}
|
|
||||||
return descriptorList;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -186,18 +186,6 @@ public final class JsDescriptorUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static List<ClassDescriptor> getAllClassesDefinedInNamespace(@NotNull NamespaceDescriptor namespaceDescriptor,
|
|
||||||
@NotNull BindingContext context) {
|
|
||||||
List<ClassDescriptor> classDescriptors = Lists.newArrayList();
|
|
||||||
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor, context)) {
|
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
|
||||||
classDescriptors.add((ClassDescriptor) descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return classDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
||||||
@NotNull BindingContext context) {
|
@NotNull BindingContext context) {
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2012 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.k2js.translate.utils;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Pavel Talanov
|
|
||||||
* <p/>
|
|
||||||
* This is very inefficient but simple implementation of partially orderered set.
|
|
||||||
* Feel free to replace with library implementation.
|
|
||||||
*/
|
|
||||||
public final class PartiallyOrderedSet<Element> {
|
|
||||||
|
|
||||||
private class Arc {
|
|
||||||
@NotNull
|
|
||||||
public final Element from;
|
|
||||||
@NotNull
|
|
||||||
public final Element to;
|
|
||||||
|
|
||||||
private Arc(@NotNull Element from, @NotNull Element to) {
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Order<Element> {
|
|
||||||
boolean firstDependsOnSecond(@NotNull Element first, @NotNull Element second);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final List<Arc> arcs = Lists.newArrayList();
|
|
||||||
@NotNull
|
|
||||||
private final Map<Element, Integer> incomingArcs = Maps.newHashMap();
|
|
||||||
@NotNull
|
|
||||||
private final List<Element> elementsWithZeroIncoming = Lists.newArrayList();
|
|
||||||
|
|
||||||
public PartiallyOrderedSet(@NotNull Collection<Element> elements, @NotNull Order<Element> order) {
|
|
||||||
elementsWithZeroIncoming.addAll(elements);
|
|
||||||
for (@NotNull Element first : elements) {
|
|
||||||
for (@NotNull Element second : elements) {
|
|
||||||
if (order.firstDependsOnSecond(first, second)) {
|
|
||||||
arcs.add(new Arc(first, second));
|
|
||||||
increaseIncomingCount(second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void increaseIncomingCount(@NotNull Element element) {
|
|
||||||
if (!incomingArcs.containsKey(element)) {
|
|
||||||
incomingArcs.put(element, 1);
|
|
||||||
elementsWithZeroIncoming.remove(element);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Integer count = incomingArcs.get(element);
|
|
||||||
incomingArcs.put(element, count + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void decreaseIncomingCount(@NotNull Element element) {
|
|
||||||
assert incomingArcs.containsKey(element);
|
|
||||||
Integer count = incomingArcs.get(element);
|
|
||||||
if (count == 1) {
|
|
||||||
incomingArcs.remove(element);
|
|
||||||
elementsWithZeroIncoming.add(element);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
incomingArcs.put(element, count - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public List<Element> partiallySortedElements() {
|
|
||||||
List<Element> result = Lists.newArrayList();
|
|
||||||
while (!elementsWithZeroIncoming.isEmpty()) {
|
|
||||||
result.add(getNextElement());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Element getNextElement() {
|
|
||||||
Element elementWithZeroIncoming = getElementWithZeroIncoming();
|
|
||||||
for (Arc arc : arcs) {
|
|
||||||
if (arc.from == elementWithZeroIncoming) {
|
|
||||||
decreaseIncomingCount(arc.to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return elementWithZeroIncoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Element getElementWithZeroIncoming() {
|
|
||||||
int indexOfLast = elementsWithZeroIncoming.size() - 1;
|
|
||||||
Element element = elementsWithZeroIncoming.get(indexOfLast);
|
|
||||||
elementsWithZeroIncoming.remove(indexOfLast);
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -129,12 +129,11 @@ var Kotlin = {};
|
|||||||
var property = properties[i];
|
var property = properties[i];
|
||||||
object[property] = source[property];
|
object[property] = source[property];
|
||||||
}
|
}
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return function () {
|
return function () {
|
||||||
var result = {};
|
var result = arguments[0];
|
||||||
for (var i = 0, length = arguments.length; i < length; i++) {
|
for (var i = 1, n = arguments.length; i < n; i++) {
|
||||||
add(result, arguments[i]);
|
add(result, arguments[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -112,16 +112,7 @@ var Kotlin = {};
|
|||||||
|
|
||||||
|
|
||||||
Kotlin.definePackage = function (functionsAndClasses, nestedNamespaces) {
|
Kotlin.definePackage = function (functionsAndClasses, nestedNamespaces) {
|
||||||
//var p = parent[localName];
|
|
||||||
//if (!p) {
|
|
||||||
// p = Object.create(null, functionsAndClasses || undefined);
|
|
||||||
// Object.defineProperty(parent, localName, {value: p});
|
|
||||||
//}
|
|
||||||
//else if (functionsAndClasses) {
|
|
||||||
// Object.defineProperties(p, functionsAndClasses);
|
|
||||||
//}
|
|
||||||
var p = Object.create(null, functionsAndClasses || undefined);
|
var p = Object.create(null, functionsAndClasses || undefined);
|
||||||
|
|
||||||
if (nestedNamespaces) {
|
if (nestedNamespaces) {
|
||||||
var keys = Object.keys(nestedNamespaces);
|
var keys = Object.keys(nestedNamespaces);
|
||||||
for (var i = 0, n = keys.length; i < n; i++) {
|
for (var i = 0, n = keys.length; i < n; i++) {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
open class A() {
|
||||||
|
fun f() = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = (A().f() + bar.A().f()) == 9
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
open class A() {
|
||||||
|
fun f() = 6
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user