expression as statement bug fixed

This commit is contained in:
Pavel Talanov
2012-01-24 21:51:53 +04:00
parent 46b7ab194a
commit 439e28cfea
10 changed files with 722 additions and 679 deletions
+572 -654
View File
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
}
}