Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
Reorganize to support potentially multiple languages
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed Jan 2, 2021
1 parent 6d739d0 commit 9e658db
Show file tree
Hide file tree
Showing 90 changed files with 138 additions and 107 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ In order to get printed, the code goes through a couple of transformations. The

### Text to AST

When the prettier process first spins up, it examines which files it's going to print and selects an appropriate plugin for each one. Once selected, it runs that plugin's `parse` function, seen [here](src/parser.js). For the case of the Ruby plugin, that entails spawning a Ruby process that runs [parser.rb](src/parser.rb) with the input code preloaded on stdin.
When the prettier process first spins up, it examines which files it's going to print and selects an appropriate plugin for each one. Once selected, it runs that plugin's `parse` function, seen [here](src/ruby/parser.js). For the case of the Ruby plugin, that entails spawning a Ruby process that runs [parser.rb](src/ruby/parser.rb) with the input code preloaded on stdin.

`parser.rb` will read the text off of stdin and then feed it to a new `Ripper` instance, which is a Ruby standard library recursive-descent parser. Briefly, the way that `Ripper` works is by tokenizing the input and then matching those tokens against a grammar to form s-expressions. To extend `Ripper`, you overwrite the methods that control how those s-expressions are formed, e.g., to modify the s-expression that is formed when `Ripper` encounters a string literal, you would override the `#on_string_literal` method. Below is an example for seeing that in action.

