UNPKG

9.83 kBJavaScriptView Raw
1"use strict";
2var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6 return c > 3 && r && Object.defineProperty(target, key, r), r;
7};
8var Converter_1;
9Object.defineProperty(exports, "__esModule", { value: true });
10const ts = require("typescript");
11const _ = require("lodash");
12const declaration_1 = require("../utils/options/declaration");
13const context_1 = require("./context");
14const components_1 = require("./components");
15const component_1 = require("../utils/component");
16const fs_1 = require("../utils/fs");
17const paths_1 = require("../utils/paths");
18let Converter = Converter_1 = class Converter extends component_1.ChildableComponent {
19 initialize() {
20 this.nodeConverters = {};
21 this.typeTypeConverters = [];
22 this.typeNodeConverters = [];
23 }
24 addComponent(name, componentClass) {
25 const component = super.addComponent(name, componentClass);
26 if (component instanceof components_1.ConverterNodeComponent) {
27 this.addNodeConverter(component);
28 }
29 else if (component instanceof components_1.ConverterTypeComponent) {
30 this.addTypeConverter(component);
31 }
32 return component;
33 }
34 addNodeConverter(converter) {
35 for (let supports of converter.supports) {
36 this.nodeConverters[supports] = converter;
37 }
38 }
39 addTypeConverter(converter) {
40 if ('supportsNode' in converter && 'convertNode' in converter) {
41 this.typeNodeConverters.push(converter);
42 this.typeNodeConverters.sort((a, b) => (b.priority || 0) - (a.priority || 0));
43 }
44 if ('supportsType' in converter && 'convertType' in converter) {
45 this.typeTypeConverters.push(converter);
46 this.typeTypeConverters.sort((a, b) => (b.priority || 0) - (a.priority || 0));
47 }
48 }
49 removeComponent(name) {
50 const component = super.removeComponent(name);
51 if (component instanceof components_1.ConverterNodeComponent) {
52 this.removeNodeConverter(component);
53 }
54 else if (component instanceof components_1.ConverterTypeComponent) {
55 this.removeTypeConverter(component);
56 }
57 return component;
58 }
59 removeNodeConverter(converter) {
60 const converters = this.nodeConverters;
61 const keys = _.keys(this.nodeConverters);
62 for (let key of keys) {
63 if (converters[key] === converter) {
64 delete converters[key];
65 }
66 }
67 }
68 removeTypeConverter(converter) {
69 const typeIndex = this.typeTypeConverters.indexOf(converter);
70 if (typeIndex !== -1) {
71 this.typeTypeConverters.splice(typeIndex, 1);
72 }
73 const nodeIndex = this.typeNodeConverters.indexOf(converter);
74 if (nodeIndex !== -1) {
75 this.typeNodeConverters.splice(nodeIndex, 1);
76 }
77 }
78 removeAllComponents() {
79 super.removeAllComponents();
80 this.nodeConverters = {};
81 this.typeTypeConverters = [];
82 this.typeNodeConverters = [];
83 }
84 convert(fileNames) {
85 const normalizedFiles = fileNames.map(fs_1.normalizePath);
86 const program = ts.createProgram(normalizedFiles, this.application.options.getCompilerOptions());
87 const checker = program.getTypeChecker();
88 const context = new context_1.Context(this, normalizedFiles, checker, program);
89 this.trigger(Converter_1.EVENT_BEGIN, context);
90 const errors = this.compile(context);
91 const project = this.resolve(context);
92 this.trigger(Converter_1.EVENT_END, context);
93 return {
94 errors: errors,
95 project: project
96 };
97 }
98 convertNode(context, node) {
99 if (context.visitStack.includes(node)) {
100 return;
101 }
102 const oldVisitStack = context.visitStack;
103 context.visitStack = oldVisitStack.slice();
104 context.visitStack.push(node);
105 let result;
106 if (node.kind in this.nodeConverters) {
107 result = this.nodeConverters[node.kind].convert(context, node);
108 }
109 context.visitStack = oldVisitStack;
110 return result;
111 }
112 convertType(context, node, type) {
113 if (node) {
114 type = type || context.getTypeAtLocation(node);
115 for (let converter of this.typeNodeConverters) {
116 if (converter.supportsNode(context, node, type)) {
117 return converter.convertNode(context, node, type);
118 }
119 }
120 }
121 if (type) {
122 for (let converter of this.typeTypeConverters) {
123 if (converter.supportsType(context, type)) {
124 return converter.convertType(context, type);
125 }
126 }
127 }
128 }
129 convertTypes(context, nodes = [], types = []) {
130 const result = [];
131 _.zip(nodes, types).forEach(([node, type]) => {
132 const converted = this.convertType(context, node, type);
133 if (converted) {
134 result.push(converted);
135 }
136 });
137 return result;
138 }
139 compile(context) {
140 const program = context.program;
141 const exclude = paths_1.createMinimatch(this.application.exclude || []);
142 const isExcluded = (file) => exclude.some(mm => mm.match(file.fileName));
143 const includedSourceFiles = program.getSourceFiles()
144 .filter(file => !isExcluded(file));
145 const isRelevantError = ({ file }) => !file || includedSourceFiles.includes(file);
146 includedSourceFiles.forEach((sourceFile) => {
147 this.convertNode(context, sourceFile);
148 });
149 let diagnostics = program.getOptionsDiagnostics().filter(isRelevantError);
150 if (diagnostics.length) {
151 return diagnostics;
152 }
153 diagnostics = program.getSyntacticDiagnostics().filter(isRelevantError);
154 if (diagnostics.length) {
155 return diagnostics;
156 }
157 diagnostics = program.getGlobalDiagnostics().filter(isRelevantError);
158 if (diagnostics.length) {
159 return diagnostics;
160 }
161 diagnostics = program.getSemanticDiagnostics().filter(isRelevantError);
162 if (diagnostics.length) {
163 return diagnostics;
164 }
165 return [];
166 }
167 resolve(context) {
168 this.trigger(Converter_1.EVENT_RESOLVE_BEGIN, context);
169 const project = context.project;
170 for (let id in project.reflections) {
171 if (!project.reflections.hasOwnProperty(id)) {
172 continue;
173 }
174 this.trigger(Converter_1.EVENT_RESOLVE, context, project.reflections[id]);
175 }
176 this.trigger(Converter_1.EVENT_RESOLVE_END, context);
177 return project;
178 }
179 getDefaultLib() {
180 return ts.getDefaultLibFileName(this.application.options.getCompilerOptions());
181 }
182};
183Converter.EVENT_BEGIN = 'begin';
184Converter.EVENT_END = 'end';
185Converter.EVENT_FILE_BEGIN = 'fileBegin';
186Converter.EVENT_CREATE_DECLARATION = 'createDeclaration';
187Converter.EVENT_CREATE_SIGNATURE = 'createSignature';
188Converter.EVENT_CREATE_PARAMETER = 'createParameter';
189Converter.EVENT_CREATE_TYPE_PARAMETER = 'createTypeParameter';
190Converter.EVENT_FUNCTION_IMPLEMENTATION = 'functionImplementation';
191Converter.EVENT_RESOLVE_BEGIN = 'resolveBegin';
192Converter.EVENT_RESOLVE = 'resolveReflection';
193Converter.EVENT_RESOLVE_END = 'resolveEnd';
194__decorate([
195 component_1.Option({
196 name: 'name',
197 help: 'Set the name of the project that will be used in the header of the template.'
198 })
199], Converter.prototype, "name", void 0);
200__decorate([
201 component_1.Option({
202 name: 'externalPattern',
203 help: 'Define patterns for files that should be considered being external.',
204 type: declaration_1.ParameterType.Array
205 })
206], Converter.prototype, "externalPattern", void 0);
207__decorate([
208 component_1.Option({
209 name: 'includeDeclarations',
210 help: 'Turn on parsing of .d.ts declaration files.',
211 type: declaration_1.ParameterType.Boolean
212 })
213], Converter.prototype, "includeDeclarations", void 0);
214__decorate([
215 component_1.Option({
216 name: 'excludeExternals',
217 help: 'Prevent externally resolved TypeScript files from being documented.',
218 type: declaration_1.ParameterType.Boolean
219 })
220], Converter.prototype, "excludeExternals", void 0);
221__decorate([
222 component_1.Option({
223 name: 'excludeNotExported',
224 help: 'Prevent symbols that are not exported from being documented.',
225 type: declaration_1.ParameterType.Boolean
226 })
227], Converter.prototype, "excludeNotExported", void 0);
228__decorate([
229 component_1.Option({
230 name: 'excludePrivate',
231 help: 'Ignores private variables and methods',
232 type: declaration_1.ParameterType.Boolean
233 })
234], Converter.prototype, "excludePrivate", void 0);
235__decorate([
236 component_1.Option({
237 name: 'excludeProtected',
238 help: 'Ignores protected variables and methods',
239 type: declaration_1.ParameterType.Boolean
240 })
241], Converter.prototype, "excludeProtected", void 0);
242Converter = Converter_1 = __decorate([
243 component_1.Component({ name: 'converter', internal: true, childClass: components_1.ConverterComponent })
244], Converter);
245exports.Converter = Converter;
246//# sourceMappingURL=converter.js.map
\No newline at end of file