Implement f# pipeline in parser (#9450)
This commit is contained in:
committed by
Nicolò Ribaudo
parent
0a98814329
commit
6b8a37c413
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user