function literal as the last parameter supported
added temporary and partial solution to global namespace polluting problem
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
package com.google.dart.compiler.backend.js.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -12,7 +12,7 @@ import java.util.List;
|
||||
*/
|
||||
public class JsBlock extends JsStatement {
|
||||
|
||||
private final List<JsStatement> stmts = new ArrayList<JsStatement>();
|
||||
private final LinkedList<JsStatement> stmts = new LinkedList<JsStatement>();
|
||||
|
||||
public JsBlock() {
|
||||
}
|
||||
@@ -47,6 +47,11 @@ public class JsBlock extends JsStatement {
|
||||
return NodeKind.BLOCK;
|
||||
}
|
||||
|
||||
/*Pavel Talanov*/
|
||||
public void addVarDeclaration(JsVars vars) {
|
||||
stmts.offerFirst(vars);
|
||||
}
|
||||
|
||||
public void setStatements(List<JsStatement> statements) {
|
||||
assert this.stmts.isEmpty() : "Already contains statements.";
|
||||
this.stmts.addAll(statements);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package org.jetbrains.k2js.translate.context;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsBlock;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||
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.jet.lang.descriptors.DeclarationDescriptor;
|
||||
|
||||
@@ -53,7 +51,11 @@ public class DynamicContext {
|
||||
|
||||
@NotNull
|
||||
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
|
||||
return new TemporaryVariable(namingScope.declareTemporary(), initExpression);
|
||||
|
||||
JsName temporaryName = namingScope.declareTemporary();
|
||||
JsVars temporaryDeclaration = AstUtil.newVar(temporaryName, null);
|
||||
jsBlock().addVarDeclaration(temporaryDeclaration);
|
||||
return new TemporaryVariable(temporaryName, initExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -49,6 +49,11 @@ public final class TranslationContext {
|
||||
return new TranslationContext(staticContext, dynamicContext.innerScope(enclosingScope));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TranslationContext innerBlock(@NotNull JsBlock block) {
|
||||
return new TranslationContext(staticContext, dynamicContext.innerBlock(block));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TranslationContext newNamespace(@NotNull NamespaceDescriptor namespace) {
|
||||
return newDeclaration(namespace);
|
||||
|
||||
@@ -62,10 +62,11 @@ 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 blockContext = context.innerBlock(jsBlock);
|
||||
for (JetElement statement : statements) {
|
||||
assert statement instanceof JetExpression : "Elements in JetBlockExpression " +
|
||||
"should be of type JetExpression";
|
||||
JsNode jsNode = statement.accept(this, context);
|
||||
JsNode jsNode = statement.accept(this, blockContext);
|
||||
jsBlock.addStatement(AstUtil.convertToStatement(jsNode));
|
||||
}
|
||||
return jsBlock;
|
||||
|
||||
@@ -42,14 +42,17 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
private final TranslationContext functionBodyContext;
|
||||
@NotNull
|
||||
private final FunctionDescriptor descriptor;
|
||||
|
||||
// function body needs to be explicitly created here to include it in the context
|
||||
@NotNull
|
||||
private final JsBlock functionBody;
|
||||
|
||||
private FunctionTranslator(@NotNull JetDeclarationWithBody functionDeclaration,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.functionBody = new JsBlock();
|
||||
this.functionDeclaration = functionDeclaration;
|
||||
this.functionObject = createFunctionObject();
|
||||
this.functionBodyContext = functionBodyContext();
|
||||
this.functionBodyContext = functionBodyContext().innerBlock(functionBody);
|
||||
this.descriptor = getFunctionDescriptor(context.bindingContext(), functionDeclaration);
|
||||
}
|
||||
|
||||
@@ -72,7 +75,8 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private JsFunction generateFunctionObject() {
|
||||
functionObject.setParameters(translateParameters());
|
||||
functionObject.setBody(translateBody());
|
||||
translateBody();
|
||||
functionObject.setBody(functionBody);
|
||||
restoreContext();
|
||||
return functionObject;
|
||||
}
|
||||
@@ -105,13 +109,12 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
(functionDeclaration instanceof JetPropertyAccessor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsBlock translateBody() {
|
||||
private void translateBody() {
|
||||
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
||||
//TODO decide if there are cases where this assert is illegal
|
||||
assert jetBodyExpression != null : "Function without body not supported";
|
||||
JsNode body = Translation.translateExpression(jetBodyExpression, functionBodyContext);
|
||||
return wrapWithReturnIfNeeded(body, !functionDeclaration.hasBlockBody());
|
||||
JsNode realBody = Translation.translateExpression(jetBodyExpression, functionBodyContext);
|
||||
functionBody.addStatement(wrapWithReturnIfNeeded(realBody, !functionDeclaration.hasBlockBody()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -69,9 +69,18 @@ public class FunctionTest extends AbstractExpressionTest {
|
||||
testFooBoxIsTrue("defaultParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void functionLiteralAsLastParameter() throws Exception {
|
||||
testFooBoxIsTrue("functionLiteralAsLastParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void kt921() throws Exception {
|
||||
checkOutput("KT-921.kt", "");
|
||||
try {
|
||||
checkOutput("KT-921.kt", "");
|
||||
} catch (Throwable e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
import java.util.*
|
||||
|
||||
class Lifetime() {
|
||||
val attached = ArrayList< Function0<Unit> >()
|
||||
|
||||
public fun attach(action : ()->Unit)
|
||||
{
|
||||
attached.add(action)
|
||||
}
|
||||
|
||||
fun close()
|
||||
{
|
||||
for(x in attached) x()
|
||||
attached.clear()
|
||||
}
|
||||
val attached = ArrayList< Function0<Unit> >()
|
||||
|
||||
public fun attach(action : ()->Unit)
|
||||
{
|
||||
attached.add(action)
|
||||
}
|
||||
|
||||
fun close()
|
||||
{
|
||||
for(x in attached) x()
|
||||
attached.clear()
|
||||
}
|
||||
}
|
||||
|
||||
public class Viewable<T>()
|
||||
{
|
||||
val items = ArrayList<T>()
|
||||
|
||||
fun add(item:T)
|
||||
{
|
||||
items.add(item)
|
||||
}
|
||||
|
||||
fun remove(item:T)
|
||||
{
|
||||
items.remove(item)
|
||||
}
|
||||
|
||||
fun view(lifetime: Lifetime, viewer: (itemLifetime:Lifetime, item:T) -> Unit)
|
||||
{
|
||||
for(item in items)
|
||||
viewer(lifetime, item)
|
||||
}
|
||||
val items = ArrayList<T>()
|
||||
|
||||
fun add(item:T)
|
||||
{
|
||||
items.add(item)
|
||||
}
|
||||
|
||||
fun remove(item:T)
|
||||
{
|
||||
items.remove(item)
|
||||
}
|
||||
|
||||
fun view(lifetime: Lifetime, viewer: (itemLifetime:Lifetime, item:T) -> Unit)
|
||||
{
|
||||
for(item in items)
|
||||
viewer(lifetime, item)
|
||||
}
|
||||
}
|
||||
|
||||
fun lifetime(body: (Lifetime)->Unit)
|
||||
{
|
||||
val l = Lifetime()
|
||||
body(l)
|
||||
l.close()
|
||||
val l = Lifetime()
|
||||
body(l)
|
||||
l.close()
|
||||
}
|
||||
|
||||
fun<T> Dump(items:ArrayList<T>)
|
||||
{
|
||||
for(item in items)
|
||||
System.out?.print(item.toString() + ", ")
|
||||
System.out?.println()
|
||||
for(item in items)
|
||||
System.out?.print(item.toString() + ", ")
|
||||
System.out?.println()
|
||||
}
|
||||
|
||||
fun main(args:Array<String>)
|
||||
{
|
||||
val v = Viewable<Int>()
|
||||
val x = ArrayList<Int>()
|
||||
v.add(1)
|
||||
v.add(2)
|
||||
lifetime(
|
||||
{
|
||||
v.view(it, {(itemLifetime, item)->
|
||||
x.add(item)
|
||||
Dump(x)
|
||||
itemLifetime.attach { x.remove(item); Dump(x) }
|
||||
})
|
||||
})
|
||||
val v = Viewable<Int>()
|
||||
val x = ArrayList<Int>()
|
||||
v.add(1)
|
||||
v.add(2)
|
||||
lifetime(
|
||||
{
|
||||
v.view(it, {(itemLifetime, item)->
|
||||
x.add(item)
|
||||
Dump(x)
|
||||
itemLifetime.attach { x.remove(item); Dump(x) }
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package foo
|
||||
|
||||
fun f(a: (Int) -> Int) = a(1)
|
||||
|
||||
fun box() : Boolean {
|
||||
|
||||
if (f() {
|
||||
it + 2
|
||||
} != 3) return false
|
||||
|
||||
if (f() {(a : Int) -> a * 300} != 300) return false;
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user