forked from dsherret/ts-morph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJSDoc.ts
120 lines (106 loc) · 3.93 KB
/
JSDoc.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
import { removeChildren, replaceTextPossiblyCreatingChildNodes } from "../../../manipulation";
import { getPreviousMatchingPos } from "../../../manipulation/textSeek";
import { WriterFunction } from "../../../types";
import { ts } from "../../../typescript";
import { getTextFromStringOrWriter, StringUtils } from "../../../utils";
import { Node } from "../common";
import { JSDocTag } from "./JSDocTag";
import { JSDocStructure, JSDocSpecificStructure, StructureKind } from "../../../structures";
import { callBaseGetStructure } from "../callBaseGetStructure";
import { callBaseSet } from "../callBaseSet";
export const JSDocBase = Node;
/**
* JS doc node.
*/
export class JSDoc extends JSDocBase<ts.JSDoc> {
/**
* Gets the tags of the JSDoc.
*/
getTags(): JSDocTag[] {
const tags = this.compilerNode.tags;
if (tags == null)
return [];
return tags.map(t => this._getNodeFromCompilerNode(t));
}
/**
* Gets the comment.
*/
getComment() {
return this.compilerNode.comment;
}
/**
* Gets the JSDoc's text without the surrounding comment.
*/
getInnerText() {
const innerTextWithStars = this.getText().replace(/^\/\*\*[^\S\n]*\n?/, "").replace(/(\r?\n)?[^\S\n]*\*\/$/, "");
return innerTextWithStars.split(/\n/).map(line => {
const starPos = getStarPosIfFirstNonWhitespaceChar(line);
if (starPos === -1)
return line;
const substringStart = line[starPos + 1] === " " ? starPos + 2 : starPos + 1;
return line.substring(substringStart);
}).join("\n");
function getStarPosIfFirstNonWhitespaceChar(text: string) {
for (let i = 0; i < text.length; i++) {
const char = text[i];
if (char === "*")
return i;
else if (!StringUtils.isWhitespaceChar(char))
break;
}
return -1;
}
}
/**
* Sets the comment.
* @param textOrWriterFunction - Text or writer function to set.
*/
setComment(textOrWriterFunction: string | WriterFunction) {
const tags = this.getTags();
const startEditPos = this.getStart() + 3;
const endEditPos = tags.length > 0
? getPreviousMatchingPos(this._sourceFile.getFullText(), tags[0].getStart(), c => c === "*") - 1
: this.getEnd() - 2;
const indentationText = this.getIndentationText();
const newLineKind = this._context.manipulationSettings.getNewLineKindAsString();
const text = getTextFromStringOrWriter(this._getWriter(), textOrWriterFunction);
const lines = text.split(/\r?\n/).map(l => l.length === 0 ? `${indentationText} *` : `${indentationText} * ${l}`).join(newLineKind);
const newText = newLineKind + lines + newLineKind + indentationText + " ";
replaceTextPossiblyCreatingChildNodes({
parent: this,
newText,
replacePos: startEditPos,
replacingLength: endEditPos - startEditPos
});
return this;
}
/**
* Removes this JSDoc.
*/
remove() {
removeChildren({
children: [this],
removeFollowingSpaces: true,
removeFollowingNewLines: true
});
}
/**
* Sets the node from a structure.
* @param structure - Structure to set the node with.
*/
set(structure: Partial<JSDocStructure>) {
callBaseSet(JSDocBase.prototype, this, structure);
if (structure.description != null)
this.setComment(structure.description);
return this;
}
/**
* Gets the structure equivalent to this node.
*/
getStructure(): JSDocStructure {
return callBaseGetStructure<JSDocSpecificStructure>(JSDocBase.prototype, this, {
kind: StructureKind.JSDoc,
description: this.getInnerText() // good enough for now
});
}
}