/
syntax-parser.ts
141 lines (119 loc) · 3.78 KB
/
syntax-parser.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
import {readFileSync, writeFileSync} from 'fs';
import * as glob from 'glob';
import * as ts from 'typescript';
export interface Parameter {
kind: number;
name: string;
initializer?: any;
children?: Array<Parameter>
}
export function parse(sourceFile: ts.SourceFile): Object|undefined {
for (let statement of sourceFile.statements) {
let result = parseNode(statement);
if (result) {
return result;
}
}
}
export function parseNode(node: ts.Node): Object|undefined {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration:
return parseClassMembers(<ts.ClassDeclaration>node);
}
}
export function parseClassMembers(node: ts.ClassDeclaration): Object {
for (let member of node.members) {
let result = {className: node.name.text, parameters: parseClassMember(member)};
if (result.parameters) {
return result;
}
}
}
export function parseClassMember(node: ts.Node): Object|undefined {
switch (node.kind) {
case ts.SyntaxKind.MethodDeclaration:
return parseMethod(<ts.MethodDeclaration>node);
}
return;
}
export function parseMethod(method: ts.MethodDeclaration): Array<Parameter>|undefined {
let result: Array<Parameter>;
if ((<ts.Identifier>method.name).text === 'transform') {
result = parseParameters(method.parameters);
}
return result;
}
export function parseParameters(parameters: ts.NodeArray<ts.ParameterDeclaration>):
Array<Parameter> {
let result: Array<Parameter> = [];
parameters.forEach((parameter) => {
result.push(parseParameter(parameter));
});
return result;
}
export function parseParameter(parameter: ts.ParameterDeclaration): Parameter {
let result: Parameter;
if (parameter.type) {
result = parseType(parameter.name, parameter.initializer, parameter.type);
} else {
parameter;
}
return result;
}
export function parseType(name: ts.BindingName, initializer: any, type: ts.TypeNode): Parameter {
let result: Parameter = {name: (<ts.Identifier>name).text, kind: undefined};
if (initializer) {
result.initializer = initializer.text;
}
switch (type.kind) {
case ts.SyntaxKind.TypeLiteral:
result.kind = type.kind;
result.children = parseTypeLiteral(<ts.TypeLiteralNode>type);
break;
default:
result.kind = type.kind;
break;
}
return result;
}
export function parseTypeLiteral(typeLiteral: ts.TypeLiteralNode): Array<Parameter> {
return parseTypeLiteralMembers(typeLiteral.members);
}
export function parseTypeLiteralMembers(types: ts.NodeArray<ts.TypeElement>): Array<Parameter> {
let result: Array<Parameter> = [];
types.forEach((type: any) => {
type.parameters.forEach((param) => {
result.push(parseTypeLiteralMember(param));
});
});
return result;
}
export function parseTypeLiteralMember(type: any): Parameter {
let result: Parameter = {name: undefined, kind: undefined};
result.name = type.name.text;
result.kind = type.kind;
if (type.parameters) {
result.children = parseParameters(type.parameters);
}
return result;
}
// get all ng-pipes *.pipe.ts files
glob('./node_modules/ng-pipes/src/**/*.pipe.ts', {}, (error: Error, filePaths) => {
let result = {};
if (error) {
console.log(error.message);
} else {
filePaths.forEach(filePath => {
console.log(filePath);
let sourceFile = ts.createSourceFile(
filePath, readFileSync(filePath).toString(), ts.ScriptTarget.ES5, true);
let parseResult: any = parse(sourceFile);
let filePaths = filePath.split('/');
result[parseResult.className] = parseResult;
result[parseResult.className].fileName = filePaths[filePaths.length - 1];
result[parseResult.className].moduleName = filePaths[filePaths.length - 2];
});
}
let json = JSON.stringify(result);
writeFileSync('syntax.json', json, 'utf8');
});