@putout/printer 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ChangeLog ADDED
@@ -0,0 +1,4 @@
1
+ 2023.03.17, v1.4.0
2
+
3
+ feature:
4
+ - 1faf3ff @putout/printer: add support of leadingComments
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [NPMIMGURL]: https://img.shields.io/npm/v/@putout/printer.svg?style=flat&longCache=true
4
4
  [NPMURL]: https://npmjs.org/package/@putout/printer "npm"
5
5
 
6
- **EasyPrint** prints [**Babel AST**](https://github.com/coderaiser/estree-to-babel) to readable **JavaScript**.
6
+ **@putout/printer** prints [**Babel AST**](https://github.com/coderaiser/estree-to-babel) to readable **JavaScript**.
7
7
 
8
8
  - ☝️ Similar to **Recast**, but simpler and easier in maintenance, since it supports only **Babel**.
9
9
  - ☝️ As opinionated as **Prettier**, but has more user-friendly output and works directly with **AST**.
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ module.exports.parseComments = (path, {write}) => {
4
+ const {leadingComments} = path.node;
5
+
6
+ if (leadingComments)
7
+ parseLeadingComments(path, {write});
8
+ };
9
+
10
+ function parseLeadingComments(path, {write}) {
11
+ const {leadingComments} = path.node;
12
+
13
+ for (const {value}of leadingComments) {
14
+ write(`//${value}`);
15
+ write.newline();
16
+ }
17
+ }
@@ -1,13 +1,16 @@
1
1
  'use strict';
2
2
 
3
- const {hasPrevNewline} = require('../mark');
3
+ const {
4
+ hasPrevNewline,
5
+ isMarkedParentBefore,
6
+ } = require('../mark');
4
7
 
5
8
  const {entries} = Object;
6
9
 
7
10
  module.exports.CallExpression = (path, {traverse, indent, write, incIndent, decIndent, maybeWrite}) => {
8
11
  const isParentCall = toLong(path) && path.parentPath.isCallExpression();
9
12
 
10
- if (shouldAddNewLine(path) && !hasPrevNewline(path.parentPath)) {
13
+ if (shouldAddNewLine(path) && !hasPrevNewline(path.parentPath) && !isMarkedParentBefore(path)) {
11
14
  write.newline();
12
15
  write.indent();
13
16
  }
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ const {isMarkedPrevAfter} = require('../mark');
3
4
  const isFirst = (path) => path.node === path.parentPath.node.body[0];
4
5
 
5
6
  module.exports.ArrowFunctionExpression = (path, {write, traverse}) => {
@@ -38,7 +39,7 @@ module.exports.ObjectMethod = (path, {write, traverse}) => {
38
39
  };
39
40
 
40
41
  module.exports.FunctionDeclaration = (path, {write, traverse}) => {
41
- if (!isFirst(path))
42
+ if (!isFirst(path) && !isMarkedPrevAfter(path))
42
43
  write('\n');
43
44
 
44
45
  write('function ');
@@ -13,8 +13,8 @@ const {AssignmentExpression} = require('./assignment-expression');
13
13
  const {ArrayExpression} = require('./array-expression');
14
14
  const {ArrayPattern} = require('./array-pattern');
15
15
  const {AssignmentPattern} = require('./assignment-pattern');
16
- const {RestElement} = require('./RestElement');
17
- const {SpreadElement} = require('./SpreadElement');
16
+ const {RestElement} = require('./rest-element');
17
+ const {SpreadElement} = require('./spread-element');
18
18
 
19
19
  module.exports = {
20
20
  ...functions,
@@ -11,48 +11,58 @@ const isForOf = (path) => {
11
11
  return false;
12
12
  };
13
13
 
14
- module.exports.ObjectExpression = (path, {traverse, write, maybeWrite, maybeIndent, incIndent, decIndent}) => {
15
- incIndent();
14
+ const isFirstMethod = (path) => path.get('properties.0').isObjectMethod();
15
+
16
+ module.exports.ObjectExpression = (path, {traverse, write, maybe, indent}) => {
17
+ indent.inc();
16
18
 
17
19
  const properties = path.get('properties');
18
20
  const parens = isBodyOfArrow(path);
19
21
  const isCall = path.parentPath.isCallExpression();
20
- const isOneLine = isCall && properties.length < 2 || isForOf(path);
22
+ const {length} = properties;
23
+ const isOneLine = !length || isCall && length < 2 && !isFirstMethod(path) || isForOf(path);
21
24
 
22
- maybeWrite(parens, '(');
25
+ maybe.write(parens, '(');
23
26
  write('{');
24
27
 
25
- maybeWrite(!isOneLine, '\n');
28
+ maybe.write(!isOneLine, '\n');
26
29
 
27
30
  for (const property of properties) {
28
31
  if (property.isSpreadElement()) {
32
+ maybe.indent(properties.length > 1);
29
33
  traverse(property);
34
+
35
+ if (properties.length > 1) {
36
+ write(',');
37
+ write.newline();
38
+ }
39
+
30
40
  continue;
31
41
  }
32
42
 
33
43
  const {shorthand, computed} = property.node;
34
44
 
35
- maybeIndent(!isOneLine);
45
+ maybe.indent(!isOneLine);
36
46
 
37
47
  if (property.isObjectMethod()) {
38
48
  traverse(property);
39
49
  continue;
40
50
  }
41
51
 
42
- maybeWrite(computed, '[');
52
+ maybe.write(computed, '[');
43
53
  traverse(property.get('key'));
44
- maybeWrite(computed, ']');
54
+ maybe.write(computed, ']');
45
55
 
46
56
  if (!shorthand) {
47
57
  write(': ');
48
58
  traverse(property.get('value'));
49
59
  }
50
60
 
51
- maybeWrite(!isOneLine, ',\n');
61
+ maybe.write(!isOneLine, ',\n');
52
62
  }
53
63
 
54
- decIndent();
55
- maybeIndent(!isOneLine);
64
+ indent.dec();
65
+ maybe.indent(!isOneLine);
56
66
  write('}');
57
- maybeWrite(parens, ')');
67
+ maybe.write(parens, ')');
58
68
  };
@@ -9,6 +9,9 @@ function unaryExpressions(path, {traverse, write}) {
9
9
  if (prefix)
10
10
  write(operator);
11
11
 
12
+ if (operator === 'typeof')
13
+ write(' ');
14
+
12
15
  traverse(path.get('argument'));
13
16
 
14
17
  if (!prefix)
@@ -2,4 +2,3 @@
2
2
 
3
3
  module.exports.isPrevBody = (path) => path.getPrevSibling().isBlockStatement();
4
4
  module.exports.isNext = (path) => path.getNextSibling().node;
5
-
@@ -1,21 +1,40 @@
1
1
  'use strict';
2
2
 
3
- const WATER_MARK = '__putout_newline';
3
+ const WATER_MARK_BEFORE = '__putout_newline_before';
4
+ const WATER_MARK_AFTER = '__putout_newline_after';
4
5
 
5
- module.exports.mark = mark;
6
+ module.exports.markBefore = markBefore;
7
+ module.exports.markAfter = markAfter;
6
8
 
7
- function mark(path) {
8
- path[WATER_MARK] = true;
9
+ function markBefore(path) {
10
+ path[WATER_MARK_BEFORE] = true;
9
11
  }
10
12
 
11
- module.exports.isMarked = isMarked;
13
+ function markAfter(path) {
14
+ path[WATER_MARK_AFTER] = true;
15
+ }
16
+
17
+ module.exports.isMarkedBefore = isMarkedBefore;
18
+ module.exports.isMarkedAfter = isMarkedAfter;
19
+
20
+ function isMarkedBefore(path) {
21
+ return path[WATER_MARK_BEFORE];
22
+ }
12
23
 
13
- function isMarked(path) {
14
- return path[WATER_MARK];
24
+ function isMarkedAfter(path) {
25
+ return path[WATER_MARK_AFTER];
15
26
  }
16
27
 
17
28
  module.exports.hasPrevNewline = (path) => {
18
- return isMarked(path.getPrevSibling());
29
+ return isMarkedAfter(path.getPrevSibling());
19
30
  };
20
31
 
21
- module.exports.maybeMark = (a, path) => a && mark(path);
32
+ module.exports.maybeMarkAfter = (a, path) => a && markAfter(path);
33
+
34
+ module.exports.isMarkedParentBefore = (path) => {
35
+ return isMarkedBefore(path.parentPath);
36
+ };
37
+
38
+ module.exports.isMarkedPrevAfter = (path) => {
39
+ return isMarkedAfter(path.getPrevSibling());
40
+ };
@@ -1,8 +1,16 @@
1
1
  'use strict';
2
2
 
3
+ const {
4
+ markBefore,
5
+ markAfter,
6
+ isMarkedPrevAfter,
7
+ } = require('../mark');
8
+ const {isNext} = require('../is');
9
+
3
10
  module.exports.ExpressionStatement = (path, {write, indent, traverse}) => {
4
- if (isCoupleLinesExpression(path) && !isFirst(path) && shouldAddNewLine(path)) {
11
+ if (isCoupleLinesExpression(path) && !isFirst(path) && shouldAddNewLine(path) && !isMarkedPrevAfter(path)) {
5
12
  write.linebreak();
13
+ markBefore(path);
6
14
  }
7
15
 
8
16
  const expressionPath = path.get('expression');
@@ -12,8 +20,10 @@ module.exports.ExpressionStatement = (path, {write, indent, traverse}) => {
12
20
  write(';');
13
21
  write.newline();
14
22
 
15
- if (isStrictMode(path))
23
+ if (isStrictMode(path) || isCoupleLinesExpression(path) && isNext(path)) {
16
24
  write.newline();
25
+ markAfter(path);
26
+ }
17
27
  };
18
28
 
19
29
  function isCoupleLinesExpression(path) {
@@ -1,12 +1,13 @@
1
1
  'use strict';
2
2
 
3
+ const {isMarkedAfter} = require('../mark');
3
4
  const isPrevNewLine = (path) => {
4
5
  const prev = path.getPrevSibling();
5
6
 
6
7
  if (!prev.node)
7
8
  return true;
8
9
 
9
- return prev.__putout_newline;
10
+ return isMarkedAfter(prev);
10
11
  };
11
12
 
12
13
  module.exports.ForOfStatement = (path, {write, indent, traverse}) => {
@@ -36,9 +37,4 @@ module.exports.ForOfStatement = (path, {write, indent, traverse}) => {
36
37
  write(' ');
37
38
  traverse(bodyPath);
38
39
  }
39
-
40
- if (path.getNextSibling().node) {
41
- //write.newline();
42
- //path.__putout_newline = true;
43
- }
44
40
  };
@@ -31,7 +31,7 @@ module.exports.VariableDeclaration = (path, {write, maybe, maybeIndent, traverse
31
31
 
32
32
  maybe.indent(is);
33
33
  maybe.write(is, '\n');
34
- maybe.mark(is, path);
34
+ maybe.markAfter(is, path);
35
35
  };
36
36
  function isCoupleLinesExpression(path) {
37
37
  const start = path.node?.loc?.start.line;
@@ -6,7 +6,11 @@ const statements = require('./statements');
6
6
  const literals = require('./literals');
7
7
  const {TYPES} = require('../types');
8
8
  const {createDebug} = require('./debug');
9
- const {maybeMark} = require('./mark');
9
+ const {
10
+ maybeMarkAfter,
11
+ maybeMarkBefore,
12
+ } = require('./mark');
13
+ const {parseComments} = require('./comments');
10
14
 
11
15
  const {assign} = Object;
12
16
 
@@ -68,7 +72,8 @@ module.exports.tokenize = (ast) => {
68
72
  const maybe = {
69
73
  write: maybeWrite,
70
74
  indent: maybeIndent,
71
- mark: maybeMark,
75
+ markBefore: maybeMarkBefore,
76
+ markAfter: maybeMarkAfter,
72
77
  };
73
78
 
74
79
  const printer = {
@@ -101,6 +106,7 @@ module.exports.tokenize = (ast) => {
101
106
  if (!currentTraverse)
102
107
  throw Error(`Node type '${type}' is not supported yet: '${path}'`);
103
108
 
109
+ parseComments(path, printer);
104
110
  currentTraverse(path, printer);
105
111
  debug(path.type);
106
112
  }
package/package.json CHANGED
@@ -1,14 +1,11 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "type": "commonjs",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "Easiest possible opinionated Babel AST printer made with ❤️ to use in 🐊Putout",
7
7
  "homepage": "https://github.com/putoutjs/printer#readme",
8
8
  "main": "./lib/printer.js",
9
- "release": false,
10
- "tag": false,
11
- "changelog": false,
12
9
  "exports": {
13
10
  ".": "./lib/printer.js"
14
11
  },
@@ -25,6 +22,7 @@
25
22
  "lint:fresh": "madrun lint:fresh",
26
23
  "fix:lint": "madrun fix:lint",
27
24
  "coverage": "madrun coverage",
25
+ "coverage:html": "madrun coverage:html",
28
26
  "report": "madrun report"
29
27
  },
30
28
  "dependencies": {