expression as statement bug fixed
This commit is contained in:
Generated
+572
-654
File diff suppressed because it is too large
Load Diff
@@ -120,7 +120,7 @@ public final class K2JSTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void includeRtJar() {
|
private void includeRtJar() {
|
||||||
final File rtJar = CompileEnvironment.findRtJar(true);
|
final File rtJar = CompileEnvironment.findRtJar();
|
||||||
environment.addToClasspath(rtJar);
|
environment.addToClasspath(rtJar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.jetbrains.k2js.translate.declaration;
|
package org.jetbrains.k2js.translate.declaration;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
|
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
|
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lang.psi.JetParameter;
|
|||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
|
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -67,14 +68,14 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addSuperclassReferences(@NotNull JsInvocation jsClassDeclaration) {
|
private void addSuperclassReferences(@NotNull JsInvocation jsClassDeclaration) {
|
||||||
for (JsNameRef superClassReference : getSuperclassNameReferences()) {
|
for (JsExpression superClassReference : getSuperclassNameReferences()) {
|
||||||
jsClassDeclaration.getArguments().add(superClassReference);
|
jsClassDeclaration.getArguments().add(superClassReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JsNameRef> getSuperclassNameReferences() {
|
private List<JsExpression> getSuperclassNameReferences() {
|
||||||
List<JsNameRef> superclassReferences = new ArrayList<JsNameRef>();
|
List<JsExpression> superclassReferences = new ArrayList<JsExpression>();
|
||||||
List<ClassDescriptor> superclassDescriptors =
|
List<ClassDescriptor> superclassDescriptors =
|
||||||
BindingUtils.getSuperclassDescriptors(context().bindingContext(), classDeclaration);
|
BindingUtils.getSuperclassDescriptors(context().bindingContext(), classDeclaration);
|
||||||
addAncestorClass(superclassReferences, superclassDescriptors);
|
addAncestorClass(superclassReferences, superclassDescriptors);
|
||||||
@@ -82,7 +83,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
return superclassReferences;
|
return superclassReferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTraits(@NotNull List<JsNameRef> superclassReferences,
|
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
||||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
for (ClassDescriptor superClassDescriptor :
|
for (ClassDescriptor superClassDescriptor :
|
||||||
superclassDescriptors) {
|
superclassDescriptors) {
|
||||||
@@ -91,7 +92,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAncestorClass(@NotNull List<JsNameRef> superclassReferences,
|
private void addAncestorClass(@NotNull List<JsExpression> superclassReferences,
|
||||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
//here we remove ancestor class from the list
|
//here we remove ancestor class from the list
|
||||||
ClassDescriptor ancestorClass = findAndRemoveAncestorClass(superclassDescriptors);
|
ClassDescriptor ancestorClass = findAndRemoveAncestorClass(superclassDescriptors);
|
||||||
@@ -101,10 +102,14 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsNameRef getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
||||||
//TODO we actually know that in current implementation superclass must have an alias but
|
//TODO we actually know that in current implementation superclass must have an alias but
|
||||||
// in future it might change
|
// in future it might change
|
||||||
return context().aliaser().getAliasForDeclaration(superClassDescriptor).makeRef();
|
if (aliaser().hasAliasForDeclaration(superClassDescriptor)) {
|
||||||
|
return context().aliaser().getAliasForDeclaration(superClassDescriptor).makeRef();
|
||||||
|
} else {
|
||||||
|
return ReferenceTranslator.translateAsFQReference(superClassDescriptor, context());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
|||||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.DefaultValueArgument;
|
import org.jetbrains.jet.lang.resolve.calls.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
|
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
@@ -52,7 +49,7 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
List<JsExpression> arguments = Collections.emptyList();
|
List<JsExpression> arguments = Collections.emptyList();
|
||||||
ResolvedCall<?> resolvedCall =
|
ResolvedCall<?> resolvedCall =
|
||||||
getResolvedCall(context.bindingContext(), unaryExpression.getOperationReference());
|
getResolvedCall(context.bindingContext(), unaryExpression.getOperationReference());
|
||||||
return new CallTranslator(receiver, arguments, resolvedCall, null, context);
|
return new CallTranslator(receiver, null, arguments, resolvedCall, null, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: method too long
|
//TODO: method too long
|
||||||
@@ -75,7 +72,7 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
ResolvedCall<?> resolvedCall =
|
ResolvedCall<?> resolvedCall =
|
||||||
getResolvedCall(context.bindingContext(), binaryExpression.getOperationReference());
|
getResolvedCall(context.bindingContext(), binaryExpression.getOperationReference());
|
||||||
return new CallTranslator(receiver, arguments, resolvedCall, null, context);
|
return new CallTranslator(receiver, null, arguments, resolvedCall, null, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -83,7 +80,23 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
@Nullable JsExpression receiver) {
|
@Nullable JsExpression receiver) {
|
||||||
ResolvedCall<?> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
|
ResolvedCall<?> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
|
||||||
List<JsExpression> arguments = translateArgumentsForCallExpression(callExpression, context);
|
List<JsExpression> arguments = translateArgumentsForCallExpression(callExpression, context);
|
||||||
return new CallTranslator(receiver, arguments, resolvedCall, null, context);
|
JsExpression callee = null;
|
||||||
|
if (resolvedCall.getCandidateDescriptor() instanceof ExpressionAsFunctionDescriptor) {
|
||||||
|
callee = Translation.translateAsExpression(getCallee(callExpression), context);
|
||||||
|
}
|
||||||
|
return new CallTranslator(receiver, callee, arguments, resolvedCall, null, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private JsExpression translateCalleeIfExpressionAsFunction(@NotNull JetCallExpression callExpression) {
|
||||||
|
//TODO: util
|
||||||
|
JetExpression calleeExpression = callExpression.getCalleeExpression();
|
||||||
|
assert calleeExpression != null;
|
||||||
|
JsExpression callee = null;
|
||||||
|
if (isExpressionAsFunction(context.bindingContext(), calleeExpression)) {
|
||||||
|
callee = Translation.translateAsExpression(calleeExpression, context);
|
||||||
|
}
|
||||||
|
return callee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -134,7 +147,7 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
@NotNull ResolvedCall<?> resolvedCall,
|
@NotNull ResolvedCall<?> resolvedCall,
|
||||||
@Nullable CallableDescriptor descriptorToCall,
|
@Nullable CallableDescriptor descriptorToCall,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new CallTranslator(receiver, arguments, resolvedCall, descriptorToCall, context)).translate();
|
return (new CallTranslator(receiver, null, arguments, resolvedCall, descriptorToCall, context)).translate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -172,7 +185,10 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JsExpression receiver;
|
private /*var*/ JsExpression receiver;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final JsExpression callee;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final List<JsExpression> arguments;
|
private final List<JsExpression> arguments;
|
||||||
@@ -183,13 +199,15 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final CallableDescriptor descriptor;
|
private final CallableDescriptor descriptor;
|
||||||
|
|
||||||
private CallTranslator(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
private CallTranslator(@Nullable JsExpression receiver, @Nullable JsExpression callee,
|
||||||
|
@NotNull List<JsExpression> arguments,
|
||||||
@NotNull ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
@NotNull ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||||
@Nullable CallableDescriptor descriptorToCall,
|
@Nullable CallableDescriptor descriptorToCall,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
|
this.callee = callee;
|
||||||
this.resolvedCall = resolvedCall;
|
this.resolvedCall = resolvedCall;
|
||||||
if (descriptorToCall != null) {
|
if (descriptorToCall != null) {
|
||||||
this.descriptor = descriptorToCall;
|
this.descriptor = descriptorToCall;
|
||||||
@@ -268,6 +286,9 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression calleeReference() {
|
private JsExpression calleeReference() {
|
||||||
|
if (callee != null) {
|
||||||
|
return callee;
|
||||||
|
}
|
||||||
if (isVariableDescriptor(descriptor)) {
|
if (isVariableDescriptor(descriptor)) {
|
||||||
//TODO: write tests on this cases
|
//TODO: write tests on this cases
|
||||||
VariableDescriptor variableDescriptor =
|
VariableDescriptor variableDescriptor =
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
@@ -307,4 +308,14 @@ public final class BindingUtils {
|
|||||||
return hasNextDescriptor;
|
return hasNextDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isExpressionAsFunction(@NotNull BindingContext context,
|
||||||
|
@NotNull JetExpression calleeExpression) {
|
||||||
|
DeclarationDescriptor declarationDescriptor =
|
||||||
|
context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, calleeExpression);
|
||||||
|
if (declarationDescriptor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (declarationDescriptor instanceof ExpressionAsFunctionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ public final class ClassSorter {
|
|||||||
private ClassDescriptor popFromList() {
|
private ClassDescriptor popFromList() {
|
||||||
assert !classesWithNoAncestors.isEmpty();
|
assert !classesWithNoAncestors.isEmpty();
|
||||||
ClassDescriptor result = classesWithNoAncestors.get(classesWithNoAncestors.size() - 1);
|
ClassDescriptor result = classesWithNoAncestors.get(classesWithNoAncestors.size() - 1);
|
||||||
classesWithNoAncestors.remove(classesWithNoAncestors.size() - 1);
|
ClassDescriptor removed = classesWithNoAncestors.remove(classesWithNoAncestors.size() - 1);
|
||||||
|
assert removed != null;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +106,16 @@ public final class ClassSorter {
|
|||||||
private void setInitialCount() {
|
private void setInitialCount() {
|
||||||
for (ClassDescriptor descriptor : descriptorList) {
|
for (ClassDescriptor descriptor : descriptorList) {
|
||||||
List<ClassDescriptor> superclasses = getSuperclassDescriptors(descriptor);
|
List<ClassDescriptor> superclasses = getSuperclassDescriptors(descriptor);
|
||||||
|
int count = 0;
|
||||||
|
for (ClassDescriptor superclassDescriptor : superclasses) {
|
||||||
|
if (descriptorList.contains(superclassDescriptor)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
classWasInheritedCount.put(descriptor, superclasses.size());
|
classWasInheritedCount.put(descriptor, superclasses.size());
|
||||||
if (!superclasses.isEmpty()) {
|
if (count > 0) {
|
||||||
classesWithNoAncestors.remove(descriptor);
|
boolean success = classesWithNoAncestors.remove(descriptor);
|
||||||
|
assert success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public final class PsiUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
/*package*/ static JetExpression getCallee(@NotNull JetCallExpression expression) {
|
public static JetExpression getCallee(@NotNull JetCallExpression expression) {
|
||||||
JetExpression calleeExpression = expression.getCalleeExpression();
|
JetExpression calleeExpression = expression.getCalleeExpression();
|
||||||
assert calleeExpression != null;
|
assert calleeExpression != null;
|
||||||
return calleeExpression;
|
return calleeExpression;
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.jetbrains.k2js.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pavel Talanov
|
||||||
|
*/
|
||||||
|
public final class StdlibTest extends TranslationTest {
|
||||||
|
final private static String MAIN = "stdlib/";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String mainDirectory() {
|
||||||
|
return MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void filter() throws Exception {
|
||||||
|
testFooBoxIsTrue("Filter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
open class Foo {
|
open class Foo() {
|
||||||
fun xyzzy(): String = "xyzzy"
|
fun xyzzy(): String = "xyzzy"
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bar(): Foo {
|
class Bar(): Foo() {
|
||||||
fun test(): String = xyzzy()
|
fun test(): String = xyzzy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import js.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class NoSuchElementException() : Exception() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Filters given iterator
|
||||||
|
*/
|
||||||
|
inline fun <T> Iterator<T>.filter(f: (T)-> Boolean) : Iterator<T> = FilterIterator<T>(this, f)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Adds filtered elements in to given container
|
||||||
|
*/
|
||||||
|
inline fun <T,U : Collection<in T>> Iterable<T>.filterTo(var container: U, filter: (T)->Boolean) : U {
|
||||||
|
for(element in this) {
|
||||||
|
if(filter(element))
|
||||||
|
container.add(element)
|
||||||
|
}
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create iterator filtering given java.lang.Iterable
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
inline fun <T> Iterable<T>.filter(f: (T)->Boolean) : Iterator<T> = (iterator() as Iterator<T>).filter(f)
|
||||||
|
*/
|
||||||
|
|
||||||
|
private class FilterIterator<T>(val original: Iterator<T>, val filter: (T)-> Boolean) : Iterator<T> {
|
||||||
|
var state = 0
|
||||||
|
var nextElement: T? = null
|
||||||
|
|
||||||
|
override val hasNext: Boolean
|
||||||
|
get() =
|
||||||
|
when(state) {
|
||||||
|
1 -> true // checked and next present
|
||||||
|
2 -> false // checked and next not present
|
||||||
|
else -> {{() : Boolean ->
|
||||||
|
while(original.hasNext) {
|
||||||
|
val candidate = original.next()
|
||||||
|
if((filter)(candidate)) {
|
||||||
|
nextElement = candidate
|
||||||
|
state = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = 2
|
||||||
|
return false
|
||||||
|
}()}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): T {
|
||||||
|
val res = nextElement as T
|
||||||
|
nextElement = null
|
||||||
|
state = 0
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user