Skip to content

Instantly share code, notes, and snippets.

@bradzacher
Created July 20, 2022 19:51
Show Gist options
  • Save bradzacher/69288d4c20a4ea9953cd3f462746e7da to your computer and use it in GitHub Desktop.
Save bradzacher/69288d4c20a4ea9953cd3f462746e7da to your computer and use it in GitHub Desktop.
diff --git a/node_modules/prettier/index.js b/node_modules/prettier/index.js
index 4d15c89..aef7249 100644
--- a/node_modules/prettier/index.js
+++ b/node_modules/prettier/index.js
@@ -48363,6 +48363,12 @@ var parsers$6 = {
return require$$1$3.parsers.flow;
},
+ // JS - hermes - flow
+ get hermes() {
+ const hermesParser = require('./parser-hermes.js');
+ return hermesParser.parsers.hermes;
+ },
+
// JS - TypeScript
get typescript() {
return require$$2$4.parsers.typescript;
@@ -48651,7 +48657,7 @@ var require$$5 = {
const languages$7 = [createLanguage(require$$0$6, data => ({
since: "0.0.0",
- parsers: ["babel", "espree", "meriyah", "babel-flow", "babel-ts", "flow", "typescript"],
+ parsers: ["babel", "espree", "meriyah", "babel-flow", "babel-ts", "flow", "typescript", "hermes"],
vscodeLanguageIds: ["javascript", "mongo"],
interpreters: [...data.interpreters, // https://github.com/google/zx
"zx"],
@@ -48661,7 +48667,7 @@ const languages$7 = [createLanguage(require$$0$6, data => ({
})), createLanguage(require$$0$6, () => ({
name: "Flow",
since: "0.0.0",
- parsers: ["flow", "babel-flow"],
+ parsers: ["flow", "babel-flow", "hermes"],
vscodeLanguageIds: ["javascript"],
aliases: [],
filenames: [],
@@ -48669,7 +48675,7 @@ const languages$7 = [createLanguage(require$$0$6, data => ({
})), createLanguage(require$$0$6, () => ({
name: "JSX",
since: "0.0.0",
- parsers: ["babel", "babel-flow", "babel-ts", "flow", "typescript", "espree", "meriyah"],
+ parsers: ["babel", "babel-flow", "babel-ts", "flow", "typescript", "espree", "meriyah", "hermes"],
vscodeLanguageIds: ["javascriptreact"],
aliases: undefined,
filenames: undefined,
diff --git a/node_modules/prettier/parser-hermes.js b/node_modules/prettier/parser-hermes.js
new file mode 100644
index 0000000..21be4fc
--- /dev/null
+++ b/node_modules/prettier/parser-hermes.js
@@ -0,0 +1,205 @@
+/**
+ * @format
+ */
+
+'use strict';
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/parse/utils/replace-hashbang.js
+function replaceHashbang(text) {
+ if (text.charAt(0) === '#' && text.charAt(1) === '!') {
+ return '//' + text.slice(2);
+ }
+
+ return text;
+}
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/utils/get-last.js
+const getLast = arr => arr[arr.length - 1];
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/utils/is-non-empty-array.js
+function isNonEmptyArray(object) {
+ return Array.isArray(object) && object.length > 0;
+}
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/loc.js#L9-L23
+function locStart(node, opts) {
+ const {ignoreDecorators} = opts || {};
+
+ // Handle nodes with decorators. They should start at the first decorator
+ if (!ignoreDecorators) {
+ const decorators =
+ (node.declaration && node.declaration.decorators) || node.decorators;
+
+ if (isNonEmptyArray(decorators)) {
+ return locStart(decorators[0]);
+ }
+ }
+
+ return node.range ? node.range[0] : node.start;
+}
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/loc.js#L25-L27
+function locEnd(node) {
+ return node.range ? node.range[1] : node.end;
+}
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/parse/postprocess/visit-node.js
+function visitNode(node, fn) {
+ if (Array.isArray(node)) {
+ // As of Node.js 16 using raw for loop over Array.entries provides a
+ // measurable difference in performance. Array.entries returns an iterator
+ // of arrays.
+ for (let i = 0; i < node.length; i++) {
+ node[i] = visitNode(node[i], fn);
+ }
+ return node;
+ }
+ if (node && typeof node === 'object' && typeof node.type === 'string') {
+ // As of Node.js 16 this is benchmarked to be faster over Object.entries.
+ // Object.entries returns an array of arrays. There are multiple ways to
+ // iterate over objects but the Object.keys combined with a for loop
+ // benchmarks well.
+ const keys = Object.keys(node);
+ for (let i = 0; i < keys.length; i++) {
+ node[keys[i]] = visitNode(node[keys[i]], fn);
+ }
+ return fn(node) || node;
+ }
+ return node;
+}
+
+// adapted from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/parse/postprocess/index.js
+function postprocess(ast, options) {
+ ast = visitNode(ast, node => {
+ switch (node.type) {
+ // Espree
+ case 'ChainExpression': {
+ return transformChainExpression(node.expression);
+ }
+ case 'LogicalExpression': {
+ // We remove unneeded parens around same-operator LogicalExpressions
+ if (isUnbalancedLogicalTree(node)) {
+ return rebalanceLogicalTree(node);
+ }
+ break;
+ }
+ // fix unexpected locEnd caused by --no-semi style
+ case 'VariableDeclaration': {
+ const lastDeclaration = getLast(node.declarations);
+ if (lastDeclaration && lastDeclaration.init) {
+ overrideLocEnd(node, lastDeclaration);
+ }
+ break;
+ }
+
+ case 'SequenceExpression': {
+ // Babel (unlike other parsers) includes spaces and comments in the range. Let's unify this.
+ const lastExpression = getLast(node.expressions);
+ node.range = [
+ locStart(node),
+ Math.min(locEnd(lastExpression), locEnd(node)),
+ ];
+ break;
+ }
+ }
+ });
+
+ return ast;
+
+ /**
+ * - `toOverrideNode` must be the last thing in `toBeOverriddenNode`
+ * - do nothing if there's a semicolon on `toOverrideNode.end` (no need to fix)
+ */
+ function overrideLocEnd(toBeOverriddenNode, toOverrideNode) {
+ if (options.originalText[locEnd(toOverrideNode)] === ';') {
+ return;
+ }
+ toBeOverriddenNode.range = [
+ locStart(toBeOverriddenNode),
+ locEnd(toOverrideNode),
+ ];
+ }
+}
+function transformChainExpression(node) {
+ switch (node.type) {
+ case 'CallExpression':
+ node.type = 'OptionalCallExpression';
+ node.callee = transformChainExpression(node.callee);
+ break;
+ case 'MemberExpression':
+ node.type = 'OptionalMemberExpression';
+ node.object = transformChainExpression(node.object);
+ break;
+ // typescript
+ case 'TSNonNullExpression':
+ node.expression = transformChainExpression(node.expression);
+ break;
+ // No default
+ }
+ return node;
+}
+function isUnbalancedLogicalTree(node) {
+ return (
+ node.type === 'LogicalExpression' &&
+ node.right.type === 'LogicalExpression' &&
+ node.operator === node.right.operator
+ );
+}
+function rebalanceLogicalTree(node) {
+ if (!isUnbalancedLogicalTree(node)) {
+ return node;
+ }
+
+ return rebalanceLogicalTree({
+ type: 'LogicalExpression',
+ operator: node.operator,
+ left: rebalanceLogicalTree({
+ type: 'LogicalExpression',
+ operator: node.operator,
+ left: node.left,
+ right: node.right.left,
+ range: [locStart(node.left), locEnd(node.right.left)],
+ }),
+ right: node.right.right,
+ range: [locStart(node), locEnd(node)],
+ });
+}
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/pragma.js#L19-L22
+function hasPragma(text) {
+ const pragmas = Object.keys(parseDocBlock(text).pragmas);
+ return pragmas.includes('prettier') || pragmas.includes('format');
+}
+
+// copied from https://github.com/prettier/prettier/blob/89f90fc01363c31e4c9b21f34e3f1942994b1565/src/language-js/parse/utils/create-parser.js
+function createParser(options) {
+ options = typeof options === 'function' ? {parse: options} : options;
+
+ return {
+ astFormat: 'estree',
+ hasPragma,
+ locStart,
+ locEnd,
+ ...options,
+ };
+}
+
+function parse(originalText, parsers, options = {}) {
+ const textToParse = replaceHashbang(originalText);
+
+ const {parse} = require('hermes-parser');
+ const result = parse(textToParse, {
+ allowReturnOutsideFunction: true,
+ flow: 'all',
+ sourceType: 'module',
+ tokens: true,
+ });
+
+ options.originalText = originalText;
+ return postprocess(result, options);
+}
+
+module.exports = {
+ parsers: {
+ hermes: createParser(parse),
+ },
+};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment