-
-
Notifications
You must be signed in to change notification settings - Fork 92
/
writeProcessor.ts
144 lines (121 loc) · 3.79 KB
/
writeProcessor.ts
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import opts from './commandOptions';
import { TypeDefinition } from './typeDefinition';
export type ReferenceResolver = (baseSchema: JsonSchemaOrg.Schema, ref: string) => TypeDefinition | undefined;
export class WriteProcessor {
public indentChar = ' ';
public indentStep = 4;
private indent = 0;
private results = '';
private alreadlyIndentThisLine = false;
private referenceStack: string[] = [];
constructor(private refResolver: ReferenceResolver) {}
get referenceResolve(): ReferenceResolver {
return this.refResolver;
}
public pushReference(referenceName: string): number {
return this.referenceStack.push(referenceName);
}
public popReference(): string | undefined {
return this.referenceStack.pop();
}
public checkCircularReference(referenceName: string): boolean {
return this.referenceStack.indexOf(referenceName) < 0;
}
public output(str: string): this {
this.doIndent();
this.results += str;
return this;
}
public outputType(type: string, primitive: boolean = false): this {
const prefix = opts.prefix;
if (prefix && !primitive) {
this.output(prefix);
}
type = type.replace(/[^0-9A-Za-z_$]/g, '_');
if (/^\d/.test(type)) {
type = '$' + type;
}
this.output(type);
return this;
}
public outputKey(name: string, optional: boolean = false): this {
if (/[^0-9A-Za-z_$]/.test(name) || /^\d/.test(name)) {
this.output('\"').output(name).output('\"');
} else {
this.output(name);
}
if (optional) {
this.output('?');
}
return this;
}
public outputLine(str?: string): this {
this.doIndent();
if (str) {
this.output(str);
}
this.output('\n');
this.alreadlyIndentThisLine = false;
return this;
}
private protectComment(str: string): string {
return str.replace(/\*\//g, '*\u200B/'); // Unicode [ZERO WIDTH SPACE]
}
public outputJSDoc(spec: any): this {
const { description, example } = spec;
if (!description && !example) {
return this;
}
this.outputLine('/**');
if (description) {
description.toString().split('\n').forEach((line: string) => {
this.output(' * ').outputLine(this.protectComment(line));
});
}
if (example) {
const split = example.toString().split('\n');
if (split.length === 1) {
this.outputLine(` * example: ${this.protectComment(example)}`);
} else {
this.outputLine(' * example:');
split.forEach((line: string) => {
this.output(' * ').outputLine(this.protectComment(line));
});
}
}
this.outputLine(' */');
return this;
}
public doIndent(): this {
if (!this.alreadlyIndentThisLine) {
const indent = this.getIndent();
this.results += indent;
this.alreadlyIndentThisLine = true;
}
return this;
}
get indentLevel(): number {
return this.indent;
}
public increaseIndent(): this {
this.indent++;
return this;
}
public decreaseIndent(): this {
this.indent--;
return this;
}
public getIndent(): string {
return this.repeatString(this.indent * this.indentStep, this.indentChar);
}
public repeatString(n: number, s: string): string {
let result = '';
for (let i = 0; i < n; i++) {
result += s;
}
return result;
}
public toDefinition(): string {
return this.results;
}
}