Worked on namer.

This commit is contained in:
Pavel Talanov
2011-11-28 19:10:17 +04:00
parent 99114132ac
commit ee2cee31af
13 changed files with 151 additions and 70 deletions
@@ -4,12 +4,14 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
import org.jetbrains.k2js.utils.ClassSorter;
@@ -95,7 +97,8 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
private void removeAliases() {
for (JetClass jetClass : getClassDeclarations()) {
context().aliaser().removeAliasForDeclaration(jetClass);
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context().bindingContext(), jetClass);
context().aliaser().removeAliasForDescriptor(descriptor);
}
}
@@ -118,11 +121,13 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
return AstUtil.newVar(localClassName, classDeclarationExpression);
}
@NotNull
private JsName generateLocalAlias(@NotNull JetClass declaration) {
JsName globalClassName = context().getNameForElement(declaration);
JsName localAlias = dummyFunctionScope.declareName(globalClassName.getIdent());
localToGlobalClassName.put(localAlias, globalClassName);
context().aliaser().setAliasForDeclaration(declaration, localAlias);
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context().bindingContext(), declaration);
context().aliaser().setAliasForDescriptor(descriptor, localAlias);
return localAlias;
}
}
@@ -16,7 +16,6 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
import java.util.ArrayList;
import java.util.List;
@@ -53,9 +52,9 @@ public final class ClassTranslator extends AbstractTranslator {
@NotNull
private JsInvocation classCreateMethodInvocation() {
if (classDeclaration.isTrait()) {
return AstUtil.newInvocation(Namer.traitCreationMethodReference());
return AstUtil.newInvocation(context().namer().traitCreationMethodReference());
} else {
return AstUtil.newInvocation(Namer.classCreationMethodReference());
return AstUtil.newInvocation(context().namer().classCreationMethodReference());
}
}
@@ -102,8 +101,7 @@ public final class ClassTranslator extends AbstractTranslator {
private JsNameRef getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
//TODO we actually know that in current implementation superclass must have an alias but
// if future it might change
return context().aliaser().getAliasForDeclaration(
BindingUtils.getClassForDescriptor(context().bindingContext(), superClassDescriptor));
return context().aliaser().getAliasForDeclaration(superClassDescriptor);
}
@Nullable
@@ -57,7 +57,7 @@ public final class NamespaceTranslator extends AbstractTranslator {
@NotNull
private JsInvocation namespaceCreateMethodInvocation() {
return AstUtil.newInvocation(Namer.namespaceCreationMethodReference());
return AstUtil.newInvocation(context().namer().namespaceCreationMethodReference());
}
@NotNull
@@ -12,7 +12,6 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
/**
@@ -62,7 +61,7 @@ public final class PatternTranslator extends AbstractTranslator {
private JsExpression translateTypePattern(@NotNull JsExpression expressionToMatch,
@NotNull JetTypePattern pattern) {
JsInvocation isCheck = AstUtil.newInvocation(Namer.isOperationReference(),
JsInvocation isCheck = AstUtil.newInvocation(context().namer().isOperationReference(),
expressionToMatch, getClassReference(pattern));
if (isNullable(pattern)) {
return addNullCheck(expressionToMatch, isCheck);
@@ -4,18 +4,26 @@ import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import java.util.HashMap;
import java.util.Map;
public class Aliaser {
static public Aliaser aliasesForStandardClasses() {
Aliaser result = new Aliaser();
//result.setAliasForDescriptor();
return result;
}
@NotNull
private final Map<JetDeclaration, JsName> aliases = new HashMap<JetDeclaration, JsName>();
private final Map<DeclarationDescriptor, JsName> aliases = new HashMap<DeclarationDescriptor, JsName>();
@Nullable
private JsName aliasForThis = null;
public Aliaser() {
private Aliaser() {
}
@NotNull
@@ -36,23 +44,23 @@ public class Aliaser {
return (aliasForThis != null);
}
public boolean hasAliasForDeclaration(@NotNull JetDeclaration declaration) {
public boolean hasAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
return aliases.containsKey(declaration);
}
@NotNull
public JsNameRef getAliasForDeclaration(@NotNull JetDeclaration declaration) {
public JsNameRef getAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
JsName alias = aliases.get(declaration);
assert alias != null : "Use has alias for declaration to check.";
return alias.makeRef();
}
public void setAliasForDeclaration(@NotNull JetDeclaration declaration, @NotNull JsName alias) {
public void setAliasForDescriptor(@NotNull DeclarationDescriptor declaration, @NotNull JsName alias) {
assert (!hasAliasForDeclaration(declaration)) : "This declaration already has an alias!";
aliases.put(declaration, alias);
}
public void removeAliasForDeclaration(@NotNull JetDeclaration declaration) {
public void removeAliasForDescriptor(@NotNull DeclarationDescriptor declaration) {
assert (hasAliasForDeclaration(declaration)) : "This declaration does not has an alias!";
aliases.remove(declaration);
}
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.k2js.declarations.Declarations;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
/**
* @author Talanov Pavel
@@ -40,7 +41,7 @@ public final class TranslationContext {
JsScope rootScope = program.getRootScope();
Scopes scopes = new Scopes(rootScope, rootScope, rootScope);
return new TranslationContext(null, program, bindingContext,
scopes, extractor, new Aliaser());
scopes, extractor, Aliaser.aliasesForStandardClasses(), Namer.newInstance(rootScope));
}
@NotNull
@@ -55,17 +56,21 @@ public final class TranslationContext {
private final Declarations declarations;
@NotNull
private final Aliaser aliaser;
@NotNull
private final Namer namer;
private TranslationContext(@Nullable JsName namespaceName, @NotNull JsProgram program,
@NotNull BindingContext bindingContext, @NotNull Scopes scopes,
@NotNull Declarations declarations, @NotNull Aliaser aliaser) {
@NotNull Declarations declarations, @NotNull Aliaser aliaser,
@NotNull Namer namer) {
this.program = program;
this.bindingContext = bindingContext;
this.namespaceName = namespaceName;
this.scopes = scopes;
this.declarations = declarations;
this.aliaser = aliaser;
this.namer = namer;
}
@NotNull
@@ -79,7 +84,7 @@ public final class TranslationContext {
JsName namespaceName = getNameForDescriptor(descriptor);
Scopes newScopes = new Scopes(namespaceScope, namespaceScope, namespaceScope);
return new TranslationContext(namespaceName, program, bindingContext, newScopes,
declarations, new Aliaser());
declarations, aliaser, namer);
}
@NotNull
@@ -92,7 +97,7 @@ public final class TranslationContext {
JsScope classScope = declarations.getScope(descriptor);
Scopes newScopes = new Scopes(classScope, classScope, scopes.namespaceScope);
return new TranslationContext(namespaceName, program, bindingContext,
newScopes, declarations, aliaser);
newScopes, declarations, aliaser, namer);
}
@NotNull
@@ -115,26 +120,21 @@ public final class TranslationContext {
JsScope functionScope = declarations.getScope(descriptor);
Scopes newScopes = new Scopes(functionScope, scopes.classScope, scopes.namespaceScope);
return new TranslationContext(namespaceName, program, bindingContext,
newScopes, declarations, aliaser);
newScopes, declarations, aliaser, namer);
}
// @NotNull TranslationContext newAliases(Map<JetDeclaration, JsName> newAliases) {
// Map<JetDeclaration, JsName> aliases = new HashMap<JetDeclaration, JsName>(this.aliases);
// aliases.putAll(newAliases);
// return new TranslationContext(namespaceName, program, bindingContext, scopes, declarations, aliases);
// }
// Note: Should be used if and only if scope has no corresponding descriptor
@NotNull
public TranslationContext newEnclosingScope(@NotNull JsScope enclosingScope) {
Scopes newScopes = new Scopes(enclosingScope, scopes.classScope, scopes.namespaceScope);
return new TranslationContext(namespaceName, program, bindingContext,
newScopes, declarations, aliaser);
newScopes, declarations, aliaser, namer);
}
//TODO: move to namer
@NotNull
public JsNameRef getNamespaceQualifiedReference(JsName name) {
public JsNameRef getNamespaceQualifiedReference(@NotNull JsName name) {
if (namespaceName != null) {
return AstUtil.newNameRef(namespaceName.makeRef(), name);
}
@@ -200,7 +200,13 @@ public final class TranslationContext {
return declarations.isDeclared(descriptor);
}
@NotNull
public Aliaser aliaser() {
return aliaser;
}
@NotNull
public Namer namer() {
return namer;
}
}
@@ -35,7 +35,7 @@ public abstract class AbstractInitializerTranslator extends AbstractTranslator {
@NotNull
public JsPropertyInitializer generateInitializeMethod() {
JsPropertyInitializer initializer = new JsPropertyInitializer();
initializer.setLabelExpr(context().program().getStringLiteral(Namer.INITIALIZE_METHOD_NAME));
initializer.setLabelExpr(Namer.initializeMethodReference());
initializer.setValueExpr(generateInitializerFunction());
return initializer;
}
@@ -8,7 +8,6 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.k2js.translate.utils.Namer;
import java.util.HashMap;
import java.util.Map;
@@ -52,8 +51,9 @@ public final class OperatorTable {
binaryOperatorsMap.put(JetTokens.PERCEQ, JsBinaryOperator.ASG_MOD);
}
//TODO: resolve
static {
operatorToFunctionNameReference.put(JetTokens.IS_KEYWORD, Namer.isOperationReference());
//operatorToFunctionNameReference.put(JetTokens.IS_KEYWORD, Namer.isOperationReference());
}
public static boolean hasCorrespondingBinaryOperator(@NotNull JetToken token) {
@@ -7,7 +7,6 @@ import com.google.dart.compiler.backend.js.ast.JsNameRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
@@ -55,15 +54,11 @@ public class ReferenceTranslator extends AbstractTranslator {
BindingUtils.getDescriptorForReferenceExpression(context().bindingContext(), expression);
if (referencedDescriptor == null) return null;
JetDeclaration declaration =
BindingUtils.getDeclarationForDescriptor(context().bindingContext(), referencedDescriptor);
if (declaration == null) return null;
if (!context().aliaser().hasAliasForDeclaration(declaration)) {
if (!context().aliaser().hasAliasForDeclaration(referencedDescriptor)) {
return null;
}
return context().aliaser().getAliasForDeclaration(declaration);
return context().aliaser().getAliasForDeclaration(referencedDescriptor);
}
@Nullable
@@ -1,33 +1,46 @@
package org.jetbrains.k2js.translate.utils;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author Talanov Pavel
*/
/*
* This class is a complete dummy and should completely change in the future
* This class is a dummy and should completely change in the future
*/
//TODO: rework into stateful class and include into context
public final class Namer {
private Namer() {
}
public static final String INITIALIZE_METHOD_NAME = "initialize";
private static final String INITIALIZE_METHOD_NAME = "initialize";
private static final String CLASS_OBJECT_NAME = "Class";
//private static final String CLASS_CREATE_METHOD_NAME = "create";
private static final String TRAIT_OBJECT_NAME = "Trait";
private static final String NAMESPACE_OBJECT_NAME = "Namespace";
private static final String SETTER_PREFIX = "set_";
private static final String GETTER_PREFIX = "get_";
private static final String BACKING_FIELD_PREFIX = "$";
// TODO: work on the unified approach to string constants
public static final String SUPER_METHOD_NAME = "super_init";
// public static final String DEFAULT_SETTER_PARAM_NAME = "val";
private static final String KOTLIN_OBJECT_NAME = "Kotlin";
public static String getClassObjectName() {
//TODO dummy representation
return CLASS_OBJECT_NAME;
@NotNull
public static JsNameRef initializeMethodReference() {
return AstUtil.newQualifiedNameRef(INITIALIZE_METHOD_NAME);
}
@NotNull
public static JsNameRef superMethodReference() {
return AstUtil.newQualifiedNameRef(SUPER_METHOD_NAME);
}
@NotNull
public static String nameForClassesVariable() {
return "classes";
}
public static String getNameForAccessor(String propertyName, boolean isGetter) {
@@ -54,38 +67,61 @@ public final class Namer {
return prefix + name;
}
public static String getNameForNamespace(String name) {
return name;
public static Namer newInstance(@NotNull JsScope rootScope) {
return new Namer(rootScope);
}
//TODO: dummy
public static JsNameRef classObjectReference() {
return AstUtil.newQualifiedNameRef("Class");
@NotNull
private final JsName kotlinName;
@NotNull
private final JsScope kotlinScope;
@NotNull
private final JsName className;
@NotNull
private final JsName traitName;
@NotNull
private final JsName namespaceName;
private Namer(@NotNull JsScope rootScope) {
kotlinName = rootScope.declareName(KOTLIN_OBJECT_NAME);
kotlinScope = new JsScope(rootScope, "Kotlin standard object");
traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME);
namespaceName = kotlinScope.declareName(NAMESPACE_OBJECT_NAME);
className = kotlinScope.declareName(CLASS_OBJECT_NAME);
}
public static JsNameRef classCreationMethodReference() {
return AstUtil.newQualifiedNameRef("Class.create");
@NotNull
public JsNameRef classCreationMethodReference() {
return kotlin(createMethodReference(className));
}
public static JsNameRef traitCreationMethodReference() {
return AstUtil.newQualifiedNameRef("Trait.create");
@NotNull
public JsNameRef traitCreationMethodReference() {
return kotlin(createMethodReference(traitName));
}
public static JsNameRef namespaceCreationMethodReference() {
return AstUtil.newQualifiedNameRef("Namespace.create");
@NotNull
public JsNameRef namespaceCreationMethodReference() {
return kotlin(createMethodReference(namespaceName));
}
public static JsNameRef isOperationReference() {
return AstUtil.newQualifiedNameRef("isType");
@NotNull
private JsNameRef createMethodReference(@NotNull JsName name) {
JsNameRef qualifier = name.makeRef();
JsNameRef reference = AstUtil.newQualifiedNameRef("create");
AstUtil.setQualifier(reference, qualifier);
return reference;
}
public static JsNameRef initializeMethodReference() {
return AstUtil.newQualifiedNameRef("initialize");
@NotNull
private JsNameRef kotlin(@NotNull JsNameRef reference) {
JsNameRef kotlinReference = kotlinName.makeRef();
AstUtil.setQualifier(reference, kotlinReference);
return reference;
}
public static String nameForClassesVariable() {
return "classes";
@NotNull
public JsNameRef isOperationReference() {
return kotlin(AstUtil.newQualifiedNameRef("isType"));
}
}
@@ -0,0 +1,20 @@
package org.jetbrains.k2js.test;
import org.junit.Test;
/**
* @author Talanov Pavel
*/
public class StandardClassesTest extends TranslationTest {
final private static String MAIN = "standardClasses/";
@Override
protected String mainDirectory() {
return MAIN;
}
@Test
public void array() throws Exception {
testFooBoxIsTrue("array.kt");
}
}
+5
View File
@@ -458,3 +458,8 @@ Kotlin.Array = Class.create({
this.array[index] = value;
}
})
Kotlin.Class = Class
Kotlin.Namespace = Namespace
Kotlin.Trait = Trait
Kotlin.isType = isType
@@ -0,0 +1,9 @@
namespace foo
fun box() : Boolean {
val a = Array<Int>(2)
a.set(1, 2)
return a.get(1) == 2
}