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;
|
package com.google.dart.compiler.backend.js.ast;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,7 +12,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class JsBlock extends JsStatement {
|
public class JsBlock extends JsStatement {
|
||||||
|
|
||||||
private final List<JsStatement> stmts = new ArrayList<JsStatement>();
|
private final LinkedList<JsStatement> stmts = new LinkedList<JsStatement>();
|
||||||
|
|
||||||
public JsBlock() {
|
public JsBlock() {
|
||||||
}
|
}
|
||||||
@@ -47,6 +47,11 @@ public class JsBlock extends JsStatement {
|
|||||||
return NodeKind.BLOCK;
|
return NodeKind.BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Pavel Talanov*/
|
||||||
|
public void addVarDeclaration(JsVars vars) {
|
||||||
|
stmts.offerFirst(vars);
|
||||||
|
}
|
||||||
|
|
||||||
public void setStatements(List<JsStatement> statements) {
|
public void setStatements(List<JsStatement> statements) {
|
||||||
assert this.stmts.isEmpty() : "Already contains statements.";
|
assert this.stmts.isEmpty() : "Already contains statements.";
|
||||||
this.stmts.addAll(statements);
|
this.stmts.addAll(statements);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package org.jetbrains.k2js.translate.context;
|
package org.jetbrains.k2js.translate.context;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsBlock;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsName;
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsScope;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
|
||||||
@@ -53,7 +51,11 @@ public class DynamicContext {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
|
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
|
@NotNull
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ public final class TranslationContext {
|
|||||||
return new TranslationContext(staticContext, dynamicContext.innerScope(enclosingScope));
|
return new TranslationContext(staticContext, dynamicContext.innerScope(enclosingScope));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public TranslationContext innerBlock(@NotNull JsBlock block) {
|
||||||
|
return new TranslationContext(staticContext, dynamicContext.innerBlock(block));
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TranslationContext newNamespace(@NotNull NamespaceDescriptor namespace) {
|
public TranslationContext newNamespace(@NotNull NamespaceDescriptor namespace) {
|
||||||
return newDeclaration(namespace);
|
return newDeclaration(namespace);
|
||||||
|
|||||||
@@ -62,10 +62,11 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
public JsNode visitBlockExpression(@NotNull JetBlockExpression jetBlock, @NotNull TranslationContext context) {
|
public JsNode visitBlockExpression(@NotNull JetBlockExpression jetBlock, @NotNull TranslationContext context) {
|
||||||
List<JetElement> statements = jetBlock.getStatements();
|
List<JetElement> statements = jetBlock.getStatements();
|
||||||
JsBlock jsBlock = new JsBlock();
|
JsBlock jsBlock = new JsBlock();
|
||||||
|
TranslationContext blockContext = context.innerBlock(jsBlock);
|
||||||
for (JetElement statement : statements) {
|
for (JetElement statement : statements) {
|
||||||
assert statement instanceof JetExpression : "Elements in JetBlockExpression " +
|
assert statement instanceof JetExpression : "Elements in JetBlockExpression " +
|
||||||
"should be of type JetExpression";
|
"should be of type JetExpression";
|
||||||
JsNode jsNode = statement.accept(this, context);
|
JsNode jsNode = statement.accept(this, blockContext);
|
||||||
jsBlock.addStatement(AstUtil.convertToStatement(jsNode));
|
jsBlock.addStatement(AstUtil.convertToStatement(jsNode));
|
||||||
}
|
}
|
||||||
return jsBlock;
|
return jsBlock;
|
||||||
|
|||||||
@@ -42,14 +42,17 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
private final TranslationContext functionBodyContext;
|
private final TranslationContext functionBodyContext;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final FunctionDescriptor descriptor;
|
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,
|
private FunctionTranslator(@NotNull JetDeclarationWithBody functionDeclaration,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
this.functionBody = new JsBlock();
|
||||||
this.functionDeclaration = functionDeclaration;
|
this.functionDeclaration = functionDeclaration;
|
||||||
this.functionObject = createFunctionObject();
|
this.functionObject = createFunctionObject();
|
||||||
this.functionBodyContext = functionBodyContext();
|
this.functionBodyContext = functionBodyContext().innerBlock(functionBody);
|
||||||
this.descriptor = getFunctionDescriptor(context.bindingContext(), functionDeclaration);
|
this.descriptor = getFunctionDescriptor(context.bindingContext(), functionDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +75,8 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private JsFunction generateFunctionObject() {
|
private JsFunction generateFunctionObject() {
|
||||||
functionObject.setParameters(translateParameters());
|
functionObject.setParameters(translateParameters());
|
||||||
functionObject.setBody(translateBody());
|
translateBody();
|
||||||
|
functionObject.setBody(functionBody);
|
||||||
restoreContext();
|
restoreContext();
|
||||||
return functionObject;
|
return functionObject;
|
||||||
}
|
}
|
||||||
@@ -105,13 +109,12 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
(functionDeclaration instanceof JetPropertyAccessor);
|
(functionDeclaration instanceof JetPropertyAccessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private void translateBody() {
|
||||||
private JsBlock translateBody() {
|
|
||||||
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
||||||
//TODO decide if there are cases where this assert is illegal
|
//TODO decide if there are cases where this assert is illegal
|
||||||
assert jetBodyExpression != null : "Function without body not supported";
|
assert jetBodyExpression != null : "Function without body not supported";
|
||||||
JsNode body = Translation.translateExpression(jetBodyExpression, functionBodyContext);
|
JsNode realBody = Translation.translateExpression(jetBodyExpression, functionBodyContext);
|
||||||
return wrapWithReturnIfNeeded(body, !functionDeclaration.hasBlockBody());
|
functionBody.addStatement(wrapWithReturnIfNeeded(realBody, !functionDeclaration.hasBlockBody()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -69,9 +69,18 @@ public class FunctionTest extends AbstractExpressionTest {
|
|||||||
testFooBoxIsTrue("defaultParameters.kt");
|
testFooBoxIsTrue("defaultParameters.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void functionLiteralAsLastParameter() throws Exception {
|
||||||
|
testFooBoxIsTrue("functionLiteralAsLastParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void kt921() throws Exception {
|
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.*
|
import java.util.*
|
||||||
|
|
||||||
class Lifetime() {
|
class Lifetime() {
|
||||||
val attached = ArrayList< Function0<Unit> >()
|
val attached = ArrayList< Function0<Unit> >()
|
||||||
|
|
||||||
public fun attach(action : ()->Unit)
|
public fun attach(action : ()->Unit)
|
||||||
{
|
{
|
||||||
attached.add(action)
|
attached.add(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun close()
|
fun close()
|
||||||
{
|
{
|
||||||
for(x in attached) x()
|
for(x in attached) x()
|
||||||
attached.clear()
|
attached.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Viewable<T>()
|
public class Viewable<T>()
|
||||||
{
|
{
|
||||||
val items = ArrayList<T>()
|
val items = ArrayList<T>()
|
||||||
|
|
||||||
fun add(item:T)
|
fun add(item:T)
|
||||||
{
|
{
|
||||||
items.add(item)
|
items.add(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(item:T)
|
fun remove(item:T)
|
||||||
{
|
{
|
||||||
items.remove(item)
|
items.remove(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun view(lifetime: Lifetime, viewer: (itemLifetime:Lifetime, item:T) -> Unit)
|
fun view(lifetime: Lifetime, viewer: (itemLifetime:Lifetime, item:T) -> Unit)
|
||||||
{
|
{
|
||||||
for(item in items)
|
for(item in items)
|
||||||
viewer(lifetime, item)
|
viewer(lifetime, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lifetime(body: (Lifetime)->Unit)
|
fun lifetime(body: (Lifetime)->Unit)
|
||||||
{
|
{
|
||||||
val l = Lifetime()
|
val l = Lifetime()
|
||||||
body(l)
|
body(l)
|
||||||
l.close()
|
l.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun<T> Dump(items:ArrayList<T>)
|
fun<T> Dump(items:ArrayList<T>)
|
||||||
{
|
{
|
||||||
for(item in items)
|
for(item in items)
|
||||||
System.out?.print(item.toString() + ", ")
|
System.out?.print(item.toString() + ", ")
|
||||||
System.out?.println()
|
System.out?.println()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(args:Array<String>)
|
fun main(args:Array<String>)
|
||||||
{
|
{
|
||||||
val v = Viewable<Int>()
|
val v = Viewable<Int>()
|
||||||
val x = ArrayList<Int>()
|
val x = ArrayList<Int>()
|
||||||
v.add(1)
|
v.add(1)
|
||||||
v.add(2)
|
v.add(2)
|
||||||
lifetime(
|
lifetime(
|
||||||
{
|
{
|
||||||
v.view(it, {(itemLifetime, item)->
|
v.view(it, {(itemLifetime, item)->
|
||||||
x.add(item)
|
x.add(item)
|
||||||
Dump(x)
|
Dump(x)
|
||||||
itemLifetime.attach { x.remove(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