.
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");
|
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);
|
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) {
|
public static JsExpression equalsTrue(JsExpression expression, JsProgram program) {
|
||||||
return equals(expression, program.getTrueLiteral());
|
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
|
@Override
|
||||||
public Void visitPropertyDescriptor(@NotNull PropertyDescriptor descriptor, @NotNull JsScope enclosingScope) {
|
public Void visitPropertyDescriptor(@NotNull PropertyDescriptor descriptor, @NotNull JsScope enclosingScope) {
|
||||||
String propertyName = descriptor.getName();
|
String propertyName = descriptor.getName();
|
||||||
|
declarations.putName(descriptor, enclosingScope.declareName(Namer.getKotlinBackingFieldName(propertyName)));
|
||||||
extractAccessor(descriptor.getGetter(), true, propertyName, enclosingScope);
|
extractAccessor(descriptor.getGetter(), true, propertyName, enclosingScope);
|
||||||
if (descriptor.isVar()) {
|
if (descriptor.isVar()) {
|
||||||
extractAccessor(descriptor.getSetter(), false, propertyName, enclosingScope);
|
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);
|
JsScope accessorScope = new JsScope(enclosingScope, (isGetter ? "getter " : "setter ") + propertyName);
|
||||||
declarations.putScope(descriptor, accessorScope);
|
declarations.putScope(descriptor, accessorScope);
|
||||||
declarations.putName(descriptor, jsName);
|
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
|
@Override
|
||||||
public Void visitNamespaceDescriptor(NamespaceDescriptor descriptor, JsScope enclosingScope) {
|
public Void visitNamespaceDescriptor(@NotNull NamespaceDescriptor descriptor, @NotNull JsScope enclosingScope) {
|
||||||
JsScope namespaceScope = extractNamespaceDeclaration(descriptor, enclosingScope);
|
JsScope namespaceScope = extractNamespaceDeclaration(descriptor, enclosingScope);
|
||||||
visitMemberDeclarations(descriptor, namespaceScope);
|
visitMemberDeclarations(descriptor, namespaceScope);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsNameRef getterReference =
|
JsNameRef getterReference =
|
||||||
TranslationUtils.generateCorrectReference(translationContext(), expression, getterName);
|
TranslationUtils.getReference(translationContext(), expression, getterName);
|
||||||
return AstUtil.newInvocation(getterReference);
|
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
|
// Problem is that namespace properties do not generate getters and setter actually so they must be referenced
|
||||||
// by name
|
// by name
|
||||||
JsExpression result;
|
JsExpression result;
|
||||||
|
String name = expression.getReferencedName();
|
||||||
|
result = resolveAsPropertyAccess(expression);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
result = resolveAsGlobalReference(expression);
|
result = resolveAsGlobalReference(expression);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
@@ -36,15 +41,15 @@ public class ReferenceTranslator extends AbstractTranslator {
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
JsInvocation getterCall =
|
|
||||||
Translation.propertyAccessTranslator(translationContext()).resolveAsPropertyGet(expression);
|
|
||||||
if (getterCall != null) {
|
|
||||||
return getterCall;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Undefined name in this scope: " + expression.getReferencedName());
|
throw new AssertionError("Undefined name in this scope: " + expression.getReferencedName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private JsInvocation resolveAsPropertyAccess(@NotNull JetSimpleNameExpression expression) {
|
||||||
|
return Translation.propertyAccessTranslator(translationContext()).resolveAsPropertyGet(expression);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JsExpression resolveAsGlobalReference(@NotNull JetSimpleNameExpression expression) {
|
private JsExpression resolveAsGlobalReference(@NotNull JetSimpleNameExpression expression) {
|
||||||
DeclarationDescriptor referencedDescriptor =
|
DeclarationDescriptor referencedDescriptor =
|
||||||
@@ -56,17 +61,19 @@ public class ReferenceTranslator extends AbstractTranslator {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsName referencedName = translationContext().getNameForDescriptor(referencedDescriptor);
|
JsName referencedName = translationContext().getNameForDescriptor(referencedDescriptor);
|
||||||
return TranslationUtils.generateCorrectReference(translationContext(), expression, referencedName);
|
return TranslationUtils.getReference(translationContext(), expression, referencedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JsExpression resolveAsLocalReference(@NotNull JetSimpleNameExpression expression) {
|
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) {
|
if (localReferencedName == null) {
|
||||||
return 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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
@@ -16,50 +15,28 @@ public final class TranslationUtils {
|
|||||||
static public JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
|
static public JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
|
||||||
@NotNull JsExpression expressionToCheck) {
|
@NotNull JsExpression expressionToCheck) {
|
||||||
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
||||||
return new JsBinaryOperation
|
return AstUtil.notEqual(expressionToCheck, nullLiteral);
|
||||||
(JsBinaryOperator.NEQ, expressionToCheck, nullLiteral);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public JsBinaryOperation isNullCheck(@NotNull TranslationContext context,
|
static public JsBinaryOperation isNullCheck(@NotNull TranslationContext context,
|
||||||
@NotNull JsExpression expressionToCheck) {
|
@NotNull JsExpression expressionToCheck) {
|
||||||
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
||||||
return new JsBinaryOperation
|
return AstUtil.equals(expressionToCheck, nullLiteral);
|
||||||
(JsBinaryOperator.REF_EQ, expressionToCheck, nullLiteral);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: make logic clear
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public JsNameRef generateCorrectReference(@NotNull TranslationContext context,
|
static public JsNameRef getReference(@NotNull TranslationContext context,
|
||||||
@NotNull JetSimpleNameExpression expression,
|
@NotNull JetSimpleNameExpression expression,
|
||||||
@NotNull JsName referencedName) {
|
@NotNull JsName referencedName) {
|
||||||
if (requiresNamespaceQualifier(context, referencedName)) {
|
return (new ReferenceProvider(context, expression, referencedName)).generateCorrectReference();
|
||||||
return context.getNamespaceQualifiedReference(referencedName);
|
|
||||||
} else if (requiresThisQualifier(context, expression, referencedName)) {
|
|
||||||
return AstUtil.thisQualifiedReference(referencedName);
|
|
||||||
}
|
|
||||||
return referencedName.makeRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
@Nullable
|
||||||
static public JsName getLocalReferencedName(@NotNull TranslationContext context,
|
static public JsName getLocalReferencedName(@NotNull TranslationContext context,
|
||||||
@NotNull JetSimpleNameExpression expression) {
|
@NotNull String name) {
|
||||||
String referencedName = expression.getReferencedName();
|
return context.enclosingScope().findExistingName(name);
|
||||||
return context.enclosingScope().findExistingName(referencedName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
*/
|
*/
|
||||||
//TODO: fix members order
|
|
||||||
public class WhenTranslator extends AbstractTranslator {
|
public class WhenTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -70,6 +69,11 @@ public class WhenTranslator extends AbstractTranslator {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsVars generateInitStatement() {
|
||||||
|
return AstUtil.newVar(dummyCounterName, translationContext().program().getNumberLiteral(0));
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsBinaryOperation generateConditionStatement() {
|
private JsBinaryOperation generateConditionStatement() {
|
||||||
JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size());
|
JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size());
|
||||||
@@ -81,11 +85,6 @@ public class WhenTranslator extends AbstractTranslator {
|
|||||||
return new JsPrefixOperation(JsUnaryOperator.INC, dummyCounterName.makeRef());
|
return new JsPrefixOperation(JsUnaryOperator.INC, dummyCounterName.makeRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsVars generateInitStatement() {
|
|
||||||
return AstUtil.newVar(dummyCounterName, translationContext().program().getNumberLiteral(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsStatement translateEntry(@NotNull JetWhenEntry entry) {
|
private JsStatement translateEntry(@NotNull JetWhenEntry entry) {
|
||||||
JsStatement statementToExecute = translateExpressionToExecute(entry);
|
JsStatement statementToExecute = translateExpressionToExecute(entry);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class BasicClassTest extends IncludeLibraryTest {
|
|||||||
testFooBoxIsTrue("methodDeclarationAndCall.kt");
|
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
|
@Test
|
||||||
public void constructorWithParameter() throws Exception {
|
public void constructorWithParameter() throws Exception {
|
||||||
testFooBoxIsTrue("constructorWithParameter.kt");
|
testFooBoxIsTrue("constructorWithParameter.kt");
|
||||||
|
|||||||
@@ -50,6 +50,14 @@ public class KotlinLibTest extends TranslationTest {
|
|||||||
runPropertyTypeCheck("Class", propertyToType);
|
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
|
@Test
|
||||||
public void traitObjectHasCreateMethod() throws Exception {
|
public void traitObjectHasCreateMethod() throws Exception {
|
||||||
final Map<String, Class<? extends Scriptable>> propertyToType
|
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() {
|
(function() {
|
||||||
|
|
||||||
var _toString = Object.prototype.toString,
|
var _toString = Object.prototype.toString,
|
||||||
|
|||||||
Reference in New Issue
Block a user