Added support for record and tuple syntax. (#10865)

* Added support for record and tuple syntax.

This commit adds support for both the hash #{} and bar {||}
syntaxes to babel-parser, as well as adds the supporting
babel-plugin-syntax-record-and-tuple plugin to enable support
for the syntax. Does not include any transform for records and
tuples.

* typo

* added check to ensure recordAndTuple in babel-parser

* switched to syntaxType option instead of explicit entries for each record and tuple type

* switched to using recordAndTupleSyntaxType for generator options instead of adding to node

* added tests for generator option recordAndTupleSyntaxType

* added test for record and tuple bar syntax with flow typings

* added tests for invalid/missing recordAndTuple syntaxType parser option

* fixed flowcheck errors

* fix merge with class privates in tokenizer

* Update packages/babel-parser/src/types.js

Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>

* improved recordAndTuple generator error message, added tests for invalid,missing options

* updated error messages for invalid parser syntaxType option

* updated error message

* added better error messages for when the recordAndTuple syntaxType is doesn't match the syntax used

* updated record and tuple support to use new error message templates

* added recordAndTuple to missing plugin helpers

* Fix linting

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
Rick Button
2020-03-16 18:57:44 -04:00
committed by GitHub
parent e06bf8ffdb
commit 3ce7c2e394
69 changed files with 2253 additions and 30 deletions

View File

@@ -405,6 +405,28 @@ export default class Tokenizer extends LocationParser {
}
if (
this.hasPlugin("recordAndTuple") &&
(next === charCodes.leftCurlyBrace ||
next === charCodes.leftSquareBracket)
) {
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "hash") {
throw this.raise(
this.state.pos,
next === charCodes.leftCurlyBrace
? Errors.RecordExpressionHashIncorrectStartSyntaxType
: Errors.TupleExpressionHashIncorrectStartSyntaxType,
);
}
if (next === charCodes.leftCurlyBrace) {
// #{
this.finishToken(tt.braceHashL);
} else {
// #[
this.finishToken(tt.bracketHashL);
}
this.state.pos += 2;
} else if (
this.hasPlugin("classPrivateProperties") ||
this.hasPlugin("classPrivateMethods") ||
this.getPluginOption("pipelineOperator", "proposal") === "smart"
@@ -453,12 +475,12 @@ export default class Tokenizer extends LocationParser {
readToken_interpreter(): boolean {
if (this.state.pos !== 0 || this.length < 2) return false;
let ch = this.input.charCodeAt(this.state.pos + 1);
if (ch !== charCodes.exclamationMark) return false;
const start = this.state.pos;
this.state.pos += 1;
let ch = this.input.charCodeAt(this.state.pos);
if (ch !== charCodes.exclamationMark) return false;
while (!isNewLine(ch) && ++this.state.pos < this.length) {
ch = this.input.charCodeAt(this.state.pos);
}
@@ -514,6 +536,37 @@ export default class Tokenizer extends LocationParser {
this.finishOp(tt.pipeline, 2);
return;
}
// '|}'
if (
this.hasPlugin("recordAndTuple") &&
next === charCodes.rightCurlyBrace
) {
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
throw this.raise(
this.state.pos,
Errors.RecordExpressionBarIncorrectEndSyntaxType,
);
}
this.finishOp(tt.braceBarR, 2);
return;
}
// '|]'
if (
this.hasPlugin("recordAndTuple") &&
next === charCodes.rightSquareBracket
) {
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
throw this.raise(
this.state.pos,
Errors.TupleExpressionBarIncorrectEndSyntaxType,
);
}
this.finishOp(tt.bracketBarR, 2);
return;
}
}
if (next === charCodes.equalsTo) {
@@ -682,16 +735,48 @@ export default class Tokenizer extends LocationParser {
this.finishToken(tt.comma);
return;
case charCodes.leftSquareBracket:
++this.state.pos;
this.finishToken(tt.bracketL);
if (
this.hasPlugin("recordAndTuple") &&
this.input.charCodeAt(this.state.pos + 1) === charCodes.verticalBar
) {
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
throw this.raise(
this.state.pos,
Errors.TupleExpressionBarIncorrectStartSyntaxType,
);
}
// [|
this.finishToken(tt.bracketBarL);
this.state.pos += 2;
} else {
++this.state.pos;
this.finishToken(tt.bracketL);
}
return;
case charCodes.rightSquareBracket:
++this.state.pos;
this.finishToken(tt.bracketR);
return;
case charCodes.leftCurlyBrace:
++this.state.pos;
this.finishToken(tt.braceL);
if (
this.hasPlugin("recordAndTuple") &&
this.input.charCodeAt(this.state.pos + 1) === charCodes.verticalBar
) {
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
throw this.raise(
this.state.pos,
Errors.RecordExpressionBarIncorrectStartSyntaxType,
);
}
// {|
this.finishToken(tt.braceBarL);
this.state.pos += 2;
} else {
++this.state.pos;
this.finishToken(tt.braceL);
}
return;
case charCodes.rightCurlyBrace:
++this.state.pos;

View File

@@ -93,9 +93,13 @@ export const types: { [name: string]: TokenType } = {
// Punctuation token types.
bracketL: new TokenType("[", { beforeExpr, startsExpr }),
bracketHashL: new TokenType("#[", { beforeExpr, startsExpr }),
bracketBarL: new TokenType("[|", { beforeExpr, startsExpr }),
bracketR: new TokenType("]"),
bracketBarR: new TokenType("|]"),
braceL: new TokenType("{", { beforeExpr, startsExpr }),
braceBarL: new TokenType("{|", { beforeExpr, startsExpr }),
braceHashL: new TokenType("#{", { beforeExpr, startsExpr }),
braceR: new TokenType("}"),
braceBarR: new TokenType("|}"),
parenL: new TokenType("(", { beforeExpr, startsExpr }),