Operator overloading: simple cases with ++ and --.
This commit is contained in:
Generated
+1
-3
@@ -1,11 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DependencyValidationManager">
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</component>
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="IdProvider" IDEtalkID="C5E9A8C8EEE7359144ADEDA64003CE1D" />
|
||||
<component name="JavadocGenerationManager">
|
||||
<option name="OUTPUT_DIRECTORY" />
|
||||
<option name="OPTION_SCOPE" value="protected" />
|
||||
|
||||
Generated
+365
-509
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@ import java.util.List;
|
||||
* This class contains some code related to BindingContext use. Intention is not to pollute other classes.
|
||||
*/
|
||||
public final class BindingUtils {
|
||||
|
||||
private BindingUtils() {
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
public JsNode visitBlockExpression(@NotNull JetBlockExpression jetBlock, @NotNull TranslationContext context) {
|
||||
List<JetElement> statements = jetBlock.getStatements();
|
||||
JsBlock jsBlock = new JsBlock();
|
||||
TranslationContext newContext = context.newBlock();
|
||||
TranslationContext newContext = context.newBlock(jsBlock);
|
||||
for (JetElement statement : statements) {
|
||||
assert statement instanceof JetExpression : "Elements in JetBlockExpression " +
|
||||
"should be of type JetExpression";
|
||||
|
||||
@@ -26,16 +26,24 @@ public final class OperationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JsPostfixOperation translatePostfixOperation(@NotNull JetPostfixExpression expression) {
|
||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
|
||||
JsExpression translatePostfixOperation(@NotNull JetPostfixExpression expression) {
|
||||
JsExpression baseExpression = translateBaseExpression(expression);
|
||||
JsNameRef operationReference = getOverloadedOperationReference(expression);
|
||||
if (operationReference != null) {
|
||||
return overloadedMethodInvocation(baseExpression, operationReference);
|
||||
}
|
||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
|
||||
return new JsPostfixOperation(operator, baseExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JsPrefixOperation translatePrefixOperation(@NotNull JetPrefixExpression expression) {
|
||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
|
||||
JsExpression translatePrefixOperation(@NotNull JetPrefixExpression expression) {
|
||||
JsExpression baseExpression = translateBaseExpression(expression);
|
||||
JsNameRef operationReference = getOverloadedOperationReference(expression);
|
||||
if (operationReference != null) {
|
||||
return overloadedMethodInvocation(baseExpression, operationReference);
|
||||
}
|
||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
|
||||
return new JsPrefixOperation(operator, baseExpression);
|
||||
}
|
||||
|
||||
@@ -46,6 +54,12 @@ public final class OperationTranslator extends AbstractTranslator {
|
||||
return Translation.translateAsExpression(baseExpression, translationContext());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression overloadedMethodInvocation(@NotNull JsExpression base, @NotNull JsNameRef operationReference) {
|
||||
AstUtil.setQualifier(operationReference, base);
|
||||
return AstUtil.newInvocation(operationReference);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetToken getOperationToken(@NotNull JetUnaryExpression expression) {
|
||||
JetSimpleNameExpression operationExpression = expression.getOperationSign();
|
||||
@@ -104,14 +118,13 @@ public final class OperationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private JsExpression overloadedMethodInvocation(JsExpression left, JsExpression right, JsNameRef operationReference) {
|
||||
operationReference.setQualifier(left);
|
||||
AstUtil.setQualifier(operationReference, left);
|
||||
return AstUtil.newInvocation(operationReference, right);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsNameRef getOverloadedOperationReference(@NotNull JetBinaryExpression expression) {
|
||||
DeclarationDescriptor operationDescriptor = BindingUtils.getDescriptorForReferenceExpression
|
||||
(translationContext().bindingContext(), expression.getOperationReference());
|
||||
private JsNameRef getOverloadedOperationReference(@NotNull JetExpression expression) {
|
||||
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression);
|
||||
if (operationDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -121,6 +134,20 @@ public final class OperationTranslator extends AbstractTranslator {
|
||||
return translationContext().getNameForDescriptor(operationDescriptor).makeRef();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DeclarationDescriptor getOperationDescriptor(@NotNull JetExpression expression) {
|
||||
JetSimpleNameExpression operationReference = null;
|
||||
if (expression instanceof JetBinaryExpression) {
|
||||
operationReference = ((JetBinaryExpression) expression).getOperationReference();
|
||||
}
|
||||
if (expression instanceof JetUnaryExpression) {
|
||||
operationReference = ((JetUnaryExpression) expression).getOperationSign();
|
||||
}
|
||||
assert operationReference != null : "should be applied only to unary or binary operations";
|
||||
return BindingUtils.getDescriptorForReferenceExpression
|
||||
(translationContext().bindingContext(), operationReference);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateRightExpression(@NotNull JetBinaryExpression expression) {
|
||||
JetExpression rightExpression = expression.getRight();
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class Translation {
|
||||
public static void generateAst(@NotNull JsProgram result, @NotNull BindingContext bindingContext,
|
||||
@NotNull Declarations declarations, @NotNull JetNamespace namespace) {
|
||||
JsBlock block = result.getFragmentBlock(0);
|
||||
TranslationContext context = TranslationContext.rootContext(result, bindingContext, declarations);
|
||||
TranslationContext context = TranslationContext.rootContext(result, bindingContext, declarations, block);
|
||||
block.addStatement(Translation.translateNamespace(namespace, context));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
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.backend.js.ast.JsProgram;
|
||||
import com.google.dart.compiler.backend.js.ast.JsScope;
|
||||
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;
|
||||
@@ -35,10 +32,10 @@ public final class TranslationContext {
|
||||
|
||||
@NotNull
|
||||
public static TranslationContext rootContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
||||
@NotNull Declarations extractor) {
|
||||
@NotNull Declarations extractor, @NotNull JsBlock block) {
|
||||
JsScope rootScope = program.getRootScope();
|
||||
Scopes scopes = new Scopes(rootScope, rootScope, rootScope);
|
||||
return new TranslationContext(null, program, bindingContext, scopes, extractor);
|
||||
return new TranslationContext(null, program, bindingContext, scopes, extractor, block);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -51,16 +48,19 @@ public final class TranslationContext {
|
||||
private final JsName namespaceName;
|
||||
@NotNull
|
||||
private final Declarations declarations;
|
||||
@NotNull
|
||||
private final JsBlock block;
|
||||
|
||||
|
||||
private TranslationContext(@Nullable JsName namespaceName, @NotNull JsProgram program,
|
||||
@NotNull BindingContext bindingContext, @NotNull Scopes scopes,
|
||||
@NotNull Declarations declarations) {
|
||||
@NotNull Declarations declarations, @NotNull JsBlock block) {
|
||||
this.program = program;
|
||||
this.bindingContext = bindingContext;
|
||||
this.namespaceName = namespaceName;
|
||||
this.scopes = scopes;
|
||||
this.declarations = declarations;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -73,14 +73,14 @@ public final class TranslationContext {
|
||||
JsScope namespaceScope = declarations.getScope(descriptor);
|
||||
JsName namespaceName = scopes.enclosingScope.findExistingName(descriptor.getName());
|
||||
Scopes newScopes = new Scopes(namespaceScope, namespaceScope, namespaceScope);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations, block);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TranslationContext newBlock() {
|
||||
public TranslationContext newBlock(@NotNull JsBlock newBlock) {
|
||||
Scopes newScopes = new Scopes(new JsScope
|
||||
(scopes.enclosingScope, "Scope for a block"), scopes.classScope, scopes.namespaceScope);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations, newBlock);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -92,7 +92,7 @@ public final class TranslationContext {
|
||||
public TranslationContext newClass(@NotNull ClassDescriptor descriptor) {
|
||||
JsScope classScope = declarations.getScope(descriptor);
|
||||
Scopes newScopes = new Scopes(classScope, classScope, scopes.namespaceScope);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations, block);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -114,20 +114,20 @@ public final class TranslationContext {
|
||||
public TranslationContext newFunctionDeclaration(@NotNull FunctionDescriptor descriptor) {
|
||||
JsScope functionScope = declarations.getScope(descriptor);
|
||||
Scopes newScopes = new Scopes(functionScope, scopes.classScope, scopes.namespaceScope);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations, block);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TranslationContext newFunctionLiteral(@NotNull JsScope correspondingScope) {
|
||||
Scopes newScopes = new Scopes(correspondingScope, scopes.classScope, scopes.namespaceScope);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations, block);
|
||||
}
|
||||
|
||||
// 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);
|
||||
return new TranslationContext(namespaceName, program, bindingContext, newScopes, declarations, block);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,4 +18,14 @@ public class OperatorOverloadingTest extends TranslationTest {
|
||||
public void plusOverload() throws Exception {
|
||||
testFooBoxIsTrue("plusOverload.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postfixInc() throws Exception {
|
||||
testFooBoxIsTrue("postfixIncOverload.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefixInc() throws Exception {
|
||||
testFooBoxIsTrue("prefixDecOverload.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace foo
|
||||
|
||||
class MyInt() {
|
||||
var b = 0
|
||||
|
||||
fun inc() {
|
||||
b = b + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box() : Boolean {
|
||||
var c = MyInt()
|
||||
c++;
|
||||
return (c.b == 1);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace foo
|
||||
|
||||
class MyInt() {
|
||||
var b = 0
|
||||
|
||||
fun dec() {
|
||||
b = b + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box() : Boolean {
|
||||
var c = MyInt()
|
||||
--c;
|
||||
return (c.b == 1);
|
||||
}
|
||||
Reference in New Issue
Block a user