-
Notifications
You must be signed in to change notification settings - Fork 85
Expand file tree
/
Copy pathslangPrinter.ts
More file actions
110 lines (101 loc) · 4.04 KB
/
slangPrinter.ts
File metadata and controls
110 lines (101 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { isBlockComment } from './slang-utils/is-comment.js';
import { locEnd, locStart } from './slang-utils/loc.js';
import type { AstPath, Doc, ParserOptions } from 'prettier';
import type { AstNode, StrictAstNode } from './slang-nodes/types.d.ts';
import type { PrintFunction } from './types.d.ts';
import type { ArgumentsDeclaration } from './slang-nodes/ArgumentsDeclaration.js';
import type { ConstructorAttribute } from './slang-nodes/ConstructorAttribute.js';
import type { FallbackFunctionAttribute } from './slang-nodes/FallbackFunctionAttribute.js';
import type { FunctionAttribute } from './slang-nodes/FunctionAttribute.js';
import type { FunctionTypeAttribute } from './slang-nodes/FunctionTypeAttribute.js';
import type { ModifierAttribute } from './slang-nodes/ModifierAttribute.js';
import type { ReceiveFunctionAttribute } from './slang-nodes/ReceiveFunctionAttribute.js';
import type { StateVariableAttribute } from './slang-nodes/StateVariableAttribute.js';
import type { UnnamedFunctionAttribute } from './slang-nodes/UnnamedFunctionAttribute.js';
import type { ContractMember } from './slang-nodes/ContractMember.js';
import type { SourceUnitMember } from './slang-nodes/SourceUnitMember.js';
import type { Statement } from './slang-nodes/Statement.js';
import type { YulStatement } from './slang-nodes/YulStatement.js';
import type { ContractSpecifier } from './slang-nodes/ContractSpecifier.js';
import type { ElementaryType } from './slang-nodes/ElementaryType.js';
import type { ExperimentalFeature } from './slang-nodes/ExperimentalFeature.js';
function hasNodeIgnoreComment({ comments }: StrictAstNode): boolean {
// Prettier sets SourceUnit's comments to undefined after assigning comments
// to each node.
return Boolean(
comments?.some(
(comment) =>
comment.value
.slice(2, isBlockComment(comment) ? -2 : undefined)
.trim() === 'prettier-ignore'
)
);
}
function ignoreComments(path: AstPath<AstNode>): void {
const node = path.node;
// We ignore anything that is not an object
if (node === null || typeof node !== 'object') return;
let key: keyof StrictAstNode;
for (key in node) {
switch (key) {
// We ignore `kind`, `loc`, and `comments` since these are added by the
// parser. `updateMetadata` is an internal function.
case 'kind':
case 'loc':
case 'updateMetadata':
break;
// The key `comments` will contain every comment for this node.
case 'comments':
path.each((commentPath) => (commentPath.node.printed = true), key);
break;
default:
// If the value for that key is an Array or an Object we go deeper.
const childNode = node[key];
if (typeof childNode === 'object') {
if (Array.isArray(childNode)) {
path.each(ignoreComments, key);
return;
}
path.call(ignoreComments, key);
}
}
}
}
// Nodes take care of undefined and string properties so we can restrict path
// to AstPath<StrictAstNode>
function genericPrint(
path: AstPath<
Exclude<
StrictAstNode,
| ArgumentsDeclaration
| ConstructorAttribute
| FallbackFunctionAttribute
| FunctionAttribute
| FunctionTypeAttribute
| ModifierAttribute
| ReceiveFunctionAttribute
| StateVariableAttribute
| UnnamedFunctionAttribute
| ContractMember
| SourceUnitMember
| Statement
| YulStatement
| ContractSpecifier
| ElementaryType
| ExperimentalFeature
>
>,
options: ParserOptions<AstNode>,
print: PrintFunction
): Doc {
const node = path.node;
if (hasNodeIgnoreComment(node)) {
ignoreComments(path);
return options.originalText.slice(locStart(node), locEnd(node));
}
// Since each node has a print function with a specific AstPath, the union of
// all nodes into AstNode creates a print function with an AstPath of the
// intersection of all nodes. This forces us to cast this with a never type.
return node.print(path as AstPath<never>, print, options);
}
export default genericPrint;