[K/JS] Compile Kotlin coroutines as JS generator ^KT-63038 Fixed
This commit is contained in:
@@ -178,6 +178,7 @@ public class JsAstMapper {
|
||||
return mapSetElem(node);
|
||||
|
||||
case TokenStream.FUNCTION:
|
||||
case TokenStream.GENERATOR:
|
||||
return mapFunction(node);
|
||||
|
||||
case TokenStream.BLOCK:
|
||||
@@ -199,6 +200,9 @@ public class JsAstMapper {
|
||||
case TokenStream.CONTINUE:
|
||||
return mapContinue(node);
|
||||
|
||||
case TokenStream.YIELD:
|
||||
return mapYield(node);
|
||||
|
||||
case TokenStream.OBJLIT:
|
||||
return mapObjectLit(node);
|
||||
|
||||
@@ -387,6 +391,10 @@ public class JsAstMapper {
|
||||
return new JsContinue(getTargetLabel(contNode));
|
||||
}
|
||||
|
||||
private JsYield mapYield(Node yieldNode) {
|
||||
return new JsYield(mapExpression(yieldNode.getFirstChild()));
|
||||
}
|
||||
|
||||
private JsStatement mapDebuggerStatement(Node node) {
|
||||
// Calls an optional method to invoke the debugger.
|
||||
//
|
||||
@@ -570,7 +578,7 @@ public class JsAstMapper {
|
||||
|
||||
public JsFunction mapFunction(Node fnNode) throws JsParserException {
|
||||
int nodeType = fnNode.getType();
|
||||
assert nodeType == TokenStream.FUNCTION: "Expected function node, got: " + TokenStream.tokenToName(nodeType);
|
||||
assert nodeType == TokenStream.FUNCTION || nodeType == TokenStream.GENERATOR: "Expected function node, got: " + TokenStream.tokenToName(nodeType);
|
||||
Node fromFnNameNode = fnNode.getFirstChild();
|
||||
Node fromParamNode = fnNode.getFirstChild().getNext().getFirstChild();
|
||||
Node fromBodyNode = fnNode.getFirstChild().getNext().getNext();
|
||||
@@ -586,6 +594,10 @@ public class JsAstMapper {
|
||||
JsFunction toFn = scopeContext.enterFunction();
|
||||
toFn.setName(functionName);
|
||||
|
||||
if (nodeType == TokenStream.GENERATOR) {
|
||||
toFn.getModifiers().add(JsFunction.Modifier.GENERATOR);
|
||||
}
|
||||
|
||||
while (fromParamNode != null) {
|
||||
String fromParamName = fromParamNode.getString();
|
||||
JsName name = scopeContext.localNameFor(fromParamName);
|
||||
|
||||
@@ -180,6 +180,19 @@ public class IRFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Yield (possibly with expression)
|
||||
*/
|
||||
public Node createYield(Node expression, CodePosition location) {
|
||||
Node result = new Node(TokenStream.YIELD, location);
|
||||
if (expression == null) {
|
||||
return result;
|
||||
} else {
|
||||
result.addChildToBack(expression);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* debugger
|
||||
*/
|
||||
@@ -197,11 +210,11 @@ public class IRFactory {
|
||||
return new Node(TokenStream.BLOCK, location);
|
||||
}
|
||||
|
||||
public Node createFunction(Node name, Node args, Node statements, CodePosition location) {
|
||||
public Node createFunction(Node name, Node args, Node statements, boolean isGenerator, CodePosition location) {
|
||||
if (name == null) {
|
||||
name = createName("", location);
|
||||
}
|
||||
return new Node(TokenStream.FUNCTION, name, args, statements, location);
|
||||
return new Node(isGenerator ? TokenStream.GENERATOR : TokenStream.FUNCTION, name, args, statements, location);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -186,6 +186,10 @@ public class Parser {
|
||||
|
||||
Node nameNode;
|
||||
Node memberExprNode = null;
|
||||
|
||||
// For generators
|
||||
boolean isGenerator = ts.matchToken(TokenStream.MUL);
|
||||
|
||||
if (ts.matchToken(TokenStream.NAME)) {
|
||||
nameNode = nf.createName(ts.getString(), basePosition);
|
||||
if (!ts.matchToken(TokenStream.LP)) {
|
||||
@@ -248,7 +252,7 @@ public class Parser {
|
||||
functionNumber = savedFunctionNumber;
|
||||
}
|
||||
|
||||
Node pn = nf.createFunction(nameNode, args, body, basePosition);
|
||||
Node pn = nf.createFunction(nameNode, args, body, isGenerator, basePosition);
|
||||
if (memberExprNode != null) {
|
||||
pn = nf.createBinary(TokenStream.ASSIGN, TokenStream.NOP, memberExprNode, pn, basePosition);
|
||||
}
|
||||
@@ -897,6 +901,9 @@ public class Parser {
|
||||
CodePosition position = ts.tokenPosition;
|
||||
|
||||
switch (tt) {
|
||||
case TokenStream.YIELD:
|
||||
return nf.createUnary(TokenStream.YIELD, ts.getOp(), unaryExpr(ts), position);
|
||||
|
||||
case TokenStream.UNARYOP:
|
||||
return nf.createUnary(TokenStream.UNARYOP, ts.getOp(), unaryExpr(ts), position);
|
||||
|
||||
|
||||
@@ -254,6 +254,9 @@ public class TokenStream {
|
||||
LAST_TOKEN = 147,
|
||||
NUMBER_INT = 148,
|
||||
|
||||
GENERATOR = 149,
|
||||
YIELD = 150,
|
||||
|
||||
// This value is only used as a return value for getTokenHelper,
|
||||
// which is only called from getToken and exists to avoid an excessive
|
||||
// recursion problem if a number of lines in a row are comments.
|
||||
@@ -390,6 +393,7 @@ public class TokenStream {
|
||||
case FOR: return "for";
|
||||
case BREAK: return "break";
|
||||
case CONTINUE: return "continue";
|
||||
case YIELD: return "yield";
|
||||
case VAR: return "var";
|
||||
case WITH: return "with";
|
||||
case CATCH: return "catch";
|
||||
@@ -456,6 +460,7 @@ public class TokenStream {
|
||||
KEYWORDS.put("break", BREAK);
|
||||
KEYWORDS.put("case", CASE);
|
||||
KEYWORDS.put("continue", CONTINUE);
|
||||
KEYWORDS.put("yield", YIELD);
|
||||
KEYWORDS.put("default", DEFAULT);
|
||||
KEYWORDS.put("delete", DELPROP);
|
||||
KEYWORDS.put("do", DO);
|
||||
|
||||
Reference in New Issue
Block a user