.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user