This commit is contained in:
Pavel Talanov
2011-11-21 16:29:31 +04:00
parent 7d43131173
commit 36d033ea48
10 changed files with 111 additions and 57 deletions
@@ -308,15 +308,15 @@ public class AstUtil {
throw new AssertionError("Set qualifier should be applied only to JsInvocation or JsNameRef instances");
}
public static JsExpression equals(JsExpression arg1, JsExpression arg2) {
public static JsBinaryOperation equals(JsExpression arg1, JsExpression arg2) {
return new JsBinaryOperation(JsBinaryOperator.REF_EQ, arg1, arg2);
}
public static JsBinaryOperation notEqual(JsExpression arg1, JsExpression arg2) {
return new JsBinaryOperation(JsBinaryOperator.REF_NEQ, arg1, arg2);
}
public static JsExpression equalsTrue(JsExpression expression, JsProgram program) {
return equals(expression, program.getTrueLiteral());
}
public static void thisQualify(JsExpression expression) {
setQualifier(expression, new JsThisRef());
}
}
@@ -71,6 +71,7 @@ public final class ExtractionVisitor extends DeclarationDescriptorVisitor<Void,
@Override
public Void visitPropertyDescriptor(@NotNull PropertyDescriptor descriptor, @NotNull JsScope enclosingScope) {
String propertyName = descriptor.getName();
declarations.putName(descriptor, enclosingScope.declareName(Namer.getKotlinBackingFieldName(propertyName)));
extractAccessor(descriptor.getGetter(), true, propertyName, enclosingScope);
if (descriptor.isVar()) {
extractAccessor(descriptor.getSetter(), false, propertyName, enclosingScope);
@@ -87,13 +88,10 @@ public final class ExtractionVisitor extends DeclarationDescriptorVisitor<Void,
JsScope accessorScope = new JsScope(enclosingScope, (isGetter ? "getter " : "setter ") + propertyName);
declarations.putScope(descriptor, accessorScope);
declarations.putName(descriptor, jsName);
// Note : We do not put backing field name into declarations because it can't be referenced from outside
//TODO: find if there is repetetive code like descriptor.getCorrespondingProperty().getName())
accessorScope.declareName(Namer.getKotlinBackingFieldName(descriptor.getCorrespondingProperty().getName()));
}
@Override
public Void visitNamespaceDescriptor(NamespaceDescriptor descriptor, JsScope enclosingScope) {
public Void visitNamespaceDescriptor(@NotNull NamespaceDescriptor descriptor, @NotNull JsScope enclosingScope) {
JsScope namespaceScope = extractNamespaceDeclaration(descriptor, enclosingScope);
visitMemberDeclarations(descriptor, namespaceScope);
return null;
@@ -50,7 +50,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
return null;
}
JsNameRef getterReference =
TranslationUtils.generateCorrectReference(translationContext(), expression, getterName);
TranslationUtils.getReference(translationContext(), expression, getterName);
return AstUtil.newInvocation(getterReference);
}
@@ -0,0 +1,52 @@
package org.jetbrains.k2js.translate;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lexer.JetTokens;
/**
* @author Talanov Pavel
*/
public final class ReferenceProvider {
@NotNull
private final TranslationContext context;
@NotNull
private final JsName referencedName;
private boolean requiresThisQualifier;
private boolean requiresNamespaceQualifier;
public ReferenceProvider(@NotNull TranslationContext context,
@NotNull JetSimpleNameExpression expression,
@NotNull JsName referencedName) {
this.context = context;
this.referencedName = referencedName;
this.requiresThisQualifier = requiresThisQualifier(expression);
this.requiresNamespaceQualifier = requiresNamespaceQualifier();
}
@NotNull
public JsNameRef generateCorrectReference() {
if (requiresNamespaceQualifier) {
return context.getNamespaceQualifiedReference(referencedName);
} else if (requiresThisQualifier) {
return AstUtil.thisQualifiedReference(referencedName);
}
return referencedName.makeRef();
}
private boolean requiresNamespaceQualifier() {
return context.namespaceScope().ownsName(referencedName);
}
private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression) {
JsName name = context.enclosingScope().findExistingName(referencedName.getIdent());
boolean isClassMember = context.classScope().ownsName(name);
boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
return isClassMember || isBackingFieldAccess;
}
}
@@ -28,6 +28,11 @@ public class ReferenceTranslator extends AbstractTranslator {
// Problem is that namespace properties do not generate getters and setter actually so they must be referenced
// by name
JsExpression result;
String name = expression.getReferencedName();
result = resolveAsPropertyAccess(expression);
if (result != null) {
return result;
}
result = resolveAsGlobalReference(expression);
if (result != null) {
return result;
@@ -36,15 +41,15 @@ public class ReferenceTranslator extends AbstractTranslator {
if (result != null) {
return result;
}
JsInvocation getterCall =
Translation.propertyAccessTranslator(translationContext()).resolveAsPropertyGet(expression);
if (getterCall != null) {
return getterCall;
}
throw new AssertionError("Undefined name in this scope: " + expression.getReferencedName());
}
@Nullable
private JsInvocation resolveAsPropertyAccess(@NotNull JetSimpleNameExpression expression) {
return Translation.propertyAccessTranslator(translationContext()).resolveAsPropertyGet(expression);
}
@Nullable
private JsExpression resolveAsGlobalReference(@NotNull JetSimpleNameExpression expression) {
DeclarationDescriptor referencedDescriptor =
@@ -56,17 +61,19 @@ public class ReferenceTranslator extends AbstractTranslator {
return null;
}
JsName referencedName = translationContext().getNameForDescriptor(referencedDescriptor);
return TranslationUtils.generateCorrectReference(translationContext(), expression, referencedName);
return TranslationUtils.getReference(translationContext(), expression, referencedName);
}
@Nullable
private JsExpression resolveAsLocalReference(@NotNull JetSimpleNameExpression expression) {
JsName localReferencedName = TranslationUtils.getLocalReferencedName(translationContext(), expression);
String name = expression.getReferencedName();
assert name != null : "SimpleNameExpression should reference a name";
JsName localReferencedName = TranslationUtils.getLocalReferencedName
(translationContext(), name);
if (localReferencedName == null) {
return null;
}
return TranslationUtils.generateCorrectReference(translationContext(), expression, localReferencedName);
return localReferencedName.makeRef();
}
}
@@ -5,7 +5,6 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lexer.JetTokens;
/**
* @author Talanov Pavel
@@ -16,50 +15,28 @@ public final class TranslationUtils {
static public JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
@NotNull JsExpression expressionToCheck) {
JsNullLiteral nullLiteral = context.program().getNullLiteral();
return new JsBinaryOperation
(JsBinaryOperator.NEQ, expressionToCheck, nullLiteral);
return AstUtil.notEqual(expressionToCheck, nullLiteral);
}
@NotNull
static public JsBinaryOperation isNullCheck(@NotNull TranslationContext context,
@NotNull JsExpression expressionToCheck) {
JsNullLiteral nullLiteral = context.program().getNullLiteral();
return new JsBinaryOperation
(JsBinaryOperator.REF_EQ, expressionToCheck, nullLiteral);
return AstUtil.equals(expressionToCheck, nullLiteral);
}
//TODO: make logic clear
@NotNull
static public JsNameRef generateCorrectReference(@NotNull TranslationContext context,
@NotNull JetSimpleNameExpression expression,
@NotNull JsName referencedName) {
if (requiresNamespaceQualifier(context, referencedName)) {
return context.getNamespaceQualifiedReference(referencedName);
} else if (requiresThisQualifier(context, expression, referencedName)) {
return AstUtil.thisQualifiedReference(referencedName);
}
return referencedName.makeRef();
static public JsNameRef getReference(@NotNull TranslationContext context,
@NotNull JetSimpleNameExpression expression,
@NotNull JsName referencedName) {
return (new ReferenceProvider(context, expression, referencedName)).generateCorrectReference();
}
static private boolean requiresNamespaceQualifier(@NotNull TranslationContext context,
@NotNull JsName referencedName) {
return context.namespaceScope().ownsName(referencedName);
}
static private boolean requiresThisQualifier(@NotNull TranslationContext context,
@NotNull JetSimpleNameExpression expression,
@NotNull JsName referencedName) {
JsName name = context.enclosingScope().findExistingName(referencedName.getIdent());
boolean isClassMember = context.classScope().ownsName(name);
boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
return isClassMember || isBackingFieldAccess;
}
@Nullable
static public JsName getLocalReferencedName(@NotNull TranslationContext context,
@NotNull JetSimpleNameExpression expression) {
String referencedName = expression.getReferencedName();
return context.enclosingScope().findExistingName(referencedName);
@NotNull String name) {
return context.enclosingScope().findExistingName(name);
}
}
@@ -12,7 +12,6 @@ import java.util.List;
/**
* @author Talanov Pavel
*/
//TODO: fix members order
public class WhenTranslator extends AbstractTranslator {
@NotNull
@@ -70,6 +69,11 @@ public class WhenTranslator extends AbstractTranslator {
return result;
}
@NotNull
private JsVars generateInitStatement() {
return AstUtil.newVar(dummyCounterName, translationContext().program().getNumberLiteral(0));
}
@NotNull
private JsBinaryOperation generateConditionStatement() {
JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size());
@@ -81,11 +85,6 @@ public class WhenTranslator extends AbstractTranslator {
return new JsPrefixOperation(JsUnaryOperator.INC, dummyCounterName.makeRef());
}
@NotNull
private JsVars generateInitStatement() {
return AstUtil.newVar(dummyCounterName, translationContext().program().getNumberLiteral(0));
}
@NotNull
private JsStatement translateEntry(@NotNull JetWhenEntry entry) {
JsStatement statementToExecute = translateExpressionToExecute(entry);
@@ -24,7 +24,7 @@ public class BasicClassTest extends IncludeLibraryTest {
testFooBoxIsTrue("methodDeclarationAndCall.kt");
}
//TODO: wait for bugfix and implement properties as consructor parameter declaration
//TODO: wait for bugfix and implement properties as constructor parameter declaration
@Test
public void constructorWithParameter() throws Exception {
testFooBoxIsTrue("constructorWithParameter.kt");
@@ -50,6 +50,14 @@ public class KotlinLibTest extends TranslationTest {
runPropertyTypeCheck("Class", propertyToType);
}
@Test
public void namespaceObjectHasCreateMethod() throws Exception {
final Map<String, Class<? extends Scriptable>> propertyToType
= new HashMap<String, Class<? extends Scriptable>>();
propertyToType.put("create", Function.class);
runPropertyTypeCheck("Namespace", propertyToType);
}
@Test
public void traitObjectHasCreateMethod() throws Exception {
final Map<String, Class<? extends Scriptable>> propertyToType
+13
View File
@@ -127,6 +127,19 @@ var Trait = (function() {
};
})();
var Namespace = (function() {
function create() {
return Class.create.apply(this, arguments);
}
return {
create: create
};
})();
(function() {
var _toString = Object.prototype.toString,