Implement f# pipeline in parser (#9450)

This commit is contained in:
James DiGioia
2019-05-14 16:12:17 -04:00
committed by Nicolò Ribaudo
parent 0a98814329
commit 6b8a37c413
54 changed files with 4295 additions and 19 deletions

View File

@@ -331,8 +331,11 @@ export default class ExpressionParser extends LValParser {
const prec = this.state.type.binop;
if (prec != null && (!noIn || !this.match(tt._in))) {
if (prec > minPrec) {
const node = this.startNodeAt(leftStartPos, leftStartLoc);
const operator = this.state.value;
if (operator === "|>" && this.state.inFSharpPipelineDirectBody) {
return left;
}
const node = this.startNodeAt(leftStartPos, leftStartLoc);
node.left = left;
node.operator = operator;
if (
@@ -406,18 +409,23 @@ export default class ExpressionParser extends LValParser {
prec: number,
noIn: ?boolean,
): N.Expression {
const startPos = this.state.start;
const startLoc = this.state.startLoc;
switch (op) {
case tt.pipeline:
if (this.getPluginOption("pipelineOperator", "proposal") === "smart") {
const startPos = this.state.start;
const startLoc = this.state.startLoc;
return this.withTopicPermittingContext(() => {
return this.parseSmartPipelineBody(
this.parseExprOpBaseRightExpr(op, prec, noIn),
startPos,
startLoc,
);
});
switch (this.getPluginOption("pipelineOperator", "proposal")) {
case "smart":
return this.withTopicPermittingContext(() => {
return this.parseSmartPipelineBody(
this.parseExprOpBaseRightExpr(op, prec, noIn),
startPos,
startLoc,
);
});
case "fsharp":
return this.withSoloAwaitPermittingContext(() => {
return this.parseFSharpPipelineBody(prec, noIn);
});
}
// falls through
@@ -766,6 +774,8 @@ export default class ExpressionParser extends LValParser {
const elts = [];
let innerParenStart;
let first = true;
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
this.state.inFSharpPipelineDirectBody = false;
while (!this.eat(close)) {
if (first) {
@@ -804,6 +814,8 @@ export default class ExpressionParser extends LValParser {
this.unexpected();
}
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
return elts;
}
@@ -969,7 +981,10 @@ export default class ExpressionParser extends LValParser {
case tt.parenL:
return this.parseParenAndDistinguishExpression(canBeArrow);
case tt.bracketL:
case tt.bracketL: {
const oldInFSharpPipelineDirectBody = this.state
.inFSharpPipelineDirectBody;
this.state.inFSharpPipelineDirectBody = false;
node = this.startNode();
this.next();
node.elements = this.parseExprList(
@@ -985,11 +1000,17 @@ export default class ExpressionParser extends LValParser {
// expression by calling toReferencedListDeep.
this.toReferencedList(node.elements);
}
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
return this.finishNode(node, "ArrayExpression");
case tt.braceL:
return this.parseObj(false, refShorthandDefaultPos);
}
case tt.braceL: {
const oldInFSharpPipelineDirectBody = this.state
.inFSharpPipelineDirectBody;
this.state.inFSharpPipelineDirectBody = false;
const ret = this.parseObj(false, refShorthandDefaultPos);
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
return ret;
}
case tt._function:
return this.parseFunctionExpression();
@@ -1177,9 +1198,11 @@ export default class ExpressionParser extends LValParser {
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
const oldYieldPos = this.state.yieldPos;
const oldAwaitPos = this.state.awaitPos;
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
this.state.maybeInArrowParameters = true;
this.state.yieldPos = 0;
this.state.awaitPos = 0;
this.state.inFSharpPipelineDirectBody = false;
const innerStartPos = this.state.start;
const innerStartLoc = this.state.startLoc;
@@ -1233,6 +1256,7 @@ export default class ExpressionParser extends LValParser {
this.expect(tt.parenR);
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
let arrowNode = this.startNodeAt(startPos, startLoc);
if (
@@ -2114,7 +2138,9 @@ export default class ExpressionParser extends LValParser {
);
}
node.argument = this.parseMaybeUnary();
if (!this.state.soloAwait) {
node.argument = this.parseMaybeUnary();
}
return this.finishNode(node, "AwaitExpression");
}
@@ -2304,6 +2330,17 @@ export default class ExpressionParser extends LValParser {
}
}
withSoloAwaitPermittingContext<T>(callback: () => T): T {
const outerContextSoloAwaitState = this.state.soloAwait;
this.state.soloAwait = true;
try {
return callback();
} finally {
this.state.soloAwait = outerContextSoloAwaitState;
}
}
// Register the use of a primary topic reference (`#`) within the current
// topic context.
registerTopicReference(): void {
@@ -2320,4 +2357,25 @@ export default class ExpressionParser extends LValParser {
this.state.topicContext.maxTopicIndex >= 0
);
}
parseFSharpPipelineBody(prec: number, noIn: ?boolean): N.Expression {
const startPos = this.state.start;
const startLoc = this.state.startLoc;
this.state.potentialArrowAt = this.state.start;
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
this.state.inFSharpPipelineDirectBody = true;
const ret = this.parseExprOp(
this.parseMaybeUnary(),
startPos,
startLoc,
prec,
noIn,
);
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
return ret;
}
}