Skip to content

Commit

Permalink
Initial whiteblockOnly impl, test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
wcjohnson committed Sep 28, 2017
1 parent 5aa3ee5 commit afd89a2
Show file tree
Hide file tree
Showing 97 changed files with 992 additions and 8,569 deletions.
6 changes: 6 additions & 0 deletions src/parser/statement.js
Expand Up @@ -588,6 +588,9 @@ pp.parseExpressionStatement = function (node, expr) {
// function bodies).

pp.parseBlock = function (allowDirectives?) {
if (this.hasPlugin("whiteblockOnly")) {
this.unexpected(null, "Brace-delimited blocks are illegal in whiteblock-only mode.");
}
const node = this.startNode();
this.expect(tt.braceL);
this.parseBlockBody(node, allowDirectives, false, tt.braceR);
Expand Down Expand Up @@ -806,6 +809,9 @@ pp.parseClassBody = function (node) {
this.next();
isEnd = () => this.state.indentLevel <= indentLevel || this.match(tt.eof);
} else {
if (this.hasPlugin("whiteblockOnly")) {
this.unexpected(null, "Brace-delimited blocks are illegal in whiteblock-only mode.");
}
this.expect(tt.braceL);
isEnd = () => this.eat(tt.braceR);
}
Expand Down
99 changes: 27 additions & 72 deletions src/plugins/lightscript.js
Expand Up @@ -137,6 +137,7 @@ pp.parseObjectComprehension = function(node) {

// Parse a whiteblock body consisting of a single object expr.
pp.parseObjectWhiteBlock = function(node, blockIndentLevel) {
const errorPos = this.state.start;
const exprStmt = this.startNode();
const obj = this.parseMaybeAssign();

Expand All @@ -146,10 +147,11 @@ pp.parseObjectWhiteBlock = function(node, blockIndentLevel) {
// A tilde call can begin with { if an ObjectExpression is the thisArg.
(obj.type !== "CallExpression" || !obj.tilde)
) {
throw new Error("WRONG_SPECULATIVE_BRANCH");
this.unexpected(errorPos, "Expected an object.");
}

if (this.state.indentLevel > blockIndentLevel) {
throw new Error("WRONG_SPECULATIVE_BRANCH");
this.unexpected(errorPos, "Expected an object.");
}

exprStmt.expression = obj;
Expand All @@ -161,29 +163,6 @@ pp.parseObjectWhiteBlock = function(node, blockIndentLevel) {
return this.finishNode(node, "BlockStatement");
};

pp.tryParseObjectWhiteBlock = function(node, blockIndentLevel) {
const state = this.state.clone();
try {
return [this.parseObjectWhiteBlock(node, blockIndentLevel)];
} catch (err) {
this.state = state;
return [null, err];
}
};

pp.rethrowObjParseError = function(objParseResult, blockParseError) {
const objParseError = objParseResult ? objParseResult[1] : null;
if (objParseError) {
if (objParseError.message === "WRONG_SPECULATIVE_BRANCH") {
throw blockParseError;
} else {
throw objParseError;
}
} else {
throw blockParseError;
}
};

pp.parseInlineWhiteBlock = function(node) {
if (this.state.type.startsExpr) return this.parseMaybeAssign();
// oneline statement case
Expand All @@ -196,24 +175,13 @@ pp.parseInlineWhiteBlock = function(node) {
};

pp.parseMultilineWhiteBlock = function(node, indentLevel) {
let objParseResult = null;
if (this.match(tt.braceL) && this.hasPlugin("objectBlockAmbiguity_preferObject")) {
objParseResult = this.tryParseObjectWhiteBlock(node, indentLevel);
if (objParseResult[0]) return objParseResult[0];
if (this.match(tt.braceL) && this.hasPlugin("whiteblockOnly")) {
return this.parseObjectWhiteBlock(node, indentLevel);
}

try {
this.parseBlockBody(node, false, false, indentLevel);
if (!node.body.length) {
this.unexpected(node.start, "Expected an Indent or Statement");
}
} catch (err) {
this.rethrowObjParseError(objParseResult, err);
}
} else {
this.parseBlockBody(node, false, false, indentLevel);
if (!node.body.length) {
this.unexpected(node.start, "Expected an Indent or Statement");
}
this.parseBlockBody(node, false, false, indentLevel);
if (!node.body.length) {
this.unexpected(node.start, "Expected an Indent or Statement");
}

this.addExtra(node, "curly", false);
Expand All @@ -226,24 +194,19 @@ pp.parseWhiteBlock = function (isExpression?) {

// Oneline whiteblock
if (!this.isLineBreak()) {
let objParseResult = null;

if (isExpression) {
return this.parseInlineWhiteBlock(node);
}

if (this.match(tt.braceL) && this.hasPlugin("objectBlockAmbiguity_preferObject")) {
objParseResult = this.tryParseObjectWhiteBlock(node, indentLevel);
if (objParseResult[0]) return objParseResult[0];
}
try {
this.state.nestedBlockLevel++;
const stmt = this.parseStatement(false);
this.state.nestedBlockLevel--;
return stmt;
} catch (err) {
this.rethrowObjParseError(objParseResult, err);
if (this.match(tt.braceL) && this.hasPlugin("whiteblockOnly")) {
// Parse as object
return this.parseObjectWhiteBlock(node, indentLevel);
}

this.state.nestedBlockLevel++;
const stmt = this.parseStatement(false);
this.state.nestedBlockLevel--;
return stmt;
}

// TODO: document the fact that directives aren't parsed
Expand Down Expand Up @@ -323,24 +286,14 @@ pp.parseArrowFunctionBody = function (node) {
this.expect(tt.arrow);
if (!this.isLineBreak()) {
if (this.match(tt.braceL)) {
let objParseResult = null;

if (this.hasPlugin("objectBlockAmbiguity_preferObject")) {
objParseResult = this.tryParseObjectWhiteBlock(nodeAtArrow, indentLevel);
if (objParseResult[0]) node.body = objParseResult[0];
}

// If we couldn't parse an object...
if (!node.body) {
if (this.hasPlugin("whiteblockOnly")) {
// In whiteblock mode, arrows that start with `{` must be object exprs
node.body = this.parseObjectWhiteBlock(nodeAtArrow, indentLevel);
} else {
// restart node at brace start instead of arrow start
node.body = this.startNode();
this.next();
try {
this.parseBlockBody(node.body, true, false, tt.braceR);
} catch (err) {
node.body = null;
this.rethrowObjParseError(objParseResult, err);
}
this.parseBlockBody(node.body, true, false, tt.braceR);
this.addExtra(node.body, "curly", true);
node.body = this.finishNode(node.body, "BlockStatement");
}
Expand Down Expand Up @@ -587,8 +540,7 @@ export default function (instance) {
// first, try paren-free style
try {
const val = this.parseExpression();
// "as" for `match (foo) as bar:`, bit dirty to allow for all but not a problem
if (this.match(tt.braceL) || this.match(tt.colon) || this.isContextual("as")) {
if (this.match(tt.braceL) || this.match(tt.colon)) {
if (val.extra && val.extra.parenthesized) {
delete val.extra.parenthesized;
delete val.extra.parenStart;
Expand Down Expand Up @@ -677,6 +629,9 @@ export default function (instance) {
if (this.match(tt.colon)) {
return this.parseWhiteBlock();
}
if (this.hasPlugin("whiteblockOnly")) {
this.unexpected(null, tt.colon);
}
const block = inner.apply(this, arguments);
this.addExtra(block, "curly", true);
return block;
Expand Down
10 changes: 4 additions & 6 deletions src/registerPlugins.js
Expand Up @@ -76,16 +76,14 @@ export default function registerPlugins(plugins, metadata) {
]
});

// Speculatively parse whiteblocks and arrows beginning with `{`,
// preferring to parse as ObjectExpressions when possible.
registerPlugin("objectBlockAmbiguity_preferObject", noncePlugin, {
dependencies: ["lightscript"]
});

// Parse identifiers beginning with `_` or another user-chosen symbol
// as PlaceholderExpressions.
registerPlugin("syntacticPlaceholder", syntacticPlaceholderPlugin);

// |> infix operator for piped function calls
registerPlugin("pipeCall", pipeCallPlugin);

registerPlugin("whiteblockOnly", noncePlugin, {
dependencies: ["lightscript"]
});
}
@@ -1,11 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected { (2:7)"
},
"noLsc": {
"allPlugins": true,
"excludePlugins": ["lightscript", "match", "enhancedComprehension", "objectBlockAmbiguity_preferObject"]
"throws": "Unexpected token, expected : (2:7)"
}
}
}

This file was deleted.

@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (2:18)"
}
}
}
@@ -1,3 +1,8 @@
{
"sourceType": "module"
"sourceType": "module",
"alternatives": {
"all": {
"throws": "Brace-delimited blocks are illegal in whiteblock-only mode. (4:21)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:13)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:13)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:13)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:13)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:13)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:18)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:16)"
}
}
}
@@ -0,0 +1,7 @@
{
"alternatives": {
"all": {
"throws": "Unexpected token, expected : (1:35)"
}
}
}
7 changes: 6 additions & 1 deletion test/fixtures/comments/options.json
Expand Up @@ -2,7 +2,12 @@
"alternatives": {
"all": {
"allPlugins": true,
"excludePlugins": ["estree"]
"optionsOverride": "options.lightscript.json",
"expected": "expected.lightscript.json"
},
"noLsc": {
"allPlugins": true,
"excludePlugins": ["lightscript", "match", "enhancedComprehension", "whiteblockOnly"]
}
}
}
3 changes: 2 additions & 1 deletion test/fixtures/core/options.json
Expand Up @@ -2,12 +2,13 @@
"alternatives": {
"all": {
"allPlugins": true,
"excludePlugins": ["whiteblockOnly"],
"optionsOverride": "options.lightscript.json",
"expected": "expected.lightscript.json"
},
"noLsc": {
"allPlugins": true,
"excludePlugins": ["lightscript", "match", "enhancedComprehension", "objectBlockAmbiguity_preferObject"]
"excludePlugins": ["lightscript", "match", "enhancedComprehension", "whiteblockOnly"]
}
}
}
2 changes: 1 addition & 1 deletion test/fixtures/core/uncategorised/146/options.json
Expand Up @@ -10,7 +10,7 @@
"allPlugins": true,
"excludePlugins": [
"lightscript", "match", "enhancedComprehension",
"objectBlockAmbiguity_preferObject", "tildeCallExpression"
"whiteblockOnly", "tildeCallExpression"
],
"expected": "expected.json"
}
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/core/uncategorised/19/options.json
@@ -1,7 +1,7 @@
{
"alternatives": {
"noLsc": {
"excludePlugins": ["significantWhitespace", "bangCall", "enforceSubscriptIndentation", "lightscript", "match", "enhancedComprehension", "objectBlockAmbiguity_preferObject"]
"excludePlugins": ["significantWhitespace", "bangCall", "enforceSubscriptIndentation", "lightscript", "match", "enhancedComprehension", "whiteblockOnly"]
}
}
}
2 changes: 1 addition & 1 deletion test/fixtures/core/uncategorised/321/options.json
@@ -1,7 +1,7 @@
{
"alternatives": {
"noLsc": {
"excludePlugins": ["significantWhitespace", "bangCall", "enforceSubscriptIndentation", "enhancedComprehension", "objectBlockAmbiguity_preferObject"]
"excludePlugins": ["significantWhitespace", "bangCall", "enforceSubscriptIndentation", "enhancedComprehension", "whiteblockOnly"]
}
}
}
2 changes: 1 addition & 1 deletion test/fixtures/core/uncategorised/542/options.json
@@ -1,7 +1,7 @@
{
"alternatives": {
"noLsc": {
"excludePlugins": ["bangCall", "enforceSubscriptIndentation", "significantWhitespace", "enhancedComprehension", "objectBlockAmbiguity_preferObject"]
"excludePlugins": ["bangCall", "enforceSubscriptIndentation", "significantWhitespace", "enhancedComprehension", "whiteblockOnly"]
}
}
}

0 comments on commit afd89a2

Please sign in to comment.