forked from dsherret/ts-morph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConstructorDeclaration.ts
107 lines (93 loc) · 4.76 KB
/
ConstructorDeclaration.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
import * as getStructureFuncs from "../../../manipulation/helpers/getStructureFunctions";
import { ConstructorDeclarationOverloadStructure, ConstructorDeclarationOverloadSpecificStructure, ConstructorDeclarationStructure,
ConstructorDeclarationSpecificStructure, StructureKind, OptionalKind} from "../../../structures";
import { SyntaxKind, ts } from "../../../typescript";
import { BodyableNode, ChildOrderableNode, ScopedNode, TextInsertableNode, SignaturedDeclaration, ModifierableNode, JSDocableNode, TypeParameteredNode } from "../base";
import { callBaseSet } from "../callBaseSet";
import { FunctionLikeDeclaration, insertOverloads, OverloadableNode } from "../function";
import { callBaseGetStructure } from "../callBaseGetStructure";
import { ClassElement } from "./ClassElement";
export const ConstructorDeclarationBase = ChildOrderableNode(TextInsertableNode(OverloadableNode(ScopedNode(FunctionLikeDeclaration(BodyableNode(ClassElement))))));
export const ConstructorDeclarationOverloadBase = TypeParameteredNode(JSDocableNode(ChildOrderableNode(TextInsertableNode(ScopedNode(ModifierableNode(
SignaturedDeclaration(ClassElement)
))))));
export class ConstructorDeclaration extends ConstructorDeclarationBase<ts.ConstructorDeclaration> {
/**
* Sets the node from a structure.
* @param structure - Structure to set the node with.
*/
set(structure: Partial<ConstructorDeclarationStructure>) {
callBaseSet(ConstructorDeclarationBase.prototype, this, structure);
if (structure.overloads != null) {
this.getOverloads().forEach(o => o.remove());
this.addOverloads(structure.overloads);
}
return this;
}
/**
* Add a constructor overload.
* @param structure - Structure to add.
*/
addOverload(structure: OptionalKind<ConstructorDeclarationOverloadStructure>) {
return this.addOverloads([structure])[0];
}
/**
* Add constructor overloads.
* @param structures - Structures to add.
*/
addOverloads(structures: ReadonlyArray<OptionalKind<ConstructorDeclarationOverloadStructure>>) {
return this.insertOverloads(this.getOverloads().length, structures);
}
/**
* Inserts a constructor overload.
* @param index - Child index to insert at.
* @param structure - Structures to insert.
*/
insertOverload(index: number, structure: OptionalKind<ConstructorDeclarationOverloadStructure>) {
return this.insertOverloads(index, [structure])[0];
}
/**
* Inserts constructor overloads.
* @param index - Child index to insert at.
* @param structures - Structures to insert.
*/
insertOverloads(index: number, structures: ReadonlyArray<OptionalKind<ConstructorDeclarationOverloadStructure>>) {
const childCodes = structures.map(structure => `constructor();`);
return insertOverloads<ConstructorDeclaration, OptionalKind<ConstructorDeclarationOverloadStructure>>({
node: this,
index,
structures,
childCodes,
getThisStructure: getStructureFuncs.fromConstructorDeclarationOverload,
setNodeFromStructure: (node, structure) => node.set(structure),
expectedSyntaxKind: SyntaxKind.Constructor
});
}
/**
* Gets the structure equivalent to this node.
*/
getStructure(): ConstructorDeclarationStructure | ConstructorDeclarationOverloadStructure {
const hasImplementation = this.getImplementation() != null;
const isOverload = this.isOverload();
const basePrototype = isOverload && hasImplementation ? ConstructorDeclarationOverloadBase.prototype : ConstructorDeclarationBase.prototype;
return callBaseGetStructure<any>(basePrototype, this, getStructure(this)) as ConstructorDeclarationStructure | ConstructorDeclarationOverloadStructure;
function getStructure(thisNode: ConstructorDeclaration) {
// this is not the best typing... unit tests will catch issues though
if (hasImplementation && isOverload)
return getSpecificOverloadStructure();
return getSpecificStructure();
function getSpecificOverloadStructure(): ConstructorDeclarationOverloadSpecificStructure {
return { kind: StructureKind.ConstructorOverload };
}
function getSpecificStructure(): ConstructorDeclarationSpecificStructure {
if (!hasImplementation)
return { kind: StructureKind.Constructor };
else
return {
kind: StructureKind.Constructor,
overloads: thisNode.getOverloads().map(o => o.getStructure() as ConstructorDeclarationOverloadStructure)
};
}
}
}
}