-
Notifications
You must be signed in to change notification settings - Fork 679
/
block.ts
88 lines (76 loc) · 3.03 KB
/
block.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
import * as ts from 'typescript';
import { Reflection, ReflectionKind, ReflectionFlag } from '../../models/index';
import { createDeclaration } from '../factories/index';
import { Context } from '../context';
import { Component, ConverterNodeComponent } from '../components';
import { BindOption, SourceFileMode } from '../../utils';
const preferred: ts.SyntaxKind[] = [
ts.SyntaxKind.ClassDeclaration,
ts.SyntaxKind.InterfaceDeclaration,
ts.SyntaxKind.EnumDeclaration
];
@Component({name: 'node:block'})
export class BlockConverter extends ConverterNodeComponent<ts.SourceFile|ts.Block|ts.ModuleBlock> {
@BindOption('mode')
mode!: SourceFileMode;
/**
* List of supported TypeScript syntax kinds.
*/
supports: ts.SyntaxKind[] = [
ts.SyntaxKind.Block,
ts.SyntaxKind.ModuleBlock,
ts.SyntaxKind.SourceFile
];
/**
* Analyze the given class declaration node and create a suitable reflection.
*
* @param context The context object describing the current state the converter is in.
* @param node The class declaration node that should be analyzed.
* @return The resulting reflection or NULL.
*/
convert(context: Context, node: ts.SourceFile|ts.Block|ts.ModuleBlock): Reflection {
if (node.kind === ts.SyntaxKind.SourceFile) {
this.convertSourceFile(context, node);
} else {
this.convertStatements(context, node);
}
return context.scope;
}
/**
* Analyze the given source file node and create a suitable reflection.
*
* @param context The context object describing the current state the converter is in.
* @param node The source file node that should be analyzed.
* @return The resulting reflection or NULL.
*/
private convertSourceFile(context: Context, node: ts.SourceFile): Reflection | undefined {
let result: Reflection | undefined = context.scope;
context.withSourceFile(node, () => {
if (this.mode === SourceFileMode.Modules) {
result = createDeclaration(context, node, ReflectionKind.ExternalModule, node.fileName);
context.withScope(result, () => {
this.convertStatements(context, node);
result!.setFlag(ReflectionFlag.Exported);
});
} else {
this.convertStatements(context, node);
}
});
return result;
}
private convertStatements(context: Context, node: ts.SourceFile|ts.Block|ts.ModuleBlock) {
if (node.statements) {
const statements: ts.Statement[] = [];
node.statements.forEach((statement) => {
if (preferred.includes(statement.kind)) {
this.owner.convertNode(context, statement);
} else {
statements.push(statement);
}
});
statements.forEach((statement) => {
this.owner.convertNode(context, statement);
});
}
}
}