Expand Down Expand Up @@ -71,7 +71,7 @@ Now that the text has been transformed into an AST that we can work with, `parse

### AST to Doc

Once prettier has a working AST, it will take it and call the selected plugin's [`printNode` function](src/printer.js), whose purpose is to convert that AST into prettier's intermediate representation called Docs. It does this by handing the print function a `FastPath` object that keeps track of the state of the printing as it goes, and allows accessing various parts of the AST quickly.
Once prettier has a working AST, it will take it and call the selected plugin's [`printNode` function](src/ruby/printer.js), whose purpose is to convert that AST into prettier's intermediate representation called Docs. It does this by handing the print function a `FastPath` object that keeps track of the state of the printing as it goes, and allows accessing various parts of the AST quickly.

Effectively, it walks the AST in the reverse direction from the way `Ripper` built it (top-down instead of bottom-up). The first node that gets passed into the `print` function is the `program` node as that's always on top. Then it is the `program` node's responsibility to recursively call print on its child nodes as it best sees fit.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ The `prettier` executable is now installed and ready for use:

## Configuration

Below are the options (from [`src/ruby.js`](src/ruby.js)) that `@prettier/plugin-ruby` currently supports:
Below are the options (from [`src/plugin.js`](src/plugin.js)) that `@prettier/plugin-ruby` currently supports:

| API Option | CLI Option | Default | Description |
| ------------------ | ---------------------- | :-----: | ------------------------------------------------------------------------------------------------------------------------------------ |
Expand Down
2 changes: 1 addition & 1 deletion bin/debug
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ gemfile do
gem 'sinatra', require: 'sinatra/base'
end

require_relative '../src/parser'
require_relative '../src/ruby/parser'

class App < Sinatra::Base
HTML = DATA.read
Expand Down
2 changes: 1 addition & 1 deletion bin/pragma
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node

const fs = require("fs");
const { hasPragma } = require("../src/ruby").parsers.ruby;
const { hasPragma } = require("../src/plugin").parsers.ruby;

console.log(hasPragma(fs.readFileSync(process.argv[2], "utf-8")));
3 changes: 1 addition & 2 deletions bin/sexp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env ruby

require File.expand_path(File.join('..', 'src', 'parser.rb'), __dir__)

require_relative '../src/ruby/parser'
require 'pp'

PP.prepend(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@prettier/plugin-ruby",
"version": "1.2.2",
"description": "prettier plugin for the Ruby programming language",
"main": "src/ruby.js",
"main": "src/plugin.js",
"scripts": {
"check-format": "prettier --check '**/*'",
"lint": "eslint --cache .",
Expand Down
4 changes: 2 additions & 2 deletions src/ruby.js → src/plugin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const printer = require("./printer");
const parser = require("./parser");
const printer = require("./ruby/printer");
const parser = require("./ruby/parser");

/*
* metadata mostly pulled from linguist and rubocop:
Expand Down
4 changes: 2 additions & 2 deletions src/embed.js → src/ruby/embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const {
mapDoc,
markAsRoot,
stripTrailingHardline
} = require("./prettier");
} = require("../prettier");

const { literalLineNoBreak } = require("./utils");
const { literalLineNoBreak } = require("../utils");

const parsers = {
css: "css",
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/nodes/alias.js → src/ruby/nodes/alias.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const {
group,
hardline,
line
} = require("../prettier");
} = require("../../prettier");

// In general, return the printed doc of the argument at the provided index.
// Special handling is given for symbol literals that are not bare words, as we
Expand Down
9 changes: 8 additions & 1 deletion src/nodes/aref.js → src/ruby/nodes/aref.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const { concat, group, indent, join, line, softline } = require("../prettier");
const {
concat,
group,
indent,
join,
line,
softline
} = require("../../prettier");

// `aref` nodes are when you're pulling a value out of a collection at a
// specific index. Put another way, it's any time you're calling the method
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/args.js → src/ruby/nodes/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ const {
join,
line,
softline
} = require("../prettier");
} = require("../../prettier");
const { getTrailingComma } = require("../../utils");

const toProc = require("../toProc");
const { getTrailingComma } = require("../utils");

function printArgParen(path, opts, print) {
const argsNode = path.getValue().body[0];
Expand Down
5 changes: 2 additions & 3 deletions src/nodes/arrays.js → src/ruby/nodes/arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ const {
join,
line,
softline
} = require("../prettier");

const { getTrailingComma, printEmptyCollection } = require("../utils");
} = require("../../prettier");
const { getTrailingComma, printEmptyCollection } = require("../../utils");

// Checks that every argument within this args node is a string_literal node
// that has no spaces or interpolations. This means we're dealing with an array
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/assign.js → src/ruby/nodes/assign.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, group, indent, join, line } = require("../prettier");
const { skipAssignIndent } = require("../utils");
const { concat, group, indent, join, line } = require("../../prettier");
const { skipAssignIndent } = require("../../utils");

function printAssign(path, opts, print) {
const [_targetNode, valueNode] = path.getValue().body;
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/blocks.js → src/ruby/nodes/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const {
join,
removeLines,
softline
} = require("../prettier");
const { hasAncestor } = require("../utils");
} = require("../../prettier");
const { hasAncestor } = require("../../utils");

const printBlock = (braces) => (path, opts, print) => {
const [variables, statements] = path.getValue().body;
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/calls.js → src/ruby/nodes/calls.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const {
ifBreak,
indent,
softline
} = require("../prettier");
const { makeCall, noIndent } = require("../utils");
} = require("../../prettier");
const { makeCall, noIndent } = require("../../utils");

const toProc = require("../toProc");

Expand Down
2 changes: 1 addition & 1 deletion src/nodes/case.js → src/ruby/nodes/case.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
hardline,
indent,
line
} = require("../prettier");
} = require("../../prettier");

function printCase(path, opts, print) {
const statement = ["case"];
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/class.js → src/ruby/nodes/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const {
ifBreak,
indent,
line
} = require("../prettier");
} = require("../../prettier");

function printClass(path, opts, print) {
const [_constant, superclass, bodystmt] = path.getValue().body;
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/commands.js → src/ruby/nodes/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const {
join,
line,
softline
} = require("../prettier");
const { makeCall } = require("../utils");
} = require("../../prettier");
const { makeCall } = require("../../utils");

function docLength(doc) {
if (doc.length) {
Expand Down
6 changes: 3 additions & 3 deletions src/nodes/conditionals.js → src/ruby/nodes/conditionals.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ const {
ifBreak,
indent,
softline
} = require("../prettier");
} = require("../../prettier");

const { containsAssignment, isEmptyStmts } = require("../utils");
const inlineEnsureParens = require("../utils/inlineEnsureParens");
const { containsAssignment, isEmptyStmts } = require("../../utils");
const inlineEnsureParens = require("../../utils/inlineEnsureParens");

const printWithAddition = (keyword, path, print, { breaking = false } = {}) =>
concat([
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/constants.js → src/ruby/nodes/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, group, indent, join, softline } = require("../prettier");
const { makeCall } = require("../utils");
const { concat, group, indent, join, softline } = require("../../prettier");
const { makeCall } = require("../../utils");

function printConstPath(path, opts, print) {
return join("::", path.map(print, "body"));
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/flow.js → src/ruby/nodes/flow.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, join } = require("../prettier");
const { literal } = require("../utils");
const { concat, join } = require("../../prettier");
const { literal } = require("../../utils");

const nodeDive = (node, steps) => {
let current = node;
Expand Down
11 changes: 9 additions & 2 deletions src/nodes/hashes.js → src/ruby/nodes/hashes.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
const { concat, group, ifBreak, indent, join, line } = require("../prettier");
const {
concat,
group,
ifBreak,
indent,
join,
line
} = require("../../prettier");
const {
getTrailingComma,
printEmptyCollection,
skipAssignIndent
} = require("../utils");
} = require("../../utils");

// When attempting to convert a hash rocket into a hash label, you need to take
// care because only certain patterns are allowed. Ruby source says that they
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/heredocs.js → src/ruby/nodes/heredocs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, group, lineSuffix, join } = require("../prettier");
const { literalLineNoBreak } = require("../utils");
const { concat, group, lineSuffix, join } = require("../../prettier");
const { literalLineNoBreak } = require("../../utils");

function printHeredoc(path, opts, print) {
const { body, ending } = path.getValue();
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/hooks.js → src/ruby/nodes/hooks.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, group, indent, line } = require("../prettier");
const { isEmptyStmts } = require("../utils");
const { concat, group, indent, line } = require("../../prettier");
const { isEmptyStmts } = require("../../utils");

// The `BEGIN` and `END` keywords are used to hook into the Ruby process. Any
// `BEGIN` blocks are executed right when the process starts up, and the `END`
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions src/nodes/lambdas.js → src/ruby/nodes/lambdas.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, group, ifBreak, indent, line } = require("../prettier");
const { hasAncestor } = require("../utils");
const { concat, group, ifBreak, indent, line } = require("../../prettier");
const { hasAncestor } = require("../../utils");

// We can have our params coming in as the first child of the main lambda node,
// or if we have them wrapped in parens then they'll be one level deeper. Even
Expand Down
6 changes: 3 additions & 3 deletions src/nodes/loops.js → src/ruby/nodes/loops.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ const {
ifBreak,
indent,
softline
} = require("../prettier");
} = require("../../prettier");

const { containsAssignment } = require("../utils");
const inlineEnsureParens = require("../utils/inlineEnsureParens");
const { containsAssignment } = require("../../utils");
const inlineEnsureParens = require("../../utils/inlineEnsureParens");

function printLoop(keyword, modifier) {
return function printLoopWithOptions(path, { rubyModifier }, print) {
Expand Down
9 changes: 8 additions & 1 deletion src/nodes/massign.js → src/ruby/nodes/massign.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const { concat, group, indent, join, line, softline } = require("../prettier");
const {
concat,
group,
indent,
join,
line,
softline
} = require("../../prettier");

function printMAssign(path, opts, print) {
let right = path.call(print, "body", 1);
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/methods.js → src/ruby/nodes/methods.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { concat, group, hardline, indent, line } = require("../prettier");
const { concat, group, hardline, indent, line } = require("../../prettier");

function printMethod(offset) {
return function printMethodWithOffset(path, opts, print) {
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/operators.js → src/ruby/nodes/operators.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat, group, indent, line, softline } = require("../prettier");
const { noIndent } = require("../utils");
const { concat, group, indent, line, softline } = require("../../prettier");
const { noIndent } = require("../../utils");

function printBinary(path, opts, print) {
const [_leftNode, operator, rightNode] = path.getValue().body;
Expand Down
11 changes: 9 additions & 2 deletions src/nodes/params.js → src/ruby/nodes/params.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const { concat, group, join, indent, line, softline } = require("../prettier");
const { literal } = require("../utils");
const {
concat,
group,
join,
indent,
line,
softline
} = require("../../prettier");
const { literal } = require("../../utils");

function printRestParam(symbol) {
return function printRestParamWithSymbol(path, opts, print) {
Expand Down
9 changes: 8 additions & 1 deletion src/nodes/patterns.js → src/ruby/nodes/patterns.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const { concat, group, hardline, indent, join, line } = require("../prettier");
const {
concat,
group,
hardline,
indent,
join,
line
} = require("../../prettier");

const patterns = ["aryptn", "binary", "fndptn", "hshptn", "rassign"];

Expand Down
4 changes: 2 additions & 2 deletions src/nodes/regexp.js → src/ruby/nodes/regexp.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { concat } = require("../prettier");
const { hasAncestor } = require("../utils");
const { concat } = require("../../prettier");
const { hasAncestor } = require("../../utils");

function hasContent(node, pattern) {
return node.body.some(
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/rescue.js → src/ruby/nodes/rescue.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const {
indent,
join,
line
} = require("../prettier");
const { literal } = require("../utils");
} = require("../../prettier");
const { literal } = require("../../utils");

function printBegin(path, opts, print) {
return concat([
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/return.js → src/ruby/nodes/return.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const {
line,
join,
softline
} = require("../prettier");
const { literal } = require("../utils");
} = require("../../prettier");
const { literal } = require("../../utils");

// You can't skip the parentheses if you have the `and` or `or` operator,
// because they have low enough operator precedence that you need to explicitly
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/statements.js → src/ruby/nodes/statements.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {
literalline,
softline,
trim
} = require("../prettier");
} = require("../../prettier");

function printBodyStmt(path, opts, print) {
const [stmts, rescue, elseClause, ensure] = path.getValue().body;
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/strings.js → src/ruby/nodes/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
literalline,
softline,
join
} = require("../prettier");
} = require("../../prettier");

// If there is some part of this string that matches an escape sequence or that
// contains the interpolation pattern ("#{"), then we are locked into whichever
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/super.js → src/ruby/nodes/super.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { align, concat, group, join, line } = require("../prettier");
const { literal } = require("../utils");
const { align, concat, group, join, line } = require("../../prettier");
const { literal } = require("../../utils");

function printSuper(path, opts, print) {
const args = path.getValue().body[0];
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/undef.js → src/ruby/nodes/undef.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const {
group,
join,
line
} = require("../prettier");
} = require("../../prettier");

function printUndefSymbol(path, opts, print) {
const node = path.getValue();
Expand Down
File renamed without changes.
Loading

0 comments on commit 9e658db

Please sign in to comment.