Skip to content

Commit

Permalink
Whiteblock-preferred, step 1
Browse files Browse the repository at this point in the history
  • Loading branch information
wcjohnson committed Sep 30, 2017
1 parent 0a87973 commit 1aded08
Show file tree
Hide file tree
Showing 66 changed files with 7,601 additions and 63 deletions.
4 changes: 4 additions & 0 deletions src/index.js
Expand Up @@ -37,4 +37,8 @@ export function getAvailablePlugins() {
return result;
}

export function getPluginMetadata() {
return pluginMetadata;
}

export { tokTypes };
107 changes: 90 additions & 17 deletions src/plugins/lightscript.js
Expand Up @@ -163,6 +163,36 @@ 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.parseNonemptyWhiteBlock = function(node, indentLevel) {
this.parseBlockBody(node, false, false, indentLevel);
if (!node.body.length) {
this.unexpected(node.start, "Expected an Indent or Statement");
}
};

pp.parseInlineWhiteBlock = function(node) {
if (this.state.type.startsExpr) return this.parseMaybeAssign();
// oneline statement case
Expand All @@ -179,9 +209,17 @@ pp.parseMultilineWhiteBlock = function(node, indentLevel) {
return this.parseObjectWhiteBlock(node, indentLevel);
}

this.parseBlockBody(node, false, false, indentLevel);
if (!node.body.length) {
this.unexpected(node.start, "Expected an Indent or Statement");
if (this.match(tt.braceL) && this.hasPlugin("whiteblockPreferred")) {
const objParseResult = this.tryParseObjectWhiteBlock(node, indentLevel);
if (objParseResult[0]) return objParseResult[0];

try {
this.parseNonemptyWhiteBlock(node, indentLevel);
} catch (err) {
this.rethrowObjParseError(objParseResult, err);
}
} else {
this.parseNonemptyWhiteBlock(node, indentLevel);
}

this.addExtra(node, "curly", false);
Expand All @@ -198,9 +236,25 @@ pp.parseWhiteBlock = function (isExpression?) {
return this.parseInlineWhiteBlock(node);
}

if (this.match(tt.braceL) && this.hasPlugin("whiteblockOnly")) {
// Parse as object
return this.parseObjectWhiteBlock(node, indentLevel);
if (this.match(tt.braceL)) {
if (this.hasPlugin("whiteblockOnly")) {
return this.parseObjectWhiteBlock(node, indentLevel);
}

let objParseResult = null;
if (this.hasPlugin("whiteblockPreferred")) {
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);
}
}
}

this.state.nestedBlockLevel++;
Expand Down Expand Up @@ -270,6 +324,35 @@ pp.parseArrowType = function (node) {

// largely c/p from parseFunctionBody

pp.parseBraceArrowFunctionBody = function(node, indentLevel) {
// In whiteblock-only mode, `{` must be introducing an object
if (this.hasPlugin("whiteblockOnly")) {
return this.parseObjectWhiteBlock(node, indentLevel);
}

// In whiteblock-preferred mode, try to parse an object, otherwise fall back on
// a braceblock.
if (this.hasPlugin("whiteblockPreferred")) {
const objParseResult = this.tryParseObjectWhiteBlock(node, indentLevel);
if (objParseResult[0]) return objParseResult[0];
this.next();

try {
this.parseBlockBody(node, true, false, tt.braceR);
} catch (err) {
this.rethrowObjParseError(objParseResult, err);
}

this.addExtra(node, "curly", true);
return this.finishNode(node, "BlockStatement");
}

this.next();
this.parseBlockBody(node, true, false, tt.braceR);
this.addExtra(node, "curly", true);
return this.finishNode(node, "BlockStatement");
};

pp.parseArrowFunctionBody = function (node) {
// set and reset state surrounding block
const oldInAsync = this.state.inAsync,
Expand All @@ -286,17 +369,7 @@ pp.parseArrowFunctionBody = function (node) {
this.expect(tt.arrow);
if (!this.isLineBreak()) {
if (this.match(tt.braceL)) {
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();
this.parseBlockBody(node.body, true, false, tt.braceR);
this.addExtra(node.body, "curly", true);
node.body = this.finishNode(node.body, "BlockStatement");
}
node.body = this.parseBraceArrowFunctionBody(this.startNode(), indentLevel);
} else {
node.body = this.parseInlineWhiteBlock(nodeAtArrow);
}
Expand Down
12 changes: 12 additions & 0 deletions src/registerPlugins.js
Expand Up @@ -14,10 +14,18 @@ import { matchCoreSyntax, match } from "./plugins/match";
function noncePlugin() {}

export default function registerPlugins(plugins, metadata) {
metadata._reverseDeps = {};

function registerPlugin(name, plugin, meta) {
if (!plugin) plugin = noncePlugin;
plugins[name] = plugin;
metadata[name] = meta;
if (meta && meta.dependencies) {
meta.dependencies.forEach( (dep) => {
if (!metadata._reverseDeps[dep]) metadata._reverseDeps[dep] = [];
metadata._reverseDeps[dep].push(name);
});
}
}

registerPlugin("doExpressions");
Expand Down Expand Up @@ -86,4 +94,8 @@ export default function registerPlugins(plugins, metadata) {
registerPlugin("whiteblockOnly", noncePlugin, {
dependencies: ["lightscript"]
});

registerPlugin("whiteblockPreferred", noncePlugin, {
dependencies: ["lightscript"]
});
}
2 changes: 1 addition & 1 deletion test/fixtures/comments/options.json
Expand Up @@ -7,7 +7,7 @@
},
"noLsc": {
"allPlugins": true,
"excludePlugins": ["lightscript", "match", "splatComprehension", "whiteblockOnly"]
"excludePlugins": ["lightscript", "match", "splatComprehension", "whiteblockOnly", "whiteblockPreferred"]
}
}
}
2 changes: 1 addition & 1 deletion test/fixtures/core/options.json
Expand Up @@ -8,7 +8,7 @@
},
"noLsc": {
"allPlugins": true,
"excludePlugins": ["lightscript", "match", "splatComprehension", "whiteblockOnly"]
"excludePlugins": ["lightscript"]
}
}
}
5 changes: 1 addition & 4 deletions test/fixtures/core/uncategorised/146/options.json
Expand Up @@ -8,10 +8,7 @@
},
"noTildeCalls": {
"allPlugins": true,
"excludePlugins": [
"lightscript", "match", "splatComprehension",
"whiteblockOnly", "tildeCallExpression"
],
"excludePlugins": [ "tildeCallExpression" ],
"expected": "expected.json"
}
}
Expand Down
5 changes: 4 additions & 1 deletion test/fixtures/core/uncategorised/19/options.json
@@ -1,7 +1,10 @@
{
"alternatives": {
"all": {
"throws": "Only normal whitespace (ascii-32) is allowed. (1:0)"
},
"noLsc": {
"excludePlugins": ["significantWhitespace", "bangCall", "enforceSubscriptIndentation", "lightscript", "match", "splatComprehension", "whiteblockOnly"]
"excludePlugins": ["significantWhitespace"]
}
}
}
3 changes: 0 additions & 3 deletions test/fixtures/core/uncategorised/19/options.lightscript.json

This file was deleted.

5 changes: 4 additions & 1 deletion test/fixtures/core/uncategorised/321/options.json
@@ -1,7 +1,10 @@
{
"alternatives": {
"all": {
"throws": "Only '\\n' and '\\r\\n' are legal newlines in significant-whitespace mode. (1:0)"
},
"noLsc": {
"excludePlugins": ["significantWhitespace", "bangCall", "enforceSubscriptIndentation", "splatComprehension", "whiteblockOnly"]
"excludePlugins": ["significantWhitespace"]
}
}
}
3 changes: 0 additions & 3 deletions test/fixtures/core/uncategorised/321/options.lightscript.json

This file was deleted.

5 changes: 4 additions & 1 deletion test/fixtures/core/uncategorised/542/options.json
@@ -1,7 +1,10 @@
{
"alternatives": {
"all": {
"throws": "Indentation required. (2:0)"
},
"noLsc": {
"excludePlugins": ["bangCall", "enforceSubscriptIndentation", "significantWhitespace", "splatComprehension", "whiteblockOnly"]
"excludePlugins": ["enforceSubscriptIndentation"]
}
}
}
3 changes: 0 additions & 3 deletions test/fixtures/core/uncategorised/542/options.lightscript.json

This file was deleted.

0 comments on commit 1aded08

Please sign in to comment.