Skip to content

Commit ba4aad7

Browse files
author
Orta Therox
committed
Adds some docs for how a formatter works
1 parent a150d55 commit ba4aad7

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/services/formatting/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# How does TypeScript formatting work?
2+
3+
To format code you need to have a formatting context and a sourcefile. The formatting context contains
4+
all user settings like tab size, newline character, etc. The sourcefile is self explanatory.
5+
6+
The end result of formatting is represented by TextChange objects which hold the new string content, and
7+
the text to replace it with.
8+
9+
```ts
10+
export interface TextChange {
11+
span: TextSpan; // start, length
12+
newText: string;
13+
}
14+
```
15+
16+
## Internals
17+
18+
Most of the exposed APIs internally are `format*` and they all set up and configure `formatSpan` which could be considered the root call for formatting. Span in this case refers to the range of
19+
the sourcefile which should be formatted.
20+
21+
The formatSpan then uses a scanner (either with or without JSX support) which starts at the highest
22+
node the covers the span of text and recurses down through the node's children.
23+
24+
As it recurses, `processNode` is called on the children setting the indentation is decided and passed
25+
through into each of that node's children.
26+
27+
The meat of formatting decisions is made via `processPair`, the pair here being the current node and the previous node. `processPair` which mutates the formatting context to represent the current place in the scanner and requests a set of rules which can be applied to the items via `createRulesMap`.
28+
29+
There are a lot of rules, which you can find in [rules.ts](./rules.ts) each one has a left and right reference to nodes or token ranges and note of what action should be applied by the formatter.
30+
31+
### Where is this used?
32+
33+
The formatter is used mainly from the language service for formatting with an editor, but [services/textChanges.ts](/src/services/textChanges.ts) also uses this formatter when emitting code for quick fixes.
34+
35+
The formatter is not exported publicly, and so all usage comes through the language server.
36+
37+
### Sample code
38+
39+
```ts
40+
const nonFormattedText = `[js source code]`;
41+
const sourceFile = createSourceFile("any file name", nonFormattedText, ScriptTarget.ESNext, /*setParentNodes*/ true, ScriptKind.JS);
42+
const changes = formatting.formatDocument(sourceFile, formatContext);
43+
```

0 commit comments

Comments
 (0)