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.mozilla.javascript.JavaScriptException;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
* <p/>
|
||||
|
||||
@@ -34,4 +34,8 @@ public final class MultiFileTest extends MultipleFilesTranslationTest {
|
||||
public void testClassesInheritedFromOtherFile() throws Exception {
|
||||
checkFooBoxIsTrue("classesInheritedFromOtherFile");
|
||||
}
|
||||
|
||||
public void testClassOfTheSameNameInAnotherPackage() throws Exception {
|
||||
checkFooBoxIsTrue("classOfTheSameNameInAnotherPackage");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,9 @@ public final class StaticContext {
|
||||
@Nullable
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
NamingScope namingScope = getEnclosingScope(descriptor);
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return namingScope.declareUnobfuscatableName(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);
|
||||
}
|
||||
+149
-90
@@ -16,26 +16,29 @@
|
||||
|
||||
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.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.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
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.ClassSortingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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
|
||||
@@ -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.
|
||||
*/
|
||||
public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||
private int localNameCounter;
|
||||
|
||||
@NotNull
|
||||
private final List<ClassDescriptor> descriptors;
|
||||
@NotNull
|
||||
private final BiMap<JsName, JsName> localToGlobalClassName;
|
||||
private final THashMap<JetClass, ListItem> openClassToItem = new THashMap<JetClass, ListItem>();
|
||||
|
||||
private final TLinkedList<ListItem> openList = new TLinkedList<ListItem>();
|
||||
private final List<ListItem> finalList = new ArrayList<ListItem>();
|
||||
|
||||
@NotNull
|
||||
private final JsFunction dummyFunction;
|
||||
@Nullable
|
||||
private JsName declarationsObject = null;
|
||||
@Nullable
|
||||
private JsStatement declarationsStatement = null;
|
||||
|
||||
public ClassDeclarationTranslator(@NotNull List<ClassDescriptor> descriptors,
|
||||
@NotNull TranslationContext context) {
|
||||
private final JsName declarationsObject;
|
||||
private final JsVar classesVar;
|
||||
|
||||
public ClassDeclarationTranslator(@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.descriptors = descriptors;
|
||||
this.localToGlobalClassName = HashBiMap.create();
|
||||
this.dummyFunction = new JsFunction(context.jsScope());
|
||||
|
||||
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() {
|
||||
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
||||
assert declarationsObject != null;
|
||||
declarationsStatement =
|
||||
newVar(declarationsObject, generateDummyFunctionInvocation());
|
||||
}
|
||||
JsObjectLiteral valueLiteral = new JsObjectLiteral();
|
||||
JsVars vars = new JsVars();
|
||||
List<JsPropertyInitializer> propertyInitializers = valueLiteral.getPropertyInitializers();
|
||||
|
||||
@NotNull
|
||||
public JsName getDeclarationsObjectName() {
|
||||
assert declarationsObject != null : "Should run generateDeclarations first";
|
||||
return declarationsObject;
|
||||
}
|
||||
generateOpenClassDeclarations(vars, propertyInitializers);
|
||||
generateFinalClassDeclarations(vars, propertyInitializers);
|
||||
|
||||
@NotNull
|
||||
public JsStatement getDeclarationsStatement() {
|
||||
assert declarationsStatement != null : "Should run generateDeclarations first";
|
||||
return declarationsStatement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation generateDummyFunctionInvocation() {
|
||||
List<JsStatement> classDeclarations = generateClassDeclarationStatements();
|
||||
classDeclarations.add(new JsReturn(generateReturnedObjectLiteral()));
|
||||
dummyFunction.setBody(newBlock(classDeclarations));
|
||||
return AstUtil.newInvocation(dummyFunction);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsObjectLiteral generateReturnedObjectLiteral() {
|
||||
JsObjectLiteral returnedValueLiteral = new JsObjectLiteral();
|
||||
for (JsName localName : localToGlobalClassName.keySet()) {
|
||||
returnedValueLiteral.getPropertyInitializers().add(classEntry(localName));
|
||||
if (vars.isEmpty()) {
|
||||
classesVar.setInitExpr(valueLiteral);
|
||||
return;
|
||||
}
|
||||
return returnedValueLiteral;
|
||||
|
||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||
result.add(vars);
|
||||
result.add(new JsReturn(valueLiteral));
|
||||
dummyFunction.setBody(newBlock(result));
|
||||
classesVar.setInitExpr(AstUtil.newInvocation(dummyFunction));
|
||||
}
|
||||
|
||||
@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));
|
||||
private void generateOpenClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
ClassAliasingMap classAliasingMap = new OpenClassRefProvider();
|
||||
// first pass: set up list order
|
||||
for (ListItem item : openList) {
|
||||
item.translatedDeclaration = translateClassDeclaration(item.declaration, classAliasingMap, context());
|
||||
}
|
||||
return classDeclarations;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private List<JetClass> getClassDeclarations() {
|
||||
List<JetClass> classes = new ArrayList<JetClass>();
|
||||
for (ClassDescriptor classDescriptor : descriptors) {
|
||||
classes.add(BindingUtils.getClassForDescriptor(bindingContext(), classDescriptor));
|
||||
// second pass: generate
|
||||
for (ListItem item : openList) {
|
||||
generate(item, propertyInitializers, item.translatedDeclaration, vars);
|
||||
}
|
||||
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);
|
||||
private void generateFinalClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
ClassAliasingMap classAliasingMap = new FinalClassRefProvider();
|
||||
for (ListItem item : finalList) {
|
||||
generate(item, propertyInitializers, translateClassDeclaration(item.declaration, classAliasingMap, context()), vars);
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
private static void generate(@NotNull ListItem item,
|
||||
@NotNull List<JsPropertyInitializer> propertyInitializers,
|
||||
@NotNull JsExpression definition,
|
||||
@NotNull JsVars vars) {
|
||||
JsExpression value;
|
||||
if (context().isEcma5()) {
|
||||
value = JsAstUtils.createDataDescriptor(alreadyDefinedClassReference, false, context());
|
||||
if (item.label.getName() == null) {
|
||||
value = definition;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-17
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
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.JetObjectLiteralExpression;
|
||||
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.Translation;
|
||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
@@ -64,8 +64,8 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull Map<JsName, JsName> aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
|
||||
}
|
||||
|
||||
@@ -73,13 +73,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(classDeclaration, Collections.<JsName, JsName>emptyMap(), context)).translateClassOrObjectCreation();
|
||||
return (new ClassTranslator(classDeclaration, null, context)).translateClassOrObjectCreation();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), Collections.<JsName, JsName>emptyMap(), context))
|
||||
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), null, context))
|
||||
.translateObjectLiteralExpression();
|
||||
}
|
||||
|
||||
@@ -95,12 +95,12 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private final ClassDescriptor descriptor;
|
||||
|
||||
@NotNull
|
||||
private final Map<JsName, JsName> aliasingMap;
|
||||
@Nullable
|
||||
private final ClassAliasingMap aliasingMap;
|
||||
|
||||
private ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull Map<JsName, JsName> aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
@Nullable ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context.newDeclaration(classDeclaration));
|
||||
this.aliasingMap = aliasingMap;
|
||||
this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration);
|
||||
@@ -209,8 +209,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
for (ClassDescriptor superClassDescriptor :
|
||||
superclassDescriptors) {
|
||||
for (ClassDescriptor superClassDescriptor : superclassDescriptors) {
|
||||
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
||||
superclassReferences.add(getClassReference(superClassDescriptor));
|
||||
}
|
||||
@@ -227,12 +226,16 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
||||
//NOTE: aliasing here is needed for the declaration generation step
|
||||
JsName name = context().getNameForDescriptor(superClassDescriptor);
|
||||
JsName alias = aliasingMap.get(name);
|
||||
if (alias != null) {
|
||||
return alias.makeRef();
|
||||
// aliasing here is needed for the declaration generation step
|
||||
if (aliasingMap != null) {
|
||||
JsNameRef name = aliasingMap.get(BindingUtils.getClassForDescriptor(bindingContext(), superClassDescriptor),
|
||||
(JetClass) classDeclaration);
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
// from library
|
||||
return getQualifiedReference(context(), superClassDescriptor);
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -79,8 +79,7 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ClassDescriptor classDescriptor = getClassDescriptor(context.bindingContext(), expression);
|
||||
return Collections.singletonList(classDeclarationTranslator.getClassNameToClassObject(classDescriptor));
|
||||
return Collections.singletonList(classDeclarationTranslator.translateAndGetClassNameToClassObject(expression));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
-19
@@ -17,10 +17,12 @@
|
||||
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.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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
@@ -34,7 +36,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getAllClassesDefinedInNamespace;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -55,29 +56,16 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.namespaceDescriptors = namespaceDescriptors;
|
||||
this.classDeclarationTranslator = new ClassDeclarationTranslator(getAllClasses(), context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<ClassDescriptor> getAllClasses() {
|
||||
List<ClassDescriptor> result = Lists.newArrayList();
|
||||
for (NamespaceDescriptor namespaceDescriptor : namespaceDescriptors) {
|
||||
result.addAll(getAllClassesDefinedInNamespace(namespaceDescriptor, context().bindingContext()));
|
||||
}
|
||||
return result;
|
||||
classDeclarationTranslator = new ClassDeclarationTranslator(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> translate() {
|
||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||
classesDeclarations(result);
|
||||
result.add(classDeclarationTranslator.getDeclarationsStatement());
|
||||
namespacesDeclarations(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void classesDeclarations(List<JsStatement> statements) {
|
||||
classDeclarationTranslator.generateDeclarations();
|
||||
statements.add(classDeclarationTranslator.getDeclarationsStatement());
|
||||
return result;
|
||||
}
|
||||
|
||||
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.translate.context.StaticContext;
|
||||
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.NamespaceDeclarationTranslator;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.plugin.JetMainDetector.getMainFunction;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||
@@ -85,9 +85,9 @@ public final class Translation {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateClassDeclaration(@NotNull JetClass classDeclaration,
|
||||
@NotNull Map<JsName, JsName> aliasingMap,
|
||||
@NotNull ClassAliasingMap classAliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, aliasingMap, context);
|
||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, classAliasingMap, context);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@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
|
||||
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
||||
@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];
|
||||
object[property] = source[property];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
return function () {
|
||||
var result = {};
|
||||
for (var i = 0, length = arguments.length; i < length; i++) {
|
||||
var result = arguments[0];
|
||||
for (var i = 1, n = arguments.length; i < n; i++) {
|
||||
add(result, arguments[i]);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -112,16 +112,7 @@ var Kotlin = {};
|
||||
|
||||
|
||||
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);
|
||||
|
||||
if (nestedNamespaces) {
|
||||
var keys = Object.keys(nestedNamespaces);
|
||||
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