esrap 1.1.1 → 1.2.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/src/index.js CHANGED
@@ -39,10 +39,14 @@ export function print(node, opts = {}) {
39
39
  );
40
40
  }
41
41
 
42
- const chunks = handle(node, {
43
- indent: '',
44
- comments: []
45
- });
42
+ /** @type {import('./types').State} */
43
+ const state = {
44
+ commands: [],
45
+ comments: [],
46
+ multiline: false
47
+ };
48
+
49
+ handle(node, state);
46
50
 
47
51
  /** @typedef {[number, number, number, number]} Segment */
48
52
 
@@ -55,22 +59,12 @@ export function print(node, opts = {}) {
55
59
  /** @type {Segment[]} */
56
60
  let current_line = [];
57
61
 
58
- for (let i = 0; i < chunks.length; i += 1) {
59
- const chunk = chunks[i];
60
-
61
- code += chunk.content;
62
-
63
- if (chunk.loc) {
64
- current_line.push([
65
- current_column,
66
- 0, // source index is always zero
67
- chunk.loc.start.line - 1,
68
- chunk.loc.start.column
69
- ]);
70
- }
62
+ /** @param {string} str */
63
+ function append(str) {
64
+ code += str;
71
65
 
72
- for (let i = 0; i < chunk.content.length; i += 1) {
73
- if (chunk.content[i] === '\n') {
66
+ for (let i = 0; i < str.length; i += 1) {
67
+ if (str[i] === '\n') {
74
68
  mappings.push(current_line);
75
69
  current_line = [];
76
70
  current_column = 0;
@@ -78,17 +72,77 @@ export function print(node, opts = {}) {
78
72
  current_column += 1;
79
73
  }
80
74
  }
75
+ }
76
+
77
+ let newline = '\n';
78
+
79
+ /** @param {import('./types').Command} command */
80
+ function run(command) {
81
+ if (typeof command === 'string') {
82
+ append(command);
83
+ return;
84
+ }
81
85
 
82
- if (chunk.loc) {
83
- current_line.push([
84
- current_column,
85
- 0, // source index is always zero
86
- chunk.loc.end.line - 1,
87
- chunk.loc.end.column
88
- ]);
86
+ switch (command.type) {
87
+ case 'Chunk':
88
+ const loc = command.loc;
89
+
90
+ if (loc) {
91
+ current_line.push([
92
+ current_column,
93
+ 0, // source index is always zero
94
+ loc.start.line - 1,
95
+ loc.start.column
96
+ ]);
97
+ }
98
+
99
+ append(command.content);
100
+
101
+ if (loc) {
102
+ current_line.push([
103
+ current_column,
104
+ 0, // source index is always zero
105
+ loc.end.line - 1,
106
+ loc.end.column
107
+ ]);
108
+ }
109
+
110
+ break;
111
+
112
+ case 'Newline':
113
+ append(newline);
114
+ break;
115
+
116
+ case 'Indent':
117
+ newline += '\t';
118
+ break;
119
+
120
+ case 'Dedent':
121
+ newline = newline.slice(0, -1);
122
+ break;
123
+
124
+ case 'Sequence':
125
+ for (let i = 0; i < command.children.length; i += 1) {
126
+ run(command.children[i]);
127
+ }
128
+
129
+ break;
130
+
131
+ case 'Comment':
132
+ if (command.comment.type === 'Line') {
133
+ append(`//${command.comment.value}`);
134
+ } else {
135
+ append(`/*${command.comment.value.replace(/\n/g, newline)}*/`);
136
+ }
137
+
138
+ break;
89
139
  }
90
140
  }
91
141
 
142
+ for (let i = 0; i < state.commands.length; i += 1) {
143
+ run(state.commands[i]);
144
+ }
145
+
92
146
  mappings.push(current_line);
93
147
 
94
148
  const map = {
package/src/types.d.ts CHANGED
@@ -2,22 +2,52 @@ import { Comment, Node } from 'estree';
2
2
 
3
3
  type NodeOf<T extends string, X> = X extends { type: T } ? X : never;
4
4
 
5
- type Handler<T> = (node: T, state: State) => Chunk[];
5
+ type Handler<T> = (node: T, state: State) => undefined;
6
6
 
7
7
  export type Handlers = {
8
8
  [K in Node['type']]: Handler<NodeOf<K, Node>>;
9
9
  };
10
10
 
11
11
  export interface State {
12
- indent: string;
12
+ commands: Command[];
13
13
  comments: Comment[];
14
+ multiline: boolean;
14
15
  }
15
16
 
16
17
  export interface Chunk {
18
+ type: 'Chunk';
17
19
  content: string;
18
20
  loc: null | {
19
21
  start: { line: number; column: number };
20
22
  end: { line: number; column: number };
21
23
  };
22
- has_newline: boolean;
23
24
  }
25
+
26
+ export interface Newline {
27
+ type: 'Newline';
28
+ }
29
+
30
+ export interface Indent {
31
+ type: 'Indent';
32
+ }
33
+
34
+ export interface Dedent {
35
+ type: 'Dedent';
36
+ }
37
+
38
+ export interface IndentChange {
39
+ type: 'IndentChange';
40
+ offset: number;
41
+ }
42
+
43
+ export interface Sequence {
44
+ type: 'Sequence';
45
+ children: Command[];
46
+ }
47
+
48
+ export interface CommentChunk {
49
+ type: 'Comment';
50
+ comment: Comment;
51
+ }
52
+
53
+ export type Command = string | Chunk | Newline | Indent | Dedent | Sequence | CommentChunk;